Blob


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