Blob
1 #!/usr/bin/env perl2 #3 # gem2html - opinionated converter text/gemini to html4 # public domain6 use v5.10;7 use strict;8 use warnings;10 use open ":std", ":encoding(UTF-8)";12 my $in_pre = 0;13 my $in_list = 0;15 while (<>) {16 chomp;17 if ($in_pre && m/^```/) {18 $in_pre = 0;19 say "</pre>";20 } elsif (!$in_pre && m/^```/) {21 if ($in_list) {22 $in_list = 0;23 say "</ul>";24 }25 $in_pre = 1;26 print "<pre>";27 } elsif ($in_pre) {28 say san($_);29 } elsif ($in_list && m/^$/) {30 say "</ul>";31 $in_list = 0;32 } elsif (m/^\*\s+(.*)/) { # NB: at least one space33 if (!$in_list) {34 $in_list = "item";35 say "<ul>";36 } elsif ($in_list eq "link") {37 $in_list = "item";38 say "</ul>";39 say "<ul>";40 }41 output("li", $1);42 } elsif (m/^=>\s*([^\s]*)\s*(.*)$/) {43 if (!$in_list) {44 $in_list = "link";45 say "<ul class='link-list'>";46 } elsif ($in_list eq "item") {47 $in_list = "link";48 say "</ul>";49 say "<ul class='link-list'>";50 }51 say "<li><a href='$1'>". san($2 || $1) ."</a></li>";52 } elsif (m/^###\s*(.*)$/) {53 output("h3", $1);54 } elsif (m/^##\s*(.*)$/) {55 output("h2", $1);56 } elsif (m/^#\s*(.*)$/) {57 output("h1", $1);58 } elsif (m/^>\s*(.*)$/) {59 output("blockquote", $1);60 } else {61 output("p", $_);62 }63 }65 sub san {66 $_ = shift;67 s/&/\&/g;68 s/</\</g;69 s/>/\>/g;70 return $_;71 }73 sub output {74 my ($tn, $content) = @_;76 if (!$in_list && $tn eq "li") {77 $in_list = 1;78 say "<ul>";79 }81 if ($in_list && $tn ne "li") {82 $in_list = 0;83 say "</ul>";84 }86 return if $tn eq "p" && $content eq "";88 say "<$tn>". san($content) ."</$tn>";89 }