diff options
author | Thomas Schwinge <thomas@schwinge.name> | 2010-12-13 17:11:51 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas@schwinge.name> | 2010-12-13 17:11:51 +0100 |
commit | 2d75167da62e3486836e5f1773e5f1ab06e43fe8 (patch) | |
tree | e44fc83e0b1419836d1b21652ad1d38b8d0af2c4 /.library/IkiWiki/Plugin/texinfo.pm | |
parent | 217998d56f5b6424a685f8c87f2c0e924d1c89da (diff) | |
parent | 5c5c16e265d8ef56b71f319885f32bf144bdea23 (diff) |
Merge branch 'master' into external_pager_mechanism
Conflicts:
microkernel/mach/external_pager_mechanism.mdwn
Diffstat (limited to '.library/IkiWiki/Plugin/texinfo.pm')
-rw-r--r-- | .library/IkiWiki/Plugin/texinfo.pm | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/.library/IkiWiki/Plugin/texinfo.pm b/.library/IkiWiki/Plugin/texinfo.pm new file mode 100644 index 00000000..8c651160 --- /dev/null +++ b/.library/IkiWiki/Plugin/texinfo.pm @@ -0,0 +1,226 @@ +# A GNU Texinfo rendering plugin. + +# Copyright © 2007 Thomas Schwinge <tschwinge@gnu.org> +# +# 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; + $license{$page} =~ s/\@end\ ignore/-->/g; + } + + out: + return $params{content}; +} + +sub htmlize (@) +{ + my %params = @_; + my $page = $params{page}; + + my $home; + if (defined $pagesources{$page}) + { + $home = $config{srcdir} . '/' . dirname ($pagesources{$page}); + } + else + { + # This happens in the CGI web frontent, when freshly creating a + # `texi'-type page and selecting to ``Preview'' the page before doing a + # ``Save Page''. +# TODO. + $home = $config{srcdir}; + } + + 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', $home, +# 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 = <IN>; + close IN; + waitpid $pid, 0; + $SIG{PIPE} = "DEFAULT"; + + return "failed to render" if $sigpipe; + + # Cut out the interesting bits. + $ret =~ s/.*<body>//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 |