我的 TeX 文件中遍布着这种形式的命令\myedge{u}{v}
。我想在文档末尾添加一个 (TikZ) 图表,其中包含\myedge
迄今为止看到的所有边。最好的方法是什么?
为了便于理解,我试图在 LaTeX 文档中可视化定理依赖关系。如果定理 1 的证明使用引理 2 和引理 3,而引理 2 的证明使用引理 4,那么我想要一个形式为 的图形1 -> 2, 1 -> 3, 2 -> 4
。为此,我想适当地定义\myedge
,然后我将手动添加命令(如\myedge{1}{2}
定理/引理的证明中那样)来记录此依赖关系信息。我不想将此依赖关系信息单独保存在文档末尾的 tikzpicture 中,因为这样很难使其与上面的定理保持同步。
我也在考虑在 TeX 之外执行此操作的选项,比如编写一个 python 脚本,读取所有\myedge
命令并输出包含 的 TeX 文件tikzpicture
,我将\input
在我的文档中使用它。这可行,但如果不太困难的话,我更喜欢仅使用 TeX 的解决方案。
一个简短的例子说明了我想要什么。请参阅评论(%
)以了解我想进行哪些更改但不知道如何进行:
\documentclass{minimal}
\usepackage{amsthm}
\usepackage{tikz}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{layered}
\usepackage{hyperref}
\newtheorem{theorem}{Theorem}
\newcommand*{\myedge}[2]{} % what should I put here?
\begin{document}
\begin{theorem}\label{minor} Minor result.\end{theorem}
\begin{theorem}\label{major1} First major result.\end{theorem}
\begin{proof}
(Long and complicated proof) $\ldots$ \\
Using theorem \ref{minor}, we get that $\ldots$ \\
\myedge{major1}{minor} % document that we used minor in the proof of major1
(more theorem proving follows)
\end{proof}
\begin{theorem}\label{major2} Second major result.\end{theorem}
\begin{theorem}\label{grand} My grand theorem.\end{theorem}
\begin{proof}
(Long and complicated proof) $\ldots$ \\
Since ?, theorem \ref{major1} gives us that $\ldots$ \\
\myedge{grand}{major1} % document that we used major1 in the proof of grand
(more theorem proving follows) $\ldots$ \\
Using theorem \ref{major2}, we get that $\ldots$ \\
\myedge{grand}{major2} % document that we used major2 in the proof of grand
(more theorem proving follows)
\end{proof}
\begin{tikzpicture}
\graph[layered layout, sibling distance=8mm, level distance=8mm]
{
% How do I specify the edges below automatically based on the
% \myedge occurences above?
"Theorem \ref{major1}" -> "Theorem \ref{minor}";
"Theorem \ref{grand}" -> "Theorem \ref{major1}";
"Theorem \ref{grand}" -> "Theorem \ref{major2}";
};
\end{tikzpicture}
\end{document}
编辑:如果我也可以将图表放在文档的开头而不是结尾,那就太好了,但这不是硬性要求。
答案1
这是一个很有趣的问题。构建列表非常简单:我们可以使用宏扩展从一个空宏开始,并在声明节点时添加它们:
\newcommand{\edges}{}
\makeatletter
\newcommand{\myedge}[2]{%
{\let\protect\@unexpandable@protect
\xdef\edges{\edges "Theorem \protect\ref{#1}" -> "Theorem \protect\ref{#2}";}}%
}
\makeatother
请注意,我们将所有内容包装在一个组中,以便\protect
将其先前的含义保留在扩展之外。\xdef
告诉 TeX 扩展其中的所有宏并使定义成为全局的。我们设置\protect
为\@unexpandable@protect
,这告诉 TeX,每当它看到\protect\foo
它应该将其扩展为\protect\foo
(现在您对脆弱命令和背后的底层机制有所了解\protect
)。
当我们尝试传递\edges
给\graph
命令时,第一个问题出现了。TikZ 期望这里有一个简单的标记列表,因此它不会扩展\edges
宏。也许比我更精通 TikZ 的人可以提供更好的解决方案,但我最终使用了我们之前所做的命令的变体来简单地创建一个新的宏,\mygraph
它将创建一个包含\graph
上述\edges
扩展的宏:
\newcommand{\makegraph}{%
{\let\protect\@unexpandable@protect
\xdef\mygraph{\protect\graph[layered layout, sibling distance=8mm,
level distance=8mm]{\edges};}%
}%
}
\makeatother
(当您将上述内容放入文档序言中时,这正好发生在之前)。
现在,你可以在文档末尾写下
\makegraph
\begin{tikzpicture}
\mygraph
\end{tikzpicture}
并得到您想要的结果。
我曾希望可以只包含tikzpicture
环境\makegraph
,进一步简化结果,但当我尝试这样做时,我得到了
而不是预期的图表,所以我假设一些 Lua 魔法不允许我们直接将其投入\edges
到参数中,\graph
也不允许我们将tikzpicture
环境包装在宏中。无论如何,已经过了我的睡觉时间,所以我将把它放在原处并希望它有所帮助。如果有人有需要改进的地方,我会在明天高兴地更新它。