]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/HlMod.pm
Merge remote-tracking branch 'origin/danga-bundle'
[public-inbox.git] / lib / PublicInbox / HlMod.pm
index 284e4b1896d46db23fe73613849604448f9c49ec..36e311060dcf52bb41eed5f6a2cff38bbb2de006 100644 (file)
@@ -16,6 +16,8 @@ package PublicInbox::HlMod;
 use strict;
 use warnings;
 use highlight; # SWIG-generated stuff
+use PublicInbox::Hval qw(src_escape ascii_html);
+my $hl;
 
 sub _parse_filetypes ($) {
        my $ft_conf = $_[0]->searchFile('filetypes.conf') or
@@ -52,16 +54,20 @@ sub _parse_filetypes ($) {
        (\%ext2lang, \@shebang);
 }
 
+# We only need one instance, so we don't need to do
+# highlight::CodeGenerator::deleteInstance
 sub new {
        my ($class) = @_;
-       my $dir = highlight::DataDir->new;
-       $dir->initSearchDirectories('');
-       my ($ext2lang, $shebang) = _parse_filetypes($dir);
-       bless {
-               -dir => $dir,
-               -ext2lang => $ext2lang,
-               -shebang => $shebang,
-       }, $class;
+       $hl ||= do {
+               my $dir = highlight::DataDir->new;
+               $dir->initSearchDirectories('');
+               my ($ext2lang, $shebang) = _parse_filetypes($dir);
+               bless {
+                       -dir => $dir,
+                       -ext2lang => $ext2lang,
+                       -shebang => $shebang,
+               }, $class;
+       };
 }
 
 sub _shebang2lang ($$) {
@@ -117,19 +123,27 @@ sub do_hl_lang {
        # know that, so ensure it's marked as UTF-8 even if it isnt...
        my $out = $gen->generateString($$str);
        utf8::decode($out);
+       src_escape($out);
        \$out;
 }
 
-# SWIG instances aren't reference-counted, but $self is;
-# so we need to delete all the CodeGenerator instances manually
-# at our own destruction
-sub DESTROY {
-       my ($self) = @_;
-       foreach my $gen (values %$self) {
-               if (ref($gen) eq 'highlight::CodeGenerator') {
-                       highlight::CodeGenerator::deleteInstance($gen);
+# Highlight text, but support Markdown "```$LANG" notation
+# while preserving WYSIWYG of plain-text documentation.
+# This is NOT to be enabled by default or encouraged for parsing
+# emails, since it is NOT stable and can lead to standards
+# proliferation of email.
+sub do_hl_text {
+       my ($self, $str) = @_;
+
+       $$str = join('', map {
+               if (/\A(``` ?)(\w+)\s*?\n(.+)(^```\s*)\z/sm) {
+                       my ($pfx, $lang, $code, $post) = ($1, $2, $3, $4);
+                       my $hl = do_hl_lang($self, \$code, $lang) || \$code;
+                       $pfx . $lang . "\n" . $$hl . $post;
+               } else {
+                       ascii_html($_);
                }
-       }
+       } split(/(^``` ?\w+\s*?\n.+?^```\s*$)/sm, $$str));
 }
 
 1;