reference documentation generator



because my mind doesn't let go of things like this, i've hacked up a couple of
scripts which implement the core of what i discussed in a previous message.  i
want, nay, need your comments and suggestions.


in this corner, weighing in at 245 lines of pure perl code, we have
parseem.pl, the script that knows how to parse 'em.  he scans xs files for
xsub prototypes and pod comments, and prints to stdout the Data::Dumper output
of an array of xsub description hashes and an array of pod lines.

in the other corner, weighing in at 215 lines of pure perl code, we have
printem.pl, the script that knows how to print 'em.  he reads in the data
structures created by parseem.pl and a maps file and writes pod to stdout.


the sticky point is the maps file.  printem.pl needs to know how to convert C
typedefs into relevant perl type names.  it knows a small table of built-ins
(e.g., gboolean => boolean, gint => integer, gdouble => double, SV => scalar,
gchar => string), but to get other types, e.g. GtkButton => Gtk2::Button, it
needs to have a map of such things.  the obvious answer is to use the maps
file which Gtk2 already has, so printem.pl looks for "./maps" and "../maps".

that's a sticky point because i'd like to use this same mechanism on projects
which don't use a maps file, e.g. Glib.


printem.pl basically just prints out a listing of all the functions found in 
file, with call signatures.  if the XS file contains pod comments, it picks
those up, too.  there are two ways to associate a comment with a function:

 - have the comment immediately precede the function it documents.
   there must be NO blank lines between the =cut and the xsub.

 - have a first line in the comment which specifies the function it
   documents.  e.g.

        =for apidoc Gtk2::Button::new

this is an important distinction.  the attached "documented.xs" (which started
out as GtkButton.xs) uses the explicit association to put a comment on only
one of the three subs aliased together with new, and uses the normal attached
style to document new_from_stock.

here's the output of that script pair on documented.xs:

-=-=-=-=-
muppet:~/gtk2-perl-xs/Gtk2/xs$ ./parseem.pl documented.xs | ./printem.pl |
pod2text
METHODS
    widget = Gtk2::Button->new (label)

        - label (string)

        The default new takes an optional mnemonic string. If you don't like
        that, use new_with_label() explicitly.

    widget = Gtk2::Button->new_with_mnemonic (label)

        - label (string)

    widget = Gtk2::Button->new_with_label (label)

        - label (string)

    widget = Gtk2::Button->new_from_stock (stock_id)

        - stock_id (string)

        Create a new button containing a stock icon. The *stock_id* is the
        string which is #defined in the gtk+ source; see the C api reference
        for a listing.

    $button->pressed

    $button->released

    $button->clicked

    $button->enter

    $button->leave

    $button->set_relief (newstyle)

        - newstyle (Gtk2::ReliefStyle)

    reliefstyle = $button->get_relief

    $button->set_label (label)

        - label (string)

    string = $button->get_label

    $button->set_use_underline (use_underline)

        - use_underline (boolean)

    boolean = $button->get_use_underline

    $button->set_use_stock (use_stock)

        - use_stock (boolean)

-=-=-=-


this implementation is a prototype, and is missing quite a few things:

- descriptions for parameters.

- handling for preprocessor directives.  currently i just ignore them, so the
docs wind up having multiple declarations and documenting things that your
build of the library may not actually have.

- a way to override return types.  any function seen to have a PPCODE: section
will simply have the return type of "list", because that's all we can
determine from scanning.  i want the pod to be able to override and elaborate
on that, e.g.

    =for apidoc

    =return list(model, iter)

    =return scalar(iter)

    Get the iter of the currently selected row.

    =cut
    void
    gtk_tree_selection_get_selected (GtkTreeSelection * selection)
        PPCODE:
            /* code returns just the iter in scalar context, but
             * the model and the iter in list context. */
            ...

should result in

    =item iter = $treeselection->get_selected

    =item (model, iter) = $treeselection->get_selected

    Get the iter of the currently selected row.

that's not too hard to do, but to do it we need to define the format of the
doc comments.


- support for introspection --- we need to ask the type system at runtime what
properties and signals an object has, who its ascestors are, what values an
enum or flag can have, etc.

to do this right, we need to define some other pod directives to go in other
parts of the XS file, so that we know to spit out all the relevant information
for GtkButton in the pod file for Gtk2::Button.

for the enums and flags, i guess we'll either have to use a "put this type's
values here" directive or glop them all into one file.


i'm out of time to write up the description, so here are the scripts and the
sample input.

you can also run the scripts on all the files in the Gtk2/xs subdir --- i've
been doing it like this:


  for i in *.xs ; do \
       j=`basename $i .xs`; \
       echo $j ; \
       ./parseem.pl $j.xs | \
           tee $j.docpl | \
           ./printem.pl > $j.pod ; \
  done




-- 
muppet <scott at asofyet dot org>

Attachment: documented.xs
Description: Binary data

Attachment: parseem.pl
Description: Binary data

Attachment: printem.pl
Description: Binary data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]