# Create my own NSD

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.

-
 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

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
\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:

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! :-)

-
 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