我想随意重新排列带有片段的文档。可以通过 \input 完成,但片段太小,无法放入单个文件中。但如果放在 \newcommand 中,代码列表中的 # 会使编译器感到困惑。我正在寻找类似这样的内容:
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\newcommand\snippetA{
\begin{lstlisting}
something
\end{lstlisting}
}
\newcommand\snippetB{
\begin{lstlisting}
else
\end{lstlisting}
}
\newcommand\snippetC{
\begin{lstlisting}
code # | $ \%
\end{lstlisting}
}
\begin{document}
\snippetA
\snippetC
\snippetB
\end{document}
\part1 定义中的参数数量非法。}
有没有办法告诉 Latex 不要期待参数或另一个 \newcommand 宏?
答案1
到目前为止,处理涉及 catcode 更改的片段的最可靠方法是使用外部文件。您仍然可以使用单个文件进行源代码编辑,如下所示
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\begin{filecontents}[overwrite]{\jobname-A}
\begin{lstlisting}
something
\end{lstlisting}
\end{filecontents}
\begin{filecontents}[overwrite]{\jobname-B}
\begin{lstlisting}
else
\end{lstlisting}
\end{filecontents}
\begin{filecontents}[overwrite]{\jobname-C}
\begin{lstlisting}
code # | $ \%
\end{lstlisting}
\end{filecontents}
\begin{document}
\input{\jobname-A}
\input{\jobname-C}
\input{\jobname-B}
\end{document}
答案2
您可以创建自己的定义命令,该命令读取逐字分类代码制度下的定义文本并定义将内容传递给的宏\scantokens
——但是基于的方法\scantokens
可能无法很好地与 SyncTeX 交织在一起,这对某些用户来说是一个问题:
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage{hyperref}
\begingroup
\makeatletter
\catcode`\Z=14 %
\catcode`\%=12 Z
\@firstofone{Z
\endgroup
\newcommand*\defineVerbatim[1]{Z
\begingroup
\catcode`\^^I=12 Z
\@defineVerbatim{#1}Z
}Z
\@ifpackageloaded{hyperref}{Z
\NewDocumentCommand\@defineVerbatim{m+v}{Z
\endgroup
\@ifdefinable#1{Z
\DeclareRobustCommand*#1{Z
\texorpdfstring{Z
\begingroup
\newlinechar=\endlinechar
\scantokens{\endgroup#2%}Z
}{Z
Z Using snippet-macros in pdf-strings like bookmarks does not work out.
Z Therefore instances of snippet maqcros shall be removed in pdf-strings and
Z a warning-message about this shall be delivered.
\pdfstringdefWarn{#1}Z
}Z
}Z
}Z
}Z
}{Z
\NewDocumentCommand\@defineVerbatim{m+v}{Z
\endgroup
\@ifdefinable#1{Z
\DeclareRobustCommand*#1{Z
\begingroup
\newlinechar=\endlinechar
\scantokens{\endgroup#2%}Z
}Z
}Z
}Z
}Z
}%
% Indenting does matter with \defineVerbatim's second argument!
% It is relied on \defineVerbatim getting its arguments by reading
% and tokenizing .tex-input-file.
\defineVerbatim\snippetA{%
\begin{lstlisting}
something
\end{lstlisting}
}
\defineVerbatim\snippetB{%
\begin{lstlisting}
else
\end{lstlisting}
}
\defineVerbatim\snippetC{%
\begin{lstlisting}
code # | $ \%
\end{lstlisting}
}%
\defineVerbatim\snippetIndentingDoesMatter{%
\begin{lstlisting}
code # | $ \%
\end{lstlisting}
}%
\defineVerbatim\snippetIndentingDoesMatterMultiline{%
\begin{lstlisting}
code # | $ \%
code # | $ \%
code # | $ \%
\end{lstlisting}
}%
\begin{document}
\tableofcontents
\snippetA
\snippetC
\snippetB
\snippetIndentingDoesMatter
\snippetIndentingDoesMatterMultiline
% Macros defined in terms of \defineVerbatim do not work out in pdf-strings.
% Thus in case of using hyperref the following triggers a warning
% Package hyperref Warning: Token not allowed in a PDF string (Unicode):
% (hyperref) removing `\snippetA' on input line ...
% when creating the bookmark from \section's argument.
\section{Bla \snippetA}
\end{document}