![如何模仿LINQ对宏的键值的查询方法?](https://linux22.com/image/279940/%E5%A6%82%E4%BD%95%E6%A8%A1%E4%BB%BFLINQ%E5%AF%B9%E5%AE%8F%E7%9A%84%E9%94%AE%E5%80%BC%E7%9A%84%E6%9F%A5%E8%AF%A2%E6%96%B9%E6%B3%95%EF%BC%9F.png)
受到LINQ查询方法的启发,例如
deck.Take(randomCount)
.Where (card => card.Suit == "Hearts")
.Skip(2)
.Take(5)
.OrderBy (card => card.FaceValue);
deck
作为继承的类的对象将IEnumerable
具有 LINQ 的查询方法。
我想将其应用于 LaTeX 宏,例如,\includegraphics
如下所示。
\documentclass[preview,border=12pt]{standalone}
\usepackage{graphicx}
\begin{document}
\includegraphics[viewport={10cm 10cm 10cm 10cm},clip,width=3cm]{example-image-a}
\includegraphics
.viewport{10cm 10cm 10cm 10cm}
.clip{}
.width{3cm}
.file{example-image-a}
\end{document}
问题
如何创建如下行为的宏?
\includegraphics .viewport{10cm 10cm 10cm 10cm} .clip{} .width{3cm} .file{example-image-a}
请记住,如果不需要,我们可以省略一些键。例如,
\includegraphics .width{3cm} .file{example-image-a}
可以被调用。
顺序并不重要,例如,
\includegraphics .file{example-image-a} .width{3cm}
也可以调用。但至少必须有一个,在本例中为
file
。实现这种编码风格有什么缺点?
答案1
我编写了几个类似的系统,但没有一个是为 LaTeX 编写的,可能是因为 David Carlisle 提出了很好的理由,即使用这样的宏接口在 LaTeX 中会让用户感到困惑,并且会抵消这种界面所能带来的任何好处。
让我回顾一下其中一个系统,它经过仔细描述,以便您可以轻松地将这些技术应用到您的案例或其他类似情况中。
使用 getoptk 在普通 TeX 中实现类似 hbox 的界面
其中一个系统是getoptk
您可以在tex/plain/contrib/getoptk.tex
并且描述于拖船 32-2,它用纯 TeX 定义了新的宏,使用户能够定义模仿等界面的命令hbox
。hfill
getoptk 正在行动!
使用这些宏,您可以定义一个\includegraphics
可以使用的版本,如下所示:
\includegraphics
viewport{10cm 10cm 10cm 10cm}
clip
width=3cm
{example-image-a}
如您所见,我们至关重要地需要一个非可选参数来标记我们的选项列表。准备那个叛逆的青少年的定义\includegraphics
需要定义一个选项词典:
\newgetoptkdictionary{includegraphics}
\defgetoptktoks{viewport}{\def\includegraphics@viewport{#1}}
\defgetoptkflag{clip}{\cliptrue}
\defgetoptkdimen{width}{\imagewidth=#1}
这defgetoptk*
调用定义了新的可选参数和行为。这些行为的替换文本保存为宏
\getoptk@behaviour@includegraphics@viewport
\getoptk@behaviour@includegraphics@clip
\getoptk@behaviour@includegraphics@width
我们现在需要定义\includegraphics
宏本身,它看起来像
\def\includegraphics{%
\setgetoptkdictionary{includegraphics}%
\getoptk\includegraphics@M
}
以及之前对我们的\includegraphics
将被替换为
\includegraphics@M{%
\getoptk@behaviour@includegraphics@viewport{10cm 10cm 10cm 10cm}
\getoptk@behaviour@includegraphics@clip
\getoptk@behaviour@includegraphics@width{3cm}%
}{example-image-a}
很棒,不是吗?这个包有点长,使用了一些 TeX 中的中级编程技术(edef
本质futurelet
上是 和寄存器)。
其他类似宏
我是业余 TeX 格式的作者,品牌巴西 TeX— 顺便说一下,我正在寻找一个新的、更有趣的名字 — 这是我在 1999 年阅读 David Solomon 的高级 TeX 书后开始的 — 一年后我决定转向非高级名称。不过考古就到此为止了!
如果你喜欢读法语,请打开程序员手册你应该去 2.6 节寻找宏系列\getoptspec
。它们与 类似,getoptk
但使用宏而不是关键字,这当然更容易编写!如果你觉得自己足够邪恶,想玩弄.
(
和)
和其他一些 catcode,你甚至可以让 TeX 理解该语句
deck.Take(randomCount)
.Where (card => card.Suit == "Hearts")
.Skip(2)
.Take(5)
.OrderBy (card => card.FaceValue);
但这种技巧并不符合 LaTeX 的做法。