Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like this:

\begin{lstlisting}
  \mymacro[<optional argument>]{<mandatory argument>}
\end{lstlisting}

to generate output like this:

Desired output

I've made a couple attempts at this, but haven't succeeded yet.

Partial solutions

Here's a complete test document that shows what I've tried so far:

\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}
share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

It works with delimiters, if you use moredelim with the ** option. In this case, the delimiter macro is invoked not around every single word, but at the begin of the group that is made out of the delimited text. You just have to grab the group's content into a lrbox to typeset the < and > around it:

\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}

enter image description here

share|improve this answer
    
Can we add the italic correction before the right angle bracket? (Compare $\langle$\itshape optional$rlangle$ with $\langle$\itshape optional\/$\rangle$.) –  godbyk Mar 15 '12 at 22:38
    
@godbyk: Not directly as the italic content has been boxed, but we could mimic it's effect, e.g. by \kern.3ex. See updated answer. –  Daniel Mar 15 '12 at 22:56
add comment

You could try the following but I doubt a bit that it is very robust. I fear that the font changes leak out to places where you don't want them.

\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}
share|improve this answer
    
I like the succinctness of this solution. Can the spaces at the beginning of the lines be preserved? –  godbyk Mar 15 '12 at 22:14
add comment

If you are willing to list the commands as morekeywords, then you could use:

\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},
}

which yields:

enter image description here

Code:

\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}
share|improve this answer
    
I think listing each macro as a keyword might get a bit tedious. Another example use would be \mymacro{<placeholder>}{verbatim text here should be monospaced}. Your solution prints the verbatim text in italic. Thanks for the idea, though! –  godbyk Mar 15 '12 at 21:37
add comment

Apparently, the literate key cannot force listings to print the argument in italics – but we can use the package to determine what are the control sequences, the comments, and the special characters. Hence, I suggest setting the whole thing in italics and then setting everything that's not an argument back upright.

Here is how you do it:

\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}

enter image description here

I have used colours for clarity, and also because I expect some people might want them – but they are not necessary at all.

Just make sure to write which commands you are using in the optional argument of the environment.

Edit: Looking at Peter Grill's answer, I have just realised that using identifierstyle would be wiser, as it allows to remove all of the then useless font commands everywhere. I have edited my answer accordingly – it does not modify the output in any way – but I want to acknowledge that it was his idea originally.

share|improve this answer
    
In the case where I want to provide an example use, I might type \mymacro{Verbatim text here} and expect that the verbatim text appear monospaced (i.e., not italic and not surrounded by angle brackets). –  godbyk Mar 15 '12 at 21:40
    
@godbyk Inserting the angle brackets automatically seemed better as an answer to your question (because I would be lazy to type them) but obviously you should use \lstdefinestyle and create environments accordingly – so you can have several different variants. Having two environments with a semantic distinction (one for explaining macros and one for examples) allows you to modify them separately later if needed. –  ienissei Mar 15 '12 at 21:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.