我曾经使用其他语言做过很多编程,但对 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}