% This is a file written using noweb
%
% $Id: blankoutput.nw,v 1.1 1996/03/13 11:29:37 gaertner Exp $
%
% INSTRUCTIONS: Rename this file to the name of your subclass. Search
% for places marked XXXX and replace the `XXXX' with an unique
% identifier for your subclass. Then search for XXX and adjust the
% code and documentation.
%
%
\documentclass{article}
\usepackage{a4,pretzeldoc,version,noweb}
\begin{document}

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



\title{XXX%             % put the name of your subclass here
  \thanks{This file is based on a template for a subclass of the
    [[Output]] class written by Felix G\"artner.}}

\author{XXX}            % put your own name here

\maketitle


\begin{abstract}
  % fill in the abstract at the places marked XXX or write your own

  This file contains a subclass of the [[Output]] class called XXX. It
  can be used to create a prettyprinter for a XXX output device. It
  belongs to a framework supplied by the ``pretzel'' prettyprinter
  generator.

\end{abstract}


\tableofcontents


% Fill in the places marked XXX or write your own text.

\section{Introduction}

This text describes the specification \begin{impls}and
  implementation\end{impls} for a new subclass of the \CPP\ [[Output]]
class. It specializes on the XXX output device. It is a contribution
to the ``pretzel'' system, a prettyprinter generator written by Felix
G\"artner (\verb+theedge@rbg.informatik.th-darmstadt.de+).

For more examples of this kind of thing consult the files {\tt
  output.nw}, {\tt asciioutput.nw} and {\tt blankoutput.nw} included
in the pretzel distribution.

@ Here's the frame of the header for the new subclass.

<<header>>=
#ifndef XXX_H
#define XXX_H

#include "output.h"          /* base class defined in here */
<<Header files to include in the specification>>

<<Macro definitions in the specification>>

<<Declaration of the new subclass>>

#endif
@

At the moment, we don't need more headers.

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

@

\begin{impls}

  Here's the framework of the implementation.

<<implementation>>=
#include "XXX.h"
<<Header files to include in the implementation>>

<<Implementation of the new subclass>>

@


\end{impls}

In the following section of this document we will explain the purpose
of this subclass and the results obtained when using it together with
pretzel. This is the interface of the class. It will be described
mainly \C\ preprocessor macros.

First of all, this is what the name of the subclass will look like in
the program:

% Fill in the name of your class here. The first XXXX has to be
% replaced by the new name too, since we might want to use several
% subclasses in a single program and the macro definitions would
% define the same macro.

<<Macro definitions in the specification>>=
#define XXXX_SUBCLASS_NAME XXXX
@


\section{Interface}

The actual declaration of the new subclass is pretty simple, once
we've defined the name.

<<Declaration of the new subclass>>=
class XXXX_SUBCLASS_NAME : public Output {
public:
    XXXX_SUBCLASS_NAME(ostream& ostr) : Output(ostr) {};
    ~XXXX_SUBCLASS_NAME() { flush_output(); };
private:
    void flush_output();
};

@ Yes, it`s as simple as that. The only thing needed to write now is
the [[flush_output]] routine, which is a pure virtual function inside
the [[Output]] base class. The main parts of this routine are always
identical. The only differences are the different things done when
format commands are interpreted.

% XXX
% There are two possibilities now: If your target is a markup
% typesetting system, you can simply replace the strings here and
% that's that.
% However, if the interpretation of the format commands needs some
% explicit programming, you have to go into the implementation below
% and code the things yourself.

These things can be defined here using macro definitions again. Here
we specify the strings output to the internal output steam when the
corresponding format commands are interpreted. Other concrete actions
are coded directly in the implementation of [[flush_output]] below.

% XXX fill in the strings here and explain what they do.

<<Macro definitions in the specification>>=
#define XXXX_NULL_OUTPUT_STRING         ""
#define XXXX_INDENT_OUTPUT_STRING       ""
#define XXXX_OUTDENT_OUTPUT_STRING      ""
#define XXXX_OPT0_OUTPUT_STRING         ""
#define XXXX_OPT1_OUTPUT_STRING         ""
#define XXXX_OPT2_OUTPUT_STRING         ""
#define XXXX_OPT3_OUTPUT_STRING         ""
#define XXXX_OPT4_OUTPUT_STRING         ""
#define XXXX_OPT5_OUTPUT_STRING         ""
#define XXXX_OPT6_OUTPUT_STRING         ""
#define XXXX_OPT7_OUTPUT_STRING         ""
#define XXXX_OPT8_OUTPUT_STRING         ""
#define XXXX_OPT9_OUTPUT_STRING         ""
#define XXXX_BACKUP_OUTPUT_STRING       ""
#define XXXX_BREAKSPACE_OUTPUT_STRING   ""
#define XXXX_FORCE_OUTPUT_STRING        ""
#define XXXX_BIGFORCE_OUTPUT_STRING     ""
#define XXXX_NOINDENT_OUTPUT_STRING     ""
#define XXXX_CANCEL_OUTPUT_STRING       ""
@

To use this new output, you`ll have to build a prettyprinter
with pretzel and specify XXX as output class to use.

% put more text describing the use of the class here

XXX

@

\section{Implementation of [[flush_output]]}


  As part of the implementation, here's an explanation how the
  typesetter dependent parts of the new subclass 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 new subclass>>=
void XXXX_SUBCLASS_NAME::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;
};
@

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

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

<<Header files to include 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.

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

\section{Interpretation of Format Commands}

Now we will start to scan the cases in the big switch. The actions
performed are essentially the output of a special string defined in
the interface above. However, special actions are directly coded here.

% XXX code the special actions and write what you're doing

\subsection{The [[null]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case null: os << XXXX_NULL_OUTPUT_STRING ;
break;
@

\subsection{The [[indent]] and [[outdent]] format commands}

<<Cases of the interpretation switch in [[do_output]]>>=
case indent: os << XXXX_INDENT_OUTPUT_STRING ;
break;
case outdent: os << XXXX_OUTDENT_OUTPUT_STRING ;
break;

@

\subsection{The [[opt]] format command}

The next cases handle the 10 instances of the [[opt]] command.

<<Cases of the interpretation switch in [[do_output]]>>=
case opt0: os << XXXX_OPT0_OUTPUT_STRING ; break;
case opt1: os << XXXX_OPT1_OUTPUT_STRING ; break;
case opt2: os << XXXX_OPT2_OUTPUT_STRING ; break;
case opt3: os << XXXX_OPT3_OUTPUT_STRING ; break;
case opt4: os << XXXX_OPT4_OUTPUT_STRING ; break;
case opt5: os << XXXX_OPT5_OUTPUT_STRING ; break;
case opt6: os << XXXX_OPT6_OUTPUT_STRING ; break;
case opt7: os << XXXX_OPT7_OUTPUT_STRING ; break;
case opt8: os << XXXX_OPT8_OUTPUT_STRING ; break;
case opt9: os << XXXX_OPT9_OUTPUT_STRING ; break;

@

\subsection{The [[backup]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case backup: os << XXXX_BACKUP_OUTPUT_STRING ;
break;
@

\subsection{The [[break_space]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case break_space: os << XXXX_BREAKSPACE_OUTPUT_STRING ;
break;
@

\subsection{The [[force]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case force: os << XXXX_FORCE_OUTPUT_STRING ;
break;
@

\subsection{The [[big_force]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case big_force: os << XXXX_BIGFORCE_OUTPUT_STRING ;
break;
@

\subsection{The [[no_indent]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case no_indent: os << XXXX_NOINDENT_OUTPUT_STRING ;
break;
@

\subsection{The [[cancel]] format command}

<<Cases of the interpretation switch in [[do_output]]>>=
case cancel: os << XXXX_CANCEL_OUTPUT_STRING ;
break;
@


\end{document}


%
% $Log: blankoutput.nw,v $
% Revision 1.1  1996/03/13  11:29:37  gaertner
% Initial revision
%
%


