例如,这个 pdf 文档它定义了 C 编程语言的标准。库函数的描述遵循由三部分组成的固定结构,如下图所示:概要,描述和返回带有编号段落。
为了重现这个结构,我会:
- 定义一个没有编号且标题为粗体的子节(或子子节)标题。
- 使用该包
listings
来排版概要。 - 我不知道如何在页边距中排版段落编号,但对于我的特定文档,我对此功能不感兴趣。
根据上述计划,这里有一个工作代码,可以重现给定的示例页面(没有我不感兴趣的段落编号):
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{listings}
\renewcommand{\ttfamily}{\usefont{T1}{lmtt}{b}{n}}
\newcommand{\func}[1]{\texttt{#1}}
\setcounter{secnumdepth}{1}
\begin{document}
\lstset{basicstyle=\ttfamily,tabsize=8}
\section{The \func{rand} function}
\subsection{Synopsis}
\begin{lstlisting}
#include <stdlib.h>
int rand(void);
\end{lstlisting}
\subsection{Description}
The \func{rand} function computes a sequence of pseudo-random integers in the range 0 to \func{RAND\_MAX}.
The \func{rand} function is not required to avoid data races with other calls to pseudo-random sequence generation functions. The implementation shall behave as if no library function calls the rand function.
\subsection{Returns}
The \func{rand} function returns a pseudo-random integer.
\subsection{Environmental limits}
The value of the \func{RAND\_MAX} macro shall be at least 32767.
\end{document}
上述代码产生的结果:
这个结果对我来说还可以,但是我想知道:
如果您要为一个函数库编写手册,该手册包含与上述类似的几个到多个部分,具有相同的子部分序列和相同的代码缩进(此处使用制表符实现),您会采用不同的、甚至更好的方法来编写吗?
在上文中,更好的可能意味着通过定义一个环境(例如列表),其中包含用于生成正确标题序列的代码和项目的参数。
答案1
你写
[...] 你会用不同的、甚至更好的方法来做这件事吗?[...]更好的可能意味着通过定义一个环境(例如列表),其中包含用于生成正确标题序列的代码和项目的参数。
让您的生活更轻松
争取自动化,一致性, 和可维护性。(请注意,这些要求都是有点交织在一起的,并不是严格独立的。)这里有一些提示。
您应该定义一个环境(
fun
下面称为)来排版专用于某个函数的整个部分。此环境应该- 接受一个强制参数,对应于感兴趣的函数的名称,并定义一个宏以便轻松排版该函数的名称;
- 排版章节标题;
- 定义一些“子环境”描述,返回等,排版相应的小节标题。
最后一点(定义那些
四三种环境之内环境fun
(而不是全球)的封装,因为这些环境只能被调用之内环境fun
。例如,如果你尝试写\begin{fundesc} ... \end{fundesc}
在
fun
环境之外(没有意义的地方),您将收到编译错误。这可以防止您在不属于的地方排版内容。编辑:不幸的是,
listings
定义自定义环境的机制(\lstnewenvironment
)在全球的范围;因此,对于专门用于概要的环境来说,封装是不可能的。如果没有对策,任何内部凹痕
lstlisting
环境内的任何缩进都会被排版逐字在输出中。请参阅我的评论我如何才能自动在列表的每一行前面添加提示(例如 $)?。为了避免输入中不一致的缩进,你应该使用 Martin Scharrer 的
lstautogobble
包或我的实验lstautodedent
包裹,让listings
我们的xleftmargin
关键照顾列表的左边距为您:\usepackage{lstautodedent} %... \lstset{ %... autodedent, xleftmargin = 4em, % (for instance) }
执行
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{listings}
\usepackage{lstautodedent}
\renewcommand{\ttfamily}{\usefont{T1}{lmtt}{b}{n}}
\newcommand{\func}[1]{\texttt{#1}}
\setcounter{secnumdepth}{1}
% `Synopsis' environment
\lstnewenvironment{funsynop}{
\subsection{Synopsis}
\lstset{
basicstyle = \ttfamily,
tabsize = 8,
autodedent,
xleftmargin = 4em,
}%
}{}
% Custom environment for typesetting everything related to a function
\newenvironment{fun}[1]{%
\newcommand\funname{\func{#1}}
\section{The \funname{} function}
% `Description' environment
\newenvironment{fundesc}{%
\subsection{Description}
}{}
% `Returns' environment
\newenvironment{funret}{%
\subsection{Returns}
}{}
% `Environmental limits' environment
\newenvironment{funlim}{%
\subsection{Environmental limits}
}{}
}{}
\begin{document}
\begin{fun}{rand}
\begin{funsynop}
#include <stdlib.h>
int rand(void);
\end{funsynop}
%
\begin{fundesc}
The \funname{} function computes a sequence of pseudo-random integers
in the range 0 to \func{RAND\_MAX}.
The \funname{} function is not required to avoid data races with other calls
to pseudo-random sequence generation functions.
The implementation shall behave as if no library function calls the
\funname{} function.
\end{fundesc}
%
\begin{funret}
The \funname{} function returns a pseudo-random integer.
\end{funret}
%
\begin{funlim}
The value of the \func{RAND\_MAX} macro shall be at least 32767.
\end{funlim}
\end{fun}
\begin{fun}{foo}
\begin{funsynop}
foo = foo : foos <--- messed up indentation
(but output is fine)
\end{funsynop}
%
\begin{fundesc}
The \funname{} function blah blah blah
\end{fundesc}
%
\begin{funret}
The \funname{} function returns a foo.
\end{funret}
%
\begin{funlim}
The \funname{} function is limited to \func{bar}.
\end{funlim}
\end{fun}
\end{document}
可能的改进
- 强制执行四个“子环境”出现的顺序。
- (如果需要)如果缺少一个或多个“子环境”,则引发编译错误。