我知道 dtx 文件是文学编程风格的文件。我也知道我可以用 pdflatex 编译它来生成 pdf 文件。但我想知道我是否可以将 tex 代码提取到一个独立的文件中?我想我可以从 tex 源代码中学到一些东西。
答案1
DTX 文件已经是 LaTeX 文件(有时称为.tex
文件),但它使用了一些特殊的东西。它包含注释行形式的描述和软件包源代码。它包含一个“驱动程序”前言和正文,其中包含相同的文件,但%
注释字符被禁用,因此最初注释掉的部分现在被读取为正常的 LaTeX 代码。如果您不介意注释样式,只需查看文件即可查看描述部分。
如果要将其转换为普通的 LaTeX 文件,只需%
从代码中删除注释字符并完全删除实现部分。然后我会将“驱动程序”头部部分更改为不包含文件,而是将描述主体直接放在那里,方法是删除\DocInput{..}
并将移动\end{document}
到文件末尾。
因此基本上改变:
% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage{mypkg}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{mypkg.dtx}
\PrintChanges
\PrintIndex
\end{document}
%</driver>
%\fi
% Description
% ...
% Implementation
% \begin{macrocode}
%<*package>
code
%</package>
% \end{macrocode}
% ...
% END of file
到:
\documentclass{ltxdoc}
\usepackage{mypkg}
\begin{document}
Description
...
\end{document}
您仍然可以并且应该使用该ltxdoc
课程。
答案2
通常package.dtx
伴随着package.ins
并在后者上运行 LaTeX 来提取代码(通常在package.sty
,但在某些情况下会创建其他文件)。
在某些情况下package.ins
不存在;在这些情况下,
pdflatex package.dtx
将排版文档和提取代码;但有时需要运行
tex package.dtx
用于提取代码(H. Oberdiek 的包就是这种情况)。
然而,的目的package.dtx
不仅仅是提供包文档,还提供代码的注释。
如果运行 LaTeX 时package.dtx
没有排版注释代码,您可以ltxdoc.cfg
在工作目录中编写一个包含以下行的文件
\AlsoImplementation
并再次运行 LaTeX package.dtx
。
答案3
更具体的指南 + 执行此操作时需要注意的事项。
在某处获取 .dtx 文件。例如,用于
dtxgen a.sty
生成默认的“模板”文件。你会得到(除其他外)
a.dtx
看起来像这样% \iffalse meta-comment % vim: textwidth=75 %<*internal> \iffalse %</internal> %<*readme> | -------:| ----------------------------------------------------------------- a:| A new LaTeX package Author:| (not set) E-mail:| (not set) License:| Released under the LaTeX Project Public License v1.3c or later See:| http://www.latex-project.org/lppl.txt Short description: Some text about the package: probably the same as the abstract. %</readme> %<*internal> \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi %</internal> %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble -------:| ----------------------------------------------------------------- a:| A new LaTeX package Author:| (not set) E-mail:| (not set) License:| Released under the LaTeX Project Public License v1.3c or later See:| http://www.latex-project.org/lppl.txt \endpreamble \postamble [... more things ...]
复制(保留原件
a.dtx
!) 至a.tex
。准确的文件名在这里很重要,并将其保存在同一个文件夹中。编译它。不出所料,它可以被编译,并且输出大致如下
完毕!
然而……这里你可能指的是“以正常方式写入的 TeX 文件”。
备注/如果它有助于理解情况,你可以用非常不正常的方式编写 TeX 文件,例如https://tex.stackexchange.com/a/104263/250119,这是因为其精心设计的 catcode 系统才得以实现。
因此首先删除
%
TeX 文件中的所有内容(不要在 dtx 文件中这样做!)\iffalse | -------:| ----------------------------------------------------------------- a:| A new LaTeX package Author:| (not set) E-mail:| (not set) License:| Released under the LaTeX Project Public License v1.3c or later See:| http://www.latex-project.org/lppl.txt Short description: Some text about the package: probably the same as the abstract. \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi
...
\ProvidesFile{a.dtx} [2022/03/29 v1.00 A new LaTeX package] \documentclass{ltxdoc} \usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[numbered]{hypdoc} \usepackage{\jobname} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\jobname.dtx} \end{document}
好的,它现在看起来更像一个普通文档,顶部有一些“不相关的”代码。
删除多余的内容。剩余:
\ProvidesFile{a.dtx} [2022/03/29 v1.00 A new LaTeX package] \documentclass{ltxdoc} \usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[numbered]{hypdoc} \usepackage{\jobname} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\jobname.dtx} \end{document}
仍然编译为相同的输出,很好。
这里基本上(也在https://tex.stackexchange.com/a/530511/250119)
\DocInput
是一个类似于\input
但“忽略%
符号”的特殊命令。因此,\DocInput
用 a.dtx 的内容替换该行,然后删除所有%
符号,除了紧接在之前的符号\end{macrocode}
得到结果:\ProvidesFile{a.dtx} [2022/03/29 v1.00 A new LaTeX package] \documentclass{ltxdoc} \usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[numbered]{hypdoc} \usepackage{\jobname} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \iffalse meta-comment vim: textwidth=75 <*internal> \iffalse </internal> <*readme> | -------:| ----------------------------------------------------------------- a:| A new LaTeX package Author:| (not set) E-mail:| (not set) License:| Released under the LaTeX Project Public License v1.3c or later See:| http://www.latex-project.org/lppl.txt Short description: Some text about the package: probably the same as the abstract. </readme> <*internal> \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi </internal> <*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble -------:| ----------------------------------------------------------------- a:| A new LaTeX package Author:| (not set) E-mail:| (not set) License:| Released under the LaTeX Project Public License v1.3c or later See:| http://www.latex-project.org/lppl.txt \endpreamble \postamble Copyright (C) 2022 by (not set) <(not set)> This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this license or (at your option) any later version. The latest version of this license is in the file: http://www.latex-project.org/lppl.txt This work is "maintained" (as per LPPL maintenance status) by (not set). This work consists of the file a.dtx and a Makefile. Running "make" generates the derived files README, a.pdf and a.sty. Running "make inst" installs the files in the user's TeX tree. Running "make install" installs the files in the local TeX tree. \endpostamble \usedir{tex/latex/a} \generate{ \file{\jobname.sty}{\from{\jobname.dtx}{package}} } </install> <install>\endbatchfile <*internal> \usedir{source/latex/a} \generate{ \file{\jobname.ins}{\from{\jobname.dtx}{install}} } \nopreamble\nopostamble \usedir{doc/latex/a} \generate{ \file{README.txt}{\from{\jobname.dtx}{readme}} } \ifx\fmtname\nameofplainTeX \expandafter\endbatchfile \else \expandafter\endgroup \fi </internal> \fi \iffalse <*driver> \ProvidesFile{a.dtx} </driver> <package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] <package>\ProvidesPackage{a} <*package> [2022/03/29 v1.00 A new LaTeX package] </package> <*driver> \documentclass{ltxdoc} \usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[numbered]{hypdoc} \usepackage{\jobname} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\jobname.dtx} \end{document} </driver> \fi \GetFileInfo{\jobname.dtx} \DoNotIndex{\newcommand,\newenvironment} \title{\textsf{a} --- A new LaTeX package\thanks{This file describes version \fileversion, last revised \filedate.} } \author{(not set)\thanks{E-mail: (not set)}} \date{Released \filedate} \maketitle \changes{v1.00}{2022/03/29}{First public release} \begin{abstract} ==== Put abstract text here. ==== \end{abstract} \section{Usage} ==== Put descriptive text here. ==== \DescribeMacro{\dummyMacro} This macro does nothing.\index{doing nothing|usage} It is merely an example. If this were a real macro, you would put a paragraph here describing what the macro is supposed to do, what its mandatory and optional arguments are, and so forth. \DescribeEnv{dummyEnv} This environment does nothing. It is merely an example. If this were a real environment, you would put a paragraph here describing what the environment is supposed to do, what its mandatory and optional arguments are, and so forth. \StopEventually{^^A \PrintChanges \PrintIndex } \section{Implementation} \begin{macrocode} <*package> % \end{macrocode} \begin{macro}{\dummyMacro} This is a dummy macro. If it did anything, we'd describe its implementation here. \begin{macrocode} \newcommand{\dummyMacro}{} % \end{macrocode} \end{macro} \begin{environment}{dummyEnv} This is a dummy environment. If it did anything, we'd describe its implementation here. \begin{macrocode} \newenvironment{dummyEnv}{ }{ % \end{macrocode} \changes{v1.00a}{2022/03/29}{Added a spurious change log entry to show what a change \emph{within} an environment definition looks like.} Don't use || to introduce a code comment within a |macrocode| environment. Instead, you should typeset all of your comments with LaTeX---doing so gives much prettier results. For comments within a macro/environment body, just do an |\end{macrocode}|, include some commentary, and do another |\begin{macrocode}|. It's that simple. \begin{macrocode} } % \end{macrocode} \end{environment} \begin{macrocode} \endinput </package> % \end{macrocode} \Finale \end{document}
(可选)删除该
\iffalse ... \fi
部分。您需要一些 TeX 知识才能知道它与哪个 \fi 匹配(它与最后一个匹配)。结果以
\ProvidesFile{a.dtx} [2022/03/29 v1.00 A new LaTeX package] \documentclass{ltxdoc} \usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[numbered]{hypdoc} \usepackage{\jobname} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \GetFileInfo{\jobname.dtx} \DoNotIndex{\newcommand,\newenvironment} \title{\textsf{a} --- A new LaTeX package\thanks{This file describes version \fileversion, last revised \filedate.} } \author{(not set)\thanks{E-mail: (not set)}} \date{Released \filedate} ...
备注:显然步骤 7 不是可以应用于所有 dtx 文件的通用技术(也在https://tex.stackexchange.com/a/16864/250119(英文):然而它对这个特别有用。
备注:如果您认为注释掉很\end
奇怪,请查看上面链接的代码,以比较 TeX 的功能。
备注:这依赖于makeindex
实用程序来生成索引。