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 my $href = $1;
50 $_ = $2 || $1;
51 say "<li><a href='$href'>". san() ."</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 s/&/\&amp;/g;
67 s/</\&lt;/g;
68 s/>/\&gt;/g;
69 return $_;
70 }
72 sub output {
73 my ($tn, $content) = @_;
75 if (!$in_list && $tn eq "li") {
76 $in_list = 1;
77 say "<ul>";
78 }
80 if ($in_list && $tn ne "li") {
81 $in_list = 0;
82 say "</ul>";
83 }
85 if ($tn eq "p" && $content eq "") {
86 return;
87 }
89 $_ = $content;
90 say "<$tn>". san() ."</$tn>";
91 }