pp2sdf - translates PerlPoint to SDF


This manual describes version 0.12.


This is a demonstration application of the PerlPoint package. It translates PerlPoint into SDF.

SDF is, of course, no presentation format by itself. Nevertheless it is useful as a target format because sdf can produce various other formats. Presentation formats are fine but often one wants to provide additional handouts, notes or a printed version. pp2sdf opens a simple way to do this.


pp2sdf [<options>] <PerlPoint sources>


All options can be abbreviated uniqly.


PerlPoint sources can embed Perl code which is evaluated while the source is parsed. For reasons of security this feature is deactivated by default. Set this option to active it. You can use -safeOpcode to fine tune which operations shall be permitted.


parsing of one and the same document several times can be accelerated by activating the PerlPoint parser cache by this option. The performance boost depends on your document structure.

Cache files are written besides the source and named ".<source file>.ppcache".

It can be useful to (temporarily) deactivate the cache to get correct line numbers in parser error messages (currently numbers cannot always reported correctly with activated cache because of a special perl behaviour).


PerlPoint parser cache files grow (with every modified version of a source parsed) because they store expressions for every parsed variant of a paragraph. This is usually uncritical but you may wish to clean up the cache occasionally. Use this option to perform the task (or remove the cache file manually).

-docstreaming <mode>

sets up the mode the converter handles document streams. Document streams are document parts belonging to the last recent headline and starting with a document stream entry point (which is a special paragraph):

 =This is the main stream

 Bla bla

 ~A special document stream starts here

 Blu blu

 ~And this is another one

 Bli bli

 =The next headline switches back to the main stream

 Bla bla

You might think of these streams as "document threads" or "docs in docs".

Now, the transformations of those streams are controled by this option.

Mode 0 is the default. It is entered automatically if a document contains docstreams and -docstreaming is not set.

This mode causes pp2sdf to produce one document per document stream, each of them containing only the main stream and the parts written of one certain stream. For example, the first produced document according to the code above would be equivalent to the following source:

 =This is the main stream

 Bla bla

 Blu blu

 =The next headline switches back to the main stream

 Bla bla

Result files will be named as specified by -sdffile, with a sequentially incremented appendix (name.stream1, name.stream2 etc.). If the document contains no docstream, the result file defaults to the specified name (without appendix).

Mode 1 causes the converter to ignore everything except of the main stream. In this mode, the example above is converted according to this source:

 =This is the main stream

 Bla bla

 =The next headline switches back to the main stream

 Bla bla

Mode 2 transforms every stream entry point into a sub-headline of the same name. In the example, this results in a document part equivalent to the following source:

 =This is the main stream

 Bla bla

 ==A special document stream starts here

 Blu blu

 ==And this is another one

 Bli bli

 =The next headline switches back to the main stream

 Bla bla

So results are slightly different in different modes. The best way to get an impression is to give a certain mode a try.


displays an online help and terminates the script.


suppresses the copyright message;


supresses runtime informations;


supresses warnings;


a shortcut for "-nocopyright -noinfo -nowarn": all non critical runtime messages are suppressed;

-safeOpcode <opcode>

If active contents is enabled (-activeContents), Perl code embedded into the translated PerlPoint sources will be evaluated. To keep security this is done via an object of class Safe which restricts code to permitted operations. By this option you can declare which opcode (or opcode tag) is permitted. Please see the Safe and Opcode manual pages for further details. (These modules come with perl.)

Pass ALL to allow everything.

This option can be used multiply.

You may want to store these options in default option files, see below for details.

-sdffile <filename>

The file to store results in. This option is mandatory.

-set <flag>

This option allows you to pass certain settings - of your choice - to active contents (like conditions) where it can be accessed via the $PerlPoint hash reference. For example, your PerlPoint code could contain a condition like

  ? $PerlPoint->{userSettings}{special}

  Special part.

  ? 1

. The special part enclosed by the two conditions would then be processed only if you call pp2sdf with

  -set special

- and if active contents was enabled by -active, of course.

This option can be used multiply.

-skipstream <stream identifier>

instructs the converter to ignore the document stream specified by the identifier string.

  -skipstream 'The stream seldomly read'

This would ignore everything between a

  ~The stream seldomly read

paragraph and the next document stream entry point or the next headline, depending on what follows first.

-trace [<level>]

activates traces of the specified level. You may use the environment variable SCRIPTDEBUG alternatively (but an option overwrites environment settings). The following levels are defined (use the numeric values) - if a description sounds cryptic to you, just ignore the setting:

zero (0)

same as omitting the option: all traces are suppressed.

one (1)

paragraph detection,

two (2)

lexer traces,

four (4)


eight (8)

semantic actions embedded into parsing,

sixteen (16)

active contents,

thirtytwo (32)

backend traces.

Using different levels may cause unexpected results.

Several levels are combined by addition.

 # activate lexer and parser traces
 -trace 6

Option files

Options may be loaded from files where they are stored exactly as you write them in the command line, but may be spread to several lines and extended by comment lines which start with a "#" character. To mark an option file in the commandline, simply enter its (path and) name prededed by a "@" character, for example

  pp2sdf @myOptions ppfile

  where the file myOptions could look like

  # suppress infos

Option files may be nested. To avoid endless recursion, every option file is resolved only the first time it is detected.

  # this is an option file which
  # refers to another option file
  -noinfo @moreOptions

The script also takes care of default option files which means that usual options can be stored in files named .pp2sdf. If such a file is placed in the directory where the script itself resides, options in the file are read in automatically by all pp2sdf calls. These are global settings. If you place such a file in your home directory, it is read automatically as well but only if pp2sdf is called under your account, so this is for personal preferences.

A personal default option file overwrites global settings, and all default options are overwritten by options passed to the script call.


All supported tags are declared by PerlPoint::Tags::SDF. Please see there for a complete list.

pp2sdf supports foreign tags like PAGEREF and SECTIONREF initially introduced by pp2html. Support means that they are handled, but possibly different to the original handling:


Makes the body a named anchor.


  \A{name="an anchor"}<text> becomes "{{N[id=q(an anchor)]text}}".

Using q() avoids sdf trouble caused by quotes in an anchor.


The tag body is made a hyperlink to the URL passed bz the url option. Any other options besides url are ignored.


  \L{url=link}<Look there!> becomes "{{CMD[jump=q(link)]Look there!}}".

Using q() avoids sdf trouble caused by quotes in the link.


The section title provided by the name option is treated as the text to be displayed. This text is made a hyperlink to the referenced chapter.


  \PAGEREF{name=chapter} becomes "{{CMD[jump=q(#chapter)]chapter".

pp2sdf currently does not replace the title by chapter numbers as usually intended by a page reference. This might be improved by later versions.

Using q() avoids sdf trouble caused by quotes in the link.


The section title provided by the name option is treated as the text to be displayed. This text is made a hyperlink to the referenced chapter.


  \SECTIONREF{name=chapter} becomes "{{CMD[jump=q(#chapter)]chapter".

Using q() avoids sdf trouble caused by quotes in the link.


The tag body is made a hyperlink to an internal target, usually declared by an \A tag or (implicitly) by a headline.


  Do not miss \XREF{name=chapter}<this>

is translated into

 "Do not miss {{CMD[jump=q(#chapter)]this".

Using q() avoids sdf trouble caused by quotes in the link.


Marks the body to be underlined


  \U<text> becomes "{{U:text}}".


There may be things you want to see in the target document but find no way to express them in PerlPoint. Well, PerlPoint lets you embed target code very easily directly into the PerlPoint script. Nevertheless, it is recommended to use native PerlPoint wherever possible ;-).

Please note that embedded target code intended for certain translators like pp2sdf may be ignored if the PerlPoint document is processed by other translators. pp2html, for example, accepts embedded HTML but ignores embedded SDF.

Embedding SDF

Just use the \EMBED and \END_EMBED tags to place native SDF if really necessary:

  This is \I<PerlPoint> with embedded


  H2: An SDF chapter

  Note: An SDF note.


You may as well include complete SDF files by \INCLUDE.

  \INLUDE{type=sdf file="snippet.sdf"}

Embedding HTML

is as easy as embedding SDF directly. It is, of course, only useful if you plan to transform your presentation to an HTML page via SDF. You can embed complete HTML sections:


  <h1>An HTML chapter</h1>

  This was written in <i>HTML</i>.


This way pp2sdf will produce SDF inline blocks like this:

  !block inline

  <h1>An HTML chapter</h1>

  This was written in <i>HTML</i>.


Further proceeding is up to sdf, so please refer to the SDF manuals for details.

Alternatively, you may choose to embed HTML directly into a PerlPoint paragraph:

  This is \I<PerlPoint> with embedded

This will be translated into an SDF inline phrase:

  This is {{I:PerlPoint}} with embedded {{INLINE:<b>HTML</b>}}.

Please note that for unknown reasons SDF processes POD tags in inlined phrases (even if it was not intended to use POD). In the example above, this causes a wrong result because an L tag is assumed. This is currently a feature of sdf, not pp2sdf.

HTML code can be embedded by complete files as well, of course:

  \INLUDE{type=html file="snippet.html"}

Embedding other languages

pp2sdf will ignore any other embedded or included target language than SDF and HTML.


Each headline is implicitly made an anchor named like the headline itself. For example,

 =Headline level 1

is converted into

 H1[id=q(Headline level 1)]Headline level 1

, making it easy to set links to certain headlines which is usually done by using the PAGEREF, SECTIONREF and XREF tags.

Anchors can be set explicitly as well. Please have a look at the description of the \A tag.


pp2sdf predeclares several variables which can be used like any user defined PerlPoint variable.


The name of the converter currently processing the document ("pp2sdf").


The version of the running converter.




may be set to a numeric value to activate certain trace levels. You can use option -trace alternatively (note that a used option overwrites an environment setting). The several levels are described with this option.


The generated SDF is not handcrafted

As pp2sdf is a generator. It produces another kind of SDF than a human would write because its target is to make a file which can be processed by sdf without problems. Nevertheless, in most cases it should be simple to manually modify the results if necessary.

Paragraph styles

SDF markes paragraphs types by special prefixes followed by a colon, like in

 Note: Think twice.

Now, authors of a PerlPoint document may start a text paragraph the same way, by a word and a colon, without thinking of SDF. If this would be plainly translated SDF could be confused (it may take words as paragraph style markers which were not intended to be this, or mention an unknown paragraph style and return an error code). That is why all text paragraphs in the generated SDF document are preceded by a backslash, except if they begin with "Note" or "Sign" because in these cases the special SDF formatting makes sense. Backslash prefixes are avoided as well if the paragraph starts with an SDF tag or inlined HTML.

SDF does only support six headline levels

While the headline level in PerlPoint is unlimited in depth, that is not the case in SDF. The sdf translator will warn you if such a headline level is detected.

SDF phrases are not disabled

SDF recognizes POD tags like I, B and C. If a string looks like such a tag, sdf tries to evaluate it the tag way. This should be suppressed.

Foreign PerlPoint tags might cause confusion

PerlPoint allows to process a document by all of its converters. Nevertheless, possibly several foreign tags might produce unexpected results.

Multiline tags in examples are handled correctly

While PerlPoint allows you to open a tag in a line and close it in a subsequent line even in examples, SDF requests a tag to be closed at the opening line. This means it is correct PerlPoint to write

  My tag \I<encloses
  line breaks>.

but it needs to be transformed into the quiet differently structured

  E: My tag {{I:encloses}}
  E: {{I:line breaks}}.

which is automatically arranged by \pp2sdf for the PerlPoint tags \B, \C, \E, \I and \U. (These are the supported tags with bodies. \L, because of its special transformation, does not need to be handled this way.)


pp2sdf activates the PerlPoint parser cache to accelerate repeated translations. Because of this the usual PerlPoint parser cache files will be written next the parsed sources (as ".<source file name>.ppcache" in the source directory).






Copyright (c) Jochen Stenzel (, 2000-2002. All rights reserved.

This script is free software, you can redistribute it and/or modify it under the terms of the Artistic License distributed with Perl version 5.003 or (at your option) any later version. Please refer to the Artistic License that came with your Perl distribution for more details.

The Artistic License should have been included in your distribution of Perl. It resides in the file named "Artistic" at the top-level of the Perl source tree (where Perl was downloaded/unpacked - ask your system administrator if you dont know where this is). Alternatively, the current version of the Artistic License distributed with Perl can be viewed on-line on the World-Wide Web (WWW) from the following URL:


This software is distributed in the hope that it will be useful, but is provided "AS IS" WITHOUT WARRANTY OF ANY KIND, either expressed or implied, INCLUDING, without limitation, the implied warranties of MERCHANTABILITY and FITNESS FOR A PARTICULAR PURPOSE.

The ENTIRE RISK as to the quality and performance of the software IS WITH YOU (the holder of the software). Should the software prove defective, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.


Please refer to the Artistic License that came with your Perl distribution for more details.