A book about the command line for humans.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.1 KiB

10 years ago
  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. $source =~ s{<!-- exec -->(.*?)<!-- end -->}{handle_block($1);}egs;
  19. chdir $cwd;
  20. $full_source .= "\n\n----\n\n" . $source;
  21. }
  22. print replace_some_stuff($markdown->markdown($full_source, $flags));
  23. sub get_input {
  24. local $/ = undef;
  25. my $source = <>;
  26. return $source;
  27. }
  28. sub handle_block {
  29. my ($block) = @_;
  30. my $cmd;
  31. if ($block =~ m/\$ (.*?)$/m) {
  32. $cmd = $1;
  33. } else {
  34. die "bogus cmd";
  35. }
  36. my $result = `$cmd`;
  37. # indent 4 spaces so we get a code block:
  38. $result =~ s/^/ /gm;
  39. return "<!-- exec -->\n\n \$ " . $cmd . "\n" . $result . "\n<!-- end -->";
  40. }
  41. # super cheeseball, man
  42. sub replace_some_stuff {
  43. my ($markup) = @_;
  44. # bold first "$ command" string in a code block
  45. # $markup =~ s{<code>(\$ .*?)$}{<code><b>$1</b>}gm;
  46. my @contents;
  47. # insert anchors in headers, accumulate a table of contents
  48. $markup =~ s{<(h[12])(.*?)>(.*?)</h[12]>}{
  49. my ($tag, $attributes, $text) = ($1, $2, $3);
  50. my $a_name = $text;
  51. $a_name =~ s/[^a-z]+/-/ig;
  52. $a_name =~ s/^-|-$//g;
  53. push @contents, make_contents_link($tag, $a_name, $text);
  54. "<$tag$attributes><a name=$a_name href=#$a_name>#</a> $text</$tag>";
  55. }iesg;
  56. my $contents_text = '<div class=contents>'
  57. . $markdown->markdown((join "\n", @contents), $flags)
  58. . '</div>';
  59. $markup =~ s/{{contents}}/$contents_text/g;
  60. return $markup;
  61. }
  62. # make an individual element of a markdown list
  63. sub make_contents_link {
  64. my ($tag, $a_name, $text) = @_;
  65. if ($tag eq 'h2') {
  66. return " * [$text](#$a_name)";
  67. } elsif ($tag eq 'h1') {
  68. return "* [$text](#$a_name)";
  69. }
  70. }