SDF for POD Users

Ian Clatworthy (ianc@mincom.com), Research Architect, Mincom Pty Ltd
25 May 1999


Table of Contents


1. Overview

Over the last few years, Perl's POD format has proven itself as a useful tool for documenting Perl's functionality and its library modules. POD is easy to learn, easy to read and easy to embed.

In 1992, I wanted to embed documentation in source code in order to make it easier to keep the documentation up to date. POD didn't exist, so I invented a similar system called SDF (Simple Document Format) and implemented it in Perl, the world's greatest programming language. SDF has grown rapidly over the years and is now a powerful general purpose documentation system. But like POD, SDF has remained simple in spirit: easy to learn, easy to read and easy to embed.

In June 1997, most of POD's syntax and functionality were merged into SDF, making it easier for people to migrate from POD to SDF. This document aims to answer the following questions for POD users:

  1. How do I convert from POD to SDF?
  2. How do I convert from SDF to POD?
  3. How do I nest SDF inside a POD document?
  4. How do I nest POD inside an SDF document?
  5. Is it hard to learn SDF?
  6. Is SDF more readable than POD?
  7. What does SDF offer me?
  8. What's wrong with SDF?

If you have other questions, check out the documentation provided with SDF. If that doesn't help, you can always email your question to sdf-users@mincom.com.


2. How do I convert from POD to SDF?

By using the pod2sdf program. Typical usage is:

  pod2sdf perlrun.pod > perlrun.sdf

As SDF is essentially a superset of POD, the SDF output is almost the same as the POD input, except that verbatim lines are marked with a leading >. For example, the following POD:

    =head1 NAME
    
    abc - output the alphabet
    
    =head1 DESCRIPTION
    
    This program displays the alphabet like this:
    
      ABCDEFGHIJ
      KLMNOPQRST
      UVWXYZ
    
    Pretty simple, eh?

gets converted to:

    =head1 NAME
    
    abc - output the alphabet
    
    =head1 DESCRIPTION
    
    This program displays the alphabet like this:
    
    >  ABCDEFGHIJ
    >  KLMNOPQRST
    >  UVWXYZ
    
    Pretty simple, eh?

Note that it isn't actually necessary to use pod2sdf unless you intend migrating to SDF format - the sdf program can be used on a POD file directly like this:

  sdf -2html perlrun.pod

How does this work? Well, the sdf program can be configured to automatically prefilter files with certain extensions. The default configuration is to prefilter .pod, .pm and .PL files with the pod filter (which converts POD to SDF).

If you want to use the sdf program on POD files without one of these extensions, you can either edit the sdf.ini configuration file, or explicitly specify the prefiltering like this:

  sdf -2html -ppod xyz.pd

3. How do I convert from SDF to POD?

By using the sdf program. Typical usage is:

  sdf -2pod mydoc.sdf

This will create a file called mydoc.pod in the current directory.

The general usage of the sdf program is:

  sdf [options] filename ...

A .sdf extension is assumed on each filename (unless a filename without the extension is found).


4. How do I nest SDF inside a POD document?

If you're generally happy with POD and only need SDF occasionally, SDF can be embedded in POD using POD's =for command or =begin/=end command pair. Some examples are:

    Here's our new logo:

    =for sdf !import "mylogo.gif"

    And these are the documentation systems we use:

    =begin sdf

    !block table
    Name    Meaning
    POD     Plain Old Documentation
    SDF     Simple Document Format
    !endblock

    =end sdf

If you want the rest of a POD file to be in SDF, simply put in an "=begin sdf" - the closing "=end sdf" isn't necessary.


5. How do I nest POD inside an SDF document?

By using the pod filter. Filters can be applied to blocks of text in a file, complete files or the output of programs. Some examples are:

    # Insert some pod
    !block pod
    =head2 My B<heading>

    A normal POD paragraph.

        And some verbatim text.
    !endblock

    # Get pod from a file
    !include "perlre.pod"; pod

    # Get pod from standard output
    !execute "getpod 'hello.c'"; pod

So reusing existing POD documentation within an SDF document is easy.


6. Is it hard to learn SDF?

No. 90% of SDF documents use a set of core features which can be summarised in a few pages. For POD users, the main things to know are these:

      style":" text
      style"["attributes"]" text
    A normal paragraph with
    a few lines.

    Note: This is a paragraph tagged with
    the Note style.

    Note[label='Important'] This is an important note!
     * item 1
       - item 1a
       - item 1b
     * item 2
     * item3

7. Is SDF more readable than POD?

To its fans, SDF is more readable than POD for the following reasons:

Of course, POD's fans argue that POD is more readable for equally valid reasons. Beauty is in the eye of the beholder - even Lisp has it's fans. :-)


8. What does SDF offer me?

The main reasons for using SDF over POD are:

  1. Tables
  2. Figures
  3. Variables
  4. Better Extensibility
  5. Configurable Expansion of Links

These are briefly considered below.


Note: Not every output format supported by SDF supports every table/figure feature. In some cases, the SDF -> xxx format driver isn't yet clever enough. In other cases, the target format isn't clever enough! So, your milage may vary with some of these features, particularly in the short term as the SDF format drivers are maturing. Of course, the Perl source code for each format driver is provided with the SDF package, so feel free to improve them.

8.1. Tables

SDF support tables via the table filter. Typically, tables are defined using the block and endblock macros like this:

!block table
Name    Meaning
POD     Plain Old Documentation
SDF     Simple Document Format
!endblock

The result is:

Name Meaning
POD Plain Old Documentation
SDF Simple Document Format

The first line specifies the headings and the input format of the data:

For readability reasons, fixed-width format is preferred. Delimited format is useful for tables already in that format and for data exported by spreadsheets.

SDF supports a large number of features for tables including:

See the SDF User Guide for further details.

8.2. Figures

Figures are supported in SDF via the import macro. The usage is:

  !import "filename" [parameters]

For example:

  !import "mylogo"; align=Right

It is generally best not to specify an extension for the filename containing the figure, as SDF will then use the best format it can find. The search rules are:

When generating The search order is
PostScript epsi, eps, wmf, mif, gif
HTML jpeg, jpg, png, gif
Windows Help bmp

See the SDF User Guide for further details.

8.3. Variables

Variables can be defined using the define macro like this:

  !define VERSION 1.34

The first argument is the variable name and the second argument is the value. You can use a Perl expression for the value if you wish. For example:

  !define LOGO $ENV{'LOGO'} || "mylogo"

Having defined a variable, it can be used in paragraph text by enclosing it within [[ and ]]. For example:

  WorldPeace [[VERSION]] is just what you need and
  is available for free download from ...

In fact, a Perl expression can be embedded in paragraph text the same way, e.g.

  !define STARS 5
  ...
  This movie gets [['*' x $var{'STARS'}]].

Within Perl expressions, SDF variables are available via the %var associative array.

8.4. Better Extensibility

From its beginning, one of SDF's primary goals has been to support the authoring of documents in a logical manner. Therefore, it is possible to define your own:

and to either alias these to existing styles/attributes or map them to target format entities.

Likewise, you can define your own macros and filters to do almost anything you want. See the SDF Guru Guide for further details.

Typically, a workgroup or project team will put their extensions in an SDF library, which is essentially a normal SDF file which is included at the start of each document. Alternatively, you can specify a configuration library on the sdf command line. This is useful if you want an SDF configuration library for a POD document, say.

8.5. Configurable Expansion of Links

For L (Link) phrases, SDF lets you customise:

This flexibility is important for non-English documentation and non-Perl documentation.

To change the text expansion rules, define one of more of the variables below:

Variable Default Value
FORMAT_LINK_PAGE the $page manpage
FORMAT_LINK_PAGE_ENTRY the $entry entry in the $page manpage
FORMAT_LINK_PAGE_SECTION the section on "$sect" in the $page manpage
FORMAT_LINK_SECTION the section on "$sect"

For example:

  !define FORMAT_LINK_SECTION 'the "$sect" section'

To change the URL generation rule, override the BuildLinkUrl subroutine like this:

!block script
sub BuildLinkUrl  {
    my ($page, $sect, $entry) = @_;
    my $url = ...
    return $url;
}
!endblock

The default implementation of BuildLinkUrl is simplistic by design. This is considered a feature. If you want intelligent URL generation ala pod2html, use the perl configuration library and set the PERL_HTML_ROOT variable like this:

  sdf -2html -cperl -DPERL_HTML_ROOT=/nmanual/perl perlrun.pod

The default value of PERL_HTML_ROOT is /perl.


9. What's wrong with SDF?

The most common complaints about SDF are:

  1. It isn't WYSIWYG.
  2. It doesn't support the output format I need.
  3. It doesn't have the features I need.
  4. It has too much functionality.

On the WYSIWYG issue, SDF is a tool for people who would rather use a text editor. It tries hard to be readable and an emacs mode is available. If that isn't good enough, then SDF isn't for you.

On the output format issue, I'm working on it. For developers with a good knowledge of Perl and the output format they need, writing an "SDF output driver" isn't hard, it just takes time. Like all of us, I only have so much free time, so any assistance anyone can offer in this regard is very welcome.

On the functionality issue, SDF is growing and will continue growing. If it doesn't have a feature you need, the Perl source code is provided, so you might be able to add it yourself.

If SDF is already too complex, then stick with POD. You can always mix in some SDF or migrate to SDF if you need to at a later date. Personally, I find the "I'm sticking with POD because SDF is too complex" argument a little short-sighted:

I prefer SDF to POD for the same reason that I prefer Perl to awk: the latter may be sufficent for a given task, but choosing it will cause me grief the moment the task grows. On the other hand, as the designer of SDF, I'm probably just a little biased. :-)


10. Credits

Thanks to the many people who have used and contributed to SDF over the years, particularly David Cox, Tim Hudson and Chris Moran. Likewise, thanks to Larry Wall for inventing Perl and to everyone who has contributed to Perl over the years. Without it, SDF wouldn't exist.

Finally, I'd like to thank the people who encouraged me to merge POD and SDF, including Kenneth Albanowski, Brad Appleton, Achim Bohnet, Jim Esten, Chaim Frenkel, Gerd Knops, Hugues Lafarge, Tuomas J. Lukka, Andy Wardley and Peter Wolfe. I hope the result is useful.