Your first question, “Why can I not reset \par
to my custom definition by using \appto\endtrivlist
?”, is pretty easy to answer, but your second one, where you ask for advice on what to do instead, requires that you specify in greater detail what you want to achieve—and please note that this is only a necessary, but not sufficient condition. (:-)
Let’s look in detail at what happens when you execute, say,
\end{center}
The first thing that the TeX compiler actually does is to expand the \end
macro, which is defined in the LaTeX kernel as follows:
\def\end#1{%
\csname end#1\endcsname\@checkend{#1}%
\expandafter\endgroup\if@endpe\@doendpe\fi
\if@ignore\@ignorefalse\ignorespaces\fi}
(see the file latex.ltx
, lines 4157–4160; but note that the version of this file which is installed on the computer I’m currently writing on is 2017/01/01, patch level 1: I’m not sure that it is the latest release). So, the next step is to execute
\csname endcenter\endcsname
that is, \endcenter
; this is defined on line 4171:
\def\endcenter{\endtrivlist}
OK, at this point \endtrivlist
is executed, and let us suppose that it contains your custom addition that resets the meaning of \par
. But there is still more code awaiting to be executed as part of the expansion of \end{center}
. The next piece is
\@checkend{center}
which is the macro that checks that \begin
and \end
declarations are correctly paired, and which plays no rôle in our present discussion. Then comes
\expandafter\endgroup\if@endpe\@doendpe\fi
This construct expands the \if@endpe
conditional before ending the current group (which is the group that was started by \begin{center}
): what’s this? Well, if you look at the definition of \endtrivlist
(which, in my version of latex.ltx
, begins on line 4616), you’ll see that one of the last things that gets executed is the \@endparenv
macro (the @noparlist
switch is certainly false in our context—provided that your center
environment is not empty—I must ask you to trust me about this, because I cannot explain all the details); this macro is defined immediately below, at lines 4638–4639:
\def\@endparenv{%
\addpenalty\@endparpenalty\addvspace\@topsepadd\@endpetrue}
You can see that the @endpe
switch is set true as the last thing.
Let’s now return to our
\expandafter\endgroup\if@endpe\@doendpe\fi
So, we’ve just seen that the @endpe
switch has just been set true as part of the execution of \endtrivlist
, and—notice this—we are now checking its value before ending the group, so we do find that it is still true. At this point, the following tokens are still awaiting execution:
\engroup \@doendpe \fi \if@ignore \@ignorefalse \ignorespaces \fi
with a true conditional pending. So, the next thing that happens is that the current group is ended (note that this undoes your custom resetting of the meaning of \par
, but this is not yet the explanation, because, at this point, you would expect \par
to resume the meaning it had before the beginning of the center
environment). Then \@doendpe
is executed.
And here lies the explanation.
Indeed, \@doendpe
is defined as follows (lines 4640–4645, that is, immediately below the definition of \@endparenv
that we saw a minute ago):
\def\@doendpe{\@endpetrue
\def\par{\@restorepar
\clubpenalty\@clubpenalty
\everypar{}\par\@endpefalse}\everypar
{{\setbox\z@\lastbox}%
\everypar{}\@endpefalse}}
We see that, when \@doendpe
is executed, \par
is redefined again.
That should suffice, for now. Of course, much more insight is needed to decide what to do next, and even to judge whether there is still some hope of pursuing your intent of figuring out an acceptable way of redefining \par
that is, at the same time, sufficiently robust to survive all the twists and turns that this control sequence undergoes in the LaTeX kernel, and not only there. In case you are now thinking of moving your patch from \endtrivlist
to \@doendpe
, bear in mind that this macro sets the definition of \par
that it sets for a very good reason, so you cannot simply overwrite it with your own. I regret to say that, like D.C., I lean toward seeing your idea as doomed to failure.
If I may, I’d like to conclude by suggesting a couple of questions that you should ask to yourself:
What should happen to paragraphs contained in lists?
Should they be treated in the same way as, or differently from,
the other ones?
Same question as 1, for paragraphs that constitute sectional headings.
(Deep breath.)
\par
primitive is saved in the macro\@@par
you can use it. – touhami Mar 15 '17 at 21:35\let\oldpar\par
and instead using\@@par
. – LaTechneuse Mar 15 '17 at 21:42\par
is redefined in multiple places all over latex, you can only do this in very restricted contexts. headings, lists, parboxes, floats .... all reset\par
– David Carlisle Mar 15 '17 at 22:53post_linebreak_filter
gets called whenever tex breaks a paragraph into lines so you can write whatever you want to write from Lua at that point. – David Carlisle Mar 15 '17 at 23:20