diff options
author | John Ankarström <john@ankarstrom.se> | 2020-11-30 22:26:50 +0100 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2020-11-30 22:26:50 +0100 |
commit | b44b23f79590d2bd9874985a253f247f33d03b20 (patch) | |
tree | 57badf8cad022153dabe4ad87b31442c3066c770 /mh | |
download | mht-b44b23f79590d2bd9874985a253f247f33d03b20.tar.gz |
Add 'mh' script
mh is a simple Perl script that translates troff-like source text
into HTML.
Diffstat (limited to 'mh')
-rwxr-xr-x | mh | 119 |
1 files changed, 119 insertions, 0 deletions
@@ -0,0 +1,119 @@ +#!/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 => '<p>%</p>', + Qp_0 => '<blockquote><p>%</p></blockquote>', + Pr_0 => '<pre>%</pre>', + Sh_0 => '<h3>%</h3>', + Sh_1 => '<h\\$1>%</h\\$1>', + Ti_0 => '<title>%</title>', +); + +# 1.2.2 Inline elements +my %inels = ( + Au_1 => '<meta name="author" content="\\$1"/>', + Bd_0 => '\\$3<b>\\$1</b>\\$2', + br_0 => '<br/>', + Cd_0 => '\\$3<code>\\$1</code>\\$2', + Cs_1 => '<meta http-equiv="Content-Type" content="text/html; charset=\\$1"/>', + Em_0 => '\\$3<em>\\$1</em>\\$2', + Hy_0 => '<a href="\\$2">\\$1</a>', + Im_0 => '<img src="\\$1" alt="\\$2"/>', + It_0 => '\\$3<i>\\$1</i>\\$2', + St_0 => '\\$3<strong>\\$1</strong>\\$2', + Tt_0 => '\\$3<tt>\\$1</tt>\\$2', + Ul_0 => '\\$3<u>\\$1</u>\\$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 = ''; +} |