From e00edb71860553e5d75b0e1cbf26625431c1c2d4 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Thu, 8 Nov 2007 17:44:02 +0100 Subject: First version of a GNU Texinfo rendering plugin. Written by Thomas Schwinge . See for details. --- .library/IkiWiki/Plugin/texinfo.pm | 212 +++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 .library/IkiWiki/Plugin/texinfo.pm diff --git a/.library/IkiWiki/Plugin/texinfo.pm b/.library/IkiWiki/Plugin/texinfo.pm new file mode 100644 index 00000000..8df2e38c --- /dev/null +++ b/.library/IkiWiki/Plugin/texinfo.pm @@ -0,0 +1,212 @@ +# A GNU Texinfo rendering plugin. + +# Copyright © 2007 Thomas Schwinge +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# http://ikiwiki.info/plugins/contrib/texinfo/ + +package IkiWiki::Plugin::texinfo; + +use warnings; +use strict; +use IkiWiki 2.00; + +# From `Ikiwiki/Plugins/teximg.pm'. +sub create_tmp_dir ($) +{ + # Create a temp directory, it will be removed when ikiwiki exits. + my $base = shift; + + my $template = $base . ".XXXXXXXXXX"; + use File::Temp qw (tempdir); + my $tmpdir = tempdir ($template, TMPDIR => 1, CLEANUP => 1); + return $tmpdir; +} + +sub import +{ + hook (type => "filter", id => "texi", call => \&filter); + hook (type => "htmlize", id => "texi", call => \&htmlize); + hook (type => "pagetemplate", id => "texi", call => \&pagetemplate); +} + +my %copyright; +my %license; + +sub filter (@) +{ + my %params = @_; + my $page = $params{page}; + +# TODO. For ``$page eq 'shortcuts''' this fails. Is this expected? + goto out unless defined $pagesources{$page}; + + # Only care for `.texi' files. + goto out unless pagetype ($pagesources{$page}) eq 'texi'; + + # No need to parse twice. + goto out if exists $copyright{$page}; + +# TODO. Check the `meta' plugin about when to do this at all. + $copyright{$page} = undef; + $license{$page} = undef; + # We assume that the copyright and licensing information is to be taken + # from the main `.texi' file. + @_ = split /\n/, $params{content}; + # Do some parsing to cut out the interesting bits, if there are any. + while (defined ($_ = shift @_)) + { + # Did we find a start tag? + last if /^\@copying$/; + } + # Already at the end of the page? + goto out unless defined $_; + while (defined ($_ = shift @_)) + { + # Already at the end of the copying section? (Shouldn't happen.) + goto out if /^\@end\ copying/; + # Found the ``^Copyright'' line? + last if /^Copyright/; + } + # Already at the end of the page? (Shouldn't happen.) + goto out unless defined $_; + # Copyright text will follow. + $copyright{$page} = $_; + while (defined ($_ = shift @_)) + { + # Found the separator of copyright and licensind information? + last if /^$/; + # Already at the end of the copying section? + goto finish if /^\@end\ copying/; + $copyright{$page} .= ' ' . $_; + } + # Already at the end of the page? (Shouldn't happen.) + goto finish unless defined $_; + # Licensing text will follow. + while (defined ($_ = shift @_)) + { + # Already at the end of the copying section? + last if /^\@end\ copying/; + $license{$page} .= ' ' . $_; + } + + finish: + # ``Render'' by hand some stuff that is commonly found in this section. + if (defined $copyright{$page}) + { + $copyright{$page} =~ s/\@copyright{}/©/g; + } + if (defined $license{$page}) + { + $license{$page} =~ s/\@quotation//g; + $license{$page} =~ s/\@end\ quotation//g; + $license{$page} =~ s/\@ignore//g; + } + + out: + return $params{content}; +} + +sub htmlize (@) +{ + my %params = @_; + my $page = $params{page}; + + my $pid; + my $sigpipe = 0; + $SIG{PIPE} = sub + { + $sigpipe = 1; + }; + + my $tmp = eval + { + create_tmp_dir ("texinfo") + }; + if (! $@ && + # `makeinfo' can't work directly on stdin. + writefile ("texinfo.texi", $tmp, $params{content}) == 0) + { + return "couldn't write temporary file"; + } + + use File::Basename; + use IPC::Open2; + $pid = open2 (*IN, *OUT, + 'makeinfo', + '--html', + '--no-split', '--output=-', + # We might be run from a directory different from the one the + # `.texi' file is stored in. +# TODO. Should we `cd' to this directory instead? + '-P', $config{srcdir} . '/' . dirname ($pagesources{$page}), +# TODO. Adding the following allows for putting files like `gpl.texinfo' into +# the top-level wiki directory. + '-I', $config{srcdir}, + $tmp . "/texinfo.texi"); + # open2 doesn't respect "use open ':utf8'" + binmode (IN, ':utf8'); +# binmode (OUT, ':utf8'); + +# print OUT $params{content}; + close OUT; + + local $/ = undef; + my $ret = ; + close IN; + waitpid $pid, 0; + $SIG{PIPE} = "DEFAULT"; + + return "failed to render" if $sigpipe; + + # Cut out the interesting bits. + $ret =~ s/.*//s; + $ret =~ s/<\/body>.*//s; + + return $ret; +} + +sub pagetemplate (@) +{ + my %params = @_; + my $page = $params{page}; + my $destpage = $params{destpage}; + + my $template = $params{template}; + +# TODO. Check the `meta' plugin about when to do this at all. + if ($template->query (name => "copyright") && + ! defined $template->param ('copyright')) + { + if (defined $copyright{$page} && length $copyright{$page}) + { + $template->param (copyright => + IkiWiki::linkify ($page, $destpage, $copyright{$page})); + } + } + if ($template->query (name => "license") && + ! defined $template->param ('license')) + { + if (defined $license{$page} && length $license{$page}) + { + $template->param (license => + IkiWiki::linkify ($page, $destpage, $license{$page})); + } + } +} + +1 -- cgit v1.2.3