% This is a file written using noweb
%
% $Id: output.nw,v 2.1 1997/07/08 19:00:45 gaertner Exp $
%

\documentclass{article}
\usepackage{a4,pretzeldoc,version,noweb}
\begin{document}

\includeversion{bigspecs}
%\includeversion{impls}
%\excludeversion{bigspecs}% without elaborate specification
\excludeversion{impls}% without implementation



\title{The Output Class}
\author{Felix G\"artner}
\maketitle


\begin{abstract}
  This text contains a description of a new \CPP\ class called
  [[Output]]. This class is used to process objects that contain
  prettyprinting information (instances of the [[Attribute]] class)
  and turn them into screen or typesetter dependent output. Also, the
  text presents a way, how to create specialized subclasses of
  [[Output]] to adapt to different output targets.
\end{abstract}


\tableofcontents




\section{Introduction to the Output Class}

This text contains the specifications \begin{impls} and implementation
\end{impls} for a new \CPP\ class called [[Output]]. This class is
part of a project called ``pretzel'' whose goal is to build a
prettyprinter generator.

So what actually are objects of type [[Output]]? To understand the
answer to this question you have to know, what attributes (in the
sense of this project) are and how the prettyprinter generated by
this system works.
 %
\begin{bigspecs}
  I will give a very brief description of this topic here now. You can
  find more information about this if you read the main documentation
  for this project.

  The prettyprinter takes a {\em formatted syntax} as input and
  produces a parser for this language. A formatted syntax is a context
  free attribute grammar that contains special terminal symbols called
  {\em format commands}. These format commands control the appearance
  of the text and (together with the textual form of the input) form
  the attributes (or semantic values) of the grammar tokens.

  When text of a language is parsed, the prettyprinter constructs a
  parse tree and an ``attribute'' tree at the same time, thus forming
  one big attribute (tree) for the final token. This tree implicitly
  contains all information needed to prettyprint the parsed text. The
  remaining task is to output this attribute tree to a file (or in
  this case a \CPP\ output stream object). As you might have guessed,
  this is the main purpose of the Output class. Outputs output
  attributes.

\end{bigspecs}

\medskip This text will first present the format commands used by the
prettyprinter and will then address the problem of typesetter
dependence. After this, it will show how objects of type [[Output]] can
be used and how specialized subclasses for other targets can be created.

@

So here is a brief overview of the header file. The named sections
will be filled up in the course of this text.

<<header>>=
#ifndef  OUTPUT_H
#define  OUTPUT_H

<<Header files to include in the specification>>

<<Macro definitions in the specification>>

<<Definition of format commands>>
<<Definition of the [[Output]] class>>

#endif
@

\begin{impls}

  The implementation will be described simultaeneously with the
  specifications. The implementation of the output class is quite
  simple and rather straightforward. There are, however, a few
  interesting (and tricky) bits that need special attention. I'll warn
  you if we come across one of them.

  The implementation starts off with this chunk.

<<implementation>>=
/* this is the implementation of the Output class */

#include"output.h" /* include the own header */
<<Other includes in the implementation>>

<<Definition of the names of the format commands>>

<<Static variables in the implementation>>

<<Implementation of the [[Output]] class>>
@

\end{impls}




\section{Format commands}

Format commands are abstract instructions for a typesetter or any
other output device.\footnote{You can use a markup formatter like
  \TeX\ or a simple line printer, which of course cannot take on
  things like automatic line and page breaks, etc.  In the following
  text I will therefore always refer to the output device as the
  typesetter.} For example they tell the typesetter to force a line
break, to add some space to the current amount of indentation or to
back up a little. They are abstract in such a way that they can be
interpreted differently depending on the capabilities of the
typesetter and the taste of the user who is using it. Format commands
are intermixed with the prettyprinted source code text in a way
specified by the user (using an attribute grammar). See table
\ref{tab:formatcommands} for a complete list of all supported format
commands. As is shown in the main part of the project documentation,
they are sufficient to format all desired features of today's
programming languages.  The special way in which to use them is again
described in the main documentation of this project.
 %
\begin{bigspecs}
  However I will give a very short example here.
\end{bigspecs}

\begin{table}
  \begin{center}
    \leavevmode
    \begin{tabular}{lp{8cm}}
{\it null}    & empty command \\
{\it indent}  & indents the next line a little more \\
{\it outdent} & takes back the last indentation (de-indent) \\
{\it force}   & forces a line break \\
{\it break\_space} & denotes a possible space for a line break \\
{\it opt$\,n$}, $n \in \{0,\dots,9\}$ & denotes an optional line
     break with the continuation line indented a litte with
     respect to the normal starting position. This line break will
     score a penalty of $10n$.\\
{\it backup} & denotes a small backspace\\
{\it big\_force} & forces a line break and inserts a little extra
     space \\
{\it no\_indent} & causes the current line to be output
     flushleft\\
{\it cancel} & obliterates any {\it break\_space}, {\it opt},
     {\it force} or {\it big\_force} command that immediatly
     precedes or follows it and also cancels any {\it backup}
     command that follows it.
    \end{tabular}
    \caption{List of format commands supported by the [[Output]] class.}
    \label{tab:formatcommands}
  \end{center}
\end{table}

\begin{bigspecs}
To give you a faint idea of how these format commands work
here's a small example that introduce the [[indent]], [[outdent]] and
[[force]] commands:

\smallskip Say we want to format an \res{if}-\res{then} construct in
\PASCAL\ and we want to indent the conditional part of it a little. To
achieve this you would have to insert the format commands into the
source text as follows:

\begin{inp}
if a>0 then \fmt{indent} \fmt{force} begin abs := 1 end; \fmt{outdent}
\end{inp}

\noindent The previous text would yield something like this:

\begin{outp}
\res{if} $a>0$ \res{then} \myindent\myforce
  \res{begin} \id{abs}\ass$1$ \res{end};\myoutdent\myforce
\end{outp}

\noindent This example shows nicely that \fmt{indent} and
\fmt{outdent} only take effect after a line break, e.g.~they determine
the indentation of the following line. This is useful if you sometimes
want a line break and other times you don't. For example you could
only want a line break in the previous example if there are
\res{begin} and \res{end} keywords in the source code. If they are
missing you might want to have the formatting like this:

\begin{outp}
\res{if} $a>0$ \res{then} \id{abs}\ass$1$; \myforce
\end{outp}

\noindent The only thing you have to do is {\em not} to insert a
\fmt{force}. This leaves you free to insert \fmt{indent}s and
\fmt{outdent}s automatically before and behind the conditional part of
the construct, as is usefull during automatic parsing of this small
example. Again you must confer the main documentation of this project
for a more detailed description.

\end{bigspecs}


@ Format commands are declared as an enumeration type
[[Format_command]] using the names from the above list. The numbers assigned
to the commands are only important for the implementation.

<<Definition of format commands>>=
enum Format_command {
    null        = 0,
    indent      = 1,
    outdent     = 2,
    opt0        = 3,
    opt1        = 4,
    opt2        = 5,
    opt3        = 6,
    opt4        = 7,
    opt5        = 8,
    opt6        = 9,
    opt7        = 10,
    opt8        = 11,
    opt9        = 12,
    backup      = 13,
    break_space = 14,
    force       = 15,
    big_force   = 16,
    no_indent   = 17,
    cancel      = 18
};

@ As the format commands are declared as an enumeration type, they are
represented by a number at run time. To nevertheless have access to
the actual {\em name} of a format command there is an array of strings
present from which the name of a format command can be won.

So suppose [[fc]] is a format command, then
 %
\begin{quote}
  [[Format_command_str[fc] ]]\par
\end{quote}
 %
is the name of [[fc]] as a string ([[char*]]).

<<Definition of format commands>>=
extern char *Format_command_str[];

@

\begin{impls}

The names of the format commands are stored in the following array.

<<Definition of the names of the format commands>>=
char *Format_command_str[] =
    {
    "null",
    "indent",
    "outdent",
    "opt0",
    "opt1",
    "opt2",
    "opt3",
    "opt4",
    "opt5",
    "opt6",
    "opt7",
    "opt8",
    "opt9",
    "backup",
    "break_space",
    "force",
    "big_force",
    "no_indent",
    "cancel"
};

@

\end{impls}






\section{Typesetter Dependence}

As mentioned above, the interpretation of format commands by the
output device (the typesetter) depends on the capabilities of
this `machine'. For example, a simple matrix-dot line
printer will have problems doing a \fmt{backup} or determining
the place of a line break by itself, whereas a sophisticated
formatting system like \TeX\ will be able to do all this and
even more.

It is clear, that the typesetter dependence starts on a level
below the formatting commands. Indeed, formatting commands have been
introduced specifically to have an abstraction of formatting
requirements. So the typesetter dependence can be encapsulated
within the [[Output]] class presented here.

How is this done? In general, objects of the [[Output]] class are
filters that interpret a stream of attributes and put them into
a form that the typesetter can understand. We cannot hardcode
this interpretation into the class, as this would inhibit a user
from using several prettyprinters with different targets in a
single program. Here object oriented approaches come in handy.

We will think of typesetter dependent output objects as
specializations of an `abstract' output.  This maps to the idea of
having an abstract base class [[Output]] and having one subclass per
typesetter that we want as target. The specialized subclasses have all
typesetter dependencies built in to them and the abstract base class
does nothing else as dynamic dispatch.

This module will present the abstract base class definition and
will show by example how to build a specialized [[Output]] class.
The example has \LaTeX\ as target typesetter.


\section{Using the Output Class (Overview)}

\begin{flushright}
{\it Outputs output attributes.}
\end{flushright}

\noindent Here now is an overview of how to use [[Outputs]]. You need at
least one output to output an attribute. Outputs have the
interpretation of the format commands built in to them. However, as
this is typesetter dependent. you will need to choose a specific
subclass of the [[Output]] class.

\begin{table}
  \begin{center}
    \leavevmode
    \begin{tabular}{llp{6cm}}
[[Output(ostream&)]] & & constructor, sends all output to this object
  to the given [[ostream]] \\
[[~Output()]] & & destructor \\
[[do_output(char*)]] & [[void]] & output a string \\
[[do_output(Format_command)]] & [[void]] & output a format command \\
    \end{tabular}
    \caption{Member functions of the [[Output]] class.}
    \label{tab:outputfunctions}
  \end{center}
\end{table}




Table \ref{tab:outputfunctions} lists the functions you can use on an
output.  So, if you want to create an output called [[outp]] that is
connected to the output stream [[os]], then you should say something
like this:
 %
\begin{quote}
  [[Output outp(os);]]
\end{quote}
 %
The overloaded [[do_output]] member function does automatic
interpretation of the format commands. So, if [[o]] is an output the
command
 %
\begin{quote}
  [[o.do_output(force);]]
\end{quote}
 %
will produce an interpretation of a \fmt{force} format command
on the output stream connected to the output. The sequence
 %
\begin{quote}
  [[o.do_output("some text");]]
\end{quote}
 %
will simply pass this string on to the same output stream.

\subsection*{Debugging}

Table \ref{tab:outputdebug} shows two special debug member functions that
can be called on an output object. They make the format commands
passed to the output object visible before they are interpreted:

\begin{table}
  \begin{center}
    \leavevmode
    \begin{tabular}{llp{6cm}}
[[debug_on()]] & [[void]] & start making format commands visible \\
[[debug_off()]] & [[void]] & end debug mode \\
    \end{tabular}
    \caption{Special debug member functions of the [[Output]] class.}
    \label{tab:outputdebug}
  \end{center}
\end{table}

If you call [[debug_on]] on an output object it will output the name
of the format command as string to the connected output stream.  This
name is encapsulated in angled brackets but this can be changed (see
page \pageref{changedebugoutput}). The [[debug_off]] member function
turns all this off again.





\section{The Interface to the Output Class (Details)}

Here at last is the final reference of the abstract base class.
The private and protected members are only interesting for the
implementation.

<<Definition of the [[Output]] class>>=
class Output {
public:
        Output(ostream& ostr);
        virtual ~Output();
        void do_output(char*);
        void do_output(Format_command);

        <<Debug member functions of the [[Output]] class>>
protected:
        <<Protected members of the [[Output]] class>>
private:
        <<Private members of the [[Output]] class>>
};

@

\begin{impls}
  The output class is used to output attributes to an output stream.
  Attributes basicly are simple strings or format commands (that
  basicly are instructions for a typesetter). The information they
  contain is output by using the two [[do_output]] member functions.
  Strings are simply sent to the output stream. But format commands
  need a small overhead of interpretation. Also, the output produced
  by the format commands is typesetter dependent!
\end{impls}

It is important to note here that the output is buffered with one
element of lookahead. This is necessary because of the interpretation
performed on the format commands. You can only be sure that a format
command has been output until you have destroyed the output object with
the destructor or until you have output a string.


@ You can switch on a debug mode as you use an output if you call the
member function [[debug_on]]. If an output is in debug mode, it not only
interprets format commands, but also prints out the names of the
format commands to the [[ostream]] {\em before} they are
interpreted. (This is important because some format commands never are
actually output, like [[cancel]].) These names are surrounded by two
strings [[bs]] (for ``beginning string'') and [[es]] (for ``ending
string'') that you can pass on to [[debug_on]] as arguments. So if you
are using \TeX\ you could switch on the debug option with
\label{changedebugoutput}
 %
\begin{quote}
  [[o.debug_on("% ","\n");]]
\end{quote}
 %
to make these names invisible for \TeX.

Note that the contents of [[bs]] and [[es]] are copied. You can re-use the
string pointers later if you wish. The maximum length of the beginning and
ending delimiters is set to [[max_debug_del_size]]. If you pass on longer
strings to [[debug_on]] they will be cut off after the given number of
characters.

<<Macro definitions in the specification>>=
#define max_debug_del_size              10
@

The default setting for the [[debug_on]] member function is with [["["]] and
[["]"]] as beginning and ending strings. You can switch off the debug mode
with [[debug_off]].

<<Debug member functions of the [[Output]] class>>=
void debug_on(char *bs = "[", char *es = "]" ); /* turn on debug mode */
void debug_off(); /* get back to normal mode again */
@

\begin{impls}

  Whether the output is in debug mode is stored in the private member
  [[debug_mode]] that can be [[on]] or [[off]]. During debug mode, the names
  of the format commands are output as strings before they are
  interpreted. The names are surrounded by the two strings stored in
  the private members [[begin_string]] and [[end_string]].

<<Protected members of the [[Output]] class>>=
enum {                  /* are we debugging or not? */
     yes, no
} debug_mode;
char begin_string[max_debug_del_size+1];
char end_string[max_debug_del_size+1];
@

So assuming that the format command that shall be interpreted next is
stored in [[next_output]] and that [[os]] is the [[ostream]] connected to our
output, every interpretation is preceded by the following text:

<<Print the name of the format command if debugging>>=
if (debug_mode==yes) {
    os  << begin_string << Format_command_str[next_output]
        << end_string;
}
@

@ The [[debug_on]] member function turns the debug mode on. You can
change the default values of the beginning and ending strings by
passing string values to the function. The maximum length of these
strings is [[max_debug_del_size]] as defined in the specification.  The
strings are copied and we make sure that the strings are terminated if
the user passes on a long string to the function.

<<Implementation of the [[Output]] class>>=
void
Output::debug_on(char *bs, char *es) {
    strncpy(begin_string,bs, max_debug_del_size);
    begin_string[max_debug_del_size] = '\0';
    strncpy(end_string,es, max_debug_del_size);
    end_string[max_debug_del_size] = '\0';
    debug_mode=yes;
}

@

<<Other includes in the implementation>>=
#include<string.h>

@ The [[debug_off]] member function simply turns the debug mode off
again.

<<Implementation of the [[Output]] class>>=
void
Output::debug_off() {
    debug_mode=no;
}

@

\end{impls}



\begin{impls}
  Before we go further in the description of the implementation, we
  need to present the basic mechanism within each output.



\subsection*{The Mechanism inside every Output}

Outputting attributes through an output class object has to obey a set
of two rules.
 %
\begin{itemize}

\item First, a continuous sequence of [[break_space]], [[force]] and/or
  [[big_force]] primitives will be transformed into a single command
  (the maximum of the given ones).

\item Second, a [[cancel]] command cancels any [[break_space]], [[opt]],
  [[force]], or [[big_force]] that immediately precede or follow it and
  also cancels any [[backup]] command that follows it.

\end{itemize}
 %
It is beyond the scope of this document to explain the motivation
behind these rules. The reader is referred to the main part of the
documentation of the ``pretzel'' project, of which this text is only a
small part.

The transformation rules are implemented using a lookahead storage and
a finite state machine. The lookahead is stored in the private member
[[next_output]] and the finite state machine is implemented as a static
table.  The idea behind this choice is that the next element to be
output to the output stream is a function of the last element and the
newly read element. For example, if the last element was a [[force]]
command and the newly read element is a string, we'll have to output
the [[force]] and the [[string]] at once. However, if we have just
recieved another [[force]] command, we won't send anything to the output
stream, because of the first rule (and the fact that there might be
some more [[force]]s coming \ldots). Note that because strings are always
output directly, the lookahead only needs to be able to store the last
format command.

The lookahead [[next_output]] can be [[in_use]] or [[empty]] that is stored in
[[next_output_type]]. If it is [[in_use]] there is a format command stored in
it. Table \ref{tab:usenextoutput} summarizes the use of [[next_output_type]].

\begin{table}
  \begin{center}
    \leavevmode
    \begin{tabular}{|c|c|}
      \hline
      contents of [[next_output_type]] & state of lookahead \\
      \hline
      [[in_use]] & stores a format command \\
      [[empty]]  & no format command in sight \\
      \hline
    \end{tabular}
    \caption{Summary of possible values of [[next_output]].}
    \label{tab:usenextoutput}
  \end{center}
\end{table}


  The protected members are only interesting for the implementation.

<<Protected members of the [[Output]] class>>=
Format_command next_output;     /* lookahead */
enum {                  /* type of the lookahead */
    in_use,             /* lookahead is in use */
    empty               /* lookahead is empty */
} next_output_type;
ostream& os;            /* this is where the output is going */
virtual void flush_output() = 0;    /* outputs [[next_output]] to [[os]] */

@

@ I have put a few more member functions into the private section of
the [[Output]] class to prevent \CPP\ from using any implicit casts or
anything when dealing with outputs.

<<Private members of the [[Output]] class>>=
        Output();
        Output(const Output&);
        const Output& operator=(const Output&);

@ As I have used an [[ostream]] type object above, I need to include the
following header. It is the only header file needed in this
specification.

<<Header files to include in the specification>>=
#include<iostream>

using namespace std;

@

So let's handle a formality first: Here is the definition of the
constructor of an output class object. A [[Output]] always has to be
connected to an existing [[ostream]] during declaration. All information
trespassing the output will go to this output stream. The output
stream is stored in the private member [[os]]. Initially the lookahead
is [[empty]] and the [[debug_mode]] is off.

<<Implementation of the [[Output]] class>>=
Output::Output(ostream& ostr) : os (ostr)
{
    next_output_type=empty;
    debug_mode=no;
}

@

@ A central part of the interpretation mechanism is a private member
function called [[flush_output]]. It encapsulates (and performs) the
interpretation of the format command that is momentarily stored in
[[next_output]].  This function is invoked if the lookahead needs to be
cleared. This is the case if for instance a string shall be output and
there may still be an uniterpreted format command in the lookahead. If
the lookahead is empty, [[flush_output]] does nothing, because it's task
is to clear the lookahead (and this is already the case).

The [[flush_output]] function is the only typesetter dependent part of
the [[Output]] class and thus is declared virtual. We'll see what
happens within [[flush_output]] later. Let's say that [[flush_output]]
already works, then we can turn to the central public output routine
[[do_output]] that is the basic interface to the outside world.

[[do_output]] can take either a string or a format command as argument.
Let's look at the ``string version'' first and then turn to the more
interesting ``format command version''.

@ The first version of [[do_output]] (for strings) simply outputs the
string to the output stream [[os]]. If there happens to be a format
command in the lookahead, this command is interpreted first with
[[flush_output]]. (Again remember: If the lookahead is empty,
[[flush_output]] doesn't do anything.)

<<Implementation of the [[Output]] class>>=
void Output::do_output(char *s)
{
        flush_output();
        os << s;
}
@




\subsection{The Table Driven Output Routine}

Outputting a format command is a little more complicated, because
the lookahead has to be inspected before a format command is output.
The lookahead storage [[next_output]] always holds the format command
that is the hottest candidate to be interpreted next. However there
are these ominous rules that have to be followed before a format
command is actually output.  These two rules are implemented with a
table-driven finite state machine. Every time [[do_output]] is called
with a format command and there still is a format command in the
lookahead, the program looks up in a table, whether this special
combination of commands triggers a rule. If so, the lookahead command
is replaced with the result of the rule that was applied to the two
initial commands.  So if there is for instance a [[force]] command
stored in the lookahead and [[do_output]] is called with a [[big_force]],
the [[force]] will be replaced by the [[big_force]] as lookahead.

So the [[do_output]] routine for format commands first inspects the state
of the lookahead. If the lookahead is empty, then the incoming command
becomes the lookahead.

But if the lookahead is [[in_use]], the routine tries to apply a rule by
looking into the internal table. But if there is no appropriate rule,
it simply flushs the lookahead and takes the incoming token as new
lookahead.

<<Implementation of the [[Output]] class>>=
void Output::do_output(Format_command f)
{
        if (next_output_type==empty)
        {
                next_output_type=in_use;
                next_output=f;  /* take new command as lookahead */
                return;
        }
    /* now try if a rule can be applied */
    <<Apply a rule with [[f]] as incoming command and [[return]]. If there's no rule, do nothing>>

        flush_output();   /* otherwise output the lookahead and store [[f]] */
        next_output_type=in_use;
        next_output=f;
}

@ The rules stated in the above section are listed in table \ref{tab:rules}.
The finite state machine operates with this table.
The columns of the table represent the incoming token and the
lines represent the lookahead command. So if there is a [[force]]
in the lookahead and a [[big_force]] coming in, you will look into the
sixth line at the seventh column to read what command results from
the combination of those two primitives and should be written into the
lookahead.

Note that the only asymmetry in the table is due to the fact that
a [[cancel]] cancels only [[backups]] that follow it (and not ones that
precede it).

If the table entry is only a star, then there is no rule that can be
applied with these two tokens. I have used the following abbreviations:
ind = [[indent]], out = [[outdent]], opt = [[opt0]],\dots,[[opt9]], bkp = [[backup]],
bsp = [[break_space]], bigf = [[big_force]], nind = [[no_indent]].

\begin{table}
  \begin{center}
    \leavevmode
    \begin{tabular}{llllllllll}
$\delta$  & ind & out & opt  & bkp &  bsp  &   force &  bigf &  nind
& cancel \\
\hline
indent    & $*$    &   $*$   & $*$  &   $*$  &  $*$  &   $*$   &   $*$
&   $*$
&   $*$  \\
outdent   & $*$    &   $*$   & $*$  &   $*$  &  $*$  &   $*$   &   $*$
&   $*$
&   $*$  \\
opt       & $*$    &   $*$   & $*$  &   $*$  &  $*$  &   $*$   &   $*$
&   $*$
&   cancel \\
backup    & $*$    &   $*$   & $*$  &   $*$  &  $*$  &   $*$   &   $*$
&   $*$
&   $*$  \\
bsp & $*$  &   $*$   & $*$  &   $*$  & bsp & force & bigf & $*$
&  cancel \\
force     &  $*$   &   $*$   & $*$  &   $*$  & force &  force  & bigf  &
$*$
&   cancel \\
bigf & $*$    &   $*$   & $*$  &   $*$  & bigf & bigf & bigf & $*$
& cancel \\
nind & $*$    &   $*$   & $*$  &   $*$  &  $*$  &   $*$   &   $*$      &
$*$
&   $*$  \\
cancel    & $*$    &   $*$   & cancel & cancel & cancel & cancel & cancel
& $*$
&   $*$  \\
    \end{tabular}
    \caption{Table used to implement the two preprocessing rules with the [[Output]] class.}
    \label{tab:rules}
  \end{center}
\end{table}

@ Table \ref{tab:rules} is encoded in a two dimensional array [[delta]]. There
are several more lines and columns with the implementation because the
[[opt]] commands have to be listed in all and the [[null]] command takes a
line and a column of it's own. The star from the table above is
implemented as a [[null]] entry in the array.

% hier habe ich in der Eile ein paar Fehler bei der Einrueckung gemacht!
% man beachte die zusaetzliche Spalte!

<<Static variables in the implementation>>=
static
Format_command
delta[cancel+1][cancel+1] = {

/* this line is for the [[null]] command */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    null},

/* now [[indent]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    null},

/* now [[outdent]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    null},

/* now [[opt0]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt1]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt2]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt3]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt4]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt5]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt6]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt7]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt8]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[opt9]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    cancel},

/* now [[backup]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    null},

/* now [[break_space]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,break_space,force,big_force,null, cancel},

/* now [[force]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    force,   force,big_force,null,   cancel},

/* now [[big_force]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null, null, big_force,big_force,big_force,null,  cancel},

/* now [[no_indent]]: */
{null,   null,    null,
          null, null, null, null, null, null, null, null, null,
null,    null,    null,    null,    null,    null,    null},

/* now [[cancel]]: */
{null,   null,    null,    cancel,
           cancel,cancel,cancel,cancel,cancel,cancel,cancel,cancel,
cancel,  cancel,  cancel,  cancel,  cancel, null,    null }

};

@ To check whether a rule can be applied, you simply have to look
up the appropriate entry in the table.

<<Apply a rule with [[f]] as incoming command and [[return]]. If there's no rule, do nothing>>=
if (delta[next_output][f]!=null)
{
    next_output=delta[next_output][f];
    return;
}

@ If the last element of an attribute happens to be a format command
it will stay in the lookahead of the output forever. This is why the
destructor for the output object is explicitly defined here. Before
an output object is destroyed, it's lookahead is flushed.

<<Implementation of the [[Output]] class>>=
Output::~Output()
{
    // synonym for flush_output();
    // missing?! possibly in the subclasses!
}

@

\end{impls}





\section{An Output for LaTeX}

This section will give an example on how to build your own typesetter
dependent output class. Here I will present a specialized output
for \LaTeX. To build your own subclass for a specialized target
look into the user manual or confer the file {\tt blankoutput.nw}.

@ The first thing you have to do is to think of a good name. I`ll
take [[Latex_cweb_output]], because the target is \LaTeX\ and the
interpretation of format commands is based upon the macros of
the \CWEB\ system.

Now that we have a name, we can present the class declaration.

<<Definition of the [[Output]] class>>=
class Latex_cweb_output : public Output {
public:
    Latex_cweb_output(ostream& ostr) : Output(ostr) {};
    ~Latex_cweb_output() { flush_output(); };
private:
    void flush_output();
};

@ Yes, it`s as simple as that. Experienced readers will have noticed
that only the [[flush_output]] routine was a virtual function and
indeed, it is this single function that encapsulates the whole
translation. So the next thing you have to do is to define the
function [[flush_output]] in an implemenation file. As the only things
that change in different implementations are the translations of the
format commands, there is a special file in which you only have to
replace preprocessor macro strings to do this.

@ To use the LaTeX output, you`ll have to build a prettyprinter
with pretzel and specify [[Latex_cweb_output]] as output class to use.
The prettyprinted code will have special macros inserted into the
output that are defined in {\tt pretzel-latex.sty}. Now you can
use a new environment called {\tt ppcode}. Inbetween this environment
the code will be formatted nicely.


\begin{impls}

  As part of the implementation, here's an explanation how the
  typesetter dependent parts of [[Output]] subclasses should work.
  Essentially this is an explanation of an example implementation of
  the virtual [[flush_output]] routine.

@

Here`s the frame of [[flush_output]]. It will always be called when the
lookahead needs to be cleared. If the lookahead is empty, we don`t
need to do anything.

<<Implementation of the [[Output]] class>>=
void Latex_cweb_output::flush_output()
{
        if (next_output_type==empty)
                return;
        /* otherwise: */
        <<Interpret the format command in [[next_output]] and write the interpretation to [[os]]>>
        next_output_type=empty;
}

@ Ok, so now let's turn to the part, where format commands are
actually interpreted. Suppose the next format command to be
interpreted is stored in [[next_output]]; the only thing to do now is to
have a giant switch inspecting [[next_output]]. Every case in this
switch outputs the corresponding code for this case to the [[ostream
os]] that is connected to our output class object.

<<Interpret the format command in [[next_output]] and write the interpretation to [[os]]>>=
<<Print the name of the format command if debugging>>
switch (next_output)
{
    <<Cases of the interpretation switch in [[do_output]]>>
    default: <<An unknown format command!>> break;
};

@ This shouldn't (can't) happen.

<<An unknown format command!>>=
cerr << endl
    << "Unknown format command detected! Something's wrong here." << endl
    << endl;
exit(EXIT_FAILURE);

@ To use [[exit]], we have to include this:

<<Other includes in the implementation>>=
#include<stdlib.h>
@

And since some (really old) operating systems don't have the
common [[EXIT_FAILURE]] and [[EXIT_SUCCESS]] macros defined
(in [[stdlib.h]]), we'll define them here. (Introduced for
Denis Roegel, \verb"roegel@lorraine.loria.fr".)

<<Header files to include in the implementation>>=
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
@

Now we will start to scan the cases in the big switch. The easiest
command is surely the [[null]] command. It has an ``empty'' interpretation.

<<Cases of the interpretation switch in [[do_output]]>>=
case null: /* do nothing */ break;

@ The next two cases are [[indent]] and [[outdent]]. They correspond to the
{\tt pretzel-latex} macros \verb+\pretzelindent+ and \verb+\pretzeloutdent+.

<<Cases of the interpretation switch in [[do_output]]>>=
case indent: os << "\\pretzelindent{}"; break;
case outdent: os << "\\pretzeloutdent{}"; break;

@ The next cases handle the 10 instances of the [[opt]] command. The [[opt]]
command is turned into the macro \verb+\pretzelopt+ with the number of [[opt]]
(like 6 in [[opt6]]) as an additional digit.

<<Cases of the interpretation switch in [[do_output]]>>=
case opt0: os << "\\pretzelopt0{}"; break;
case opt1: os << "\\pretzelopt1{}"; break;
case opt2: os << "\\pretzelopt2{}"; break;
case opt3: os << "\\pretzelopt3{}"; break;
case opt4: os << "\\pretzelopt4{}"; break;
case opt5: os << "\\pretzelopt5{}"; break;
case opt6: os << "\\pretzelopt6{}"; break;
case opt7: os << "\\pretzelopt7{}"; break;
case opt8: os << "\\pretzelopt8{}"; break;
case opt9: os << "\\pretzelopt9{}"; break;

@ The [[backup]] command corresponds to \verb+\pretzelbackup+ in {\tt
pretzel-latex.sty}.

<<Cases of the interpretation switch in [[do_output]]>>=
case backup: os << "\\pretzelbackup{}"; break;

@ [[break_space]] is a \verb+\pretzelbreakspace+ \dots

<<Cases of the interpretation switch in [[do_output]]>>=
case break_space: os << "\\pretzelbreakspace{}"; break;

@ Here is the [[force]] command \dots

<<Cases of the interpretation switch in [[do_output]]>>=
case force: os << "\\pretzelforce{}"; break;

@ \dots and here is the [[big_force]] command.

<<Cases of the interpretation switch in [[do_output]]>>=
case big_force: os << "\\pretzelbigforce{}"; break;

@ Here is [[no_indent]]:

<<Cases of the interpretation switch in [[do_output]]>>=
case no_indent: os << "\\pretzelnoindent{}"; break;

@ And finally we arrive at the [[cancel]] command. In the actual output,
[[cancel]] is interpreted like [[null]]. This is due to the fact that [[cancel]]
influences the interpretation before the commands are actually output to
the [[ostream]].

<<Cases of the interpretation switch in [[do_output]]>>=
case cancel: /* do nothing */ break;

@

\end{impls}

\section*{Identifier Index}
\begin{multicols}{2}
\nowebindex
\end{multicols}

\end{document}


%
% $Log: output.nw,v $
% Revision 2.1  1997/07/08 19:00:45  gaertner
% Bug fix proposed by Holger Uhr: cancel cancels big_force now.
%
% Revision 2.0  1996/12/16 17:26:59  gaertner
% *** empty log message ***
%
% Revision 1.1  1996/03/13  11:28:37  gaertner
% Initial revision
%
%


