来自终端的章节名称

来自终端的章节名称

有没有现成的方法可以通过 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}

相关内容