#! /usr/bin/env perl use strict; use warnings; use Text::Markdown qw(markdown); use FindBin qw($Bin); my $title = "no title"; my $body = "no body"; # 解析 GET 参数 my $query = $ENV{QUERY_STRING}; my %query = map {$1 => $2 if /(\w+)=(\S+)/} split('&', $query); my $mdpath = $query{p}; response() unless $mdpath; $mdpath = "$Bin/$mdpath.md"; response() unless -r $mdpath; my $mdfile = prefile($mdpath); my $text = join("", @{$mdfile->{content}}); # my $text = join("\n", @{$mdfile->{content}}); #
will add anthor empty line $title = $mdfile->{title} if $mdfile->{title}; $body = markdown($text, {tab_width => 2}); fixlink(); # postbody(); response(); # read markdown file, save some information with hash # Text::Markdown fail to handle code block such as # ```perl # any code snippet # ``` sub prefile { my ($filename) = @_; my $filemark = {content => [], title => '', tags => [], }; my $codeblok = 0; open(my $fh, '<', $filename) or die "cannot open $filename $!"; # local $/ = undef; $text = <$fh>; while (<$fh>) { # chomp; # title line if ($. == 1) { push(@{$filemark->{content}}, $_); (my $title = $_ ) =~ s/^[#\s]+//; $filemark->{title} = $title; next; } # tag line elsif ($. == 2){ my @tags = /`([^`]+)`/g; if (@tags) { push(@{$filemark->{tags}}, @tags); next; } } # begin/end code block ```perl if (/^\s*```(\S*)\s*$/) { my $line = $_; if (!$codeblok) { $line = qq{\n}; $codeblok = 0; } push(@{$filemark->{content}}, $line); } else { push(@{$filemark->{content}}, $_); } } close($fh); return $filemark; } # 回应输出 sub response { print "Content-type:text/html\n\n"; print <}; $codeblok = 1; } else { $line = qq{
$title $body EndOfHTML } sub debug_query { $body = ""; while (my ($key, $value) = each %query) { $body .= "$key => $value
"; } } sub postbody { $body .= qq{
\n}; for my $tag (@{$mdfile->{tags}}) { $body .= qq{$tag
}; } } # fix links from/to home content and prev/next pages sub fixlink { my $base = $ENV{SCRIPT_NAME}; my $subname = $query{p}; if ($subname =~ /^content$/) { $body =~ s/href="(.+)\.md"/href="$base?p=$1"/g; } else { my ($prev, $next) = findprenext($subname); my @foot = (); push(@foot, "
"); $prev ? push(@foot, qq{Prev}) : push(@foot, qq{First}); push(@foot, qq{| Home |}); $next ? push(@foot, qq{Next}) : push(@foot, qq{Last}); $body .= sprintf(qq{\n%s \n\n}, join("\n", @foot)); } } # read content.md, find the prev/next page sub findprenext { my $curname = shift; my ($prev, $next) = ('', ''); my $tocname = "$Bin/content.md"; return ($prev, $next) unless -f $tocname; open(my $fh, '<', $tocname) or die "cannot open $tocname $!"; my ($prev_may, $cur_may); while (<$fh>) { chomp; next unless /\((\S+)\.md\)/; $prev_may = $cur_may; $cur_may = $1; if ($cur_may eq $curname) { $prev = $prev_may; next; } if ($prev_may eq $curname) { $next = $cur_may; last; } } close($fh); return ($prev, $next); }