Skip to content

Commit d546ee9

Browse files
committed
Added module, wrote readme
1 parent ff1a53a commit d546ee9

File tree

2 files changed

+134
-3
lines changed

2 files changed

+134
-3
lines changed

IkiWiki/Plugin/mathjax.pm

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package IkiWiki::Plugin::mathjax;
2+
3+
use warnings;
4+
use strict;
5+
use IkiWiki 3.00;
6+
use MIME::Base64;
7+
8+
# Strategy:
9+
## - filter replaces normal TeX delimiters with imath and dmath directives
10+
## (perhaps while considering a mathconf directive); also, it adds a script
11+
## block if there is any math on the page relevant.
12+
## - preprocess handles the directives themselves.
13+
##
14+
## Later: config hooks for mathjax script tag and mathjax config block
15+
##
16+
17+
sub import {
18+
hook(type => "filter", id => "mathjax", call => \&filter);
19+
hook(type => "format", id=>"mathjax", call=> \&format);
20+
}
21+
22+
sub format {
23+
my %params = @_;
24+
my $content = $params{content};
25+
return $content unless $content =~ /\!\!mathjaxbegin/; #]/{{
26+
$content =~ s{\!\!mathjaxbegin-i!! (.*?)\s\!\!mathjaxend-i\!\!}{'\('.decode_base64($1).'\)'}ges; #{
27+
$content =~ s{\!\!mathjaxbegin-d!! (.*?)\s\!\!mathjaxend-d\!\!}{'\['.decode_base64($1).'\]'}ges; #{
28+
my $scripttag = _scripttag();
29+
$content =~ s{(</head>)}{$scripttag\n$1}i; #}{
30+
return $content;
31+
}
32+
33+
sub filter (@) {
34+
my %params=@_;
35+
my $content = $params{content};
36+
return $content unless $content =~ /\$[^\$]+\$|\\[\(\[][\s\S]+\\[\)\]]/;
37+
# first, handle display math...
38+
$content =~ s{(?<!\\)\\\[(.+?)(?<!\\)\\\]}{_escape_mathjax('d', $1)}ges; #};[}
39+
$content =~ s{(?<!\\)\$\$(.+?)(?<!\\)\$\$}{_escape_mathjax('d', $1)}ges; #};[}
40+
# then, the inline math -- note that it must stay on one line
41+
$content =~ s{(?<!\\)\\\((.+?)(?<!\\)\\\)}{_escape_mathjax('i', $1)}ge; #};[}
42+
# note that the 'parsing' of $..$ is extremely fragile
43+
$content =~ s{(?<!\\)\$(.+?)(?<!\\)\$}{_escape_mathjax('i', $1)}ge; #};[}
44+
return $content;
45+
}
46+
47+
sub _escape_mathjax {
48+
my ($mode, $formula) = @_;
49+
my %modes = qw/i inline d display/;
50+
my $directive = "!!mathjaxbegin-$mode!! ";
51+
$formula =~ s/"/&quot;/g;
52+
$formula =~ s/&/&amp;/g; #"/}[{
53+
$formula =~ s/</&lt;/g;
54+
$formula =~ s/>/&gt;/g; #{"
55+
$directive .= encode_base64($formula);
56+
$directive .= " !!mathjaxend-$mode!!";
57+
return $directive;
58+
}
59+
60+
sub _scripttag {
61+
my $config = 'TeX-AMS_HTML'; # another possibility: TeX-AMS-MML_HTMLorMML
62+
return '<script type="text/x-mathjax-config">'
63+
. 'MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });'
64+
. '</script>'
65+
. '<script type="text/javascript" '
66+
. 'src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config='
67+
. $config
68+
. '"></script>';
69+
}
70+
71+
sub _scriptblock {
72+
return qq%
73+
<script type="text/javascript">//<![CDATA[
74+
(function () {
75+
if (window.MathJax && MathJax.Hub) return;
76+
var script = document.createElement("script");
77+
script.type = "text/javascript";
78+
script.src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js";
79+
80+
var config = 'MathJax.Hub.Config({' +
81+
'extensions: ["tex2jax.js"],' +
82+
'jax: ["input/TeX","output/HTML-CSS"],' +
83+
'TeX: { equationNumbers: { autoNumber: "AMS" } }' +
84+
'});' +
85+
'MathJax.Hub.Startup.onload();';
86+
87+
if (window.opera) {script.innerHTML = config}
88+
else {script.text = config}
89+
90+
document.getElementsByTagName("head")[0].appendChild(script);
91+
})();
92+
//]]></script>
93+
%;
94+
}
95+
96+
1;

README.md

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,39 @@
1-
ikiwiki-plugin-mathjax
2-
======================
1+
IkiWiki::Plugin::mathjax
2+
========================
3+
4+
IkiWiki's default support for math is rather clumsy and old-fashioned. Also, it
5+
requires a working LaTeX installation.
6+
7+
A much better option is Pandoc, available to IkiWiki users through the
8+
IkiWiki::Plugin::pandoc plugin (which can be found in a few versions on
9+
GitHub). However, it has some drawbacks as well:
10+
11+
- If you are using shared hosting, Pandoc can be cumbersome to
12+
install.
13+
- If you don't need its markdown extensions, footnotes,
14+
extra source and target formats, bibliography support, etc., but just want to
15+
have some nicely formatted math on your wiki/blog, Pandoc seems like
16+
overkill.
17+
- Because an external process will be called for each page, a rebuild of a
18+
large wiki takes an uncomfortably long time.
19+
- It is difficult to get Pandoc with MathJax and the smiley plugin to work
20+
together, since the latter tends mangle the content which MathJax is supposed
21+
to work its magic on.
22+
- You need to change page.tmpl, which means that you have to check for
23+
compatibility with the new page.tmpl every time you upgrade IkiWiki.
24+
25+
This simple plugin solves these issues, making it easy to use MathJax in
26+
IkiWiki. Features:
27+
28+
- No changes to page.tmpl are needed -- the MathJax Javascript is only loaded
29+
on pages where it is needed.
30+
- Both display ($$...$$ or \\[...\\]) and inline ($...$ or \\(...\\)) math are
31+
supported. Just take care that **inline math must stay on one line** in your
32+
markdown source. A single literal dollar sign in a line does not need to be
33+
escaped, but two do.
34+
35+
If you want to change the MathJax configuration, you currently must edit the
36+
source of the module. I may later add configuration hooks so that one may
37+
control its behaviour through the setup file for the wiki. Let me know if you
38+
need this.
339

4-
MathJax plugin for IkiWiki

0 commit comments

Comments
 (0)