3

Is it possible to tie a TeX macro to some text (e.g. the next paragraph) or another macro?

For your information, here is a more specific description of the problem:

I am using a set-up macro

\responsible{myname}

that simply puts "myname" into the footer until the command is used again with another option. So it just expands to something like:

\def\responsible#1{\ifoot{#1}}

The problem I have is that sometimes LaTeX inserts a pagebreak before a paragraph (or \chapter, \section, ...). Since the author's name often changes from page to page \responsible must be expanded on the same page as the corresponding text.

On the one side it is clear that, when a chapter or section command is involved, \responsible could be used after the chapter command to ensure the correct function. On the other side this solution does not work for a text paragraph.

%% This works fine
\chapter{My Chapter}
\responsible{myname}

%% This:  
\responsible{myname}
example text, example text, example text.
%% or this does not work
\responsible{myname}
\chapter{My Chapter}

Is it possible to tie the command to the following paragraph without affecting the character or word spacing? Maybe even ~ is a possible solution, if the inserted space is somehow ignored by TeX.

For example the solution could look like:

\responsible{myname}\tieto example text, example text.\par 

or even:

\def\responsible#1{\ifoot{#1}\tieto} 

EDIT: MWE for the chapter/section problem:

\documentclass[a4paper,12pt]{scrreprt}
\usepackage[utf8]{inputenc}
% Footer Package
\usepackage{scrpage2}
\pagestyle{scrheadings}
% Clear footer and header
\clearscrheadfoot
% Define \responsible and set footer
\makeatletter
    \let\@responsible\relax
    \def\responsible#1{\gdef\@responsible{#1}}
    \ifoot{\@responsible}
\makeatother

% For test texts
\usepackage{blindtext}

\begin{document}
% Set author
\responsible{My Name}
\blindtext

% Does not work 
\responsible{My Name 2}% \ignorespaces here or in the definition also does not work
\chapter{A Chapter}
\blindtext

\end{document}

MWE for the text/paragraph problem:

\documentclass[a4paper,12pt]{scrreprt}
\usepackage[utf8]{inputenc}
% Footer Package
\usepackage{scrpage2}
\pagestyle{scrheadings}
% Clear footer and header
\clearscrheadfoot
% Define \responsible and set footer
\makeatletter
    \let\@responsible\relax
    \def\responsible#1{\gdef\@responsible{#1}}
    \ifoot{\@responsible}
\makeatother

% For test texts
\usepackage{blindtext}

\begin{document}
% Set author
\responsible{My Name}
\blindtext\blindtext \blindtext
\blindtext
Donec ullamcorper, felis non sodales commodo, lectus velit ultrices augue, a dignissim nibh
lectus placerat pede.
Vivamus nunc nunc, molestie ut, ultricies vel, semper in, velit.
Ut porttitor. Praesent in sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Duis fringilla tristique neque. Sed interdum libero ut metus. Pellentesque placerat.
Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent
blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a,
turpis. Mauris lacinia lorem sit amet ipsum. Nunc quis urna dictum turpis accumsan
semper.

% Does not work 
\responsible{My Name 2}% \ignorespaces here or in the definition also does not work
\blindtext

\end{document}
  • 2
    \ignorespaces? – Ulrike Fischer Apr 13 '15 at 11:48
  • Thanks! Did not know that macro. Nevertheless this does not seem to work for me (tested). – Simon M. Laube Apr 13 '15 at 11:52
  • The \chapter command issues \cleardoublepage, so the \responsible command sets things that go in the ejected page. Just set \responsible{My Name 2} after \chapter. – egreg Apr 13 '15 at 12:30
  • As I wrote, there is no big problem with chapters, but what about adjacent paragraphs? – Simon M. Laube Apr 13 '15 at 12:40
  • 2
    If you have three different paragraphs by three different people on a page, which author should be printed in the foot? – Johannes_B Apr 13 '15 at 16:36
4

This approach, using everypage, concatenates all the \responsibles into the footer in a comma separated list. Upon each page break, only the last invocation of responsible is retained going into the next page.

In order to meet the needs of the OP, I also introduce a macro \Newresponsible{} to wipe the slate clean and not carry over the prior list of names.

One of the issues cited by the OP was a desire to delay the activation of a \responsible{} invocation until the next paragraph. This request addresses the issue of when \responsible is invoked at a page boundary, it would apply the name to the prior page, instead of just at the new page. I consider my fix for this issue something of a kludge, requiring two parts.

  1. I typeset a ~\par and then negative \vspace in order to undo the \baselineskip+\parskip (kludge alert!); and

  2. I redefine \par to make the change to \@responsible at the next \par invocation.

This MWE shows several features. It provides a \responsible on page 1. It then provides a \Newresponsible at the page 1/2 boundary to show that the page 1 responsible is not carried over to page 2 and that the page 2 responsible is not pre-listed on page 1. And it also provides two \responsibles on page 2, so that one can see that only the final \responsible is carried over to page 3.

\documentclass[a4paper,12pt]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage{everypage}
% Footer Package
\usepackage{scrpage2}
\pagestyle{scrheadings}
% Clear footer and header
\clearscrheadfoot
% Define \responsible and set footer
\makeatletter
\def\@responsible{}
    \let\svpar\par
    \def\responsible#1{~\par\vspace{\dimexpr-\baselineskip-\parskip}%
      \def\par{~%
        \if\relax\@responsible\relax%
          \xdef\@responsible{#1}%
        \else%
          \xdef\@responsible{\@responsible,\ #1}%
        \fi
        \xdef\@futureresponsible{#1}%
        \let\par\svpar% 
        \svpar%
      }%
    }
\AddEverypageHook{%
  \xdef\current@responsible{\@responsible}%
  \ifoot{\current@responsible}%
  \xdef\@responsible{\@futureresponsible}%
}
\def\Newresponsible#1{\responsible{#1}\AddThispageHook{\gdef\@responsible{}}}
\makeatother

% For test texts
\usepackage{blindtext}
\begin{document}
% Set author
\responsible{My Name}
\blindtext\blindtext \blindtext
\blindtext
Donec ullamcorper, felis non sodales commodo, lectus velit ultrices augue, a dignissim nibh
lectus placerat pede.
Vivamus nunc nunc, molestie ut, ultricies vel, semper in, velit.
Ut porttitor. Praesent in sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Duis fringilla tristique neque. Sed interdum libero ut metus. Pellentesque placerat.
Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent
blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a,
turpis. Mauris lacinia lorem sit amet ipsum. Nunc quis urna dictum turpis accumsan
semper.

\Newresponsible{Name 2}%
\blindtext

\responsible{Name 3}%
\blindtext[6]
\end{document}

page 1 footer:

enter image description here

page 2 footer:

enter image description here

page 3 footer:

enter image description here

  • Wow! That's a nice solution. I will definetely be able to add this to my document(s). It might sound a bit annoying, but I still want to know if it's possible to tie the \responsible macro to the following paragraph, since your solution takes care of the names in the footer but still executes the second responsible on the first page instead of the second. – Simon M. Laube Apr 14 '15 at 17:22
  • @SimonM.Laube Please see my addendum code. Let me know if does what you desire, that is, delaying the redefinition of @responsible until the next \par invocation. – Steven B. Segletes Apr 14 '15 at 17:29
  • Thank you for your efforts. The additional code doesn't seem to work, though. I'm still getting two names on the first page. – Simon M. Laube Apr 14 '15 at 17:38
  • @SimonM.Laube I think I better understand the problem you mean. Let me think on it more. – Steven B. Segletes Apr 14 '15 at 17:40
  • 1
    This, \def\@responsible{} \let\svpar\par \def\responsible#1{~\par\vspace{\dimexpr-\baselineskip-\parskip}% \def\par{~% \if\relax\@responsible\relax% \xdef\@responsible{#1}% \else% \xdef\@responsible{\@responsible,\ #1}% \fi \xdef\@futureresponsible{#1}% \let\par\svpar% \svpar% }% } works in the sense that it delays the invocation of Name2 until the 2nd page. However, in this case, Name1 is carried over from the first page. – Steven B. Segletes Apr 14 '15 at 18:05
1

The only sure way to tell what page you are on is to use the aux file. However, to force \responsible to not occur until the second page you must use \ignorespaces or remove the \par (blank line) between it and the text.

It is possible that \listfooter will work with standard footer packages. I haven't tried it.

\documentclass[a4paper,12pt]{scrreprt}
\usepackage[utf8]{inputenc}
% Footer Package
\pagestyle{empty}
\usepackage{everypage}
\makeatletter
\newcommand{\mylabel}[2]% #1 = label name, #2 = text for \ref
{\protected@write\@auxout{}{\string\newlabel{#1}{{#2}{\thepage}}}}

\newcounter{responsible}
\newcounter{irresponsible}
\setcounter{irresponsible}{1}

\newcommand{\smartfooter}%
{\raisebox{\dimexpr -\topmargin-\headheight-\headsep-\textheight-\footskip}[0pt][0pt]{\rlap{%
  \ifodd\c@page\hspace{\oddsidemargin}\makebox[\textwidth][l]{\listfooter\hfill\thepage}%
  \else\hspace{\evensidemargin}\makebox[\textwidth][l]{\thepage\hfill\listfooter}%
  \fi}}
}%

\newcommand{\listfooter}{\ifnum\c@responsible=0\relax
  \else
    \ifnum\c@irresponsible=\c@responsible
      \ref{author:\theresponsible}%
    \else\ifnum\c@page=\pageref{author:\theresponsible}\relax
      \stepcounter{irresponsible}%
      \fi
    \ref{author:\theirresponsible}%
  \fi
\fi}

\AddEverypageHook{\smartfooter}
\makeatother

% Define \responsible and set footer
\newcommand*{\responsible}[1]{\pagebreak[3]\stepcounter{responsible}\mylabel{author:\theresponsible}{#1}}

% For test texts
\usepackage{blindtext}
\usepackage{everypage}

\begin{document}
% Set author
\responsible{My Name}
\blindtext\blindtext \blindtext
\blindtext
Donec ullamcorper, felis non sodales commodo, lectus velit ultrices augue, a dignissim nibh
lectus placerat pede.
Vivamus nunc nunc, molestie ut, ultricies vel, semper in, velit.
Ut porttitor. Praesent in sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Duis fringilla tristique neque. Sed interdum libero ut metus. Pellentesque placerat.
Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent
blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a,
turpis. Mauris lacinia lorem sit amet ipsum. Nunc quis urna dictum turpis accumsan
semper.

% Does not work 
\responsible{My Name 2}% \ignorespaces here or in the definition also does not work
\blindtext

\end{document}
  • Thank you for this answer. I will consider this solution when improving the macro. Unfortunately this still doesn't solve my problem, namely how to tie the macro to a following paragraph. – Simon M. Laube Apr 14 '15 at 17:03
  • I revised the approach to use the aux file, assuming only one author per page. – John Kormylo Apr 14 '15 at 22:49

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.