下午好,我遇到了以下问题:我必须描述一组具有相同格式的项目,比如属性 1、属性 2、ecc。为此,我创建了一个新命令,这样我就可以仅指定相关信息并依赖固定结构。当我想使用 \lstinline 将一段代码作为命令的参数时,问题就出现了。下面是给我带来麻烦的部分:
命令:
%1: title
%2: description
%3: HTTP request
%4: Path parameters
%5: Request body
%6: Response body
\newcommand{\API}[6]{
\subsubsection*{#1}
#2 \\ \\
\textbf{HTTP request:} \api{#3} \\
\textbf{Path parameters:} #4 \\
\textbf{Request body:} #5 \\
\textbf{Response body:} #6
}
文档中的用法:
\API{getProfile}
{Gets the current user's Gmail profile.}
{GET /gmail/v1/users/{userId}/profile}
{
\begin{itemize}
\item \textbf{userId:} The user's email address. The special value me can be used to indicate the authenticated user.
\end{itemize}
}
{The request body must be empty.}
{If successful, the response body contains data with the following structure:
\lstinline{
{
"emailAddress": string,
"messagesTotal": integer,
"threadsTotal": integer,
"historyId": string
}
}}
问题是会产生各种错误,并且无法按预期呈现。您能提供一种方法来解决它吗?欢迎提供任何进一步的建议以获得更好的结果。
编辑: 这里有一个例子背页。
答案1
关于您的代码的一些评论:
- 您尝试使用
\lstinline
创建包含多行的代码列表。这是不可能的。的整个参数\lstinline
必须出现在 .tex-input 的同一行内。 \lstinline
的语法类似于 的语法\verb
,其中在 .tex-input 中,参数也不能跨越多行,并且也不能在宏定义等中使用,因为它还依赖于在不同的 category-code-régime/verbatim-category-code-régime 下对参数进行标记:
您可以执行\lstinline|some code snippet|
。
作为一种特殊情况,如果左分隔符是{
,则右分隔符应为}
。这种特殊情况的问题是\lstinline
不会跟踪括号匹配。
因此\lstinline{Some {nice} code}
不会按预期工作:\lstinline
将采取Some {nice
代码片段。尾随code}
包含不匹配的右括号,这会导致错误消息! Extra }, or forgotten \endgroup.
- 当你使用 inputenc 和 utf8 编码(顺便说一下,这是最近安装的 TeX 的默认设置)时,我建议你阅读2.5 特殊字符列表包手册。
如何处理这个问题:
您可以使用xparse-包's +v
-type-argument 用于让 LaTeX 读取并标记逐字分类代码体系中的所有内容,然后将内容传递给\scantokens
重新标记。
关于以逐字论证→\scantokens
方式执行此操作的想法的一些评论:
- 如果这样做,该命令
\API
只能以通过读取/标记 .tex-input 或通过从另一个宏传递它们来获取其参数的方式使用,在其中一个宏在 verbatim-category-code-régime 下对它们进行标记。 - 如果你这样做,你需要注意在 .tex-input 中使用以下环境时正确缩进
lstlistings
:verbatim
处理 verbatim-material 的
\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\usepackage{listings}
\begingroup
\newcommand\scantokenswithendlinechar[1]{%
\endgroup
\DeclareRobustCommand\scantokenswithendlinechar[1]{%
\begingroup\newlinechar=\endlinechar\scantokens{\endgroup##1#1}%
}%
}%
\catcode`\%=12\relax
\scantokenswithendlinechar{%}%
\newcommand\apibreak{%
\ifhmode\\\null\else\ifvmode\noindent\fi\fi
}%
\newcommand{\api}[1]{\textbf{\texttt{#1}}}
\NewDocumentCommand\API{}{%
\begingroup
\catcode`\^^I=12 %
\innerAPI
}%
\NewDocumentCommand{\innerAPI}{+v+v+v+v+v+v}{%
\endgroup
\subsubsection*{\scantokenswithendlinechar{#1}}%
\scantokenswithendlinechar{#2}\apibreak\bigskip
\textbf{HTTP request:} \api{\scantokenswithendlinechar{#3}}\apibreak
\textbf{Path parameters:} \scantokenswithendlinechar{#4}\apibreak
\textbf{Request body:} \scantokenswithendlinechar{#5}\apibreak
\textbf{Response body:} \scantokenswithendlinechar{#6}\par
}
\begin{document}
\API{getProfile}
{Gets the current user's Gmail profile.}
{GET /gmail/v1/users/{userId}/profile}
{%
\begin{itemize}
\item \textbf{userId:} The user's email address. The special value me
can be used to indicate the authenticated user.
\end{itemize}
}%
{The request body must be empty.}
{If successful, the response body contains data with the following structure:
%!!! Be aware of the indenting with verbatim-environments !!!
\begin{lstlisting}
{
"emailAddress": string,
"messagesTotal": integer,
"threadsTotal": integer,
"historyId": string
}
\end{lstlisting}
}
\end{document}
您可能对使用-environment 感兴趣description
:
\documentclass[12pt]{article}
%% The following three packages are not needed with up-to-date LaTeX
%% but may be needed with not so recent LaTeX distros:
%\usepackage[utf8]{inputenc}
%\usepackage[T1]{fontenc}
%% \NewDocumentCommand etc:
% \usepackage{xparse}
%% These packages provide bold typewriter font:
%\usepackage[ttdefault=true]{AnonymousPro}
%\usepackage{tgcursor}
\usepackage{lmodern}
%% For code-listings:
\usepackage{listings}
\lstset{basicstyle=\ttfamily}
\begingroup
\newcommand\scantokenswithendlinechar[1]{%
\endgroup
\DeclareRobustCommand\scantokenswithendlinechar[1]{%
\begingroup\newlinechar=\endlinechar\scantokens{\endgroup##1#1}%
}%
}%
\catcode`\%=12\relax
\scantokenswithendlinechar{%}%
\NewDocumentCommand\API{}{%
\begingroup
\catcode`\^^I=12 %
\innerAPI
}%
\NewDocumentCommand{\innerAPI}{+v+v+v+v+v+v}{%
\endgroup
\subsubsection*{\scantokenswithendlinechar{#1}}%
\scantokenswithendlinechar{#2}%
\bigskip
\begin{description}%
\item[{HTTP request:}]%
\expandafter\scantokenswithendlinechar\expandafter{%
% !!!!! It is assumed that the argument #3 for the HTTP-request !!!!!
% !!!!! does _not_ contain the character | !!!!!
% !!!!! If the case of #3 containing | can occur, for delimiting !!!!!
% !!!!! #3 choose a different character which definitely never !!!!!
% !!!!! occurs within #3 !!!!!
\string\lstinline[basicstyle=\bfseries\ttfamily]|#3|%
}%
\item[{Path parameters:}]\scantokenswithendlinechar{#4}%
\item[{Request body:}]\scantokenswithendlinechar{#5}%
\item[{Response body:}]\scantokenswithendlinechar{#6}%
\end{description}%
}
\makeatletter
% ----------------------------------------------------------------------
% Environment adjustitemize where itemlabels of itemizations are aligned
% with second lines of surrounding description-items:
% ----------------------------------------------------------------------
\newcommand\adjustitemize{%
\settowidth{\labelwidth}{%
\csname labelitem%
\romannumeral
\numexpr\@itemdepth\ifnum\@itemdepth >\thr@@\else+1\fi\relax
\endcsname
}%
\csname leftmargin%
\romannumeral
\numexpr\@listdepth\ifnum \@listdepth >5 \else+1\fi\relax
\endcsname
=\dimexpr\labelwidth+\labelsep\relax
\itemize
}%
\@ifundefined{endadjustitemize}%
{\let\endadjustitemize=\enditemize}%
{\@ifdefinable\endadjustitemize{}}%
%
% ----------------------------------------------------------------------
% Environment adjustdescription where description-labels have
% enumeration-bullets:
% ----------------------------------------------------------------------
\newcommand\adjustdescription{%
\ifnum \@itemdepth >\thr@@\@toodeep\else\advance\@itemdepth\@ne\fi
\list{}{%
\settowidth\labelwidth{%
\hspace\labelsep
{\csname labelitem\romannumeral\@itemdepth\endcsname}%
}%
\advance\leftmargin\labelwidth
\labelwidth=\z@
\itemindent -\leftmargin
\let\makelabel\adjustdescriptionlabel
}%
}%
\newcommand*\adjustdescriptionlabel[1]{%
\hspace\labelsep
{\csname labelitem\romannumeral\@itemdepth\endcsname}%
\hspace\labelsep
{\normalfont\bfseries#1}%
}%
\@ifundefined{endadjustdescription}%
{\let\endadjustdescription=\enddescription}%
{\@ifdefinable\endadjustdescription{}}%
% ----------------------------------------------------------------------
\makeatother
\begin{document}
\API{getProfile}
{Gets the current user's Gmail profile.}
{GET /gmail/v1/users/{userId}/profile}
{%
% The \empty rule makes the line non-empty so that \\ is possible
\rule{0pt}{0pt}%
\\Let's test the \verb|adjustdescription|-environment:
\begin{adjustdescription}
\item[userId:]The user's email address. The special value me
can be used to indicate the authenticated user.
\item[userId:]The user's email address. The special value me
can be used to indicate the authenticated user.
\end{adjustdescription}
Let's test the \verb|adjustitemize|-environment:
\begin{adjustitemize}
\item \textbf{userId:} The user's email address. The special value me
can be used to indicate the authenticated user.
\item \textbf{userId:} The user's email address. The special value me
can be used to indicate the authenticated user.
\end{adjustitemize}
Let's test the \verb|description|-environment:
\begin{description}
\item[userId:]The user's email address. The special value me
can be used to indicate the authenticated user.
\item[userId:]The user's email address. The special value me
can be used to indicate the authenticated user.
\end{description}
}%
{The request body must be empty. The request body must be empty.
The request body must be empty. The request body must be empty.}
{If successful, the response body contains data with the following structure:
%!!! Be aware of the indenting with verbatim-environments !!!
\begin{lstlisting}
{
"emailAddress": string,
"messagesTotal": integer,
"threadsTotal": integer,
"historyId": string
}
\end{lstlisting}
}
\end{document}