我想实现 pgfmanual(pgf-tikz 官方手册)中代码与结果共存的效果('side-by-side' code examples),比如
或者
这样类似的排布(手册中代码摘录部分还有超链接跳转功能,这个不需要实现)。
在 pgfmanual 中,官方制作了 codeexample 环境实现,我本想照搬它的源码,但奈何对应的 tex 文件找不到(控制 codeexample 的 tex 文件我不知道具体是哪个/哪些)。
现在有两条路:
对于 2. tex-se 上有人提出问题,也有一部分解答:
Code examples, like in the TikZ/PGF manual
但这个回答有一些问题:
请问如何找到 codeexample 对应的 tex 文件,或者制作一个比较接近的环境?
主要难点是涉及整个tikz
库多文件之间的相互关联。
提取一个「相对比较简单的」MWE如下,其中:
\input{pgfmanual-en-main-preamble.tex}
需要的代码来自./base/doc/pgfmanual-en-main-preamble.tex
ltxdoc
文档类,其中定义了一些关键的命令和环境截自v3.10(2025-06-22),该文件可在这里获得:pgfmanual-en-main-preamble.tex
\documentclass{ltxdoc}
\usepackage{tikz}
\usepackage{pgf}
\input{pgfmanual-en-main-preamble.tex}
\begin{document}
\begin{codeexample}[]
\begin{tikzpicture}
\foreach \x in {1,2,...,5,7,8,...,12}
\foreach \y in {1,...,5}
{
\draw (\x,\y) +(-.5,-.5) rectangle ++(.5,.5);
\draw (\x,\y) node{\x,\y};
}
\end{tikzpicture}
\end{codeexample}
\end{document}
当然,\input{pgfmanual-en-main-preamble.tex}
内部多达300行,还是不够简的。
纵览整个pgfmanual-en-main-preamble.tex
文件,其核心在于:
% Line 187
\input{pgfmanual-en-macros}
根据TSE上搜索的结果和kpathsea
的索引逻辑,该文件的位置位于./base/tex/latex/doc/pgfmanual-en-macros.tex
上面的文件调用了pgfmanual-en-macros.tex
,我们同时还发现:
% pgfmanual-en-macros.tex
% Line 1858
\usepackage{pgfmanual}
这将会调用./base/tex/latex/doc/pgfmanual.sty
文件:
% pgfmanual.sty
\ProvidesPackage{pgfmanual}[2009/10/15]
\input pgfmanual.code.tex
其中的\input pgfmanual.code.tex
会调用上面截图路径中的pgfmanual.code.tex
:
% pgfmanual.code.tex
\input pgfmanual.prettyprinter.code.tex
\input pgfmanual.pdflinks.code.tex
接下来只要用二分删除的方式,理论上可以只提取出「最轻量」的「仅仅用于codeexample
环境实现」的部分「最短代码」。
首先尝试二分删除简化「pgfmanual-en-main-preamble.tex
」,似乎仅有这两行是必不可少的:
\usepackage{calc,listings}
% \usepackage[version=latest]{pgf}
\input{pgfmanual-en-macros}
这里[version=latest]
会报错...懒得管,先注释这个选项即可...
非常初步简化的MWE如下:
\documentclass{ltxdoc}
\usepackage{tikz,pgf,calc,listings}
\input{pgfmanual-en-macros.tex}
\begin{document}
\begin{codeexample}[]
\begin{tikzpicture}
\foreach \x in {1,2,...,5,7,8,...,12}
\foreach \y in {1,...,5}
{
\draw (\x,\y) +(-.5,-.5) rectangle ++(.5,.5);
\draw (\x,\y) node{\x,\y};
}
\end{tikzpicture}
\end{codeexample}
\end{document}
换言之,下面的工作只要专心把pgfmanual-en-macros.tex
进一步做简化即可。
TBC.
感谢大佬
@u26254 我还没码完其实😭😭😭
@u70550 最核心的部分已经实现了,哈哈
Claim:由于我短时间看不太懂,暂时删减到300行左右的代码(转念一想,过于追求轻量化在这个例子里似乎也没必要,都怪
pgf-en-macros
没有做好模块化管理😡😡😡等后来人补充吧):由于
pgfmanual-en-macros
在texmf
树内,换言之可以在任何地方通过\input{pgfmanual-en-macros}
调用,因此上面「非常初步的MWE」实际上已经是不错的较短的实践了。Note: 在提取MWE要注意到可以编译得到
pgfmanual.pdf
的pgfmanual.tex
代码中:其文档类为
ltxdoc.cls
,这可能是被OP忽略的。