Tue Jan 27 19:54:40 GMT 2009

Embedding HTML in MoinMoin page contents

Question: How to use my wiki to store and test bits and pieces of plain html?

Answer: It should be simple, but there's no such formatter in MoinMoin (and no way I know to just say 'embed this text as-is') but surely this must be one of the simplest MoinMoin Parsers that could be written - so let's have a look...

The CSV Parser looked quite simple - from there it became clear that all you really need to do is initialise a couple of attributes in the constructor and then write the simplest-case format method:

 1  class Parser:
 2      """ Format HTML as HTML
 3      """
 4
 5      def __init__(self, raw, request, **kw):
 6          """ Store the source text.
 7          """
 8          self.raw = raw
 9          self.request = request
10          self._ = request.getText
11
12      def format(self, formatter):
13          """ Send it back as it came
14          """
15          self.request.write(self.raw)

Load this into your wiki plugin directory as data/plugin/parser/html.py directory, start a document with #FORMAT html and it just works. This probably wouldn't be a great feature for a public wiki, but it's nice to be able to roll your own so easily. :)


Posted by Bradley Dean | Permalink

Thu Jan 22 11:27:42 GMT 2009

Using Time::Local::timelocal rather than POSIX::strftime('%s', ...) to find seconds since the epoch

I ran into a cross-platform gotcha today with the perl POSIX::strftime function. I was after the seconds since the epoch for a given date and had called:

1    # ... determine second, minute, hour, day, month, year
2    my $epoch_seconds = strftime('%s', $second, $minute, $hour
3                                , $day, $month - 1, $year - 1900 );

Which of course works fine under *nix - but it turns out (a bit obviously with hindsight) that the windows strftime does not support '%s'. Unfortunately this does not result in any sort of error - rather you just end up with the literal string '%s'

Time::Local to the rescue - this module implements the reverse of the builtin localtime and gmtime functions.

Here's a version of the above code which works cross-platform:

1    use Time::Local;
2    # ... determine second, minute, hour, day, month, year
3    my $epoch_seconds = timelocal( $second, $minute, $hour
4                                 , $day, $month - 1, $year);

As an aside - the module extends the interpretation of the year to be more user friendly (so you can use fully qualified years, the familiar '$year - 1900' or two-digit years with a rolling window). It's probably better to stick with the fully qualified year - particularly when using old dates as it's possible that '$year - 1900' will end up in a sliding window and drop you in the wrong century.

(For other approaches read `perldoc -q epoch`)


Comment by: Bradley Dean at Thu, 22 Jan 2009 14:18:27 (GMT)

So why isn't this problem more apparent? When I first started looking around for the causes I couldn't really see much. One reason is probably that some developers 'just know' that their strftime has '%s' (not to mention that their time is based on the epoch) while others have never run into the epoch so would never call on '%s'.

The perl strftime documentation refers the reader to the local strftime man page for conversion specifiers, while others (I've looked at python, ruby and php) give a list of available conversion specifiers. I've checked time.strftime in python and it support '%s' (but it's undocumented) which I suspect will be true for most other languages as they'll be wrapping the system strftime rather than reimplimenting it.


Posted by Bradley Dean | Permalink