如何创建一个新命令来框选两个单词的每个字母

如何创建一个新命令来框选两个单词的每个字母

我曾经使用其他语言做过很多编程,但对 LaTeX 还很陌生。

最好参考下面的文档:

\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}

在此处输入图片描述

版本 1 的结果符合我的要求。但我想创建一个新命令,以便简化语法。我不想输入所有单个字母,而是只给出两个单词。所以我只想输入:\boxwords{ABCDE}{.GH..} 来生成相同的方框单词。

我的第一次尝试是版本 2。

问题 A:末尾有一个空白的额外列。我知道这是由于&每个单词的最后一个字母的尾部所致。在其他编程语言中,我知道如何隐藏循环末尾的最后一个 &,但不确定如何在 Latex 中做到这一点?

问题 B:我不希望出现点。我只是希望它们成为函数输入中的占位符,这样它们就会以空格的形式出现。

我尝试在版本 3 中直接放入空格,但空格不但不会造成空框,反而会导致框遗漏。

答案1

关键是\seq_use:Nn生成表格行。首先我们设置包含两个项目的序列(更改.为后\relax),使其长度相等并打印表格。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

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

\seq_new:N \l_suhada_boxwords_a_seq
\seq_new:N \l_suhada_boxwords_b_seq
\tl_new:N \l_suhada_boxwords_temp_tl

\cs_new_protected:Nn \suhada_boxwords:nn
 {
  % replace . with \scan_stop: in the first argument
  % and set the first sequence
  \tl_set:Nn \l_suhada_boxwords_temp_tl { #1 }
  \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { . } { \scan_stop: }
  \seq_set_split:NnV \l_suhada_boxwords_a_seq { } \l_suhada_boxwords_temp_tl
  % replace . with \scan_stop: in the first argument
  % and set the first sequence
  \tl_set:Nn \l_suhada_boxwords_temp_tl { #2 }
  \tl_replace_all:Nnn \l_suhada_boxwords_temp_tl { . } { \scan_stop: }
  \seq_set_split:NnV \l_suhada_boxwords_b_seq { } \l_suhada_boxwords_temp_tl
  % make the same number of items in both sequences
  \int_compare:nT
   {
    \seq_count:N \l_suhada_boxwords_a_seq < \seq_count:N \l_suhada_boxwords_b_seq
   }
   {
    \prg_replicate:nn
     {
      \seq_count:N \l_suhada_boxwords_b_seq - \seq_count:N \l_suhada_boxwords_a_seq
     }
     {
      \seq_put_right:Nn \l_suhada_boxwords_a_seq { \scan_stop: }
     }
   }
  \int_compare:nT
   {
    \seq_count:N \l_suhada_boxwords_b_seq < \seq_count:N \l_suhada_boxwords_a_seq
   }
   {
    \prg_replicate:nn
     {
      \seq_count:N \l_suhada_boxwords_a_seq - \seq_count:N \l_suhada_boxwords_b_seq
     }
     {
      \seq_put_right:Nn \l_suhada_boxwords_b_seq { \scan_stop: }
     }
   }
  % print the table
  \begin{tabular}{|*{\seq_count:N \l_suhada_boxwords_a_seq}{c|}}
  \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}

在此处输入图片描述

答案2

Expl3 有布尔值其用法与其他语言中的布尔值类似。要创建空框,您可以使用{}空组。

\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}

相关内容