7

During pdfLaTeX processing, I'm writing a string of key-value pairs to an external file. Sometimes the value will contain \# and I want only the # to be written to the file.

Here is my code which works fine as long as I just need to write plain text. Assume that every key is defined as \@empty by default; it is only written to the file if it has a value other than \@empty.

e.g. \def\objects{\@empty}\def\mystring{\@empty}

\newcommand{\setoptions}{%
  \global\edef\finaloption{}
  \getkeyval{objects}\getkeyval{mystring}
}
\newcommand{\getkeyval}[1]{%
  \def\tmpkey{#1}
  \edef\tmpval{\csname #1\endcsname}
  \ifx\@empty\tmpval
  \else
  \edef\finaloption{\finaloption,\tmpkey=\tmpval}
  \fi
}

Then later this line writes the key-value pairs to the external file:

\setoptions
\immediate\write\mypgm{\finaloption}

I suppose I need to loop through \tmpval checking for \char23? Is that a step in the right direction?

Edit: An example of the LaTeX input:

\mytag[mystring=val, objects=App\#1 App\#2,caption={my title}]{myarg}

I parse and retrieve the key-value pairs and I want to write this line to the external file:

mystring=val, objects=App#1 App#2
5

2 Answers 2

10

You can simply locally redefine \#, which is a macro (a control character to be specific, normal macros are control words) to expand to a verbatim #. This can be simply done using the newverbs package which provides \Verbdef.

% Preamble
\usepackage{newverbs}

% write code
\begingroup
\Verbdef\#{#}%
\immediate\write\mypgm{\finaloption}%
\endgroup

Without this package you can do it the following way:

% outside of any macro
% globally defines a macro \hashchar which holds a verbatim `#`
\begingroup
\catcode`\#=12
\gdef\hashchar{#}%
\endgroup

% write code
\begingroup
\let\#\hashchar
\immediate\write\mypgm{\finaloption}%
\endgroup

Usually people would use \@hashchar (requires \makeatletter .. \makeatother outside package or class files) to reduce the risk of name clashes.

(Not tested due to the lack of a MWE.)

2
1

I would defer the execution of the macro when # has category code 12:

\newcommand{\getkeyval}{\begingroup\catcode`#=12 \@getkeyval}
\newcommand{\@getkeyval}[1]{%
  \edef\tmpval{\csname #1\endcsname}%
  \ifx\@empty\tmpval
  \else
    \xdef\finaloption{\finaloption,#1=\tmpval}%
  \fi
  \endgroup}

You should not write \# in the argument, but only #. Seeing a "real life" example would be useful.

You must log in to answer this question.

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