Librsvg's documentation tooling is pretty ancient. The man page for
rsvg-convert
is written by hand in troff
, and the C library's
reference documentation still uses the venerable gtk-doc.
As part of the modernization effort, I have turned the man page into a reStructuredText document, and the C API documentation into gi-docgen. This post describes how I did that.
You can read librsvg's new documentation here.
From man to rst
The man page for rsvg-convert
was written in troff
, which is pretty cumbersome. The following gunk defines a little paragraph and a table:
.P
You can also specify dimensions as CSS lengths, for example
.B 10px
or \"
.BR 8.5in .
The unit specifiers supported are as follows:
.RS
.TS
tab (@);
l lx.
px@T{
pixels (the unit specifier can be omitted)
T}
in@T{
inches
T}
cm@T{
centimeters
T}
mm@T{
millimeters
T}
pt@T{
points, 1/72 inch
T}
pc@T{
picas, 1/6 inch
T}
.TE
Yeah, nope. We have better tools now like rst2man
, which take a
reStructuredText document — fancy plain text — and turn it into a
troff
man page. I just had to use a command line like
pandoc --from=man --to=rst rsvg-convert.1 > rsvg-convert.rst
and then tweak the output a little:
You can also specify dimensions as CSS lengths, for example ``10px`` or
``8.5in``. The unit specifiers supported are as follows:
== ==========================================
px pixels (the unit specifier can be omitted)
in inches
cm centimeters
mm millimeters
pt points, 1/72 inch
pc picas, 1/6 inch
== ==========================================
Much better, right?
I've learned that Pandoc is awesome. Pure magic, highly recommended.
I hope to integrate the man page into a prettier user manual for rsvg-convert at some point. It's no longer a trivial program, and its options allow for some interesting combinations that could use some illustrations and generally more detail than a man page.
From gtk-doc to gi-docgen
I highly recommend that you read Emmanuele's initial description of gi-docgen, which includes the history of gtk-doc, a description of its shortcomings, and how gi-docgen is a simpler tool that leverages the fact that GObject Introspection already slurps documentation from source code and so obviates most of gtk-doc already.
Summary of how gi-docgen works:
-
The C code has documentation comments in Markdown format, with annotations for GObject Introspection. (Note: librsvg has no C code for the library, so those documentation comments actually live in the
.h
header files that it installs for the benefit of C programs.) -
The library gets compiled and introspected. In this step,
g-ir-scanner(1)
extracts annotations and documentation from the source code and puts them in theMyLibrary.gir
XML file. -
You write a small configuration file to tell gi-docgen about the structure of your documentation. Unlike gtk-doc, you don't need to write a DocBook skeleton or anything complicated. Stand-alone chapters can be individual Markdown files, and the configuration file just lists them in the order you want them to appear. Gi-docgen automatically includes all the classes, types, functions, etc. from your code into the docs.
-
... it runs very fast. Gtk-doc was always slow due to xsltproc and complicated stylesheets to turn a DocBook document into browsable HTML documentation. Gi-docgen is much leaner.
Doing the conversion
Unlike the mostly automatic pandoc
step for the man page, I
converted the documentation comments to from DocBook to Markdown by
hand. For librsvg this took me a moderately caffeinated afternoon;
it's a little fiddly business, but nothing out of this world.
You can look forward to having good error messages from gi-docgen when something goes wrong, unlike gtk-doc, whose errors I always tended to ignore until the last minute because they were so hard to discern and diagnose.
Some hints:
-
DocBook hyperlinks that looked like
<ulink url="blahblah.html">blah blah</ulink>
get turned into[blah blah](blahblah.html)
Markdown. -
Gi-docgen allows references to methods like
[method@Gtk.Button.set_child]
- see the linking documentation for other kinds of links. -
You can get progressively fancy with introspection attributes.
-
There is no direct mapping between DocBook's extremely granular semantic markup and Markdown conventions, so for example I'd substitute both
<literal>foobar</literal>
and<filename>/foo/bar</filename>
for `foobar` and `/foo/bar`, respectively (i.e. the text I wanted to show, between backticks, to indicate verbatim text).
Librsvg seemed to include verbatim text blocks in gtk-doc delimited like this:
/**
* blah_blah():
*
* For example:
*
* |[
* verbatim text goes here
* ]|
*
* Etc. etc.
*/
Those can go between ``` triple backticks in Markdown:
/**
* blah_blah():
*
* For example:
*
* ```
* verbatim text goes here
* ```
*
* Etc. etc.
*/
Errors I found
My first manual run of gi-docgen looked like this:
$ gi-docgen check Rsvg-2.0.gir
INFO: Loading config file: None
INFO: Search paths: ['/home/federico/src/librsvg/gi-docgen/_build', '/home/federico/.local/share/gir-1.0', '/home/federico/.local/share/flatpak/exports/share/gir-1.0', '/var/lib/flatpak/exports/share/gir-1.0', '/usr/local/share/gir-1.0', '/usr/share/gir-1.0']
INFO: Elapsed time 1.601 seconds
WARNING: Symbol 'Rsvg.HandleFlags' at <unknown>:0 is not documented
WARNING: Return value for symbol 'Rsvg.Handle.get_dimensions_sub' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.get_geometry_for_element' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.get_geometry_for_layer' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.get_position_sub' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.render_document' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.render_element' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.render_layer' is not documented
WARNING: Return value for symbol 'Rsvg.Handle.set_stylesheet' is not documented
WARNING: Symbol 'Rsvg.Handle.base-uri' at <unknown>:0 is not documented
WARNING: Symbol 'Rsvg.Handle.dpi-x' at <unknown>:0 is not documented
WARNING: Symbol 'Rsvg.Handle.dpi-y' at <unknown>:0 is not documented
WARNING: Symbol 'Rsvg.cleanup' at include/librsvg/rsvg.h:447 is not documented
WARNING: Symbol 'Rsvg.DEPRECATED_FOR' at include/librsvg/rsvg.h:47 is not documented
WARNING: Parameter 'f' of symbol 'Rsvg.DEPRECATED_FOR' is not documented
The warnings like WARNING: Return value ... is not documented
are easy
to fix; the comment blocks had their descriptions, but they were
missing the Returns:
part.
The warnings like WARNING: Symbol 'Rsvg.Handle.base-uri' at <unknown>:0 is not documented
are different. Those are GObject properties, which previously were documented like this:
/**
* RsvgHandle::base-uri:
*
* Base URI, to be used to resolve relative references for resources. See the section
* "Security and locations of referenced files" for details.
*/
There is a syntax error there! The symbol line should use a single
colon between the class name and the property name,
e.g. RsvgHandle:base-uri
instead of RsvgHandle::base-uri
. This
one, plus the other properties that showed up as not documented, had
the same kind of typo.
The first warning, WARNING: Symbol 'Rsvg.HandleFlags' at <unknown>:0
is not documented
, turned out to be that there were two
documentation comments with the same title for RsvgHandleFlags
, and
the second one was empty — and the last one wins. I left a single one
with the actual docs.
Writing standalone chapters
Librsvg had a few chapters like doc/foo.xml
, doc/bar.xml
that were
included in the reference documentation; those were a DocBook
<chapter>
each. I was able to convert them to Markdown with
pandoc
individually, and then add a Title:
heading in the first
line of each .md
file — that's what gi-docgen uses to build the
table of contents in the documentation's starting page.
Title: Overview of Librsvg
# Overview of Librsvg
Librsvg is a library for rendering Scalable Vector Graphics files (SVG).
Blah blah blah blah.
Build scripts
There are plenty of examples for using gi-docgen with meson; you can look at how it is done in gtk.
However, librsvg is still using Autotools! You can steal the following bits:
Publishing the documentation
Gtk-doc assumed that magic happened somewhere in
developer.gnome.org
to generate the documentation and publish it.
Gi-docgen assumes that your project publishes it with Gitlab pages.
Indeed, the new documentation is published there — you can see how
it is generated in .gitlab-ci.yml. Note that there are
two jobs: the reference
job generates gi-docgen's HTML in a
public/Rsvg-2.0
directory, and the pages
job integrates it with
the Rust API documentation and publishes both together.
Linking the docs to the main developer's site
Finally, librsvg's docs are linked from the GNOME Platform
Introduction. I submitted a merge request to the
developer-www
project to update it.
That's all! I hope this is useful for someone who wants to move from gtk-doc to gi-docgen, which is a much more pleasant tool!