This is extensible by adding character translations. It uses the standard array
environment.
The idea is to change an input such as |bo|x|
into
\multicolumn{1}{|c}{\__fukai_mymacro_char:n{b}} &
\multicolumn{1}{c|}{\__fukai_mymacro_char:n{o}} &
\multicolumn{1}{c|}{\__fukai_mymacro_char:n{x}}
where the last function translates b
into a phantom, just to be sure it occupies the same space as the other characters, o
into \bigcirc
and x
into \bigotimes
.
The search regular expression means: find zero or one occurrences of |
followed by a letter and zero or one occurrences of |
. This is replaced by \multicolumn
as shown above. At the end of this multiple replacement we need to remove an unwanted trailing &
.
The number of columns is computed by examining the arguments and passing +1
for anything that's not |
.
\documentclass{article}
\usepackage{array}
\ExplSyntaxOn
\NewDocumentCommand{\mymacro}{mm}
{
\fukai_mymacro:nn { #1 } { #2 }
}
\tl_new:N \l__fukai_mymacro_a_tl
\tl_new:N \l__fukai_mymacro_b_tl
\cs_new_protected:Nn \fukai_mymacro:nn
{
% normalize the input
\__fukai_mymacro_normalize:Nn \l__fukai_mymacro_a_tl { #1 }
\__fukai_mymacro_normalize:Nn \l__fukai_mymacro_b_tl { #2 }
% start the array with the suitable number of columns
\begin{array}
{
* { \int_max:nn { \__fukai_mymacro_count:n { #1 } } { \__fukai_mymacro_count:n { #1 } } } { c }
}
\tl_use:N \l__fukai_mymacro_a_tl
\\ \hline
\tl_use:N \l__fukai_mymacro_b_tl
\end{array}
}
\cs_new_protected:Nn \__fukai_mymacro_normalize:Nn
{
\tl_set:Nn #1 { #2 }
\regex_replace_all:nnN
{ (\|)??([[:alpha:]])(\|?) } % |<char>|
{ \c{multicolumn}\{1\}\{\1 c \3\}\{ \c{__fukai_mymacro_char:n}\{\2\} \} \& }
#1
\regex_replace_once:nnN { \& \Z } { } #1
}
% count the non-| characters
\cs_new:Nn \__fukai_mymacro_count:n
{
\int_eval:n { 0 + \str_map_function:nN { #1 } \__fukai_mymacro_ischar:n }
}
\cs_new:Nn \__fukai_mymacro_ischar:n
{
\str_if_eq:nnF { #1 } { | } { +1 }
}
% the translations
\cs_new:Nn \__fukai_mymacro_char:n
{
\str_case:nn { #1 }
{
{b}{\phantom{\bigcirc}}
{o}{\bigcirc}
{x}{\bigotimes}
}
}
\ExplSyntaxOff
\begin{document}
$\mymacro{|b|b|ooo|x|}{oooooo}$
\bigskip
$\mymacro{|bo|x|}{o|x|b}$
\bigskip
$
\begin{array}{ccc}
\multicolumn{1}{|c}{} & \multicolumn{1}{c|}{\bigcirc} & \multicolumn{1}{c|}{\bigotimes}
\\\hline
\multicolumn{1}{c|}{\bigcirc} & \multicolumn{1}{c|}{\bigotimes} & \multicolumn{1}{c}{}
\end{array}
$
\end{document}
In the image, the third array is “hand made” to show the result is the same as with the second array done with \mymacro
.
