7

Here is an MWE representing my attempt to achieve antilabe in dramatic verse. (I felt the implementation in eledmac was more than I needed.) Ideally, I'd like the macro to set the spacing by just "looking" at the previous line of dialogue, but I think I may need to learn more TeX to do that. Do you think there is a simple way to do that?

\documentclass{article}
\usepackage{calc}
\makeatletter
\def\@hspace#1{\begingroup\setlength\dimen@{#1}\hskip\dimen@\endgroup}
\makeatother
\newcommand{\cn}[1]{\textsc{#1}}
\newcommand{\labe}[1]{\hspace{\widthof{#1}-\widthof{\cn{Xxx.}}}}

\begin{document} \setlength{\parindent}{0in}

\cn{Sat}. But who would not lie down here in the meadow\ & long daydream on the blossom-stained glade’s\ Wide & warm & welcoming breast?

\cn{Fur}. \labe{Wide & warm & welcoming breast?} Please let’s go\ Into the Deep White Wood as the light fades\ For this bright pocked & dappled field abrades\ The eye! & no one wants more songs about...

\end{document}

Sample Antilabe

Update: the solutions that are working well appear to use the position on the page rather than the width of the text to be followed. egreg's solution, for example, handles multiple antilabes per metrical line:

Sample Multi-Antilabe

commonhare
  • 2,630

4 Answers4

9

You can use zref-savepos. Two runs of LaTeX are necessary if a new \antilabe macro appears.

The macro \antilabe will save the x-position of the last word in the line and in the next nonempty line (that should start with \cn) the initial x-position is saved too, so we can issue the wanted \hspace (the character's name is typeset in a zero width box, in this case).

\documentclass{article}
\usepackage{zref-savepos,zref-user}

\newif\ifantilabe \newcounter{antilabe} \newcommand{\cn}[1]{% \par \ifantilabe \makebox[0pt][l]{\textsc{#1}.}% \zsaveposx{antilabe-\theantilabe-b}% \hspace{\numexpr\zposx{antilabe-\theantilabe-a}-\zposx{antilabe-\theantilabe-b}\relax sp}% \space \else \textsc{#1.}% \fi \antilabefalse }

\newcommand{\antilabe}{% \unskip \stepcounter{antilabe}% \antilabetrue \zsaveposx{antilabe-\theantilabe-a}% }

\newenvironment{dialogue} {\par\setlength{\parindent}{0pt}} {\par}

\begin{document}

\begin{dialogue} \cn{Sat} But who would not lie down here in the meadow\ & long daydream on the blossom-stained glade’s\ Wide & warm & welcoming breast?\antilabe

\cn{Fur} Please let’s go\ Into the Deep White Wood as the light fades\ For this bright pocked & dappled field abrades\ The eye! & no one wants more songs about...

\cn{Sat} But who would not lie down here in the meadow\ & long daydream on the blossom-stained glade’s\ Wide & warm & welcoming breast?\antilabe \end{dialogue}

\end{document}

enter image description here

egreg
  • 1,121,712
5

Out-of-the box approach: Use \hphantom

You are reimplementing \hphantom. (And verse). The following produces the same results, except for some indentation before the verse environment. You can remove that by adding this to your preamble: \AtBeginEnvironment{verse}{\setlength{\leftmargini}{0pt}}.

\documentclass{article}
\newcommand{\cn}[1]{\textsc{#1.}}

\begin{document} \begin{verse} \cn{Sat} But who would not lie down here in the meadow\ & long daydream on the blossom-stained glade’s\ Wide & warm & welcoming breast?

\cn{Fur} \hphantom{Wide \& warm \& welcoming breast?} Please let’s go\\
Into the Deep White Wood as the light fades\\
For this bright pocked \& dappled field abrades\\
The eye! \& no one wants more songs about\dots{}

\end{verse}

\end{document}

More automatic solution

Instead of repeating the text you want to offset in the argument to \hphantom you can create a command that will store that text the first time you use it and then recall it.

\documentclass{article}
\NewDocumentCommand{\cn}{ m }{\textsc{#1.}}

\makeatletter % Define blank dummy text in private command \NewDocumentCommand{@thisantilabe}{}{}

% Create a command to store dummy text, and print the text \NewDocumentCommand{\antilabethis}{ m }{% \RenewDocumentCommand{@thisantilabe}{}{#1}% #1% }

% Insert horizontal space, using either stored dummy text, or the optional % argument if provided \NewDocumentCommand{\antilabe}{ o }{% \IfValueTF{#1} {\hphantom{#1}} {\hphantom{@thisantilabe}}% } \makeatother

\begin{document} \begin{verse} \cn{Sat} But who would not lie down here in the meadow \ & long daydream on the blossom-stained glade’s \ \antilabethis{Wide & warm & welcoming breast?} % mark the text

\cn{Fur} \antilabe{} Please let’s go \\
Into the Deep White Wood as the light fades \\
For this bright pocked \& dappled field abrades \\
The eye! \& no one wants more songs about\dots{}

\antilabethis{\cn{Knuth} expanding macros---} \\
\antilabe{} but still no one wants \\
to set the type by hand \\

\cn{Lamport}
\antilabe[to set the type by hand] so we keep using \\
software built in nineteen eighty-two.

\end{verse}

\end{document}

enter image description here

musarithmia
  • 12,463
  • So much goodness here; please give me a bit of time to study this. But quickly: does verse environment contribute anything if entire document is in verse? – commonhare Oct 01 '21 at 13:38
  • Yes. It is usually a bad practice to use \ in ordinary text because it can cause spacing problems and generate other unexpected behavior (https://tex.stackexchange.com/questions/82664/when-to-use-par-and-when-newline-or-blank-lines). The verse environment redefines it in a way that works for verse; it automatically "reflows" and indents lines that are longer than the width of the text block; and it can span multiple pages. You can nest it inside a multicolumn and other kinds of things without any problems, and it's a core component of LaTeX. – musarithmia Oct 01 '21 at 16:54
  • All that said, reledmac really is the best package for typesetting verse of greater complexity, but it does have a steep learning curve and the commands it provides are lower-level than I would prefer; in other words the user interface is too much "in the weeds" of typesetting. But this is the strength of LaTeX as a macro system: you can figure out what your most common patterns are with low-level commands and then abstract them into a higher level command where you don't have to think about it again. – musarithmia Oct 01 '21 at 16:56
  • I'm using the new command syntax that was first introduced in the xparse package and now is integrated into the LaTeX core. Instead of \newcommand{\applychange}[1]{\change{#1}} you would write \NewDocumentCommand{\applychange}{ m }{\change{#1}}. The m means a mandatory argument. I also use one with an optional argument, using o in that place. The IfValueTF{#1}{true}{false} checks the value of the argument, and if an optional argument is supplied, it uses the first branch of code (where I wrote true just now); otherwise it uses the second branch. – musarithmia Oct 01 '21 at 17:04
  • 1
    Just one (possible) problem with \hphantom: It is a fixed width, and thus starts after whatever is produced by \cn (and you also leave a typed space which will be an end-of-sentence space in the output. If the argument of \cn is particularly wide (granted, that's unlikely), the actual output text will be shoved even further to the right. If it's important that this text begin a fixed distance to the right of the end of the previous line, you should look at this again. – barbara beeton Oct 01 '21 at 20:59
  • I am having trouble with this new syntax on Overleaf's distribution. (I don't know if Overleaf is a dirty word round here...I only recently switched to it.) – commonhare Oct 02 '21 at 20:50
  • @commonhare Use the tools that work for you! :) no prejudice against Overleaf here, I just don't know anything about it. You would need to add \usepackage{xparse} before the first \NewDocumentCommand if they aren't using the latest version of LaTeX. – musarithmia Oct 02 '21 at 21:47
4

Just for fun. Don't forget to run it twice.

\documentclass{article}
\usepackage{calc}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\newcounter{markindex} \newcommand{\eol}{\stepcounter{markindex}\tikzmark{eol\themarkindex}\par}

\newcommand{\cn}[1]{\tikz[remember picture, baseline=(origin)]{\coordinate (origin) at (0,0); \node[inner sep=0pt, anchor=base west]{\textsc #1.}; \coordinate (eol) at (pic cs:eol\themarkindex); \path(origin -| eol);}}

\begin{document} \setlength{\parindent}{0in}\rlap{\tikzmark{eol0}}%

\cn{Sat} But who would not lie down here in the meadow & long daydream on the blossom-stained glade’s Wide & warm & welcoming breast?\eol

\cn{Fur} Wide & warm & welcoming breast? Please let’s go Into the Deep White Wood as the light fades For this bright pocked & dappled field abrades The eye! & no one wants more songs about...\eol

\end{document}

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
4

Here is a solution using the tabbing environment from plain LaTeX: Remember the current position (\=), start a new line, typeset the label, and jump to the remembered position (\>).

\documentclass{article}
\newcommand\cn[1]{\textsc{#1}.}
\begin{document}
\begin{tabbing}
\cn{Sat}  But who would not lie down here in the meadow\\
\& long daydream on the blossom-stained glade’s\\
Wide \& warm \& welcoming breast? \=\\
\cn{Fur}\>Please let’s go\\
Into the Deep White Wood as the light fades\\
For this bright pocked \& dappled field abrades\\
The eye!  \& no one wants more songs about...
\end{tabbing}
\end{document}

enter image description here

gernot
  • 49,614
  • It was not clear to me how to adapt this to suppress the behaviour when antilabe is not desired. – commonhare Oct 02 '21 at 21:00
  • @commonhare This makes it in fact easier. Thought you want it always to happen, automatically, which incurred the problem of starting the process. – gernot Oct 03 '21 at 10:39