diff --git a/build.pl b/build.pl index b264e02..bd8a4b6 100755 --- a/build.pl +++ b/build.pl @@ -9,7 +9,7 @@ use File::Slurp; use POSIX qw(strftime); use Text::FrontMatter::YAML; use Text::Template; -use Text::MultiMarkdown 'markdown'; +use Markdent::Simple::Fragment; use strict; use utf8; @@ -31,6 +31,69 @@ my $post_tmpl = Text::Template->new(SOURCE => "$tmpl_dir/post.html.tmpl"); my $assets_path = $cwd . ASSETS_PATH; my $out_path = $cwd . OUT_PATH; my $postout_path = $out_path . POSTS_PATH; +my $return_link = qq{}; + +# used across a couple functions +my $parser = Markdent::Simple::Fragment->new; + +sub make_fragment { + my $body = shift; + $parser->markdown_to_html( + dialect => 'GitHub', + markdown => $body, + ); +} + +sub strip_id { + my $id = shift; + $id =~ s/[ \t]/-/g; + $id =~ s/[^A-Za-z0-9_-]//g; + return $id; +} + +sub do_footnotes { + my $text = shift; + + my %footnotes; + my @used; + + my $footnote_counter = 0; + + # First grab the definitions + while ($text =~ s{ + \n\[\^([^\n]+?)\]\:[ \t]* + \n? + (.*?)(?:\n{1,2} # end at new paragraph + (?=\n[ ]{0,4}\S)|\Z) # Lookahead for non-space at line-start, or end of doc + }{\n}sx) { + my $id = strip_id($1); + $footnotes{$1} = make_fragment(qq{$2 [$return_link](#fnref:$id)}); + } + + # then replace the inline footnotes + $text =~ s{ + \[\^(.*?)\] + }{ + my $result = ''; + my $id = strip_id($1); + if (defined $footnotes{$id}) { + $footnote_counter++; + $result = qq{[$footnote_counter]}; + push(@used, $id); + } + $result; + }xsge; + + my $fn_block = qq{

    }; + # finally, append the footnotes + foreach my $id (@used) { + my $footnote = $footnotes{$id}; + $fn_block .= qq{
  1. $footnote
  2. }; + } + $fn_block .= qq{
}; + + return ($text, $fn_block); +} # Converts a post file to a metadata hash. # @@ -49,19 +112,65 @@ sub post_to_meta { my $metadata = $mdfm->frontmatter_hashref; - if (chomp($mdfm->body_text) ne "") { - my $parser = Text::MultiMarkdown->new( - disable_bibliography => 1, - use_metadata => 0, - document_format => 'fragment' - ); + chomp(my $body = $mdfm->data_text); + if ($body ne "") { # for very funny bits, i assure you - $mdfm->body_text =~ s{\$cn\$}{ - "[citation needed]" + $body =~ s{\[\^citation\sneeded\]}{ + "[citation needed]" }egm; - $metadata->{content} = $parser->markdown( $mdfm->body_text ); + my $tag_attrs = qr{ + (?: # Match one attr name/value pair + \s+ # There needs to be at least some whitespace + # before each attribute name. + [\w.:_-]+ # Attribute name + \s*=\s* + (?: + ".+?" # "Attribute value" + | + '.+?' # 'Attribute value' + | + [^\s]+? # AttributeValue (HTML5) + ) + )* # Zero or more + }x; + my $markdown_attr = qr{ \s* markdown \s* = \s* (['"]) (.*?) \1 }xs; + my $empty_tag = qr{< \w+ $tag_attrs \s* />}oxms; + + use Text::Balanced qw(gen_extract_tagged); + my $extract_block = gen_extract_tagged(qr{< div $tag_attrs \s* >}oxms, + undef, + undef, + { ignore => [$empty_tag] }); + + $body =~ s{ + ( + + ) + }{ + my $return = $1; + my ($tag, $remainder, $prefix, $opening_tag, $text_in_tag, $closing_tag) = $extract_block->($return); + if ($tag) { + if ($opening_tag =~ s/$markdown_attr//i) { + my $markdown = $2; + if ($markdown =~ /^(1|on|yes)$/) { + $tag = $prefix . $opening_tag . "\n" + . make_fragment($text_in_tag) . "\n" . $closing_tag; + } else { + $tag = $prefix . $opening_tag . $text_in_tag . $closing_tag; + } + $return = $tag; + } + } + $return; + }egmxs; + + my $fn_body; + ($body, $fn_body) = do_footnotes($body); + $fn_body = "" unless defined $fn_body; + + $metadata->{content} = make_fragment($body) . $fn_body; } # HACK: Stuffing the basename in the metadata because I don't want diff --git a/ptouch.pl b/ptouch.pl index 0330b38..a113753 100755 --- a/ptouch.pl +++ b/ptouch.pl @@ -3,9 +3,10 @@ use strict; use utf8; use Getopt::Std; -use Tie::File; +use File::Slurp; +use Text::FrontMatter::YAML; -$::VERSION = "1.0.0"; +$::VERSION = "2.0.0"; getopts("ne", \my %opts); @@ -23,24 +24,20 @@ if (defined $opts{n}) { my $timestamp = time; my $fname = shift @ARGV; -tie my @fharr, 'Tie::File', $fname or die $!; -my $done = 0; -for (@fharr) { - if (s/^$metavar=.+/$metavar=$timestamp/) { - print "$fname:$.: Overwriting existing \`$metavar\'\n"; - $done++; - } - if (s/^(--.+?--)$/$metavar=$timestamp\n$1/) { - print "$fname:$.: Inserting new \`$metavar\'\n"; - $done++; - } - last if ($done); -} +my $fdata = read_file($fname); +my $mdfm = Text::FrontMatter::YAML->new( + document_string => $fdata +); -if (!$done) { - print "$fname: No content and no \`$metavar\', inserting at end\n"; - push @fharr, "$metavar=$timestamp"; -} +my $metadata = $mdfm->frontmatter_hashref; +$metadata->{$metavar} = $timestamp; -untie @fharr; +my $wrfm = Text::FrontMatter::YAML->new( + frontmatter_hashref => $metadata, + data_text => $mdfm->data_text +); + +write_file($fname, $wrfm->document_string); + +1;