# How to create a new command which will box every letter of two words

I've done lots of programming in other languages but very new to LaTeX.

Best to refer to the document below:

\documentclass{book}
\usepackage{xparse}

\begin{document}

Version 1

\begin{tabular}{| c | c | c | c | c |}
\hline
A & B & C & D & E \\\hline
& G & H &   &   \\\hline
\end{tabular}
\\
\\

\ExplSyntaxOn
\NewDocumentCommand{\stringprocess}{ m m }
{
\egreg_string_process:nn { #1 } { #2 }
}
\cs_new_protected:Npn \egreg_string_process:nn #1 #2
{
\tl_map_inline:nn { #2 } { #1 { ##1 } }
}
\ExplSyntaxOff

\newcommand{\boxchar}[1]{#1 &}

\newcommand{\boxwords}[2]{
\begin{tabular}{| c | c | c | c | c | c | c | c | c |}
\hline
\stringprocess{\boxchar}{#1}
\\\hline
\stringprocess{\boxchar}{#2}
\\\hline
\end{tabular}
}

Version 2

\boxwords{ABCDE}{ GH  }
\\
\\

Version 3

\boxwords{ABCDE}{.GH..}
\\
\\

\end{document}


Version 1 comes out as I would want it. But I want to create a new command to allow easier syntax. Rather than type all the individual letters I want to just give the two words. So I want to just type: \boxwords{ABCDE}{.GH..} to produce the same boxed words.

My first attempt is Version 2.

Issue A: There's an extra column on the end with blank. I understand that this comes from the trailing & on the last letter of each word. In other programming languages I'd know how to suppress this last & at the end of the loop but not sure how to do this in Latex?

Issue B: I don't want the dots to appear. I just wanted them to be placeholders in the input to the function so that they come out as spaces.

I tried just putting the spaces in directly in Version 3 but rather than cause empty boxes, the spaces cause boxes to be missed out.

The key is \seq_use:Nn for producing the table rows. First we set sequences containing the two items (after changing . into \relax), make their length equal and print the table.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\boxwords}{mm}
{
\suhada_boxwords:nn { #1 } { #2 }
}

{
% replace . with \scan_stop: in the first argument
% and set the first sequence
\tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { . } { \scan_stop: }
% replace . with \scan_stop: in the first argument
% and set the first sequence
\tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { . } { \scan_stop: }
% make the same number of items in both sequences
\int_compare:nT
{
}
{
\prg_replicate:nn
{
}
{
}
}
\int_compare:nT
{
}
{
\prg_replicate:nn
{
}
{
}
}
% print the table
\hline
\seq_use:Nn \l_suhada_boxwords_a_seq { & } \\
\hline
\seq_use:Nn \l_suhada_boxwords_b_seq { & } \\
\hline
\end{tabular}
}
\ExplSyntaxOff

\begin{document}

\boxwords{ABCDE}{.GH}

\bigskip

\boxwords{ABCDE}{.GH..}

\bigskip

\boxwords{ABC..}{.GH.I}

\end{document}


• Thanks egreg for your reply - works really well. I like your defensive programming style - for instance allowing for strings to be different length. – Adahus Aug 15 '16 at 12:16
• The line: \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { . } { \scan_stop: } solves my problem of replacing the dots. I also want to replace some other characters. I want to replace * with the multiply symbol. To test the principle I tried adding: \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { * } { m } and that works fine. I tried: \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { * } { $\times$ } but I get an error: Extra }, or forgotten $. Can't see what is wrong? – Adahus Aug 15 '16 at 12:54 • @Suhada You need braces around $\times$, so it is considered a single item when the splitting takes place: \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { * } { {$\times\$} } – egreg Aug 15 '16 at 12:57

Expl3 has booleans which can be used similar to the bools from other languages. To create the empty boxes, you can use {} for empty groups.

\documentclass{book}
\usepackage{xparse}

\begin{document}
\ExplSyntaxOn
\bool_new:N\l_is_first_bool
\NewDocumentCommand{\stringprocess}{ m m }
{
\bool_set_true:N\l_is_first_bool
\tl_map_inline:nn{#2}{#1{##1}\l_is_first_bool\bool_set_false:N\l_is_first_bool}
}

\newcommand{\boxchar}[2]{\bool_if:NTF#2{}{&}#1}
\ExplSyntaxOff

\newcommand{\boxwords}[2]{
\begin{tabular}{| c | c | c | c | c | c | c | c | c |}
\hline
\stringprocess{\boxchar}{#1}
\\\hline
\stringprocess{\boxchar}{#2}
\\\hline
\end{tabular}
}

Version 2

\boxwords{ABCDE}{{}GH{}{}}
\end{document}

• Thanks zauguin for your reply - helps me understand more about how latex programming works. I've decided to go with the sequence approach as it fits with my further development. – Adahus Aug 15 '16 at 12:15