在自定义命令中使用列表

在自定义命令中使用列表

下午好,我遇到了以下问题:我必须描述一组具有相同格式的项目,比如属性 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 中使用以下环境时正确缩进lstlistingsverbatim处理 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}

在此处输入图片描述

相关内容