]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/commitdiff
mdwn: Automatically detect which libdiscount flags to use
authorSimon McVittie <smcv@debian.org>
Thu, 8 Mar 2018 23:36:31 +0000 (23:36 +0000)
committerSimon McVittie <smcv@debian.org>
Thu, 8 Mar 2018 23:36:31 +0000 (23:36 +0000)
Unconditionally passing arbitrary numbers as flags turns out to be a
bad idea, because some of the "unused" values have historically had
side-effects internal to libdiscount. Detect whether the known flags
work by rendering short Markdown snippets the first time we htmlize,
checking whether each known flag is both necessary and sufficient.

Signed-off-by: Simon McVittie <smcv@debian.org>
IkiWiki/Plugin/mdwn.pm
doc/bugs/discount_stopped_rendering_markdown_links.mdwn
t/mdwn.t

index 66116ae014f7a94cd8bda230514258bbb75acf42..eefa29a9711204541c52b2c83fa959103fc05e67 100644 (file)
@@ -89,6 +89,55 @@ sub htmlize (@) {
                    (! exists $config{nodiscount} || ! $config{nodiscount})) {
                        eval q{use Text::Markdown::Discount};
                        if (! $@) {
+                               my $markdown = \&Text::Markdown::Discount::markdown;
+                               my $always_flags = 0;
+
+                               # Disable Pandoc-style % Title, % Author, % Date
+                               # Use the meta plugin instead
+                               $always_flags |= Text::Markdown::Discount::MKD_NOHEADER();
+
+                               # Disable Unicodification of quote marks, em dashes...
+                               # Use the typography plugin instead
+                               $always_flags |= Text::Markdown::Discount::MKD_NOPANTS();
+
+                               # Workaround for discount's eliding of <style> blocks.
+                               # https://rt.cpan.org/Ticket/Display.html?id=74016
+                               if (Text::Markdown::Discount->can('MKD_NOSTYLE')) {
+                                       $always_flags |= Text::Markdown::Discount::MKD_NOSTYLE();
+                               }
+                               elsif ($markdown->('<style>x</style>', 0) !~ '<style>' &&
+                                       $markdown->('<style>x</style>', 0x00400000) =~ m{<style>x</style>}) {
+                                       $always_flags |= 0x00400000;
+                               }
+
+                               # Enable fenced code blocks in libmarkdown >= 2.2.0
+                               # https://bugs.debian.org/888055
+                               if (Text::Markdown::Discount->can('MKD_FENCEDCODE')) {
+                                       $always_flags |= Text::Markdown::Discount::MKD_FENCEDCODE();
+                               }
+                               elsif ($markdown->("~~~\nx\n~~~", 0) !~ m{<pre\b} &&
+                                       $markdown->("~~~\nx\n~~~", 0x02000000) =~ m{<pre\b}) {
+                                       $always_flags |= 0x02000000;
+                               }
+
+                               # PHP Markdown Extra-style term\n: definition -> <dl>
+                               if (Text::Markdown::Discount->can('MKD_DLEXTRA')) {
+                                       $always_flags |= Text::Markdown::Discount::MKD_DLEXTRA();
+                               }
+                               elsif ($markdown->("term\n: def\n", 0) !~ m{<dl>} &&
+                                       $markdown->("term\n: def\n", 0x01000000) =~ m{<dl>}) {
+                                       $always_flags |= 0x01000000;
+                               }
+
+                               # Allow dashes and underscores in tag names
+                               if (Text::Markdown::Discount->can('MKD_GITHUBTAGS')) {
+                                       $always_flags |= Text::Markdown::Discount::MKD_GITHUBTAGS();
+                               }
+                               elsif ($markdown->('<foo_bar>', 0) !~ m{<foo_bar} &&
+                                       $markdown->('<foo_bar>', 0x08000000) =~ m{<foo_bar\b}) {
+                                       $always_flags |= 0x08000000;
+                               }
+
                                $markdown_sub=sub {
                                        my $t=shift;
 
@@ -96,15 +145,7 @@ sub htmlize (@) {
                                        # https://rt.cpan.org/Ticket/Display.html?id=73657
                                        return "" if $t=~/^\s*$/;
 
-                                       my $flags=0;
-
-                                       # Disable Pandoc-style % Title, % Author, % Date
-                                       # Use the meta plugin instead
-                                       $flags |= Text::Markdown::Discount::MKD_NOHEADER();
-
-                                       # Disable Unicodification of quote marks, em dashes...
-                                       # Use the typography plugin instead
-                                       $flags |= Text::Markdown::Discount::MKD_NOPANTS();
+                                       my $flags=$always_flags;
 
                                        if ($config{mdwn_footnotes}) {
                                                $flags |= Text::Markdown::Discount::MKD_EXTRA_FOOTNOTE();
@@ -114,42 +155,6 @@ sub htmlize (@) {
                                                $flags |= Text::Markdown::Discount::MKD_NOALPHALIST();
                                        }
 
-                                       # Workaround for discount's eliding
-                                       # of <style> blocks.
-                                       # https://rt.cpan.org/Ticket/Display.html?id=74016
-                                       if (Text::Markdown::Discount->can("MKD_NOSTYLE")) {
-                                               $flags |= Text::Markdown::Discount::MKD_NOSTYLE();
-                                       }
-                                       else {
-                                               # This is correct for the libmarkdown.so.2 ABI
-                                               $flags |= 0x00400000;
-                                       }
-
-                                       # Enable fenced code blocks in libmarkdown >= 2.2.0
-                                       # https://bugs.debian.org/888055
-                                       if (Text::Markdown::Discount->can("MKD_FENCEDCODE")) {
-                                               $flags |= Text::Markdown::Discount::MKD_FENCEDCODE();
-                                       }
-                                       else {
-                                               $flags |= 0x02000000;
-                                       }
-
-                                       # PHP Markdown Extra-style term\n: definition -> <dl>
-                                       if (Text::Markdown::Discount->can("MKD_DLEXTRA")) {
-                                               $flags |= Text::Markdown::Discount::MKD_DLEXTRA();
-                                       }
-                                       else {
-                                               $flags |= 0x01000000;
-                                       }
-
-                                       # Allow dashes and underscores in tag names
-                                       if (Text::Markdown::Discount->can("MKD_GITHUBTAGS")) {
-                                               $flags |= Text::Markdown::Discount::MKD_GITHUBTAGS();
-                                       }
-                                       else {
-                                               $flags |= 0x08000000;
-                                       }
-
                                        return Text::Markdown::Discount::markdown($t, $flags);
                                }
                        }
index 1d70c926ef25241d8c8b1787e9a9a0ae0b4dc5cc..cfe544b02437204e8b4a0a85f77fbc4222804326 100644 (file)
@@ -34,3 +34,8 @@ Some guesses:
 > Orthogonally, pkgsrc should probably use an up-to-date version of Discount, and
 > [we already know that Text::Markdown::Discount needs updating](https://rt.cpan.org/Public/Bug/Display.html?id=124188).
 > --[[smcv]]
+
+>> This should be [[fixed|done]] in current git. The mdwn module now
+>> detects what your version of Discount supports by trying several
+>> short HTML fragments that render differently under the different
+>> flags. --[[smcv]]
index 93b8bd8e9971a937aacedd2951219ca63c27abbf..ca3180139445f7659735e998f9c265b074db4da2 100755 (executable)
--- a/t/mdwn.t
+++ b/t/mdwn.t
@@ -8,6 +8,7 @@ BEGIN { use_ok("IkiWiki"); }
 
 %config=IkiWiki::defaultconfig();
 $config{srcdir}=$config{destdir}="/dev/null";
+$config{disable_plugins}=["htmlscrubber"];
 IkiWiki::loadplugins();
 IkiWiki::checkconfig();
 
@@ -41,4 +42,25 @@ like(IkiWiki::htmlize("foo", "foo", "mdwn",
        "This works[^1]\n\n[^1]: Sometimes it doesn't.\n"),
        qr{<p>This works<sup\W}, "footnotes can be enabled");
 
+SKIP: {
+       skip 'set $IKIWIKI_TEST_ASSUME_MODERN_DISCOUNT if you have Discount 2.2.0+', 4
+               unless $ENV{IKIWIKI_TEST_ASSUME_MODERN_DISCOUNT};
+       like(IkiWiki::htmlize("foo", "foo", "mdwn",
+                       "Definition list\n: A useful HTML structure\n"),
+               qr{<dl>.*<dt>Definition list</dt>\s*<dd>A useful HTML structure</dd>}s,
+               "definition lists are enabled by default");
+       like(IkiWiki::htmlize("foo", "foo", "mdwn",
+                       "```\n#!/bin/sh\n```\n"),
+               qr{<pre>\s*<code>\s*[#]!/bin/sh\s*</code>\s*</pre>}s,
+               "code blocks are enabled by default");
+       like(IkiWiki::htmlize("foo", "foo", "mdwn",
+                       "<foo_bar>"),
+               qr{<foo_bar>},
+               "GitHub tag name extensions are enabled by default");
+       like(IkiWiki::htmlize("foo", "foo", "mdwn",
+                       "<style>foo</style>"),
+               qr{<style>foo</style>},
+               "Styles are not stripped by default");
+}
+
 done_testing();