|
|
- #!/usr/bin/env perl
-
- use strict;
- use warnings;
- use 5.10.0;
- use feature "state";
-
- use Cwd;
- use File::Basename;
- use HTML::Entities;
- use Text::Markdown::Discount;
-
- # Enable html5 block-level tags:
- Text::Markdown::Discount::with_html5_tags();
- my $flags = Text::Markdown::Discount::MKD_EXTRA_FOOTNOTE() | Text::Markdown::Discount::MKD_AUTOLINK();
- my $markdown = Text::Markdown::Discount->new;
-
- my $cwd = Cwd::getcwd();
-
- my $full_source = '';
- my $context = slurp("$cwd/context.md");
- while (my $source = get_input()) {
-
- # A simple preprocessor:
- my ($basename, $dir) = fileparse($ARGV); # get path of target file
- chdir $dir;
- $source =~ s{<!-- exec -->(.*?)<!-- end -->}{handle_block($1);}egs;
- chdir $cwd;
-
- # $context here is for stuff like links that should be available to any
- # markdown file that gets interpreted
- $full_source .= "\n\n<article>\n\n"
- . $markdown->markdown($context . $source, $flags)
- . "\n\n</article>\n\n";
-
- }
-
- print replace_some_stuff($full_source);
-
- sub get_input {
- local $/ = undef;
- my $source = <>;
- return $source;
- }
-
- sub handle_block {
- my ($block) = @_;
-
- my $cmd;
-
- if ($block =~ m/\$ (.*?)$/m) {
- $cmd = $1;
- } else {
- die "bogus cmd";
- }
-
- my $result = `$cmd`;
-
- # indent 4 spaces so we get a code block:
- $result =~ s/^/ /gm;
-
- return "<!-- exec -->\n\n \$ " . $cmd . "\n" . $result . "\n<!-- end -->";
- }
-
- # super cheeseball, man
- sub replace_some_stuff {
- my ($markup) = @_;
-
- my @contents;
- my $a_name_prefix_for_h2;
-
- # insert anchors in headers, accumulate a table of contents
- $markup =~ s{<(h[12])(.*?)>(.*?)</h[12]>}{
- my ($tag, $attributes, $text) = ($1, $2, $3);
-
- my $a_name = $text;
- $a_name =~ s/[^a-z0-9]+/-/ig;
- $a_name =~ s/^-|-$//g;
-
- if ($tag eq 'h1') {
- $a_name_prefix_for_h2 = $a_name;
- } else {
- $a_name = $a_name_prefix_for_h2 . '-' . $a_name;
- }
-
- push @contents, make_contents_link($tag, $a_name, $text);
- "<$tag$attributes><a name=$a_name href=#$a_name>#</a> $text</$tag>";
- }iesg;
-
- my $contents_text = '<div class=contents>'
- . $markdown->markdown((join "\n", @contents), $flags)
- . '</div>';
- $markup =~ s/{{contents}}/$contents_text/g;
-
- return $markup;
- }
-
- # make an individual element of a markdown list
- sub make_contents_link {
- my ($tag, $a_name, $text) = @_;
- if ($tag eq 'h2') {
- # indented bullet
- return " * [$text](#$a_name)";
- } elsif ($tag eq 'h1') {
- # top-level ordered-list item
- return "1. [$text](#$a_name)";
- }
- }
-
- # Get contents of a file as a string, because a File::Slurp dependency seemed
- # like overkill:
- sub slurp {
- my ($file) = @_;
- my $everything;
-
- open my $fh, '<', $file
- or die "Couldn't open $file: $!\n";
-
- # line separator:
- local $/ = undef;
- $everything = <$fh>;
-
- close $fh
- or die "Couldn't close $file: $!";
-
- return $everything;
- }
|