3

I have been trying to write a simple new command to make a piece of code more flexible and readable (a MWE is below). In it I need to be able to pass a string to a new command that contains a hashtag #. I don't have any choice in the matter... I have to use a file that is auto produced and externally maintained which contains #1 or #2 in the file name.

Things I have tried that don't seem to be working:

  • escaping the hashtag in the argument (i.e. {a \#1.jpg}
  • \detokenize{} on the argument #1
  • \detokenize{} on the string passed as an argument

MWE:

\documentclass{article}
\usepackage{graphicx,grffile}

\usepackage{hyperref}

\graphicspath{
    {ABSOLUTE/PATH/TO/GRAPHICS}
}

\begin{document}        

    \newcommand{\Customjpg}[2]{\label{#2}\includegraphics[keepaspectratio,width=0.49\textwidth]{"#1"}}

    \Customjpg{a \#1.jpg}{Fig:R1a}

\end{document}
EngBIRD
  • 3,985
  • 2
    so your file is really called a #1.jpg ? (\string# probably works.) – David Carlisle Apr 02 '16 at 19:57
  • 1
    See http://tex.stackexchange.com/a/294791/2388 – Ulrike Fischer Apr 02 '16 at 20:03
  • @UlrikeFischer Thanks I have implemented \begingroup \catcode#=12and it helps keep the automation of my tex files cleaner than adding the\string`. I played around with the possibility of a verbatim command like that suggested in the alternate answer http://tex.stackexchange.com/a/294804/69378 but I think the local redefinition is the cleanest solution. I would be happy to accept this as an answer. Better yet, if it can be nested into it's own newcommand or environment (that doesn't propagate the same problem by still having to pass the # in a string) I would be most intrigued. – EngBIRD Apr 02 '16 at 20:23

2 Answers2

3

You can use

\edef\zz{\string#}
\includegraphics{a \zz1.png}

to get a non-special # (\# is a \chardef token which typesets a # but doesn't expand to a # in filenames etc).

David Carlisle
  • 757,742
  • That doesn't work for me. \includegraphics{a\string#1} gives ! Illegal parameter number in definition of \@tempb (I mean it works when grffile is used, but not in general) – Ulrike Fischer Apr 02 '16 at 20:25
  • @UlrikeFischer hmm so it does, who wrote that code:-) I fixed, but now it's more or less a duplicate of your answer on the other so perhaps vote to close... – David Carlisle Apr 02 '16 at 20:30
  • 1
    I would be happy to have this question closed or deleted and propose some edits to the linked question because it never came up during searches. While that question already has an accepted answer, I personally found your answer informative and complimentary. If this question is closed or deleted would it be appropriate to add this as a potential answer to the linked question? – EngBIRD Apr 02 '16 at 20:38
  • 1
    @EngBIRD well as you say this one has a better title, so perhaps just let it stand. – David Carlisle Apr 02 '16 at 20:53
3

You can locally change the catcode of the # in your command:

\documentclass{article}
%
\usepackage{graphicx}
\begin{document}
\makeatletter
\newcommand\Customjpg{\begingroup\catcode`\#=12\relax\@Customjpg}
\newcommand\@Customjpg[1]{\endgroup\includegraphics{#1}}
\Customjpg{a#1}
\end{document}

Be aware, that you can't use \Customjpg in the argument of another command.

Ulrike Fischer
  • 327,261
  • I am nesting this command within a \subfloat{} which is why egreg's answer in the linked question with the verbatim argument didn't work out for me. I could investigate whether it would be appropriate to but the subfloat inside (which I think would get around the "argument of another command problem...) – EngBIRD Apr 02 '16 at 20:40
  • @EngBIRD I had overlooked egreg's answer. It does basically the same, only in a bit more modern way. If you really need it inside subfloat better change the catcode of # more globally. – Ulrike Fischer Apr 02 '16 at 20:50
  • At the moment, I have placed it on the outside of my figure environments - is that the kind of "more globally" applied instance you had in mind? – EngBIRD Apr 02 '16 at 21:00