This model has the following characteristics.
\LOCALTOC{type=linked}
==Formatter based
There is a (small) number of structural \PP entities like headlines, tables and tags. A formatter of a certain entity determines how this entity is transformed into the target language. It receives the complete contents, plus entity configuration settings if available.
A tag formatter gets the tag name, tag
options and tag body. It supplies a
formatted tag.
A headline formatter gets the headline
text (possibly including smaller entities
like tagged text parts which were formatted
before), plus meta informations like headline
level etc. It supplies a formatted headline.
A page formatter gets all the preformatted
contents of the page, plus page meta informations.
It supplies (or emits) a formatted page.
==Modular
The concept is based on a module hierarchy called \BC.
\C is part of the framework and does all processing that is necessary for \all converters (or generators).
\\PP::Generator::\<language\> modules do the work specific for a certain target language. They are derived from \\PP::Generator. By choosing another language module, another target format is produced. The choice is made using the \C \REF{type=linked name="Option driven"}<option>.
The \PP::Package distribution comes with
\PP::Generator::\I<XML> for XML
handling, and \PP::Generator::\I<SDF>
for SDF handling.
To produce XML, \I<-target XML> is used.
Likewise, \I<-target SDF> produces SDF.
Additionally, \\PP::Generator::<language\::\<formatter\>> classes define special, language specific formatting. They are derived from \\PP::Generator::<language\>. By choosing another formatter module a user determines the way the target format shall be produced. \This choice is made via the \C \REF{type=linked name="Option driven"}<option>.
By convention at least a \C::Default>> module needs to be available. It is used as a fallback in case the user does not choose a formatter explicitly.
The distribution comes with several
default formatters:
\PP::Generator::XML::Default and
\PP::Generator::SDF::Default.
\I<-target XML -format Default> produces
default formatted XML.
Every user can derive further levels. See \REF{type=linked name="Style featured"}<below>.
==Option driven
All configurations are done by options, which (using option files) makes generator calls very comfortable.
Options are defined by the several (module) levels: the startup script (\C) declares a few bootstrap options only. Then \C declares options common to all generators. Then \\PP::Generator::<language\> declares options available for all converters to \<language\>, and \\PP::Generator::<language\::<formatter\>> the options that are specific to that formatter.
Option files are the base of \\REF{type=linked name="Style featured"}<styles> as well.
==Style featured
Styles were introduced into \PP with \C, Lorenz Domkes \PP converter to HTML. With the new formatter (or generator) model, \all converters can use styles, and styles of an extended definition.
A style (according to this new definition) is a \directory structure (or possibly \C file in the future) that defines several things:
* \An option collection. A configuration file combines all the options that set up a certain layout.
* \Formatters. A style can define and use \its own formatter modules. If it contains a \C subdirectory with a module \\PP::Generator::<special_language\::<special_formatter\>>, and the options set up in the style contain \-target special_language -formatter special_formatter, the \lib directory is added to the module search path dynamically and the modules of the style are loaded. This happens transparently. For users, this results in simple style choices, without need of special one shot installations.
* \Template engines. Similar to formatters, a style can extend the installed PerlPoint libraries by own \<template engines>. This works the same way: if the style contains a \lib directory with an own engine module \\PP::Template::<special_engine\> and the style options contain \-templatetype special_engine, than \perlpoint will use that engine to process your template files.
* \Templates. A formatter can be template driven. The style contains all necessary template files. The template system is not fix - \PP allows to use \any system by providing a generalized API. To add a new template system, only a small layer module needs to be written. For available template interfaces, see \PP::Template modules on CPAN.
* \Description and documentation. Style directories can be set up to hold short descriptions, screenshots and manuals for a certain style. These can be used by external tools, like librarians or Web pages, to present a style.
==One converter
Because the \Generator module does most of the work, the startup needs are really small and independent on the target format. So the few startup code lines are collected in a single script called \BC ("tdo"="template driven output", based on an initial goal of the new design (to write a common platform for the integration of arbitrary templating systems)).
To write a formatter, you first should know what the base modules of the generator already do, which methods of \C objects can be overwritten and which interface they provide.
For this, the following sections describe what's done on the several generator levels.
\LOCALTOC{type=linked depth=1}
==The startup script
\LOCALTOC{type=linked}
===Options declared on this level
The startup script declares very basic options, which will be available in general.
@| option | arguments | example | description \BC | the target format | \-target XML | mandatory \BC | the formatter to be used | \-formatter Easy | defaults to "Default" \BC | a directory to be searched for styles | \-styledir ~/perlpoint/styles | Can be used multiply. Defaults to the startup directory. For reasons of compatibility with older converters, \C is allowed as well. \BC | a style name | \-style modern | The name of a \REF{type=linked name="Style featured"}<style>.
===Function
Basically this script takes options, builds a \ object and starts it (by calling its \run() method). This is just a bootstrap.
==The generator level
This is where most of the work is done. Behind the scenes ;-)
This is \C.
\LOCALTOC{type=linked}
===Options declared on this level
The \C module is the base of all generators, so these options are generally available.
@| option | arguments | example | description \BC | | \-activeContents | enables active contents \BC | | \-cache | activates the cache \BC | | \-cacheCleanup | performs a cache cleanup \BC | method code | \-docstreaming 1 | configures the document stream handling \BC | | \-help | displays online help ("usage") \BC | directory | \-includelib inc | Adds a directory to the path searched for files to be included via \C. Can be used multiply. \BC | | \-nocopyright | suppress copyright message \BC | | \-noinfo | suppress runtime informations \BC | | \-nowarn | suppress runtime warnings \BC | | \-quiet | suppress all runtime messages except of errors \BC | an opcode or "ALL" | \-safeOpcode ALL | specifies permitted opcodes in active contents (see the Opcode manpage for details), can be used multiply \BC | a user setting | \-set test | allows user settings which can be evaluated in documents \BC | the stream name | \-skipstream left | skip a certain document stream \BC | the set | \-tagset HTML | adds a tag set to the scripts own tag declarations (making those tags available) \BC | presentation title | \-title Examples | sets up the presentation title \BC | numerical trace level | \-trace 2 | activates trace messages
===Object data defined on this level
The following public object attributes are defined by this class:
@| attribute | description \BC | generates anchor names, use: \$me-\{anchorfab}-\>generic> \BC | the backend object (see \C) \BC | a hash of options passed to the generator script \BC | the parser object (see \C)
Please note that due to the concepts of this module hierarchy and the mechanisms of Perls \C pragma, there are more attributes visible in subclasses, but those are not intended for public use.
===Function
The base module of the generator hierarchy controls the translation process. It performs initializations, parses the \PP source and prepares the results for formatters, which it invokes at the right time.
Knowledge of the internals of this class is no precondition to write subclasses, so the details are not furtherly explained here. To sum them up, a generator module performs initializations, parses the \PP sources, runs a backend object to deal with the results and invokes formatters as soon as their target entities are completely available.
===Inheritable methods
These methods are intended to be inherited and overwritten.
\LOCALTOC{type=linked}
====bootstrap()
\Invocation: called after the constructor (of a subclass).
\Function in the \Generator class: collects options and source filters.
\Intention for subclasses: perform own bootstrap operations.
\Parameters: the object.
\Return values: none expected.
\Hints: it is strongly recommended to invoke the parent method, as by \$me-\SUPER::bootstrap>.
====options()
\Invocation: called after the constructor of a subclass, by the \bootstrap() method.
\Function in the \Generator class: defines \Generator options.
\Intention for subclasses: add own options.
\Parameters: the object.
\Return values: an option list.
\Hints: it is strongly recommended to invoke the parent method, as by
# provide the base options plus your own
(
$me->SUPER::options, # base options
"newopt1=s", # new options
"newopt2=s",
);
====checkUsage()
\Invocation: called after the constructor of a subclass and \options(), by the \bootstrap() method.
\Function in the \Generator class: none that far.
\Intention for subclasses: check usage, e.g. options.
\Parameters: the object. Note that the option list is available in attribute \options.
\Return values: none expected. The method should terminate the program if necessary.
\Hints: it is strongly recommended to invoke the parent method, as by
# don't forget the base class
$me->SUPER::checkUsage;
====sourceFilters()
\Invocation: called after the constructor of a subclass and \checkUsage(), by the \bootstrap() method.
\Function in the \Generator class: enables \perl sources (should be valid for most generators).
\Intention for subclasses: add own source filters.
\Parameters: the object.
\Return values: a filter list.
\Hints: in most cases it will be useful to invoke the parent method, except when \perl filters are not required, as by
(
$me->SUPER::sourceFilters, # parent class list
"xml", # embedded XML;
);
====initParser()
\Invocation: called between parser construction and parser startup.
\Function in the \Generator class: none that far.
\Intention for subclasses: perform whatever seems appropriate in this state.
\Parameters: the object. Remember that the parser object is available in attribute \C.
\Return values: none expected.
\Hints: it is strongly recommended to invoke the parent method, as by
# don't forget the base class
$me->SUPER::initParser;
====initBackend()
\Invocation: called between backend construction and backend startup (so the sources were already parsed).
\Function in the \Generator class: binds intermediate data to the \C attribute, to allow derived methods to let the backend work on it.
\Intention for subclasses: perform whatever seems appropriate in this state.
\Parameters: the object. Remember that the backend object is available in attribute \C.
\Return values: none expected.
\Hints: it is \strongly recommended to invoke the parent method, otherwise derived methods accessing the backend object will probably not work.
# don't forget the base class
$me->SUPER::initBackend;
====finish()
\Invocation: called when everything is done.
\Function in the \Generator class: none that far.
\Intention for subclasses: perform whatever seems appropriate to complete your work.
\Parameters: the object.
\Return values: none expected.
\Hints: it is \strongly recommended to invoke the parent method, as by
# don't forget the base class
$me->SUPER::finish;
==The language level
If you plan to subclass an existing language module, please see its documentation. General informations, especially those about \REF{type=linked name="Formatters to be defined"}<formatters>, are of interest for authors of both language modules and their subclasses.
\LOCALTOC{type=linked depth=1}
===Options declared on this level
Target format specific options.
===Object data defined on this level
It is up to the language class designer to add desired attributes. Please make sure the names are not already used in base classes.
===Function
This class level is intended to do everything specific for the target language. This might include base formatting, but does not need to.
===Optional methods
\LOCALTOC{type=linked}
====preFormatter()
This is an optional method called before formatting. It is \no formatter by itself, but useful to recognize global state switches and the like (e.g. if in an embedded part and of what language). When defined, it is called for \all entities, using \the traditional directive interface. See the traditional model for details. Here is a list of parameters to expect:
\INCLUDE{type=pp file="writing-converters-entityinterfaces.pp"}
===Formatters to be defined
The generator model expects that formatters are defined for \PP entities. This should be done on this level or below.
\LOCALTOC{type=linked}
====Interface
All formatters receive \the object, \page data and \an item structure.
The \object and its attributes were described above.
The \page data ...
The \item structure is a hash with the following slots:
@| key | value \BC | A reference to an array of embedding entities, entities are represented by their \DIRECTIVE_... codes (see \C). This allows a converter to determine the entities location in a hierarchy of entities, e.g. that a list is a nested list on 45th level. \BC | A reference to an array of elements, usually the embedded parts (or the "body" part), e.g. the headline text for a headline entity, or the tag body for a tag entity. \BC | A reference to a configuration hash, see below.
The entries of the configuration hash:
@| key | value \BC | the original directive type of the entity - usually unused by a formatter \BC | the original state of an entity - should not be used by a formatter \BC | this is the interesting part, as it holds various attributes which are formatter specific
A formatter \can supply a result. This is appropriate in most cases, as the results are made part of an embedding entity and provided to thats formatter when the entity is complete. Higher level formatters receive results of lower level formatters in the \parts slot of their \item parameter, see above.
Imagine two nested tags. The body of the
innermost tag is simple text, formatted
by the simple text formatter. The formatter
of the innermost tag receives the result
of the simple text formatter in $item->{parts}.
The formatter of the outer tag receives the
result of the inner tag formatter in \I<its>
$item->{parts} parameter slot.
A result can be of any type, except for pure (unblessed) hash references which are reserved for internal purposes. As the results are only passed through to outer formatters, the formatter class can organize its own data flow.
The SDF formatter classes in the distribution
in most cases use \I<simple strings> to transfer
formatted results.
They use \I<array references> to deal with document
streams.
The XML formatter classes in the distribution
use XML::Generator \I<objects> as the intermediate
data format between formatters.
In case you subclass an existing formatter class, take care which formats are used there.
====formatHeadline()
\Invoked for: headlines
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | chapter level \BC | the headline text, without embedded tags \BC | a shortcut version of the headline text
====formatUlist()
\Invoked for: unordered lists
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the list nesting level
====formatUpoint()
\Invoked for: points of unordered lists
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the hierarchy of listlevels by array reference
====formatOlist()
\Invoked for: ordered lists
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the list nesting level
====formatOpoint()
\Invoked for: points of ordered lists
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the hierarchy of listlevels by array reference, this allows to build an individual number for this point if necessary
====formatDlist()
\Invoked for: definition lists
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the list nesting level
====formatDpoint()
\Invoked for: definition list points
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the hierarchy of listlevels by array reference
====formatDpointItem()
\Invoked for: definition list point items
\Data (\%{$item-\{cfg}{data}}):> none
====formatDpointText()
\Invoked for: definition list point texts
\Data (\%{$item-\{cfg}{data}}):> none
====formatText()
\Invoked for: text paragraphs
\Data (\%{$item-\{cfg}{data}}):> none
====formatBlock()
\Invoked for: example blocks
\Data (\%{$item-\{cfg}{data}}):> none
====formatVerbatim()
\Invoked for: verbatim blocks
\Data (\%{$item-\{cfg}{data}}):> none
====formatDStreamEntrypoint()
\Invoked for: document stream parts (\not only their entry)
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | the name of the docstream
====formatDStreamFrame()
\Invoked for: document stream frames (containing a sequence of docstreams different from "main")
\Data (\%{$item-\{cfg}{data}}):> none
====formatTag()
\Invoked for: tags
\Data (\%{$item-\{cfg}{data}}):>
@| key | value \BC | tag name \BC | a hash of tag options and their values \BC | the number of parts in the body (0 means: no tag body) - you should only check for 0 or not 0
====formatSimple()
\Invoked for: simple strings.
\Data (\%{$item-\{cfg}{data}}):> none
====formatComment()
\Invoked for: comments
\Data (\%{$item-\{cfg}{data}}):> none
====formatPage()
\Invoked for: a complete page / slide
\Data (\%{$item-\{cfg}{data}}):> none
==The formatter level
\LOCALTOC{type=linked}
===Options declared on this level
Formatter specific options.
===Object data defined on this level
It is up to the formatter class designer to add desired attributes. Please make sure the names are not already used in base classes.
===Function
On this class level, everything is about formatting. This includes result file handling, implementation of template systems and so on.
Most probably the page formatter will be implemented on this level, but almost any formatter can. Inherited formatters can be overwritten or extended. This is all up to you.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 3:
Unknown directive: =Base
- Around line 128:
Unknown directive: =Getting