A book about the command line for humans.

render.pl 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use 5.10.0;
  5. use Cwd;
  6. use File::Basename;
  7. use Text::Markdown::Discount;
  8. # Enable html5 block-level tags:
  9. Text::Markdown::Discount::with_html5_tags();
  10. my $flags = Text::Markdown::Discount::MKD_EXTRA_FOOTNOTE();
  11. my $markdown = Text::Markdown::Discount->new;
  12. my $cwd = Cwd::getcwd();
  13. my $full_source = '';
  14. while (my $source = get_input()) {
  15. # A simple preprocessor:
  16. my ($basename, $dir) = fileparse($ARGV); # get path of target file
  17. chdir $dir;
  18. # XXX: temporarily disabled until code examples are updated:
  19. # $source =~ s{<!-- exec -->(.*?)<!-- end -->}{handle_block($1);}egs;
  20. chdir $cwd;
  21. $full_source .= "\n\n----\n\n" . $source;
  22. }
  23. print replace_some_stuff($markdown->markdown($full_source, $flags));
  24. sub get_input {
  25. local $/ = undef;
  26. my $source = <>;
  27. return $source;
  28. }
  29. sub handle_block {
  30. my ($block) = @_;
  31. my $cmd;
  32. if ($block =~ m/\$ (.*?)$/m) {
  33. $cmd = $1;
  34. } else {
  35. die "bogus cmd";
  36. }
  37. my $result = `$cmd`;
  38. # indent 4 spaces so we get a code block:
  39. $result =~ s/^/ /gm;
  40. return "<!-- exec -->\n\n \$ " . $cmd . "\n" . $result . "\n<!-- end -->";
  41. }
  42. # super cheeseball, man
  43. sub replace_some_stuff {
  44. my ($markup) = @_;
  45. # bold first "$ command" string in a code block
  46. # $markup =~ s{<code>(\$ .*?)$}{<code><b>$1</b>}gm;
  47. my @contents;
  48. # insert anchors in headers, accumulate a table of contents
  49. $markup =~ s{<(h[12])(.*?)>(.*?)</h[12]>}{
  50. my ($tag, $attributes, $text) = ($1, $2, $3);
  51. my $a_name = $text;
  52. $a_name =~ s/[^a-z]+/-/ig;
  53. $a_name =~ s/^-|-$//g;
  54. push @contents, make_contents_link($tag, $a_name, $text);
  55. "<$tag$attributes><a name=$a_name href=#$a_name>#</a> $text</$tag>";
  56. }iesg;
  57. my $contents_text = '<div class=contents>'
  58. . $markdown->markdown((join "\n", @contents), $flags)
  59. . '</div>';
  60. $markup =~ s/\{\{contents\}\}/$contents_text/g;
  61. return $markup;
  62. }
  63. # make an individual element of a markdown list
  64. sub make_contents_link {
  65. my ($tag, $a_name, $text) = @_;
  66. if ($tag eq 'h2') {
  67. return " * [$text](#$a_name)";
  68. } elsif ($tag eq 'h1') {
  69. return "* [$text](#$a_name)";
  70. }
  71. }