![(如何)我可以编写 .dtx 文件而不必注释掉*所有内容*吗?](https://linux22.com/image/258898/%EF%BC%88%E5%A6%82%E4%BD%95%EF%BC%89%E6%88%91%E5%8F%AF%E4%BB%A5%E7%BC%96%E5%86%99%20.dtx%20%E6%96%87%E4%BB%B6%E8%80%8C%E4%B8%8D%E5%BF%85%E6%B3%A8%E9%87%8A%E6%8E%89*%E6%89%80%E6%9C%89%E5%86%85%E5%AE%B9*%E5%90%97%EF%BC%9F.png)
我现在对文件的工作原理有了合理的理解.dtx
。但必须%
在每行文档前添加一个字符非常麻烦。此外,根据您使用的编辑器,它基本上意味着:没有语法高亮。
这个问题已经著名的之前。但提供的解决方案仅限于编辑器设置。另外,即使我们忘记语法高亮,这个%
功能也太……不方便了。
因此,我正在寻找一种方法来省去所有注释。基本上,我想使用 guard 修饰符来分隔文档代码。像这样:
%<*documentation>
I'm going to introduce a cool new \LaTeX macro:
\begin{macrocode}
%</documentation>
\newcommand{\CoolNewMacro}{...}
%<*documentation>
\end{macrocode}
Cool, huh?
%</documentation>
我认为我可以先将文档代码提取到单独的文件中,从而弄清楚如何做到这一点。但是...我需要这样做吗?有没有更好的方法?
答案1
如果你回顾一下的历史doc
,那么就可以理解为什么当前的系统会这样运作。最初的想法是编写一个.sty
嵌入注释的文件,但要以一种可以直接由 LaTeX 处理的方式。而这需要将每一点文档都放在%
符号后面。
直到后来才出现 docstrip(用于删除注释,因为当时处理所有这些不必要的注释行需要花费明显的额外时间)。甚至后来出现了,<guards>
并且随之而来的是目标文件的无序生成。当时文件的名称更改为.dtx
,然后可以更改文档部分以使其在没有%
--- 的情况下工作,但这并没有发生。
话虽如此,人们可以稍加修改以该形式运行文档,例如,
%<*documentation>
\documentclass{article}
\usepackage{doc}
\makeatletter
\def\inlinecode{\macro@code
\frenchspacing \@vobeyspaces
\xinline@code}
\let\endinlinecode\endmacrocode
\begingroup
\catcode`\|=\z@ \catcode`\[=\@ne \catcode`\]=\tw@
\catcode`\{=12 \catcode`\}=12
\catcode`\\=\active
|gdef|xinline@code#1\end{inlinecode}[#1|end[inlinecode]]
|endgroup
\makeatother
\begin{document}
\noindent some text
\begin{inlinecode}
%</documentation>
\def\foo{bar}
%<*documentation>
\end{inlinecode}
more text
\end{document}
%</documentation>
要从这个文件中处理代码,需要一个docstrip
安装文件,例如
\input docstrip
\generate{\file{x.sty}{\from{how-can-i-write-a-dtx-file-without-having-to-comment-out-everything.dtx}{}}}
\endbatchfile
但这并不完全令人满意,因为文档保护器出现在文档中并且没有进行一些重大更改,docstrip
而且doc
我看不出有办法摆脱它们:
如果我们将保护称为“代码”,那么打印出来可能会看起来好一些(但 * 和 / 的顺序是错误的)——无论哪种方式都不是最优的。
更新
如果想要摆脱文档保护,一个简单的解决方案当然是使用 docstrip 生成单独的文档文件,正如 OP 已经建议的那样。要做到这一点,只需额外提供以下行
\generate{\file{packagedoc.tex}{\from{how-can-i-write-a-dtx-file-without-having-to-comment-out-everything.dtx}{documentation}}}
在.ins
文件中,然后在生成的文件上运行 LaTeX。但是,要充分利用 的功能doc
,例如代码索引或代码行编号,使用macrocode
环境非常重要。由于此环境使用 的特殊语法,因此% \end{macrocode}
不能直接使用它,至少如果想避免将 放入 中则不能%
。因此,上面的代码将inlinecode
环境定义为替代方案是必不可少的。
也许应该将那段代码添加到文档中以允许这种方法。
答案2
好吧,也许使用通过 LaTeX 运行文件以获取文档的“标准”方式无法优雅地做到这一点.dtx
。但我这里有一个看起来同样不错的替代解决方案。
使用此设置,只有一个文件(.ins
包括 ' 文件')。您通过 LaTeX 运行它,它会生成package.sty
和package.tex
。要获取实际文档,您仍然需要package.tex
通过 LaTeX 运行它。(我愿意做出牺牲。)
这是一个最小的工作示例(对于任何想要做同样事情的人来说,这都是一个合理的框架):
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright, license, etc... %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \CheckSum{3}
%%
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%<*driver> %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input docstrip.tex
\keepsilent
\usedir{tex/latex/package}
\nopreamble
\generate{
\file{package.tex}{\from{\jobname.dtx}{d}}
\file{package.sty}{\from{\jobname.dtx}{p}}
}
\obeyspaces
\Msg{*************************************************************}
\Msg{* *}
\Msg{* To finish the installation you have to move the following *}
\Msg{* file into a directory searched by TeX: *}
\Msg{* *}
\Msg{* package.sty *}
\Msg{* *}
\Msg{* To produce the documentation run the following file *}
\Msg{* through LaTeX: *}
\Msg{* *}
\Msg{* package.tex *}
\Msg{* *}
\Msg{* Happy TeXing! *}
\Msg{* *}
\Msg{*************************************************************}
\endbatchfile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%</driver> %
%<*d> %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ProvidesFile{package.tex}
\documentclass{ltxdoc}
\usepackage{package}[2012/11/24]
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\changes{v0.0.1}{2012/11/16}{initial version}
\changes{v0.0.2}{2012/11/24}{put the package into a .dtx file}
\GetFileInfo{package.sty}
\DoNotIndex{\newcommand,\def,\xdef,\edef,\gdef,\NewDocumentCommand}
\title{The \textsf{package} package\thanks{This document
corresponds to \textsf{package}~\fileversion, dated \filedate.}}
\author{Author Name \\ \texttt{[email protected]}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document} %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\maketitle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction} %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Put text here.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Usage} %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Put text here.
\DescribeMacro{\dummyMacro}
This macro does nothing.
\DescribeEnv{dummyEnv}
This environment does nothing.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Implementation}\StopEventually{} %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The following piece of code contains the package meta-info:
\begin{verbatim}
%</d>%%%%%%%%%%%%%%%%%%%%%%%
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\ProvidesPackage{package}
[2012/11/24 v0.0.2 description of the 'package' package]
%<*d>%%%%%%%%%%%%%%%%%%%%%%%
\end{verbatim}
\begin{macro}{\dummyMacro}
This is a dummy macro.
\begin{verbatim}
%</d> %%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\dummyMacro}{}
%<*d> %%%%%%%%%%%%%%%%%%%%%%%
\end{verbatim}
\end{macro}
\begin{environment}{dummyEnv}
This is a dummy environment.
\begin{verbatim}
%</d> %%%%%%%%%%%%%%%%%%%%%%%
\newenvironment{dummyEnv}{}{}
%<*d> %%%%%%%%%%%%%%%%%%%%%%%
\end{verbatim}
Some more information here... Very useful stuff.
\end{environment}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Finale\end{document} %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
一些评论:
- '
.ins
' 部分以 结尾\endbatchfile
,因此第一次运行时将忽略其后的所有内容。它还以 分隔%<*driver>
,因此在后续运行时将忽略其本身。 - 每个生成的文件中都会自动包含版权/许可/文件完整性内容。
- 在纯粹的文学编程风格中,我通过使用缩进使包代码“服从”文档。但您可以选择不同的缩进方式。
我唯一无法正常工作的是macrocode
环境。也许它在某种程度上取决于标准文档条设置?它的定义太难解读了。所以我verbatim
在这里使用来排版包代码,但任何代码排版技术(例如listings
)都可以。
对于任何反馈,我们都表示感谢!
编辑:之前的版本不起作用,因为我缩进了保护。%<*bla>
代码左侧不能有空格。:-( 哦,好吧。我还注意到环境verbatim
保留了所有空格。(但有解决方案。)
答案3
这是我编写的一个包的 dtx 骨架,它将在几天后出现在 CTAN 上(CTAN 上的当前版本还没有这个 dtx 文件的结构)
%<*none>
% This skeleton PKG.dtx file is one way to not have everything commented
% out in the documentation part. It produces the .sty file (and also an
% .ins file) when one does latex PKG.dtx.
%
% It *does not* use DocInput!
%
% It is also possible to not produce the .sty file, and still be able to
% compile the doc, using some boolean flag, and doing an \input which
% will get only the code, the only thing is that the log file will
% complain that we have required package `' and that package `PKG' was
% used.
%
% Here we rather first output the .sty file, and then do a normal
% \usepackage
%
% [I am of course assuming that compiling the doc for package PKG
% does require the use of PKG.sty]
%
\begingroup
\input docstrip.tex
\askforoverwritefalse
\generate{
\file{PKG.ins}{\from{PKG.dtx}{ins}}
\file{PKG.sty}{\from{PKG.dtx}{package}}
\nopreamble\nopostamble
\file{test.txt}{\from{PKG.dtx}{test}}}
\endgroup
\iffalse
%</none>
%<*ins>
\input docstrip.tex
\askforoverwritefalse
\generate{\file{PKG.sty}{\from{PKG.dtx}{package}}}
\endbatchfile
%</ins>
%<*test>
This is a another file which can be produced by the latex run
%</test>
%<*none>
\fi
\documentclass{ltxdoc}
% \OnlyDescription
\usepackage{PKG} % <- often needed to produce its own documentation!
\begin{document}
I am the best packaging package.
\makeatletter
\StopEventually{\check@checksum\end{document}}
\makeatother
\MakePercentIgnore
% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
%
% \let</none>\relax
% \def<*package>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12}
%
%</none>
%<*package>
% \begin{macrocode}
\ProvidesPackage{PKG}
[2012/11/24 v1.04 easy packaging (jfB)]
% \end{macrocode}
% Let us point out the importance of this piece of code with 31
% \cs{expandafter}'s
% \begin{macrocode}
\endinput
% \end{macrocode}
% \MakePercentComment
%</package>
\CharacterTable
{Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
Digits \0\1\2\3\4\5\6\7\8\9
Exclamation \! Double quote \" Hash (number) \#
Dollar \$ Percent \% Ampersand \&
Acute accent \' Left paren \( Right paren \)
Asterisk \* Plus \+ Comma \,
Minus \- Point \. Solidus \/
Colon \: Semicolon \; Less than \<
Equals \= Greater than \> Question mark \?
Commercial at \@ Left bracket \[ Backslash \\
Right bracket \] Circumflex \^ Underscore \_
Grave accent \` Left brace \{ Vertical bar \|
Right brace \} Tilde \~}
\CheckSum{2}
\Finale
%%
%% End of file
我的 dtx 文件中的实际情况更加复杂,我在这里简化了一些事情以获得该框架。我同意拥有所有这些 % 确实是一个问题,尽管使用 emacs 有一种模式可以执行 LaTeX 语法突出显示。所以我也想找到一种不拥有所有这些%
's 的方法。
哎呀,我忘了说这个ins
东西纯粹是可选的。它只是生成一个.ins
文件,但没有用,因为.sty
文件本身是直接输出的。