4

Note: This question is not about getting a desired visual effect in pdf, it is concerned with LaTeX/TeX internal algorithm.

In the following code, presence of \\ sometimes produces a new internal tex-paragraph when encountered in the middle of a user-paragraph, and sometimes does not. In normal text mode, the only time it seems to not produce a new paragraph is when in fully-justified (default) alignment mode.

So the question is why did LaTeX team code this discrepancy? Was it to avoid changing the paragraph indentation for partial tex-paragraphs? Is it any better than starting a new paragraph with no indent in fully justified mode (like \par\vspace{1cm}\noindent instead of \\[1cm])?

Code (lualatex):

% >> lualatex par_vs_backslashes.tex
\documentclass{article}

\directlua{
    nodetree = require"nodetree"
    function filterprint(h)
        nodetree.print(h)
        return h
    end
    luatexbase.add_to_callback("pre_linebreak_filter",filterprint,"filterprint")
}

\begin{document}

% This produces 2 tex-internal paragraphs
Hello\\[1cm] foo\par\vspace{1cm} world

\raggedright

% This produces 3 tex-internal paragraphs
Hello\\[1cm] foo\par\vspace{1cm} world

\end{document}

Console:

% Output for fully-justified mode:

├─LOCAL_PAR 
├─HLIST subtype: indent, width: 15pt
├─GLYPH subtype: 256, char: H, width: 7.5pt, height: 6.83pt
├─GLYPH subtype: 256, char: e, width: 4.44pt, height: 4.48pt, depth: 0.11pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
├─ADJUST 
│ ╚═head:
│   └─GLUE width: 28.45pt
├─PENALTY penalty: 10000
├─GLUE stretch: +1fil
├─PENALTY penalty: -10000
├─GLUE subtype: spaceskip, width: 3.33pt, stretch: 1.66pt, shrink: 1.11pt
├─GLYPH subtype: 256, char: f, width: 3.06pt, height: 7.05pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
├─KERN kern: 0.28pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
│ ╚═  properties: {['injections'] = {['leftkern'] = 18350.08}}
├─PENALTY subtype: linepenalty, penalty: 10000
└─GLUE subtype: parfillskip, stretch: +1fil

├─LOCAL_PAR 
├─HLIST subtype: indent, width: 15pt
├─GLYPH subtype: 256, char: w, width: 7.22pt, height: 4.31pt, depth: 0.11pt
├─KERN kern: -0.28pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
│ ╚═  properties: {['injections'] = {['leftkern'] = -18350.08}}
├─GLYPH subtype: 256, char: r, width: 3.92pt, height: 4.42pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: d, width: 5.56pt, height: 6.94pt, depth: 0.11pt
├─PENALTY subtype: linepenalty, penalty: 10000
└─GLUE subtype: parfillskip, stretch: +1fil

% Output for rest of the modes (\raggedright, etc):

├─LOCAL_PAR 
├─HLIST subtype: indent
├─GLYPH subtype: 256, char: H, width: 7.5pt, height: 6.83pt
├─GLYPH subtype: 256, char: e, width: 4.44pt, height: 4.48pt, depth: 0.11pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
├─PENALTY subtype: linepenalty, penalty: 10000
└─GLUE subtype: parfillskip, stretch: +1fil

├─LOCAL_PAR 
├─HLIST subtype: indent
├─GLYPH subtype: 256, char: f, width: 3.06pt, height: 7.05pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
├─KERN kern: 0.28pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
│ ╚═  properties: {['injections'] = {['leftkern'] = 18350.08}}
├─PENALTY subtype: linepenalty, penalty: 10000
└─GLUE subtype: parfillskip, stretch: +1fil

├─LOCAL_PAR 
├─HLIST subtype: indent
├─GLYPH subtype: 256, char: w, width: 7.22pt, height: 4.31pt, depth: 0.11pt
├─KERN kern: -0.28pt
├─GLYPH subtype: 256, char: o, width: 5pt, height: 4.48pt, depth: 0.11pt
│ ╚═  properties: {['injections'] = {['leftkern'] = -18350.08}}
├─GLYPH subtype: 256, char: r, width: 3.92pt, height: 4.42pt
├─GLYPH subtype: 256, char: l, width: 2.78pt, height: 6.94pt
├─GLYPH subtype: 256, char: d, width: 5.56pt, height: 6.94pt, depth: 0.11pt
├─PENALTY subtype: linepenalty, penalty: 10000
└─GLUE subtype: parfillskip, stretch: +1fil

Output:

Screenshot of output

1
9

This predates "LaTex Team" involvement, and goes back to Leslie Lamport's original LaTeX versions, so I can't really say "why" just confirm that your observation is correct.

The documented behaviour of \\ is that it never ends the paragraph, it just forces a line break, however in \centering and similar settings \\ is redefined and does, as you say, internally use \par which is a shame as sometimes that implementation detail becomes observable eg when \parskip is non zero (although latex tries to hide that by adding a negative \parskip space after the paragraph break introduced by \\ )

\documentclass{article}

\parskip=1in
\begin{document}

\begin{center}
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  zzz\linebreak zzz aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
\end{center}

\begin{center}
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  zzz\\ zzz aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
\end{center}

\begin{center}
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  zzz\par zzz aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
  aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa
\end{center}

\end{document}
7
  • Interesting. Is there another "cleaner" implementation possible for \raggedright \raggedleft \centering where they don't start new paragraph? Or is it something inherently impossible that caused the implementers to just start a new paragraph? – reportaman Dec 2 '20 at 22:12
  • @reportaman the odd thing is not \centering starting a paragraph, but \\ being \par in the scope of that command, it could (ignoring for simplicity the optional argument) be defined to be \linebreak for example, not \par. – David Carlisle Dec 2 '20 at 22:14
  • Doesn't seem like \linebreak can do the same job as \par. Try adding \vspace{\baselineskip} after all the three: \linebreak, \\, and \par. \linebreak\vspace{\baselineskip} doesn't add vspace right at the point it is inserted (between your zzz's), \\\vspace{\baselineskip} does! If there is no way to achieve that without starting a new tex paragraph, then it seems reasonable why it is coded as \par instead of \linebreak. What they could have done was to force \parskip to 0 for partial paragraphs, and making \par insertion consistent across all text justifications. – reportaman Dec 2 '20 at 22:30
  • If you add \vspace after \\ then the expected behaviour (as happens in normal justified text) is that the space comes after the next line. – David Carlisle Dec 2 '20 at 22:42
  • the way to add space at the linebreak is to use \\[1in] or put the vspace first \vspace{1in}\\ @reportaman – David Carlisle Dec 2 '20 at 22:43

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.