![来自终端的章节名称](https://linux22.com/image/356294/%E6%9D%A5%E8%87%AA%E7%BB%88%E7%AB%AF%E7%9A%84%E7%AB%A0%E8%8A%82%E5%90%8D%E7%A7%B0.png)
有没有现成的方法可以通过 MacTex 从终端列出书籍文档的章节?我想将章节列表保存在实际章节文件之外的某个地方。比如一个只有章节名称的独立纯文本文件。
我希望只对 latex 或某些外部分析器添加一些标记。我的愿望是受到 Ansible 的 --list-tags 启发。它只是收集所有标签并将它们吐出。我不想让文档文件被一些外部的东西污染。
答案1
这将生成.lch
以下格式的文件:
\documentclass{book}
\usepackage{xpatch}
\makeatletter
\xapptocmd{\@schapter}
{{\let\@mkboth\@gobbletwo\addtocontents{lch}{#1//}}}
{}{}
\xapptocmd{\@chapter}
{\addtocontents{lch}{#2//\thechapter}}
{}{}
\newwrite\tf@lch
\AtEndDocument{\immediate\openout\tf@lch=\jobname.lch}
\makeatother
\begin{document}
\frontmatter
\tableofcontents
\mainmatter
\chapter*{Introduction}
\chapter{Foo}
\chapter{Foob\r{a}r}
\end{document}
写出来的内容如下:
Contents//
Introduction//
Foo//1
Foob\r {a}r//2
未编号的章节后面将没有任何内容//
(或者0
如果\chapter
在前言中使用)。
改变输出格式非常容易。
这是如何运作的?
\@schapter
首先,我们添加一些代码,在每个(for\chapter*)
和命令)处执行\@chapter
。代码本质上
\addtocontents{lch}{<chapter title>//<chapter number}
进行调整以便\@schapter
不从中获取标题信息\@mkboth
。
指令\addtocontents{lch}{<tokens>}
将会写入
\@writefile{lch}{<tokens>}
在.aux
文件中。
当文件第二次被读取时, kernel\@writefile{<string>}{<tokens>}
命令在文件末尾改变其定义。它的工作变为:.aux
如果名为 的输出流
tf@<string>
已打开,则在其上写入<tokens>
(使用\protected@write
)。
因此我们也打开流\tf@lch
并让 LaTeX 完成其正常工作。
答案2
\jobname.chap
通过添加语句,将章节名称(不带数字)逐行逐行写入文件\immediate\write{}
。
它应该可以在任何操作系统上运行,因为在处理 LaTeX 时,写入文件是‘必须的’(除非启用,否则至少会尝试写入.log
和文件).aux
\nofiles
如果章节名称中不仅仅包含文本内容,则此方法将失败,除非\protected@write
使用:
\documentclass{book}
%Eventually morewrites package if there too many file handles
%\usepackage{morewrites}
\usepackage{xpatch}
\newwrite\chapnames
\makeatletter
\xpatchcmd{\@chapter}{%
\typeout{\@chapapp\space\thechapter.}%
}{%
\typeout{\@chapapp\space\thechapter.}%
\protected@write\chapnames{}{#2^^J}%
}{}{}
\makeatother
\AtBeginDocument{%
\immediate\openout\chapnames=\jobname.chap
}
\AtEndDocument{% Close the file
\closeout\chapnames% Do not close prematurely, so no \immediate here!
}
\begin{document}
\chapter{Foo}
\chapter{Foobar \textbf{foo}}% Not recommended to use such stuff like `\textbf{...}` anyway here
\end{document}
更新更清洁的版本 - 使用\writechapnamestrue
或\writechapnamesfalse
启用或禁用将章节名称写入文件。
\documentclass{book}
% Eventually morewrites package if there too many file handles
%\usepackage{morewrites}
\usepackage{xparse}
\newwrite\chapnames
\newif\ifwritechapnames
\makeatletter
\let\latex@@chapter\chapter
\RenewDocumentCommand{\chapter}{sO{#3}m}{%
\IfBooleanTF{#1}{%
\latex@@chapter*{#3}%
}{%
\latex@@chapter[#2]{#3}%
}%
\ifwritechapnames
\protected@write\chapnames{}{#3}%
\fi
}
\makeatother
\AtBeginDocument{%
\immediate\openout\chapnames=\jobname.chap
}
\AtEndDocument{% Close the file
\closeout\chapnames% Do not close prematurely, so no \immediate here!
}
\begin{document}
\tableofcontents
\writechapnamestrue
\chapter[Bar]{Bar stuff}
\chapter{Foo}
\chapter{Foobar \textbf{foo}}% Not recommended to use such stuff like `\textbf{...}` anyway here
\end{document}