Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.)

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer
    
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}
\begin{tabular}{ll>{\makebox[0pt]{::=}\quad}p{2cm}}
Types &$\alpha$ & $\tau | \tau \to \tau \allowbreak
              |  \mu \alpha. \tau$
\end{tabular}
\end{document}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.