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.

I have the error

! LaTeX Error: Missing \begin{document}.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.30 \AddDemo{text}{Sample Text}

in the following code

\documentclass{scrbook}

\makeatletter

\providecommand\AddDemo[2]{%
  % #1 : package/identifier
  % #2 : content
  \providecommand{\demo@content@#1}{#2}%
}

\AddDemo{text}{Sample Text}%
\makeatother
\listfiles

\begin{document}
%\PrintDemo{text}
\end{document}

which I do not understand.

Basically I want to save (large) text parts which shall be printed on request as a combination of latex and listings.

share|improve this question
2  
You must use \expandafter\providecommand\csname demo@content@#1\endcsname{#2} . You can also use the provided commands of etoolbox. See: tex.ac.uk/cgi-bin/texfaq2html?label=csname –  Marco Daniel Sep 22 '11 at 15:22
add comment

2 Answers

up vote 9 down vote accepted

You are misunderstanding how TeX constructs macro names. In the code

\providecommand\AddDemo[2]{%
  % #1 : package/identifier
  % #2 : content
  \providecommand{\demo@content@#1}{#2}%
}

TeX sees a macro \demo@content@ followed by the text supplied as #1. As a result, the later is placed in the input stream, and you see the error about text in the preamble. You need to use \csname to construct the macro name:

\providecommand\AddDemo[2]{%
  % #1 : package/identifier
  % #2 : content
  \expandafter\providecommand\csname demo@content@#1\endcsname{#2}%
}

You need the \expandafter here so that the \csname is constructed before \providecommand is 'executed'.

share|improve this answer
    
Thank you. However now a similar problem exists on printing the value: \providecommand\PrintDemo[1]{% \ifcsdef{\demo@content@#1}% { % print \demo@content@#1% }% { % error if not defined \PackageError{\packagename}% {% \MessageBreak no demo for '#1' defined \MessageBreak }{} \endinput% } } this results always in '! Undefined control sequence.' \expandafter\csname demo@content@#1\endcsname does not help here –  Matthias Pospiech Sep 22 '11 at 15:36
1  
@MatthiasPospiech etoolbox has a number of tools for checking by csname, for example \ifcsdef (which 'partners' \ifdef). –  Joseph Wright Sep 22 '11 at 15:39
2  
@MatthiasPospiech You need to use a csname for \ifcsdef, so something like \ifcsdef{demo@content@#1} (notice the lack of a \ ). A csname does not have a leading \ , whereas a control sequence does. –  Joseph Wright Sep 22 '11 at 15:50
1  
(Internally \ifcsdef creates a control sequence from its csname argument, whereas \ifdef needs a control sequence argument.) –  Joseph Wright Sep 22 '11 at 15:54
add comment
\expandafter\providecommand\csname demo@content@#1\endcsname{#2}

You can't append letters to a control sequence name that way, because \demo@content@ is already a token by itself.

share|improve this answer
1  
About 44 seconds faster than me, but I typed more :-) –  Joseph Wright Sep 22 '11 at 15:21
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.