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.

Given the following MWE, where the argument for the code function contains an underscore:

\documentclass [11pt,oneside,onecolumn]{article}
\usepackage{listings}
\usepackage{filecontents}

\begin{filecontents*}{hello_world.c}
#include <stdio.h>

int main(void) {
  printf("Hello World!\n");
  // return 0;
}
\end{filecontents*}


\makeatletter
\def\code{\@ifnextchar[{\@with}{\@without}}
\def\@with[#1]#2{
}
\def\@without#1{
  \section{#1}
  \lstinputlisting[]{#1}
}
\makeatother

\begin{document}
\code{hello_world.c}
\end{document}

The same argument #1 is used in two different functions: section, which requires the underscore to be escaped, and lstinputlisting, which requires the underscore not to be escaped.

If the user escapes the filename, compilation fails because of section. If the user doesn't escape the filename, listings cannot find the filename.

How to solve the issue?

share|improve this question
    
Please add a minimal working example (MWE) that illustrates your problem. You might think that this is better but we cannot reproduce what you mean by just copy/pasting your code and compiling. Instead we have to make our own each time which is tedious. Why don't you give a full one as I did in your previous question? –  percusse Jul 27 '12 at 15:36
    
Because I didn't know about makeatletter and makeatother, which I just saw in your answer. Putting everything in a single file without those commands was causing a Use of \@ doesn't match its definition. error, which is why I didn't use a single file. I was doing my best to ease your job. Sorry about that. –  Roberto Aloi Jul 27 '12 at 16:14
    
Note that there are many ways to define commands with optional arguments that are much more robust than using \@ifnextchar. –  egreg Jul 27 '12 at 20:37
add comment

2 Answers

up vote 19 down vote accepted

Please try to make your MWE self contained (as in this answer) it really helps when answering.

You can use the eTeX primitive \detokenize to make _ safe and then T1 font encoding so a _ character gets printed as an underscore:

\documentclass [11pt,oneside,onecolumn]{article}
\usepackage[T1]{fontenc}
\makeatletter
\usepackage{listings}

\def\code{\@ifnextchar[{\@with}{\@without}}%
\def\@with[#1]#2{%
}
\def\@without#1{%
  \section{\protect\detokenize{#1}}%
  \lstinputlisting[]{#1}%
}

\makeatother

\begin{document}

\tableofcontents

\code{hello_world.c}
\end{document}
share|improve this answer
    
Works beautifully. Thanks. –  Roberto Aloi Jul 27 '12 at 16:18
    
Well, only drawback is that the underscore is not rendered correctly in the TOC (it minimizes the "w"). –  Roberto Aloi Jul 27 '12 at 16:20
1  
Sorry a \protect was missing. Also I added some % at the ends of lines (unrelated to your problem but uncommented line ends could produce unwanted white space in the output) –  David Carlisle Jul 27 '12 at 16:27
add comment

There are several packages that takes care of typesetting file names, e.g. url, path. The following example uses package url. I have assumed that the optional argument of \code has the purpose to pass options to the lstinputlisting command. In this case the hacking with \@ifnextchar is not necessary.

\documentclass [11pt,oneside,onecolumn]{article}
\usepackage[T1]{fontenc}
\usepackage{listings}
\usepackage{url}
\usepackage{makerobust}

% Define \file that typeset a file name using the url package
% that also takes care of hyphenation issues, ...
\newcommand*{\file}{}% to get an error if \file is already defined
\DeclareUrlCommand{\file}{\urlstyle{sf}}
% Different styles are available, e.g.:
% sf: sans serif font (\sffamily)
% rm: roman font (\rmfamily)
% tt: typewriter font (\ttfamily)
\MakeRobustCommand{\file}
% as robust command \file do not need \protect

\newcommand*{\code}[2][]{%
  \section{\file{#2}}%
  \lstinputlisting[{#1}]{#2}%
}

\begin{document}

\tableofcontents

\code{hello_world.c}

\end{document}
share|improve this answer
    
you have \makeatother but I don't see a \makeatletter, is that right? –  PatrickT Feb 21 at 21:18
1  
@PatrickT: Thanks for noticing. It's probably a left-over from a previous version and I have removed it now. –  Heiko Oberdiek Feb 21 at 21:20
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.