以下演示(文件名demo.dtx
)用于演示如何在文学编程.ins
中合并文件:.dtx
% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*readme>
some readme contents
%</readme>
%<*internal>
\fi
\begingroup
\def\temp{LaTeX2e}
\expandafter\endgroup\ifx\temp\fmtname\else
\csname fi\endcsname
%</internal>
%<*install>
\input docstrip %
\generate{
\nopreamble\nopostamble
\file{README.md}{\from{demo.dtx}{readme}}}
\endbatchfile
%</install>
%<*internal>
\fi
%</internal>
%<*driver>
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\PrintChanges
\PrintIndex
\end{document}
%</driver>
% \fi
%
% \title{\LaTeX~Literate Programming}
% \author{Jack}
% \maketitle
运行tex demo.dtx
会提取README.md
文件,运行的同时pdflatex demo.dtx
会产生文档(目前只有标题和作者,仅用于演示)。
我认为代码片段:
\begingroup
\def\temp{LaTeX2e}
\expandafter\endgroup\ifx\temp\fmtname\else
\csname fi\endcsname
是重点,因为它可以通过判断格式来执行不同的任务。但我对不同格式编译时的具体过程有点困惑,尤其是和demo.dtx
的配对。\iffalse
\fi
有人能解释一下吗?谢谢!
答案1
基本问题是如何跳过条件。
如果你想跳过一些\fi
你不能做的代码
\iffalse
\foo
\bar
\fi
\hmm
\fi
因为,尽管缩进, 仍然\iffalse
匹配第一个\fi
。
\csname fi\endcsname
扩展为,\fi
因此可以(有时)用来隐藏\fi
外部条件。
但是你只能有时使用\csname fi\endcsname
:
\iftrue
hello
\csname fi\endcsname
有匹配if
和fi
打印hello
但
\iftrue
hello
\else
goodbye
\csname fi\endcsname
将跳过查找文档其余部分,\fi
因为在\else
扫描 tex 之后将\fi
不进行扩展。
在文档条中,内容变得更加有趣,因为%
它是注释或者不是注释,这取决于模式。
所以....
如果你这样做pdflatex demo.dtx
%
是注释,所以% \iffalse
第 1 行不可见,
\iffalse
第 3 行与\fi
第 9 行匹配。
\ifx
第 12 行是,\iftrue
所以 \else
分支跳过
\csname fi\endcsname
第 13 行,
\fi
第 23 行跳过,关闭\ifx
\documentclass{ltxdoc}
处理,
\DocInput{\jobname.dtx}
再次输入文件,但%
不是注释。
\iffalse
在第 1 行看到,开始跳过
\iffalse
添加到必须在第 13 行跳过的 fi 嵌套,在第 23 行
\csname fi\endcsname
看不到,因为在第 33 行\fi
\fi
删除了一层 if-fi 嵌套,在第 1 行
\fi
关闭并且跳过停止。 ,并执行。\iffalse
\title
\author
\maketitle
如果你pdftex demo.dtx
\ifx
直到第 12 行,其工作方式与上述相同 。
\ifx
因此\iffalse
,在\else
启用扩展后,它将
\csname fi\endcsname
被视为\fi
并结束\ifx
\input docstrip
在第 16 行执行的操作
\generate
将以逐字模式输入demo.dtx
,其中没有一个\if
被执行,
控制将返回到第 19 行,
\endbatchfile
在第 20 行执行并结束第 23 行 的\@@end
操作,因此看不到。\fi