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.

I'm trying to create a macro \AST (or an environment, if that helps) that will let me typeset abstract syntax trees, in the following way:

\AST{A}{\AST{B}{C\comma D}\comma E\comma \AST{F}{G}}

should produce output

A(B(C,
    D),
  E,
  F(G))

In particular, the \AST nodes should align with the baseline on their left (c.f. "A(B"), while the commas and close-parens should align with the last baseline of the contents (c.f. "D),"), and finally the commas and close-parens should be tight against the content to the left (there's no space between the E and comma, as if it would align with the comma after the D, for instance).

For extra brownie points, commas don't have to break lines, if the next content can fit on the line...but I'm ok just using a "," instead of a \comma macro for that.

I've tried using both parboxes and minipages, with [t] and [b] alignment, but that gives me the wrong vertical alignment on one or both sides, and never gives me the right horizontal alignment.

I think I could do this with TikZ, using "clever" node and anchor placements, but this question seems to be only text-based, and TikZ might be overkill.

I know I can fake it using an alignat* environment with an awful lot of "columns", but then the LateX markup doesn't match the logical structure of what I'm trying to typeset very well.

So, is there a way to build a box (or boxes) that behaves like above? Or is that just too different from the TeX box model? The closest I've come is the following environment

\newlength{\astheight}
\newsavebox{\astbox}
\newenvironment{AST}[1]{%
  \emph{#1}(\settowidth{\astheight}{\hskip 0pt plus 1 fill}\begin{lrbox}{\astbox}%
  \begin{minipage}[t]{\astheight}%
}{)\end{minipage}\end{lrbox}%
  \settoheight{\astheight}{\astbox}%
  \fboxsep=0pt\fbox{\usebox{\astbox}}%
  \addtolength{\astheight}{-\baselineskip}\vspace*{\astheight}%
}

But it produces output like

A(|B(|C,
  |  |D,
  |  |E
  |) |)

(where the pipes are zero-width, 4-line-tall fboxes) which just isn't right :) I'm clearly misunderstanding how the \hfill works in (restricted?) horizontal mode, and I'm not sure my basic premise is going to work, anyway...

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

I think using boxes here is overkill; it would be easier to use paragraph and/or spacing parameters to achieve the effects you're after, I think. Here's a rough example (kinda cheating because it assumes there will be no lines that wrap)

\documentclass{article}
\usepackage{calc}
\begin{document}
\newlength\astindent
\newcommand\AST[2]{%
  \begingroup
  \addtolength\astindent{\widthof{#1(}}%
  #1(#2)%
  \endgroup
}
\newcommand\comma{,\\\hspace*{\astindent}}

\noindent
\AST{A}{\AST{B}{C\comma D}\comma E\comma \AST{F}{G}}
\end{document}

As you can see, every time you enter an \AST, the indent space is increased locally.

share|improve this answer
    
That does indeed seem simpler than trying to use boxes, thanks! Is there a simple way to make it robust in the face of paragraph indentation? My full scenario is, \item ShortText: \AST{A}{...} and I'd like to see * ShortText: A(B(C, D), E) where the contents of the AST indent up to the 'A'. If I have to, I can wrap it in a minipage, but again that seems like overkill. –  Ben Lerner May 4 '11 at 8:18
    
@BenLerner As far as I remember, this isn't really possible in TeX in general (without extra markup around things); I think the best thing you can do here is put the whole thing into a minipage. –  Will Robertson May 4 '11 at 9:25
add comment

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.