9

I have a problem, which I think can not be solved, except for workarounds. I want to pre-define pages and insert them later into the document. The problem is, that \par (if used in the pre-defined page) causes an error.

This is my MnWE:

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[german]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{blindtext}

\makeatletter

%%%%makes a \page_#1 which expands to #2
\def\setpage#1#2{
\expandafter\def\csname page_#1\endcsname {
\newpage
#2
\clearpage
}
}

%%%%call the pages
\def\callpage#1{
\csname page_#1\endcsname 
}

%%%%define pre-defined pages
\setpage{1}{insert Seite \par
\blindtext
}
\setpage{2}{insert Seite2 % note the implicit \par here

}

\begin{document}

Text

\callpage{1}

\callpage{2}




Wieder Text

\end{document}

I tried to redefine \par inside \setpage via

\def\par{\mbox{} \linebreak \indent}

but this is not compileable (memory error).

My \setpage-command should produce a separate page with the content of the argument #1. The argument should take anything, that can also be written between \begin{document} and \end{document}.

MaestroGlanz
  • 2,348
  • 3
    \long\def is your friend. That will accept \par inside the argument of the macro that has been defined with \long (in this case adding it in \long\def\setpage#1#2 would be enough). In any case, since you are using LaTeX, why not \newcommand? – Manuel May 21 '16 at 15:59
  • @Manuel Once again, simple as that. Why not newcommand? Because I didn't know about this difference and I'm used to it, since def is shorter. – MaestroGlanz May 21 '16 at 16:02
  • Is this a duplicate of http://tex.stackexchange.com/questions/1050/whats-the-difference-between-newcommand-and-newcommand – cgnieder May 21 '16 at 16:07
  • @clemens: I would say no, because I haven't found this SX-question via googleing. But thanks for the reference. – MaestroGlanz May 21 '16 at 16:09
  • 4
    When you'll redefine an internal command and get weird errors, you'll know why \newcommand is better – egreg May 21 '16 at 16:19

2 Answers2

9

Some remarks:

  • "Long" arguments with paragraphs (\par tokens) can only be used for macros, which are defined with \long: \long\def\macro. This is the default for \newcommand. \setpage needs to be defined this way. \callpage, however, should not allow \par tokens, which are forbidden in \csname. It can be defined by \def or the star form \newcommand*.

  • Since \makeatletter is active, the following example uses \@namedef and \@nameuse to replace the lengthy expressions with \csname with a macro with a more understandable macro name.

  • Line ends are usually converted to spaces by TeX, if not ignored after command sequence names, for instance. In vertical mode, they do not harm, but they will not be ignored in horizontal mode. The following example avoids this by commenting the line ends, when needed.

Full example:

\documentclass[12pt,a4paper]{article}
\usepackage{blindtext}

\makeatletter

%%%%makes a \page_#1 which expands to #2
\newcommand{\setpage}[2]{%
  \@namedef{page_#1}{%
    \newpage
    #2%
    \clearpage
  }%
}

%%%%call the pages
\newcommand*{\callpage}[1]{%
  \@nameuse{page_#1}%
}

%%%%define pre-defined pages
\setpage{1}{insert Seite \par
  \blindtext
}
\setpage{2}{insert Seite2 % note the implicit \par here

}

\makeatother

\begin{document}

Text

\callpage{1}

\callpage{2}

Wieder Text

\end{document}
Heiko Oberdiek
  • 271,626
6

You're wrong in thinking that \def is shorter. Maybe it looks shorter by number of characters, but it can save you from pulling your hair when some weird error shows up.

Suppose you load a package you use only some features of, but that this package uses a macro named \setpage as part of its working when the feature you exploit is called.

Can you see what will go wrong?

Using \newcommand, in this case, will tell you that the name is taken and you'll just say “OK, let me change the name”.

Correct definitions follow.

\newcommand\setpage[2]{%
  \expandafter\def\csname glanz@page@#1\endcsname{%
    \newpage
    #2%
    \clearpage
  }%
}

\newcommand\callpage[1]{%
  \csname glanz@page@#1\endcsname
}

Using @ is safer than _ (some packages make _ active and your usage could break). Also adding a prefix will emulate a “namespace”, minimizing the risk that you redefine a macro already taken.

Note the % for protecting end-of-lines.

The macros defined with \newcommand are automatically \long, so they allow \par in their arguments.

egreg
  • 1,121,712