]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - IkiWiki/Plugin/mdwn.pm
66116ae014f7a94cd8bda230514258bbb75acf42
[git.ikiwiki.info.git] / IkiWiki / Plugin / mdwn.pm
1 #!/usr/bin/perl
2 # Markdown markup language
3 package IkiWiki::Plugin::mdwn;
5 use warnings;
6 use strict;
7 use IkiWiki 3.00;
9 sub import {
10         hook(type => "checkconfig", id => "mdwn", call => \&checkconfig);
11         hook(type => "getsetup", id => "mdwn", call => \&getsetup);
12         hook(type => "htmlize", id => "mdwn", call => \&htmlize, longname => "Markdown");
13         hook(type => "htmlize", id => "md", call => \&htmlize, longname => "Markdown (popular file extension)", nocreate => 1);
14 }
16 sub getsetup () {
17         return
18                 plugin => {
19                         safe => 1,
20                         rebuild => 1, # format plugin
21                         section => "format",
22                 },
23                 multimarkdown => {
24                         type => "boolean",
25                         example => 0,
26                         description => "enable multimarkdown features?",
27                         safe => 1,
28                         rebuild => 1,
29                 },
30                 nodiscount => {
31                         type => "boolean",
32                         example => 0,
33                         description => "disable use of markdown discount?",
34                         safe => 1,
35                         rebuild => 1,
36                 },
37                 mdwn_footnotes => {
38                         type => "boolean",
39                         example => 1,
40                         description => "enable footnotes in Markdown (where supported)?",
41                         safe => 1,
42                         rebuild => 1,
43                 },
44                 mdwn_alpha_lists => {
45                         type => "boolean",
46                         example => 0,
47                         description => "interpret line like 'A. First item' as ordered list when using Discount?",
48                         advanced => 1,
49                         safe => 1,
50                         rebuild => 1,
51                 },
52 }
54 sub checkconfig () {
55         $config{mdwn_footnotes} = 1 unless defined $config{mdwn_footnotes};
56         $config{mdwn_alpha_lists} = 0 unless defined $config{mdwn_alpha_lists};
57 }
59 my $markdown_sub;
60 sub htmlize (@) {
61         my %params=@_;
62         my $content = $params{content};
64         if (! defined $markdown_sub) {
65                 # Markdown is forked and splintered upstream and can be
66                 # available in a variety of forms. Support them all.
67                 no warnings 'once';
68                 $blosxom::version="is a proper perl module too much to ask?";
69                 use warnings 'all';
71                 if (exists $config{multimarkdown} && $config{multimarkdown}) {
72                         eval q{use Text::MultiMarkdown};
73                         if ($@) {
74                                 debug(gettext("multimarkdown is enabled, but Text::MultiMarkdown is not installed"));
75                         }
76                         else {
77                                 $markdown_sub=sub {
78                                         my %flags=( use_metadata => 0 );
80                                         if ($config{mdwn_footnotes}) {
81                                                 $flags{disable_footnotes}=1;
82                                         }
84                                         Text::MultiMarkdown::markdown(shift, \%flags);
85                                 }
86                         }
87                 }
88                 if (! defined $markdown_sub &&
89                     (! exists $config{nodiscount} || ! $config{nodiscount})) {
90                         eval q{use Text::Markdown::Discount};
91                         if (! $@) {
92                                 $markdown_sub=sub {
93                                         my $t=shift;
95                                         # Workaround for discount binding bug
96                                         # https://rt.cpan.org/Ticket/Display.html?id=73657
97                                         return "" if $t=~/^\s*$/;
99                                         my $flags=0;
101                                         # Disable Pandoc-style % Title, % Author, % Date
102                                         # Use the meta plugin instead
103                                         $flags |= Text::Markdown::Discount::MKD_NOHEADER();
105                                         # Disable Unicodification of quote marks, em dashes...
106                                         # Use the typography plugin instead
107                                         $flags |= Text::Markdown::Discount::MKD_NOPANTS();
109                                         if ($config{mdwn_footnotes}) {
110                                                 $flags |= Text::Markdown::Discount::MKD_EXTRA_FOOTNOTE();
111                                         }
113                                         unless ($config{mdwn_alpha_lists}) {
114                                                 $flags |= Text::Markdown::Discount::MKD_NOALPHALIST();
115                                         }
117                                         # Workaround for discount's eliding
118                                         # of <style> blocks.
119                                         # https://rt.cpan.org/Ticket/Display.html?id=74016
120                                         if (Text::Markdown::Discount->can("MKD_NOSTYLE")) {
121                                                 $flags |= Text::Markdown::Discount::MKD_NOSTYLE();
122                                         }
123                                         else {
124                                                 # This is correct for the libmarkdown.so.2 ABI
125                                                 $flags |= 0x00400000;
126                                         }
128                                         # Enable fenced code blocks in libmarkdown >= 2.2.0
129                                         # https://bugs.debian.org/888055
130                                         if (Text::Markdown::Discount->can("MKD_FENCEDCODE")) {
131                                                 $flags |= Text::Markdown::Discount::MKD_FENCEDCODE();
132                                         }
133                                         else {
134                                                 $flags |= 0x02000000;
135                                         }
137                                         # PHP Markdown Extra-style term\n: definition -> <dl>
138                                         if (Text::Markdown::Discount->can("MKD_DLEXTRA")) {
139                                                 $flags |= Text::Markdown::Discount::MKD_DLEXTRA();
140                                         }
141                                         else {
142                                                 $flags |= 0x01000000;
143                                         }
145                                         # Allow dashes and underscores in tag names
146                                         if (Text::Markdown::Discount->can("MKD_GITHUBTAGS")) {
147                                                 $flags |= Text::Markdown::Discount::MKD_GITHUBTAGS();
148                                         }
149                                         else {
150                                                 $flags |= 0x08000000;
151                                         }
153                                         return Text::Markdown::Discount::markdown($t, $flags);
154                                 }
155                         }
156                 }
157                 if (! defined $markdown_sub) {
158                         eval q{use Text::Markdown};
159                         if (! $@) {
160                                 if (Text::Markdown->can('markdown')) {
161                                         $markdown_sub=\&Text::Markdown::markdown;
162                                 }
163                                 else {
164                                         $markdown_sub=\&Text::Markdown::Markdown;
165                                 }
166                         }
167                         else {
168                                 eval q{use Markdown};
169                                 if (! $@) {
170                                         $markdown_sub=\&Markdown::Markdown;
171                                 }
172                                 else {
173                                         my $error = $@;
174                                         do "/usr/bin/markdown" ||
175                                                 error(sprintf(gettext("failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"), $error, $!));
176                                         $markdown_sub=\&Markdown::Markdown;
177                                 }
178                         }
179                 }
180                 
181                 require Encode;
182         }
183         
184         # Workaround for perl bug (#376329)
185         $content=Encode::encode_utf8($content);
186         eval {$content=&$markdown_sub($content)};
187         if ($@) {
188                 eval {$content=&$markdown_sub($content)};
189                 print STDERR $@ if $@;
190         }
191         $content=Encode::decode_utf8($content);
193         return $content;