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.

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
share|improve this question
    
It would be better if you limit your question to the core issue (the writing of the hash char). Having all the keyval things on top just makes it harder to see what you want. –  Martin Scharrer Dec 9 '11 at 20:34
    
\char23 and # are not always the same. While both will typeset the same character, the first doesn't expand to the latter. Also do you really have \# or #? In the case of \#, just redefine that macro (!) to produce a verbatim #. –  Martin Scharrer Dec 9 '11 at 20:36
    
    
thanks. That answer is for a different situation where the special characters are desired in the external file. I have source with the character escaped (so LaTeX has no problem) and I want to write it out unescaped. Sorry I wasn't clear on that. –  Tim A Dec 9 '11 at 21:08
add comment

2 Answers

up vote 8 down vote accepted

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.)

share|improve this answer
    
Thanks. I didn't see how to create a MWE but I will try harder next time. I was trying to show the method I was using. I did exactly what you said with the macros and it works great. –  Tim A Dec 9 '11 at 21:28
add comment

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.

share|improve this answer
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.