我想要这个:
\begin{lstlisting}
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
生成如下输出:
我已尝试过几次,但尚未成功。
下面是一个完整的测试文档,展示了我迄今为止所尝试的内容:
\documentclass{article}
% Macros for the syntax environment
\newcommand*{\cs}[1]{{\ttfamily\char`\\#1}}
\newcommand*{\meta}[1]{{\ensuremath{\langle}\rmfamily\itshape#1\/\ensuremath{\rangle}}}
\newcommand*{\oarg}[1]{{\ttfamily[\meta{#1}]}}
\newcommand*{\marg}[1]{{\ttfamily\char`\{\meta{#1}\char`\}}}
\newenvironment{syntax}{\par\medskip\bgroup\obeyspaces\strut}{\egroup\medskip}
\usepackage{listings}
% Shortcut for verbatim code
\lstMakeShortInline[basicstyle=\ttfamily]|
% First attempt to pretty-print the syntax
\lstdefinestyle{first}{%
columns=fullflexible,
basicstyle=\ttfamily,
moredelim={[is][\meta]{<}{>}},
}
\lstdefinestyle{second}{%
columns=fullflexible,
basicstyle=\ttfamily,
literate=*{<}{{$\langle$\itshape}}{1}{>}{{\/$\rangle$}}{1},
}
\begin{document}
\parindent0pt
\section{The problem}
I would like this:
\begin{lstlisting}
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}%
to generate output like this:
\begin{syntax}
\cs{mymacro}\oarg{optional argument}\marg{mandatory argument}
\end{syntax}
\section{Partial solutions}
The first attempt uses the |moredelim| key:
\begin{lstlisting}[style=first]
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
It looks like the |\meta| macro is applied to each ``word'' instead of the entire text delimited by |<| and |>|.
\medskip
The second attempt uses the \texttt{literate} key:
\begin{lstlisting}[style=second]
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
This successfully replaces the |<| and |>| characters, but doesn't apply the |\itshape| formatting.
Any suggestions? Thanks!
\end{document}
答案1
moredelim
如果您使用选项,它可以与分隔符一起使用**
。在这种情况下,分隔符宏不是在每个单词周围调用,而是在由分隔文本组成的组的开头调用。您只需将组的内容抓取到 a 中lrbox
以排版它周围的<
内容>
:
\documentclass{article}
% Macros for the syntax environment
\newenvironment{syntax}{\par\medskip\bgroup\obeyspaces\strut}{\egroup\medskip}
\makeatletter
\newenvironment{hl@env}
{\begin{lrbox}{\@tempboxa}\rmfamily\itshape}
{\end{lrbox}\ensuremath{\langle}\usebox{\@tempboxa}\kern.3ex\ensuremath{\rangle}}
\newcommand\boxmeta{%
\begin{hl@env}\bgroup\aftergroup\hl@endenv%
}
\def\hl@endenv{%
\end{hl@env}%
\egroup
}
\makeatother
\usepackage{listings}
% Shortcut for verbatim code
\lstMakeShortInline[basicstyle=\ttfamily]|
% First attempt to pretty-print the syntax
\lstdefinestyle{first}{%
columns=fullflexible,
basicstyle=\ttfamily,
moredelim=**[is][\boxmeta]{<}{>},
}
\begin{document}
\parindent0pt
\section{The problem}
I would like this:
\begin{lstlisting}
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}%
to generate output like this:
\begin{syntax}
\cs{mymacro}\oarg{optional argument}\marg{mandatory argument}
\end{syntax}
\section{Working solution}
The first attempt uses the |moredelim=**| key:
\begin{lstlisting}[style=first]
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
This works :-)
\end{document}
答案2
您可以尝试以下方法,但我有点怀疑它是否非常可靠。我担心字体更改会泄露到您不想要的地方。
\documentclass{article}
\usepackage[formats]{listings}
\lstdefinestyle{first}{%
columns=fullflexible,
basicstyle=\ttfamily,
}
\makeatletter
\lstdefineformat{argument}{%
<=$\langle$\aftergroup\rmfamily\aftergroup\itshape,%
>=$\rangle$\aftergroup\normalfont\aftergroup\lst@basicstyle}%
\makeatother
\begin{document}
\begin{lstlisting}[style=first,format=argument]
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
\end{document}
答案3
如果您愿意将命令列为morekeywords
,那么您可以使用:
\lstdefinelanguage{MyLanguage}{
showstringspaces=false,
identifierstyle=\color{black}\rmfamily\itshape,
keywordstyle=\color{black}\bfseries,
morekeywords={mymacro}% list your commands here,
}
\lstdefinestyle{third}{%
language=MyLanguage,
columns=fullflexible,
basicstyle=\ttfamily,
literate=*{<}{{$\langle$}}{1}{>}{{\/$\rangle$}}{1},
}
得出的结果是:
代码:
\documentclass{article}
\usepackage{xcolor}
% Macros for the syntax environment
\newcommand*{\cs}[1]{{\ttfamily\char`\\#1}}
\newcommand*{\meta}[1]{{\ensuremath{\langle}\rmfamily\itshape#1\/\ensuremath{\rangle}}}
\newcommand*{\oarg}[1]{{\ttfamily[\meta{#1}]}}
\newcommand*{\marg}[1]{{\ttfamily\char`\{\meta{#1}\char`\}}}
\newenvironment{syntax}{\par\medskip\bgroup\obeyspaces\strut}{\egroup\medskip}
\usepackage{listings}
% Shortcut for verbatim code
\lstMakeShortInline[basicstyle=\ttfamily]|
\lstdefinelanguage{MyLanguage}{
showstringspaces=false,
identifierstyle=\color{black}\rmfamily\itshape,
keywordstyle=\color{black}\bfseries,
morekeywords={mymacro}% list your commands here,
}
\lstdefinestyle{third}{%
language=MyLanguage,
columns=fullflexible,
basicstyle=\ttfamily,
literate=*{<}{{$\langle$}}{1}{>}{{\/$\rangle$}}{1},
}
\begin{document}
\parindent0pt
\section{The problem}
I would like this:
\begin{lstlisting}
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}%
to generate output like this:
\begin{syntax}
\cs{mymacro}\oarg{optional argument}\marg{mandatory argument}
\end{syntax}
\section{The Solution}
\begin{lstlisting}[style=third]
\mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}
\end{document}
答案4
显然,该literate
键不能强制listings
以斜体打印参数——但我们可以使用包来确定控制序列、注释和特殊字符是什么。因此,我建议将整个内容设置为斜体,然后将所有内容设置为不是一个正直的论点。
操作方法如下:
\documentclass{article}
\usepackage{xcolor,listings}
\newcommand{\macrocolor}[1]{\textcolor{violet}{#1}}
\newcommand{\commentcolor}[1]{\textcolor{purple}{#1}}
\newcommand{\literatecolori}[1]{\textcolor{cyan}{#1}}
\newcommand{\literatecolorii}[1]{\textcolor{blue}{#1}}
\newcommand{\literatecoloriii}[1]{\textcolor{orange}{#1}}
\lstset{
basicstyle=\ttfamily\upshape,
identifierstyle=\rmfamily\itshape,
language=[LaTex]TeX,
texcsstyle=*\macrocolor,
commentstyle=\commentcolor,
literate= {\{}{{\literatecolori{\{}$\langle$}}{2}
{\}}{{$\rangle$\literatecolori{\}}}}{2}
{[}{{\literatecolorii{[}$\langle$}}{2}
{]}{{$\rangle$\literatecolorii{]}}}{2}
{\$}{{\literatecoloriii{\$}}}{1},
}
\lstnewenvironment{macro}[1][]
{\lstset{texcs=[1]{#1},}}
{}
\begin{document}
\begin{macro}[mymacro]
\mymacro[opt. arg.]{mand. arg.}% Some comment
\end{macro}
\end{document}
我使用颜色是为了清晰起见,也因为我预计有些人可能会想要它们——但它们根本没有必要。
只需确保在环境的可选参数中写出您正在使用的命令。
编辑:看了 Peter Grill 的回答,我才意识到使用identifierstyle
会更明智,因为它允许删除所有当时无用的字体命令。我相应地编辑了我的答案——它不会以任何方式修改输出——但我想承认这最初是他的想法。