在尝试详细了解 LaTeX 的功能时,我想看看是否可以创建一个围绕创建函数的 API。输出函数如下:
\NewDocumentCommand{\foo}{mmmO{}}{
% #1 == foo, tl
% #2 == baz, clist
% #3 == bac, seq
% #4 == asdf, prop list
\typeout{#1}
\typeout{#2}
\typeout{#3}
\typeout{#4}
}
大致来说,这将由这种 API 生成:
\mycommand{examplea}{
\myarg{foo}{tl}
\myarg{baz}{clist}
\myarg{bac}{seq}
\myarg{asdf}{prop}[optional]
\mycommandbody{
\typeout{\foo}
\typeout{\baz}
\typeout{\bac}
\typeout{\asdf}
}
}
本质上我想要实现的是动态生成参数签名。也就是说,这样做:
mmmO{}
从以下内容:
\myarg{foo}{tl}
\myarg{baz}{clist}
\myarg{bac}{seq}
\myarg{asdf}{prop}[optional]
以下为 MWE:
\documentclass[a4paper]{article}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
% not sure where to define this.
\seq_new \l_example_options_seq
\tl_new \l_example_name_tl
\tl_new \l_example_datatype_tl
\prop_new \l_example_options_prop
\NewDocumentCommand{\myarg}{mmO{}}{
\tl_gset \l_example_name_tl {#1}
\tl_gset \l_example_datatype_tl {#2}
\prop_gset \l_example_options_prop {#3}
% store these values in a sequence
% of property lists
\seq_push_right {name=\l_example_name_tl,datatype=\l_example_datatype_tl,options=\l_example_options_prop}
}
% don't know how to make it into a block
\NewDocumentCommand{\mycommandbody}{m}{
\tl_gset \l_example_name_tl {#1}
}
\NewDocumentEnvironment{mycommand}{m}{
}{
% loop through \l_example_options_seq and generate
% mmmO{} (in this case) dynamically from the items.
\NewDocumentCommand{#1}{\dynamicallygeneratedargs}{\mycommandbody}
}
\begin{document}
Hello world.
\mycommand{examplea}{
\myarg{foo}{tl}
\myarg{baz}{clist}
\myarg{bac}{seq}
\myarg{asdf}{prop}[optional]
\mycommandbody{
\typeout{\foo}
\typeout{\baz}
\typeout{\bac}
\typeout{\asdf}
}
}
\end{document}
提出这个问题是为了进一步了解在 LaTeX3 中动态生成内容的复杂方法。此示例需要使用看似复杂的方法来seq
捕获参数,然后生成签名。想知道这些特定的事情在 LaTeX 中是否可行以及它们如何工作。