13

In my environment I would like to automatically make a box around each individual line of text in a paragraph so that I can operate on each line. I think this should really be done in LaTeX rather than plain TeX as not to break text coloring and wrapping. I have been on this for some time now and it is still not obvious how to do this safely with LaTeX so any help would be greatly appreciated.

This is for typesetting boustrophedonic writing as seen in Safaic, Sabean and some ancient Greek writing systems as well as reverse-boustrophedonic text as seen in Rongorongo (Easter Island). For boustrophedon I can just mirror every other line with \reflectbox because this writing direction moves like an ox turns in the field. For rongrongo I can use \rotatebox[origin=c]{180}{ because every other line is rotated 180 degrees.

1
  • 2
    Perhaps you could use the technique described in Section 5.9.6 Dissecting paragraphs with \lastbox page 72, from TeX by Topic. Commented May 21, 2012 at 22:36

3 Answers 3

18

Do you mean like this? enter image description here

This is just a starter really, I put it together without too much care over finer points. In particular it assumes that each paragraph just produces boxes and inter-line penalty and glue (one of each). If the paragraph contains any vadjust material (\vspace or inserts (begin{figure} or fancy specials (any random package:-) then you are doomed, or at least need to work harder. Also it re-inserts the interline glue that was there before but that might be visually wrong if you have flipped the text so it might be better to discard that and let TeX find its own inter-line glue again.

But anyway this hopefully gets you started:

This takes more care of inter line and inter paragraph space at the start.

\documentclass{article}

\usepackage{graphicx}

\setlength\textheight{20\baselineskip}
\raggedbottom


\def\a{One two three. }
\def\b{Red, Green, Blue. }
\def\c{\a\a\b\b\a\a\a\b\b\b\a\a\b\a\b\a\b}

\makeatletter

\def\hmmx{%
 \@tempcnta\z@
 \loop
  \advance\@tempcnta\@ne
  \setbox\z@\lastbox
  \global\dimen@i\ht\z@
  \skip@\lastskip\unskip
  \count@\lastpenalty\unpenalty
 \ifdim 5sp=\wd\z@
 \else
  \global\setbox\@ne\vbox{%
  \penalty\count@
  \vskip\skip@
  \ifodd\@tempcnta
   \hbox{\reflectbox{\box\z@}}%
  \else
   \box\z@
  \fi
  \unvbox\@ne}%
 \repeat}%


\def\hmm#1{%
 \dimen@\prevdepth
 \setbox0\vbox{%
 \hbox{\vrule\@height\z@\@width5sp\@depth\dimen@}\par
 #1\par
 \hmmx}%
 \unvbox\@ne}

\makeatother

\begin{document}

text with descender: g

\hmm{\c}

\hmm{\a\c\b\c}

\end{document}
5
  • nice one, @David, but please put struts on first/last lines of paragraphs, or at least adjust the limits of line skip so that the bottom line of a paragraph doesn't bash into the first line of the paragraph that follows. (and yes, i did read your caveats.) Commented May 22, 2012 at 13:05
  • yes boxing and unboxing a paragraph defeats tex's normal skip calculation at the start. Probably it's better to get the right glue back than put in a strut, may edit later Commented May 22, 2012 at 15:30
  • @barbarabeeton better? Commented May 22, 2012 at 23:03
  • Arg. Could you please indent your code to make it a bit more comprehensible for mere mortals? See also How does (or, what happens when) Tex typeset(s) a line and linebreak? Commented Jul 1, 2014 at 22:44
  • @MartinSchröder indented although it was just \loop..\repeat I'm not sure indenting is any clearer it's just a personal tatse. Commented Jul 1, 2014 at 23:01
13

Here is another alternative, in the form of a macro named \boustrophedon :

\documentclass{article}
\usepackage{lipsum}
\usepackage{graphicx}
\parindent0pt
\begin{document}
\newcounter{cnt}
\long\def\boustrophedon#1{%
 \setbox1=\vbox{\advance\hsize by -20pt#1}%place contents in a box
   \vfuzz=10pt % supress overull warnings 
   \splittopskip=0pt %no glue at top - normal TeX 10pt
    \def\rebox{%
      \hbox to 20pt{\strut\thecnt}%
      \nobreak
      \setbox2=\vsplit 1 to 6pt
      \vbox{\unvbox2\unskip}%
      \hskip 0pt plus 0pt\relax}%end rebox
     \loop
       \stepcounter{cnt}
       \ifodd\thecnt\reflectbox{\rebox}
       \else
         \rebox
       \fi
        % row
       \ifdim \ht1>0pt % test for more rows
    \repeat % if lines exist repeat
}

\boustrophedon{\lipsum[1]}
\boustrophedon{NI$\Psi$ON ANOMHMATA MH MONAN O$\Psi$IN\\ NI$\Psi$ON ANOMHMATA MH MONAN O$\Psi$IN} 
\end{document}

enter image description here

7

Here's another alternative using @GonzaloMedina's \lastbox suggestion:

enter image description here

\documentclass{article}
\setlength{\fboxsep}{1pt}%
\usepackage{lipsum}% http://ctan.org/pkg/lipsum

\newbox\linebox

\newcount\mycount
\def\processline{% Underline every second line
  \global\advance\mycount by 1
  \ifodd\mycount
    \makebox[\textwidth][c]{\smash{\fbox{\box\linebox}}}%
  \else
    \box\linebox
  \fi}

\def\splitlines{%
  \setbox\linebox\lastbox
  \ifvoid\linebox
    \noindent\ignorespaces
  \else
    \unskip\unpenalty
    \begingroup\splitlines\space\endgroup
    \processline
  \fi}

\long\def\doit#1{\vbox{#1\par\splitlines}}

\begin{document}

\doit{\lipsum[1]}

\end{document}

Although I've boxed every odd row, the code should be easily modifiable to accomplish your requirements (rotation, reflection, etc).

The above was taken and modified from How to display only certain lines of a paragraph? which includes some other implementations as well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .