0

Given the following files:

book.tex

\documentclass{memoir}
\usepackage{listings}

\begin{document}
\lstlistoflistings
\chapter{Hello, world!}
\lstinputlisting{C\#/hello.cs}
\end{document}

C#/hello.cs

using System;

class Hello {
    static void Main(string[] args) {
        Console.WriteLine("Hello, world!");
    }
}

What is the correct syntax to include file C#/hello.cs as a listing in book.tex?

I tried these variants, both fail:

  • \lstinputlisting{C#/hello.cs}
  • \lstinputlisting{C\#/hello.cs}

When I try the first variant, \lstinputlisting{C#/hello.cs}, I get the following error:

! Illegal parameter number in definition of \reserved@a.
<to be read again> 
/
l.7 \lstinputlisting{C#/hello.cs}
                               
? 

When I try the second variant, \lstinputlisting{C\#/hello.cs}, I get the following error:

! Missing \endcsname inserted.
<to be read again> 
#
l.7 \lstinputlisting{C\#/hello.cs}
                                
? 

I get the same behavior with (almost) identical error messages in lualatex, pdflatex, and xelatex.

I've tried to find a solution by reading the documetnation of the listings package https://mirror.mwt.me/ctan/macros/latex/contrib/listings/listings.pdf. Alas, in vain.

What is the correct way to use the listings package to include a file that has a #-character in its pathname? (As a workaround, I could of course rename the directory from C# to Csharp, but I'd like to solve the problem, not avoid it.)

1

2 Answers 2

1

Unfortunately the author of listings probably didn't account for this case, so there isn't really a "correct" solution.

I think there are two ways, if you insist.

Method 1. Patch \lstinputlisting to allow \#

You could do this...

\let\oldlstinputlisting\lstinputlisting
\def\lstinputlisting#1{%
    \begingroup
    \escapechar=-1
    \expandafter \endgroup
    \expandafter \oldlstinputlisting
    \expandafter {\detokenize{#1}}%
}

then do something like...

\lstinputlisting{\#.txt}

but one possible disadvantage is that code like \def\filename{myfile.txt}\lstinputlistings{\filename}, which would work before the patch, now wouldn't. (it might break other things as well, I don't know.)

Method 2. Inject a catcode-other # in

Ref. characters - If \@percentchar represents %, is there a macro for #? - TeX - LaTeX Stack Exchange

\edef\hashchar{\string#}

\lstinputlisting{\hashchar.txt}

Use a \hashchar everywhere you want a #.

(this method does implicitly rely on \lstinputlisting "fully expands" the arguments, but this is more likely than not since the primitive \input etc. does for file names. Otherwise putting a catcode-other-token # into the argument itself is possible, but a bit harder)

1
  • There are \@charlb \@charrb \@backslashchar \space by the way, but you need \makeatletter for the first 3.
    – user202729
    Commented Oct 18, 2022 at 11:47
2

Method 3: Use \string## instead \#, i.e.:

\lstinputlisting{C\string##/hello.cs}
1
  • Ah right, I didn't test this one. Although it depends quite a lot on the specific implementation of the macro doing \def once (which converts it to a single #) followed by "full expansion".
    – user202729
    Commented Oct 18, 2022 at 12:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .