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 set of macro-s for plain [Xe]TeX to be able to create Nassi-Shneidermann Diagrams that produces a table (\halign). (I would note the cases slant lines differently in a way, that we can ignore it for this question.)

To create a table, I need to know the columns number of the final NSD, so I need to accumulate the commands. But if I accumulate the commands, I also have to put information that at the time I call a macro, I cannot know it, namely the number of columns.

So the question is, how can I make some sort of container, that can accumulate tokens, and when expanded with a parameter, it would put in the proper final result? For an example, if we ignore the borders of such diagram and I would like to put a command structure before an if-then-else structure in the diagram, it would produce a \span\omit pair in the command's cell, or with a 5 case structure, it would put 4 \span\omit macro pairs.


I don't know how I want it to be like in it's final stage but for an exact specific example, I want something like this:

\beginstruct
\command{i:=1}
\strutif i≠5
\then
j:=j-1
\else
SKIP
\strutfi
\endstruct

to yield something like this:

\halign{
&#\vrule&\hfil#\hfil\cr
\noalign{\hrule}
&i:=1\multispan2&\cr
\noalign{\hrule}
&\char`\\\hfill i≠5\hfill/\multispan2&\cr
\noalign{\hrule}
&j:=j-1&&SKIP&\cr
\noalign{\hrule}
}

But if I only write:

\beginstruct
\command{i:=1}
\endstruct

would yield something like:

\halign{
&#\vrule&\hfil#\hfil\cr
\noalign{\hrule}
&i:=1&\cr
\noalign{\hrule}
}

The problem here is that I need to know how that there is 2 collumns (excluding the borders) are there before I could write any number to \multispan. In my first example, the \multispan after i:=1 have 2 as parameter, but it is not presents after the second example.

share|improve this question
    
Can you elaborate with a specific example of you intend to you this macro. Otherwise it is hard to understand what you want. –  Aditya Oct 5 '11 at 16:37
    
As @Aditya says, a concrete example would help. Perhaps you could add the input syntax you want, and a graphic created in some way of what the result should be. –  Joseph Wright Oct 5 '11 at 16:45
    
The part about \omit\span sounds a lot like \multispan –  morbusg Oct 5 '11 at 17:53
    
Also, could you use \halign{&\vrule#&\hfil#\hfil\cr...} ie. repeat? –  morbusg Oct 5 '11 at 18:01
    
The \multispan is a better solution, and generally the position of te # sign around \vrule is not interesting to me. –  Adam L. S. Oct 5 '11 at 20:41
show 3 more comments

1 Answer 1

The TeX-language primitive for horizontal alignment, \halign, has preamble repeating properties which could perhaps be of use here. \halign sets the contents (if not told otherwise in the preamble) into \hboxes. Here are a couple of examples of its use:

\halign{&\ThisColumnGetsRepeated{#}\cr...}

The above preamble which starts off with an ampersand (&) repeats the column definition (\ThisColumnGetsRepeated{#}, i.e., run the macro called \ThisColumnGetsRepeated for the given input) for every column repeatedly, so you can just give it (by replacing the dots above) endless amount of columns:

foo& bar& baz& foo& bar& baz& ... \cr

But what if you‘d want the first column (say) to have some special treatment while still repeating some other column ad infinitum later on? There‘s another form for that:

\halign{\SomethingDifferentForThisColumn{#}&&\ThisColumnGetsRepeated{#}\cr ...}

The column definitions after && gets repeated.

Once you fall in love with \halign's repeating capabilities, you could appreciate the possibility to turn off the \tabskip glue in them for the last column. Bruno Le Floch has found a wonderful piece of magic for just that in his answer to a previous question.


The other question asked how to repeatedly call for a sequence \omit\span. It so happens that plain-tex format has a macro for precisely that, namely, \multispan. \multispan takes as argument the number of columns it ought to \span, so \multispan3 spans three columns, while \multispan{13} spans thirteen columns.


For finding out what number to feed to \multispan, you could count the columns by typesetting the table twice; first time only to count the columns, although I bet it would be easier to count the input instead. Here I've done it the hard way:

\newcount\colcount
\newcount\maxcolcount
\long\def\maxcols#1{
  \global\maxcolcount=0
  \everycr={\noalign{\global\colcount=1}}
  \setbox0=\vbox{\halign{&##\ifnum\colcount>\maxcolcount
    \global\maxcolcount=\colcount\fi\global\advance\colcount by 1\cr#1\cr}}
  \the\maxcolcount}
\maxcols{&&\cr&&&\cr&&&&&&&\cr}

^Outputs: 8

Then I tried to reproduce a NSD from an image I found:

\newdimen\boxitspace\boxitspace=0pt
\long\def\boxit#1{\vbox{\hrule\hbox{\vrule\kern\boxitspace\vbox{%
  \kern\boxitspace\parindent0pt#1\kern\boxitspace}%
  \kern\boxitspace\vrule}\hrule}}
\offinterlineskip
\boxit{\vbox{\halign{\quad\vphantom{$\Big)$}$#$\hfil&&
  \vrule\quad\vphantom{$\Big)$}$#$\hfil\quad\cr
  a \gets 1 \cr
  \multispan3\hrulefill\cr
  b \gets 1 \cr
  \multispan3\hrulefill\cr
  do~while~a < 12 \hidewidth\cr
  \omit& \multispan2\hrulefill\cr
  \omit& b \gets a*a \cr
  \omit& \multispan2\hrulefill\cr
  \omit& output~a,b \hidewidth\cr
  \omit& \multispan2\hrulefill\cr
  \omit& if~b < 100 \cr
  \omit& \multispan2\hrulefill\cr
  \omit& T & F \cr
  \omit& \multispan2\hrulefill\cr
  \omit& a\gets a+1 & a\gets a+2 \cr}}}
\bye

It looks like this:
enter image description here

But putting all these together into a single macro is a little beyond the time I have available for right now. Maybe I'll get back to this at a later time.

Happy TeXing! :-)

share|improve this answer
    
Fascinating, thank you! Though I think I still need to know how can accumulate macros for later interpreting, as I will need some kind of counter for know the maximum size of the table, to give proper value to \multispan. (‘columns used by table’ - ‘columns used by item’ + 1) –  Adam L. S. Oct 28 '11 at 19:49
    
I've updated the question with a second example, to further demonstrate my problem. –  Adam L. S. Nov 1 '11 at 7:21
    
Well that is quite helpful! Your \maxcolcount will definitely do the trick! I still have trouble to catch how can I produce the table twice though. I'll take a look in it. –  Adam L. S. Nov 2 '11 at 18:03
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.