#!/usr/bin/env perl
use File::Find qw(find);use File::Basename qw(basename dirname);use File::Path qw(make_path);use File::Spec;
my($S,$O)=('_src','.');-d $S or die "no $S/\n";
sub r{local $/;open my$f,'<',$_[0];<$f>}
sub w{my($p,$c)=@_;my$d=dirname$p;make_path$d unless-d$d;open my$f,'>',$p;print $f $c}
my $Sg=" />";my $B=qr{(?>[^\[\]]+|\[(??{$B})\])*};my(%E,%R,$M,$N,$G,%U,%I,%H,$n,$L);$E{$_}="\cZ".ord($_)."\cZ"for split//,'\\`*_{}[]()>#+-.!';%R=(%E,qw(& &amp; < &lt; > &gt;));$M=qr/(?:[*+-]|\d+\.)/;$N=join('|',('(?:<[a-z/!\$](?:[^<>]')x6).(')*>)'x6);$G=qr/((?s:<!(?:--.*?--\s*)+>)|(?s:<\?.*?\?>)|$N)/i;
sub X{pop=~s/[*_]/$E{$&}/gr}
sub T{defined$_[0]?' title="'.X($_[0]=~s/"/&quot;/gr).'"':''}
sub A{'<a href="'.X($_[0]).'"'.T($_[1]).">$_[2]</a>"}
sub I{'<img src="'.X($_[0]).'" alt="'.($_[1]=~s/"/&quot;/gr).'"'.T($_[2]).$Sg}
sub K{$H{$k="\cY".++$n."\cY"}=pop;"\n\n$k\n\n"}
sub O{pop=~s/^ {1,4}//gmr}
sub C{pop=~s/[&<>*_{}\[\]\\]/$R{$&}/gr}
sub Y{pop=~s/\\(.)/$E{$1}\/\/"\\$1"/ger}
sub Z{pop=~s/&(?!#?\w+;)/&amp;/gr=~s{<(?![a-z/?\$!])}{&lt;}gir}
sub U{pop=~s/\cZ(\d+)\cZ/chr$1/ger}
sub V{my$i;join'',map{$i++%2?X($_):Y($_)}split$G,pop}
sub W{pop=~s{(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1}{<strong>$2</strong>}gsr=~s{([*_])(?=\S)(.+?)(?<=\S)\1}{<em>$2</em>}gsr}
sub P{pop=~s@(`+)(.+?)(?<!`)\1(?!`)@'<code>'.C($2=~s/^ *| *$//gr).'</code>'@gser}
sub D{pop=~s{(\[($B)\] ?(?:\n *)?\[(.*?)\])}{my$i=lc($3 eq''?$2:$3);defined$U{$i}?A($U{$i},$I{$i},$2):$1}gser=~s{\[($B)\]\( *<?(.*?)>? *((['"])(.*?)\4)?\)}{A($2,$5,$1)}gser}
sub Nt{pop=~s{(!\[(.*?)\] ?(?:\n *)?\[(.*?)\])}{my$i=lc($3 eq''?$2:$3);defined$U{$i}?I($U{$i},$2,$I{$i}):$1}gser=~s{!\[(.*?)\]\( *<?(\S+?)>? *((['"])(.*?)\4 *)?\)}{I($2,$1,$5//'')}gser}
sub H{K("<h$_[0]>".B($_[1])."</h$_[0]>")}
sub Q{my$t=pop;$t=~s{^(.+) *\n$_->[0]+ *\n+}{H($_->[1],$1)}gme for['=',1],['-',2];$t=~s{^(#{1,6}) *(.+?) *#*\n+}{H(length$1,$2)}gmer}
sub R{pop=~s{(?:\n\n|\A)((?: {4}.*\n+)+)((?=^ {0,4}\S)|\Z)}{K("\n\n<pre><code>".(C(O($1))=~s/\A\n+|\s+\z//gr)."\n</code></pre>\n\n")}gmer}
sub G{pop=~s{((^ *> ?.+\n(.+\n)*\n*)+)}{K("<blockquote>\n  ".(BG($1=~s/^ *> ?//gmr=~s/^ +$//gmr)=~s{(\s*<pre>.+?</pre>)}{$1=~s/^  //gmr}gser)."\n</blockquote>\n\n")}gmer}
sub L{my$t=pop;my$top=!$L;my$p=$L?'^':'(?:(?<=\n\n)|\A\n?)';$t=~s{$p(( {0,3}$M +)(?s:.+?)(?:\z|\n{2,}(?=\S)(?! *$M +)))}{my$s=$1;my$y=$2=~/[*+-]/?'ul':'ol';$s=~s/\n{2,}/\n\n\n/g;$s=~s/\n{2,}\z/\n/;$L++;$s=~s{(\n)?(^ *)$M +((?s:.+?)\n\n?)(?=\n*(?:\z|\2$M +))}{my$i=$3;'<li>'.($1||$i=~/\n\n/?BG(O($i)):B(L(O($i))=~s/\n\z//r))."</li>\n"}gme;$L--;my$r="<$y>\n$s</$y>\n";$top?K($r):$r}gmer}
sub Mr{my$t=pop;while($t=~s{^ {0,3}\[(.+)\]: *\n? *<?(\S+?)>? *\n? *(?:(?<=\s)["(](.+?)[")] *)?(?:\n+|\Z)}{}m){$U{lc$1}=Z($2);$I{lc$1}=$3 if$3}$t}
sub E{join"\n\n",map{$H{$_}//B($_)=~s/^ */<p>/r.'</p>'}split/\n{2,}/,pop=~s/\A\n+|\n+\z//gr}
sub B{W(Z(D(Nt(V(P(pop))))))=~s/ {2,}\n/ <br$Sg\n/gr}
sub BG{E(G(R(L(Q(pop=~s/^ {0,3}([*_-])(?: {0,2}\1){2,} *$/K("\n<hr$Sg\n")/gmre)))))}
sub MD{%U=%I=%H=();$n=0;my$t=pop=~s/\r\n?/\n/gr."\n\n";$t=~s{(.*?)\t}{$1.' 'x(4-length($1)%4)}ge;U(BG(Mr($t=~s/^ +$//gmr)))."\n"}
my $TPL=r('_layout/template.html');
sub pg{my($t,$b,$p,$c)=@_;local$_=$TPL;s/%title%/$t/g;s/%body%/$b/g;s/%prefix%/$p/g;s/%crumbs%/$c/g;$_}
sub cb{my@d=grep{$_ ne'.'}split'/',pop;join"\n",map{"<a href=\"./".('../'x($#d-$_))."\">$d[$_]/</a>"}0..$#d}
my(@f,@a);find(sub{return if-d;/\.md$/i?push@f,$File::Find::name:push@a,$File::Find::name unless/^[.#]|~$/},$S);$_=File::Spec->abs2rel($_,$S) for @f,@a;
for my$a(@a){my$d=dirname"$O/$a";make_path$d unless-d$d;my$rel=File::Spec->abs2rel("$S/$a",$d);unlink"$O/$a";-l"$O/$a"||symlink$rel,"$O/$a"or warn"link $a: $!"}
for my$f(@f){my$h=MD(r("$S/$f"));(my$u=$f)=~s/\.md$/.html/i;my$dp=dirname$f;my$p=$dp eq'.'?'':'../'x scalar split'/',$dp;my$t=basename$f;$t=~s/\.md$//i;$t=~s/[-_]+/ /g;$t=$1 if$h=~m{<h1[^>]*>(.*?)</h1>}is;$t=~s/<[^>]+>//g;w("$O/$u",pg($t,$h,$p,cb($dp)))}
