这个问题确实非常类似于创建一个命令,将输入的字符串逐个标记地连接起来,但解决方案可能看起来不同,而且我在阅读必要的命令时遇到了困难(所有资源似乎都非常技术性并且很难进入)。
使用expl3
和tikz-cd
我想要将字符串 A_1;f_1;A_2;f_2;...;A_n
(存储在#1
)转换为图表:
\begin{tikzcd}
A_1 \ar[r, "f_1"] & A_2 \ar[r, "f_2"] & ... & A_n
\end{tikzcd}
这里的困难当然是,我的“解析器”的行为在每个标记处都会切换。我该如何实现这一点?
答案1
有几个问题;首先您需要ampersand replacement
,因为您tikzcd
作为宏的一部分进行调用。
其次,在使用图表之前,您需要构建图表的主体。
该策略是将输入按序列拆分,然后映射它但区分奇数和偶数索引条目。
\documentclass{article}
\usepackage{xparse,tikz-cd}
\ExplSyntaxOn
\NewDocumentCommand{\exactsequence}{ O{} m }
{
\perko_exactsequence:nn { #1 } { #2 }
}
\seq_new:N \l_perko_exactsequence_data_seq
\tl_new:N \l_perko_exactsequence_body_tl
\cs_new_protected:Nn \perko_exactsequence:nn
{
\seq_set_split:Nnn \l_perko_exactsequence_data_seq { ; } { #2 }
\tl_set:Nn \l_perko_exactsequence_body_tl
{
\begin{tikzcd}[ampersand~replacement=\&,#1]
}
\int_step_inline:nnnn { 1 } { 1 } { \seq_count:N \l_perko_exactsequence_data_seq }
{
\int_if_odd:nTF { ##1 }
{
\tl_put_right:Nx \l_perko_exactsequence_body_tl
{
\seq_item:Nn \l_perko_exactsequence_data_seq { ##1 }
}
}
{
\tl_put_right:Nx \l_perko_exactsequence_body_tl
{
\exp_not:N \ar [ r , "\seq_item:Nn \l_perko_exactsequence_data_seq { ##1 }" ]
\exp_not:N \&
}
}
}
\tl_put_right:Nn \l_perko_exactsequence_body_tl { \end{tikzcd} }
\tl_use:N \l_perko_exactsequence_body_tl
}
\ExplSyntaxOff
\begin{document}
\[
\exactsequence{A;a;B;b;C;c;D}
\]
\[
\exactsequence[column sep=small]{A;a;B;b;C;c;D}
\]
\end{document}
可选参数用于选项tikzcd
。
答案2
\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\begin{tikzcd}
A_1\ar[r, "f_1"]& A_2\ar[r, "f_2"]& A_3\ar[r, "f_3"]& A_4
\end{tikzcd}
\bigskip
{\makeatletter\catcode`\&\active
\gdef\zz#1{\toks0{\begin{tikzcd}}\zza#1;!;}
\gdef\zza#1;{\toks0\expandafter{\the\toks0 #1}\zzb}
\gdef\zzb#1;{\ifx!#1%
\expandafter\@firstoftwo\else
\expandafter\@secondoftwo
\fi
{\the\toks0 \end{tikzcd}}%
{\toks0\expandafter{\the\toks0 \ar[r, "#1"]&}\zza}%
}
}
\zz{A_1;f_1;A_2;f_2;A_3;f_3;A_4}
\end{document}