1

I want to write a macro to define some text, for example header title. User will use it like:

\headertitle{Some header for a document}

I wrote it this way:

\newcommand\Headertitle{Default header title}
\newcommand\headertitle[1]{\renewcommand\Headertitle{#1}}

And it used in fancyhead like this:

\fancyhead[CO]{-\thepage- \\* \Headertitle}

Everything works perfectly. If a user won't define his own header title, Default header title would be set.

Is there some more efficient way to write this macros, where I will not create two names for one command (like \Headertitle and \headertitle in my example?

  • 3
    That's more or less the approach that the standard classes take with \title or \author, so I would say it is standard practice. If the user is not supposed to ever need \Headertitle you can make it 'private' by using a name with @ like \shalom@headertitle. Of course it would be possible to create a meta-command that sets up \headertitle and \shalom@headertitle with a default value with only one call (but the advantage of that approach only becomes visible if you have several such constructions). – moewe Feb 13 at 14:28
  • I'm not sure what would really be bad about defining two macros, but I suppose you could use a token sequence instead. If you add \newtoks\headertitle to your preamble you can set the title with e.g. \headertitle{My header title} and use it with \the\headertitle. This involves just one control sequence and defines zero macros, but does use a \toks register – Circumscribe Feb 13 at 15:34
2

There are any number of approaches. Here's one where I define two data macros: \headertitledefault for the default header and \theheadertitle for the current header. Then one command macro \setheadertitle that takes an optional header to set (or the default, if none specified).

But, as noted in comments, there is more than one "right" way to do this. It is a matter of how you think of it.

\documentclass{book}
\usepackage{fancyhdr,lipsum}
\newcommand\headertitledefault{Default header title}
\newcommand\setheadertitle[1][\headertitledefault]{\def\theheadertitle{#1}}
\setheadertitle
\pagestyle{fancy}
\begin{document}
\fancyhead[CO]{-\thepage- \\* \theheadertitle}
\section{Section}
\lipsum[1-6]
\clearpage
\setheadertitle[Some header for a document]
\lipsum[11-20]
\end{document}
2

Your approach is pretty much what the standard classes do for \title and \author, so I would say this is already a pretty solid solution (see §60.1 The Title, File F: ltsect.dtx, p. 386). Note that there is a difference between the approach of the standard styles and yours: Your definition of \Headertitle is local, the standard approach uses a global definition.

If your users are not supposed to use the value of \Headertitle anywhere in the document, you may want to consider making it into a 'private' macro with @ in its name. That also avoids the internal name with a capital letter, of which I am not too fond (I prefer all-lowercase names).

You could define a meta-macro that defines the two commands for you. That is attractive if you expect to have to define several similar macros of this general form, but obfuscates stuff unnecessarily if you only use it for one command (as in the MWE).

With Steven B. Segletes' MWE

\documentclass{book}
\usepackage{fancyhdr,lipsum}

\makeatletter
% {<name>}{<default value>}
\newcommand*{\shalom@maketitlelikecommand}[2]{%
  \expandafter\newcommand\csname shalom@#1\endcsname{#2}%
  \expandafter\newcommand\csname #1\endcsname[1]{%
    \expandafter\gdef\csname shalom@#1\endcsname{##1}}}

\shalom@maketitlelikecommand{headertitle}{Default header title}


\fancyhead[CO]{-\thepage- \\* \shalom@headertitle}
\makeatother

\headertitle{Loremm ipsum}
\pagestyle{fancy}
\begin{document}
\section{Section}
\lipsum[1-6]
\clearpage
\lipsum[11-20]
\end{document}
1

I would advise against this. What you can do is to define the second macro as a reserved one.

\documentclass{article}

\makeatletter
\newcommand{\headertitle}{%
  \@ifnextchar\bgroup{\set@headertitle}{Default header title}%
}
\newcommand{\set@headertitle}[1]{\gdef\headertitle{#1}}
\makeatother

\begin{document}

\headertitle

\headertitle{Real title}

\headertitle

\end{document}

Better is to have a \setheadertitle macro to be used in the preamble and \headertitle to be used in the document, after having been set with the former.

  • 1
    Or \newcommand{\set@headertitle}[1]{\gdef\headertitle{\@ifnextchar\bgroup{\set@headertitle}{#1}}} (followed by \set@headertitle{Default header title}), so the user can change their mind mid-document :). – Circumscribe Feb 13 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.