Added mdwn_itex.
authorW. Trevor King <wking@drexel.edu>
Thu, 30 Sep 2010 05:29:32 +0000 (01:29 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 30 Sep 2010 05:29:32 +0000 (01:29 -0400)
posts/mdwn_itex-templates.patch [new file with mode: 0644]
posts/mdwn_itex.mdwn_itex [new file with mode: 0644]
posts/mdwn_itex.patch [new file with mode: 0644]
posts/mdwn_itex.pm [new file with mode: 0644]

diff --git a/posts/mdwn_itex-templates.patch b/posts/mdwn_itex-templates.patch
new file mode 100644 (file)
index 0000000..2024bc3
--- /dev/null
@@ -0,0 +1,36 @@
+diff -ru /usr/share/ikiwiki/templates/misc.tmpl /home/wking/.ikiwiki/templates/misc.tmpl
+--- /usr/share/ikiwiki/templates/misc.tmpl     2009-06-05 15:21:43.000000000 -0400
++++ /home/wking/.ikiwiki/templates/misc.tmpl   2010-09-29 23:50:05.000000000 -0400
+@@ -1,6 +1,11 @@
+-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+-<html xmlns="http://www.w3.org/1999/xhtml">
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE html PUBLIC
++    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
++    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml"
++      xmlns:math="http://www.w3.org/1998/Math/MathML"
++      xmlns:svg="http://www.w3.org/2000/svg"
++      xml:lang="en" dir="ltr">
+ <head>
+ <TMPL_IF NAME="FORCEBASEURL">
+ <base href="<TMPL_VAR FORCEBASEURL>" />
+diff -ru /usr/share/ikiwiki/templates/page.tmpl /home/wking/.ikiwiki/templates/page.tmpl
+--- /usr/share/ikiwiki/templates/page.tmpl     2009-06-05 15:21:43.000000000 -0400
++++ /home/wking/.ikiwiki/templates/page.tmpl   2010-09-29 23:49:56.000000000 -0400
+@@ -1,6 +1,11 @@
+-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+-<html xmlns="http://www.w3.org/1999/xhtml">
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE html PUBLIC
++    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
++    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml"
++      xmlns:math="http://www.w3.org/1998/Math/MathML"
++      xmlns:svg="http://www.w3.org/2000/svg"
++      xml:lang="en" dir="ltr">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title><TMPL_VAR TITLE></title>
diff --git a/posts/mdwn_itex.mdwn_itex b/posts/mdwn_itex.mdwn_itex
new file mode 100644 (file)
index 0000000..7a95760
--- /dev/null
@@ -0,0 +1,56 @@
+In my [[last post|MathML]] I plugged Jason Blevins' [mdwn_itex
+plugin][plugin].  It turns out that it was harder than I'd expected to
+get the plugin working with ikiwiki, so I'm recording the steps I took
+here in case other ikiwiki users find this useful.
+
+* Install [itex2MML][]
+* [Install][install_plugin] my updated [[mdwn_itex.pm|mdwn_itex.pm]]
+  plugin ([[mdwn_itex.patch|mdwn_itex.patch]] against Jason's
+  version).
+* Patch your ikiwiki [templates][] to use a `DOCTYPE` supporting
+  MathML ([[mdwn_itex-templates.patch|mdwn_itex-templates.patch]]).
+* Add config options along the lines of:
+
+        # plugins to add to the default configuration
+        add_plugins => [qw{ ... mdwn_itex ...}],
+        # plugins to disable
+        disable_plugins => [qw{... htmlscrubber htmltidy ...}],
+
+        # location of template files
+        templatedir => '/path/to/patched/templates',
+
+        # mdwn_itex plugin
+        # path to the itex2MML binary
+        itex2mml => '/usr/local/bin/itex2MML',
+        # autonumber display equations?
+        itex_num_equations => 1,
+
+* Create new files with the `.mdwn_itex` extension, and start
+  including [itex][]:
+
+  Euler's identity
+
+  &#92;[ e^{i \pi} + 1 = 0 &#92;]
+
+  has lots of fun constants: &#36;e&#36;, &#36;i&#36;, &#36;\pi&#36;,
+  &#36;1&#36;, and &#36;0&#36;.
+
+Which will render as
+
+Euler's identity
+
+\[ e^{i \pi} + 1 = 0 \]
+
+has lots of fun constants: $e$, $i$, $\pi$, $1$, and $0$.
+
+The `htmlscrubber` and `htmltidy` plugins must be disabled because
+otherwise they [strip out the MathML markup][strip].
+
+[plugin]: http://jblevins.org/git/ikiwiki/plugins.git/plain/mdwn_itex.pm
+[itex2MML]: http://golem.ph.utexas.edu/~distler/blog/itex2MML.html
+[install_plugin]: http://ikiwiki.info/plugins/install/
+[templates]: http://ikiwiki.info/templates/
+[strip]: http://ikiwiki.info/todo/svg/
+[itex]: http://golem.ph.utexas.edu/~distler/blog/itex2MMLcommands.html
+
+[[!tag tags/blogging]]
diff --git a/posts/mdwn_itex.patch b/posts/mdwn_itex.patch
new file mode 100644 (file)
index 0000000..1c68aa5
--- /dev/null
@@ -0,0 +1,157 @@
+diff -u a/mdwn_itex.pm b/mdwn_itex.pm
+--- a/mdwn_itex.pm     2010-09-29 17:30:37.000000000 -0400
++++ b/mdwn_itex.pm     2010-09-29 23:59:59.713046023 -0400
+@@ -2,66 +2,70 @@
+ #
+ # itex to MathML plugin for IkiWiki.  Based on the itex MovableType
+ # plugin by Jacques Distler.
+-#
+-# Jason Blevins <jrblevin@sdf.lonestar.org>
+-# Chapel Hill, March 16, 2008
+ package IkiWiki::Plugin::mdwn_itex;
+ use warnings;
+ use strict;
+-use IkiWiki 2.00;
++use IkiWiki 3.00;
+ use File::Temp qw(tempfile);
+-my $markdown_sub;
+-my %itex_pages;
+-
+ sub import {
+-    hook(type => "getopt", id => "mdwn_itex", call => \&getopt);
+-    hook(type => "htmlize", id => "mdwn", call => \&htmlize);
+-    hook(type => "preprocess", id => "itex", call => \&preprocess_itex);
+-}
+-
+-sub getopt () {
+-    eval q{use Getopt::Long};
+-    error($@) if $@;
+-    Getopt::Long::Configure('pass_through');
+-    GetOptions(
+-        # Location of the itex2mml binary
+-        "itex2mml=s" => \$config{itex2mml},
+-        # Enable or disable numbering of \[..\] equations
+-        "itex_num_equations!" => \$config{num_equations},
+-        # Process all pages by default or require [[!itex ]] directive?
+-        "itex_default!" => \$config{itex_default},
+-    );
+-
+-    # Default settings
+-    $config{itex2mml} = '/usr/local/bin/itex2MML' unless defined $config{itex2mml};
+-    $config{itex_num_equations} = 1 unless defined $config{itex_num_equations};
+-    $config{itex_default} = 0 unless defined $config{itex_default};
+-}
+-
+-sub preprocess_itex (@) {
+-    my %params = @_;
+-    if (defined $params{disable}) {
+-        $itex_pages{$params{page}} = 0;
+-    } else {
+-        $itex_pages{$params{page}} = 1;
++    # register the plugin
++    hook(type => "getsetup", id => "mdwn_itex", call => \&getsetup);
++    hook(type => "checkconfig", id => "mdwn_itex", call => \&checkconfig);
++    hook(type => "preprocess", id => "itex", call => \&preprocess);
++    hook(type => "htmlize", id => "mdwn_itex", call => \&htmlize,
++       longname => "Markdown + itex");
++}
++
++sub getsetup () {
++    # declare plugin options etc. for the setup file
++    return
++      plugin => {
++          description => "itex to MathML conversion followed by Markdown formatting",
++          safe => 1,
++          rebuild => 1,
++          section => "format",
++        },
++        itex2mml => {
++          type => "string",
++          example => '/usr/local/bin/itex2MML',
++          description => "path to the itex2MML binary",
++          safe => 0, # path
++          rebuild => 0,
++      },
++        itex_num_equations => {
++          type => "boolean",
++          example => 1,
++          description => "autonumber \[..\] equations?",
++          safe => 1,
++          rebuild => 1,
++      },
++}
++
++sub checkconfig () {
++    # setup default settings
++    if (! exists $config{itex2mml}) {
++      $config{itex2mml} = '/usr/local/bin/itex2MML';
++    }
++    if (! exists $config{itex_num_equations}) {
++      $config{itex_num_equations} = 1;
++    }
++    if (! exists $config{itex_default}) {
++      $config{itex_default} = 0;
+     }
+-    return '';
+ }
+-# Taken from mdwn plugin and modified to call itex2MML.
+ sub htmlize (@) {
++    # convert the page contents to XHTML.
+     my %params=@_;
++
+     my $content = $params{content};
+     my $page = $params{page};
+-    # Default settings
+-    $itex_pages{$page} = $config{itex_default} unless defined $itex_pages{$page};
+-
+-    $params{content} = itex_filter($content) if $itex_pages{$page};
++    $params{content} = itex_filter($content);
+     return IkiWiki::Plugin::mdwn::htmlize(%params);
+ }
+@@ -77,6 +81,7 @@
+     my ($Reader, $outfile) = tempfile( UNLINK => 1 );
+     my ($Writer, $infile) = tempfile( UNLINK => 1 );
++    binmode $Writer, ":utf8";
+     print $Writer "$content";
+     system("$config{itex2mml} < $infile > $outfile");
+     my @out = <$Reader>;
+@@ -136,6 +141,9 @@
+ =head1 AUTHORS
++W. Trevor King <wking@drexel.edu>,
++updates to IkiWiki v3.00
++
+ Jason Blevins <jrblevin@sdf.lonestar.org>,
+ itex Blosxom plugin
+@@ -144,6 +152,12 @@
+ =head1 SEE ALSO
++W. Trevor King's blog entry for this plugin:
++http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/mdwn_itex/
++
++Jason Blevins' ikiwiki plugin:
++http://jblevins.org/git/ikiwiki/plugins.git/plain/mdwn_itex.pm
++
+ ikiwiki Homepage:
+ http://ikiwiki.info/
+@@ -155,6 +169,8 @@
+ =head1 LICENSE
++Copyright (C) 2010 W. Trevor King
++
+ Copyright (C) 2008 Jason Blevins
+ Copyright (C) 2003-2007 Jacques Distler
diff --git a/posts/mdwn_itex.pm b/posts/mdwn_itex.pm
new file mode 100644 (file)
index 0000000..2d3072f
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/perl
+#
+# itex to MathML plugin for IkiWiki.  Based on the itex MovableType
+# plugin by Jacques Distler.
+
+package IkiWiki::Plugin::mdwn_itex;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+use File::Temp qw(tempfile);
+
+sub import {
+    # register the plugin
+    hook(type => "getsetup", id => "mdwn_itex", call => \&getsetup);
+    hook(type => "checkconfig", id => "mdwn_itex", call => \&checkconfig);
+    hook(type => "preprocess", id => "itex", call => \&preprocess);
+    hook(type => "htmlize", id => "mdwn_itex", call => \&htmlize,
+        longname => "Markdown + itex");
+}
+
+sub getsetup () {
+    # declare plugin options etc. for the setup file
+    return
+       plugin => {
+           description => "itex to MathML conversion followed by Markdown formatting",
+           safe => 1,
+           rebuild => 1,
+           section => "format",
+        },
+        itex2mml => {
+           type => "string",
+           example => '/usr/local/bin/itex2MML',
+           description => "path to the itex2MML binary",
+           safe => 0, # path
+           rebuild => 0,
+       },
+        itex_num_equations => {
+           type => "boolean",
+           example => 1,
+           description => "autonumber \[..\] equations?",
+           safe => 1,
+           rebuild => 1,
+       },
+}
+
+sub checkconfig () {
+    # setup default settings
+    if (! exists $config{itex2mml}) {
+       $config{itex2mml} = '/usr/local/bin/itex2MML';
+    }
+    if (! exists $config{itex_num_equations}) {
+       $config{itex_num_equations} = 1;
+    }
+    if (! exists $config{itex_default}) {
+       $config{itex_default} = 0;
+    }
+}
+
+sub htmlize (@) {
+    # convert the page contents to XHTML.
+    my %params=@_;
+
+    my $content = $params{content};
+    my $page = $params{page};
+
+    $params{content} = itex_filter($content);
+
+    return IkiWiki::Plugin::mdwn::htmlize(%params);
+}
+
+sub itex_filter {
+    my $content = shift;
+
+    # Remove carriage returns. itex2MML expects Unix-style lines.
+    $content =~ s/\r//g;
+
+    # Process equation references
+    $content = number_equations($content) if $config{itex_num_equations};
+
+    my ($Reader, $outfile) = tempfile( UNLINK => 1 );
+    my ($Writer, $infile) = tempfile( UNLINK => 1 );
+    binmode $Writer, ":utf8";
+    print $Writer "$content";
+    system("$config{itex2mml} < $infile > $outfile");
+    my @out = <$Reader>;
+    close $Reader;
+    close $Writer;
+    eval { unlink ($infile, $outfile); };
+    return join('', @out);
+}
+
+sub number_equations {
+    my $body = shift;
+
+    my $prefix = "eq";
+    my $cls = "numberedEq";
+
+    my %eqnumber;
+    my $eqno=1;
+
+    # add equation numbers to \[...\]
+    #  - introduce a wrapper-<div> and a <span> with the equation number
+    while ($body =~ s/\\\[(.*?)\\\]/\n\n<div class=\"$cls\"><span>\($eqno\)<\/span>\$\$$1\$\$<\/div>\n\n/s)
+      {
+          $eqno++;
+      }
+
+    # assemble equation labels into a hash
+    # - remove the \label{} command, collapse surrounding whitespace
+    # - add an ID to the wrapper-<div>. prefix it to give a fighting chance
+    #   for the ID to be unique
+    # - hash key is the equation label, value is the equation number
+    while ($body =~ s/<div class=\"$cls\"><span>\((\d+)\)<\/span>\$\$((?:[^\$]|\\\$)*)\s*\\label{(\w*)}\s*((?:[^\$]|\\\$)*)\$\$<\/div>/<div class=\"$cls\" id=\"$prefix:$3\"><span>\($1\)<\/span>\$\$$2$4\$\$<\/div>/s)
+      {
+          $eqnumber{"$3"} = $1;
+      }
+
+    # add cross-references
+    # - they can be either (eq:foo) or \eqref{foo}
+    $body =~ s/\(eq:(\w+)\)/\(<a href=\"#$prefix:$1\">$eqnumber{"$1"}<\/a>\)/g;
+    $body =~ s/\\eqref\{(\w+)\}/\(<a href=\'#$prefix:$1\'>$eqnumber{"$1"}<\/a>\)/g;
+
+    return $body;
+}
+
+1
+
+  __END__
+
+=head1 NAME
+
+ikiwiki Plug-in: mdwn_itex
+
+=head1 SYNOPSIS
+
+Processes embedded itex (LaTeX-based) expressions in pages and converts
+them to MathML.  Also provides equation-numbering as described on
+Jacques Distler's itex2MML commands page.
+
+=head1 AUTHORS
+
+W. Trevor King <wking@drexel.edu>,
+updates to IkiWiki v3.00
+
+Jason Blevins <jrblevin@sdf.lonestar.org>,
+itex Blosxom plugin
+
+Jacques Distler <distler@golem.ph.utexas.edu>,
+itex2MML and itex2MML Movable Type Plugin
+
+=head1 SEE ALSO
+
+W. Trevor King's blog entry for this plugin:
+http://www.physics.drexel.edu/~wking/unfolding-disasters/posts/mdwn_itex/
+
+Jason Blevins' ikiwiki plugin:
+http://jblevins.org/git/ikiwiki/plugins.git/plain/mdwn_itex.pm
+
+ikiwiki Homepage:
+http://ikiwiki.info/
+
+ikiwiki Plugin Documentation:
+http://ikiwiki.info/plugins/write/
+
+itex2MML commands:
+http://golem.ph.utexas.edu/~distler/blog/itex2MML.html
+
+=head1 LICENSE
+
+Copyright (C) 2010 W. Trevor King
+
+Copyright (C) 2008 Jason Blevins
+
+Copyright (C) 2003-2007 Jacques Distler
+
+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 of the License, 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.