Skip to main content

Ralsina.Me — Roberto Alsina's website

Generating PDFs from Restructured text

This has al­ways been pos­si­ble, go­ing via La­TeX.

How­ev­er, La­TeX be­ing what it is, you ei­ther need to learn it, or you end up with rather plain-look­ing doc­u­ments.

While that's ok for a man­u­al, I want to use Re­struc­tured Text for ev­ery­thing in­volv­ing doc­u­ments.

So, I looked for an­oth­er so­lu­tion. Sad­ly, I could not make the ex­ist­ing rlpdf writ­er work, sooooo I de­cid­ed to write my own tool.

Since I in­tense­ly dis­like the Vis­i­tor pat­tern in­volved in writ­ing a reg­u­lar do­cu­tils writer, I adapt­ed my old rst2rst.py and end­ed with rst2pdf.py which just tra­vers­es the tree re­cur­sive­ly and writes the PDF us­ing Re­port­Lab.

And it took me about 3 hours to make it work:

  • For a lim­it­ed sub­­set of RST (no foot­notes, no links, no dec­o­ra­­tion)

  • For some sub­­set of ta­bles (no col/row span­n­ing)

  • With lim­it­ed "styling" (it's most­­ly there, but I need to write a lot of Re­­port­Lab styles.

How well does it work... rather well.

Here's a gen­er­at­ed PDF of The Re­struc­tured­Text Primer

Ig­nore aes­thet­ic­s, and con­sid­er func­tion, it's pret­ty good.

Templates that create templates...

... or why flex­i­bilty is good some­times.

Af­ter some dab­bling with Lurk­er, I de­cid­ed it's just too much trou­ble for the pro­to­type site and went look­ing for al­ter­na­tive mail­ing list archiver­s.

I found few, and de­cid­ed to try MHonArc.

Then I tried to make it fit the rest of the site. Ouch.

It's not that MHonArc does­n't pro­vide a way to cus­tom­ize the gen­er­at­ed HTM­L. It pro­vides one.

A ter­ri­bly con­vo­lut­ed one where in­stead of writ­ing a tem­plate for MHonArc to fill it has its tem­plate and it's filled from the da­ta and from a re­source file you write.

For ex­am­ple, I ex­pect­ed writ­ing a tem­plate like this (s­tupid ex­am­ple):

<h1> my archives </h1>
${toolbar}
${contents}

So that MHonArc would put a tool­bar and the con­tents where I tell it to.

In re­al­i­ty, MHonArc has a hard­cod­ed tem­plate like this:

IDXPGSSMARKUP
IDXPGBEGIN
    LISTBEGIN
        (AUTHORBEGIN |
         DAYBEGIN |
         SUBJECTBEGIN)?
        LITEMPLATE+
        (AUTHOREND |
         DAYEND |
         SUBJECTEND)?
     LISTEND
    DOC?
IDXPGEND

And you tell it what IDXP­GEND should be, or it us­es its de­fault val­ue. And there is one of these things, with sim­i­lar but dif­fer­ent vari­ables, for each kind of page it gen­er­ates.

So, you can cus­tom­ize your lay­out by putting things like this in a re­source file:

<IdxPgEnd>
$MY-FOOTER-LINK$
</body>
</html>
</IdxPgEnd>

Which is doable. But you end with stat­ic pages. How can you make that work well with a mod­ern site with­out du­pli­cat­ing the whole base lay­out? Not to men­tion all the niceties like hav­ing your user­name in the tool­bar and what­ev­er.

Gen­er­ate page tem­plates in­stead.

I cus­tom­ized the MHonArc lay­out to gen­er­ate neat Mako tem­plates that in­her­it the "re­al" base lay­out tem­plate.

I on­ly had to be care­ful to es­cape the $ signs as $$ if I want­ed them to sur­vive un­til Mako saw them.

Then cre­ate a view that pro­cess­es the tem­plates in­stead of serv­ing the stat­ic files and it works like a char­m.

A sim­ple, but neat hack­let, I think.

Everything is still around

For a project I am do­ing for one of my cus­tomer­s, I need­ed a mail­ing list ar­chive. I looked, and it seems the nicer one is Lurk­er.

Sad­ly, there are no RPM pack­ages, so I had to build it man­u­al­ly... and ran in­to mimelib. Which, look­ing closer, is the same mimelib from Doug Saud­er I used in KRN back in the late 90s.

And which I had a hand in GPLing, too. And it's still in use. One of the things I al­ways liked about FLOSS: noth­ing ev­er re­al­ly gets thrown away.

The Shadow of the Lion (Heirs of Alexandria, #1)

  • Au­thor: Mer­cedes Lack­ey
  • Rat­ing:
  • See in goodreads
  • Re­view:

    An in­­ter­est­ing al­ter­­na­­tive his­­to­ry idea, where mag­ic works and re­li­­gion is ac­­tu­al­­ly true, even if not ex­ac­t­­ly sim­i­lar to what we know to­­day, and a rec­og­niz­able world.

    I liked the sec­ond part bet­ter, but this is not bad at al­l.

New library: ChipScene

This is the re­al out­come of my Py­Week fail­ure: a neat li­brary.

Take Chip­munk and Qt mash them up, and what do you get?

A OpenGL-ac­cel­er­at­ed, mul­ti­plat­for­m, easy-­to-use play­ground!

But watch the sil­ly video that shows no in­ter­est­ing fea­tures in­stead:

You can't see it but there are 29 bal­loon­s, num­bered, that bounce around hap­pi­ly.

Per­for­mance in the video sucks be­cause I had to dis­able OpenGL in or­der to cap­ture it cor­rect­ly (and video record­ing kills my note­book,any­way). That de­mo nor­mal­ly runs in 3 sec­ond­s, not 57.

Here's the non-boil­er­plate code for that de­mo:

def fillWorld(scene):
  items=[]
  for x in range(1, 29):
      b=cs.CPBodyItem(bpos=[0+13*random.randint(0,25), -50-30*random.randint(0,10)],m=10)
      s=cs.CPCircleShapeItem(10, b, e=.5, offset=[0, 0])
      t=QtGui.QGraphicsSimpleTextItem(str(x), s)
      t.setPos(-5, -5)
      items.append(b)
  items.append(cs.CPSegmentShapeItem([0, 50], [500, 450], 1, None, e=.7))
  items.append(cs.CPSegmentShapeItem([0, 450], [500, 50], 1, None, e=.7))

  for i in items:
      scene.addItem(i)

Neat, is­n't it?

You can get it at the Chip­Scene google code project in­clud­ing, of course, the source.