# Insert tokens where TeX would put a linebreak?

Given a TeX paragraph, is there any way to insert tokens at places where TeX would automatically insert line breaks (similar to \everypar?)

To give some context, I am writing a LaTeX package for typesetting programming language syntax. Given something like

\begin{format}
Types \alpha ::= \tau | \tau \to \tau | \mu \alpha. \tau | ...
\end{format}


It should be converted to a tabularx with columns for "Types", "\alpha", "::=", and the body of the definition (specification X). The X column is defined such that its contexts are typeset in mathmode and | is redefined to \mid. However, if the line is too long, it should wrap, and the | should appear where the ::= appeared. For example,

Types \alpha ::= \tau | \tau \to \tau
|  \mu \alpha. \tau


My tentative strategy is to insert an appropriate "\ \multicolumn{...}" sequence of tokens before every TeX linebreak, such that I can insert the | in the place where the ::= went.

Any ideas?

(P.S., I don't think existing BNF packages for LaTeX can do this -- the ones I've seen require an explicit command for breaking the line and putting the | where the ::= went.)

My suggestion would be to make it ragged right and then tell TeX that the | is a good place to break a line by playing around with values to \penalty. Depending on how you're convincing TeX that | should be replaced by \mid, you could do this with something like

\documentclass{article}
\mathcode|="8000
\begingroup
\catcode|\active
\gdef|{\penalty2000\mid\nobreak}
\endgroup
\begin{document}
\begin{flushleft}
$AAAAAAAAAA|BBBBBBBBBBB|CCCCCCCCCCCCCCCCC|DDDDDDDDDDDDD |EEEEEEEEEEEEEEE|FFFFFFFFFFFFFFFFFF|GGGGGGGGGGGGGG|HHHHHHHHHHHHH$
\end{flushleft}
\end{document}


Here's a more complete example.

\documentclass{article}
\usepackage{colonequals}
\usepackage{tabularx}
\usepackage{calc}

\makeatletter
\begingroup
\catcode|\active
\gdef\setupformatpipe{%
\mathcode\|="8000
\catcode\|\active
\def|{\penalty-1\makebox[\widthof{$\m@th{}\coloncolonequals{}$}]{$\m@th\mid$}\nobreak}%
}
\endgroup

\newenvironment{format}
{\setupformatpipe
\tabularx{\linewidth}{lr@{}>{\raggedright\arraybackslash}X}}
{\endtabularx}
\def\formatrow#1 #2::=#3\\{%
#1&$\m@th#2$&$\m@th{}\coloncolonequals#3$\\
}
\makeatother
\begin{document}
\begin{format}
\formatrow Types \alpha ::= \tau | \tau \to \tau | \mu \alpha. \tau |
AAAAAAAAAAAAA | BBBBBBBBBBBB | CCCCCCCCCCC | DDDDDDDDDDDDD
| EEEEEEEEEEEEEEEEE | FFFFFFFFFFFFFFF\\
\formatrow {} \beta ::= GGGGGGGGGGGG | HHHHHHHHHHHHHH |
IIIIIIIIIIIIIII | JJJJJJJJJJJJ | KKKKKKKKKKK | LLLLLLL\\
\end{format}
\end{document}


It does require the use of that \formatrow macro though.

• But how do I know which |'s TeX decided to break at, so that I can insert extra tokens (the \multicolumn stuff) at that point? – Christopher Monsanto Dec 15 '10 at 22:57
• @Christopher: Oh sorry, I omitted part of what I meant to say. I wouldn't use a \multicolumn there. Let me see if I can hack something up. – TH. Dec 15 '10 at 23:15
• Yeah, I see what you're doing. The problem is that the | doesn't precisely line up in the center with the ::= and the item following doesn't line up with the first item. i.e., if BBBBBBBB was the first item on a new line, it should line up with \tau. The \multicolumn trick would get around this, if it was possible. – Christopher Monsanto Dec 16 '10 at 3:32
• @Christopher: Yeah, that was just a mistake. It's fixed now. (I forgot the {} before and after the \coloncolonequals.) – TH. Dec 16 '10 at 3:51

I would put the ::= so that it is actually (partly) in the third column:

\documentclass{book}
\usepackage{array}
\begin{document}
Types &$\alpha$ & $\tau | \tau \to \tau \allowbreak | \mu \alpha. \tau$
`