4

I want to align the last word of a paragraph to the right like this example from The TeXbook.

This works great with a justified paragraph, but fails with a \raggedright paragraph.

In case it's relevant, my specific example in the MWE example below includes a slightly more complicated paragraph setup for typesetting psalms based on code from this answer.

There are two issues with my current set up.

  1. The second to last word in the paragraph wraps on to the last line even when there is space for it on the previous line.
  2. The last word of the paragraph (Selah) is not set flush right.

I also want to avoid hyphenation.

\documentclass{article}

\usepackage{xparse}
\usepackage[showframe,textwidth=5.6cm,textheight=10cm]{geometry}
\parindent 0em

\ExplSyntaxOn

\dim_new:N \l__scripture_indent_dim

\dim_set:Nn \l__scripture_indent_dim { 1em }

\cs_new:Nn \scripture_vs:n
  {
    \textsuperscript {#1}
  }

\cs_new:Nn \scripture_vs_overlap_left:n
  {
    \hbox_overlap_left:n
      {
        \scripture_vs:n {#1}
      }
  }

\cs_new:Nn \scripture_format_selah:n
  {
    \emph {#1}
  }

\cs_new:Nn \scripture_selah:
  {
    {
      \unskip
      \nobreak
      \hfil
      \penalty 50
      \skip_horizontal:N 2em
      \hbox:n {}
      \nobreak
      \hfil
      \scripture_format_selah:n { Selah }
      \parfillskip = 0pt
      \finalhyphendemerits = 0
      \endgraf
      \skip_vertical:n { -\baselineskip }
      \leavevmode
    }
  }

\cs_new:Nn \scripture_vs_outdent_overlap_left:n
  {
    \skip_horizontal:N -\l__scripture_indent_dim
    \scripture_vs_overlap_left:n {#1}
    \skip_horizontal:N \l__scripture_indent_dim
  }

\cs_new_protected:Nn \scripture_psalm_par:
  {
    \mode_if_vertical:TF
      {
        \cs_set_eq:NN \vs \scripture_vs_overlap_left:n
        \noindent
      }
      {
        \cs_set_eq:NN \vs \scripture_vs_outdent_overlap_left:n
        \endgraf
      }
    \dim_set:Nn \hangindent { 4 \l__scripture_indent_dim }
  }

\NewDocumentCommand \selah { }
  {
    \scripture_selah:
  }

\NewDocumentEnvironment {psalm} { }
  {
    \raggedright
    \cs_set_eq:NN \vs \scripture_vs_overlap_left:n
    \cs_set_eq:NN \par \scripture_psalm_par:
    \dim_set_eq:NN \leftskip \l__scripture_indent_dim
    \dim_set_eq:NN \parindent \l__scripture_indent_dim
    \obeylines
  }
  { }

\ExplSyntaxOff

\begin{document}

\section*{What I get}

\begin{psalm}
  \vs{1}\textsc{Lord}, how many are my foes!
  How many rise up against me!

  \vs{2}Many are saying of me,
  ‘God will not deliver him.’\selah\medskip

  \vs{3}But you, \textsc{Lord}, are a shield around me,
  my glory, the One who lifts my head high.

  \vs{4}I call out to the Lord,
  and he answers me from his holy mountain.\selah
\end{psalm}

\section*{What I'd like}

\hspace*{2em}`God will not deliver him.'\selah

\medskip

\hspace*{2em}and he answers me from his \\
\hspace*{5em}holy mountain.\selah

\end{document}

output

4

Looks like you can slightly modify the \scripture_selah definition. I added the \hspace*{0.025\textwidth} just to make sure there is some extra space, so that Selah is padded and not immediately flush (if there is enough space, e.g. with him.').

(version using only primitives)

\cs_new:Nn \scripture_selah:
{
    \hfill\null%
    \penalty -5%
    \null\hfill%
    \kern 1em\scripture_format_selah:n {Selah}%
    \skip_vertical:n { -\baselineskip }
    \leavevmode
}

(minimal changes version)

\cs_new:Nn \scripture_selah:
  {
    {
      \unskip
      \hfil
      \penalty 50
      \hbox:n {}
      \nobreak
      \hspace*{\fill}
      \scripture_format_selah:n { \hspace*{0.025\textwidth}Selah }
      \parfillskip = 0pt
      \finalhyphendemerits = 0
      \endgraf
      \skip_vertical:n { -\baselineskip }
      \leavevmode
    }
  }

(version with minimal code)

\cs_new:Nn \scripture_selah:
  {
    {
      \hfil
      \penalty 50
      \hspace*{\fill}
      \scripture_format_selah:n { \hspace*{0.025\textwidth}Selah }
      \skip_vertical:n { -\baselineskip }
      \leavevmode
    }
  }

modified horizontal formatting

This works in the particular example that you provided. I am not sure if this will robustly work in every situation that you will be using it in.

EDIT:

I was looking more into \hbox:n and I really don't think you want to use it here (see my "version with minimal code"). It is meant roughly as a hook just before \par. If you wrap \scripture_format_selah:n within \hbox:n (i.e. \hbox:n {\scripture_format_selah:n ...}, you will get the same result as without using \hbox:n in this situation. Therefore, I opted to ignore it.

  • Thanks. I'll do some experimenting. I don't claim to fully understand the code from the TeXbook, but my use case is simpler in some respects so the code may be able to be simplified. – David Purton Dec 18 '18 at 5:43
  • BTW, using \hspace* is essentially doing the same as the \hbox:n{}\nobreak, so you're still using it. – David Purton Dec 18 '18 at 6:33
  • @DavidPurton I added a new version (at the top) using only plain TeX primitives. Not sure if you prefer this one, but it works because of the \penalty -5 which coaxes a line break (but not strongly). For example, it still produces the image above, but for #2, if you delete him then Selah jumps up to the same line as the text. – whatisit Dec 19 '18 at 2:44

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.