#!/usr/bin/perl use v5.12; use warnings; use Text::ParseWords qw/quotewords/; # 1 Definitions # 1.1 Global program state my $empty = ''; # currently buffered empty lines my $opel = ''; # currently opened element # 1.2 Elements # 1.2.1 Block elements my %blels = ( Pp_0 => '

%

', Qp_0 => '

%

', Pr_0 => '
%
', Sh_0 => '

%

', Sh_1 => '%', Ti_0 => '%', ); # 1.2.2 Inline elements my %inels = ( Au_1 => '', Bd_0 => '\\$3\\$1\\$2', br_0 => '
', Cd_0 => '\\$3\\$1\\$2', Cs_1 => '', Em_0 => '\\$3\\$1\\$2', Hy_0 => '\\$1', Im_0 => '\\$2', It_0 => '\\$3\\$1\\$2', St_0 => '\\$3\\$1\\$2', Tt_0 => '\\$3\\$1\\$2', Ul_0 => '\\$3\\$1\\$2', ); # 1.3 Subroutines # 1.3.1 Handle element request sub request { my ($el, $args) = @_; my @argv = quotewords('\s+', 0, $args); my $n = @argv; my $elkey = "${el}_$n"; if (exists $blels{$elkey}) { # Clear empty line buffer $empty = ''; # Close currently open block element, open new if (exists $blels{$opel}) { print end($blels{$opel}) . "\n"; $opel = ''; } $opel = $elkey; print interpol(start($blels{$elkey}), @argv) . "\n"; } elsif (exists $inels{$elkey}) { print interpol($inels{$elkey}, @argv) . "\n"; } else { print STDERR "Error: $el/$n not implemented\n"; exit 1; } } # 1.3.2 Interpolate \$n parameters sub interpol { my $s = shift; my $i = 1; my $arg; while ($arg = shift) { $s =~ s/\\\$$i/$arg/g; $i++; } return $s; } # 1.3.3 Retrieve first portion of block element string sub start { return (split '%', shift)[0]; } # 1.3.4 Retrieve second portion of block element string sub end { return (split '%', shift)[1]; } # 2 Program # 2.1 Translate mh source text to HTML while (<>) { chomp; if (/^\.([A-Za-z][a-z])\s*(.*)/) { request($1, $2); } elsif ($_ eq '') { $empty .= "\n"; } else { print $empty; $empty = ''; print "$_\n"; } } # 2.2 Close currently open block element if (exists $blels{$opel}) { print end($blels{$opel}) . "\n"; $opel = ''; }