Skip to content

Instantly share code, notes, and snippets.

@tzuntar
Created January 1, 2022 15:34
Show Gist options
  • Save tzuntar/15c327126271cb9cc7831c580af357c0 to your computer and use it in GitHub Desktop.
Save tzuntar/15c327126271cb9cc7831c580af357c0 to your computer and use it in GitHub Desktop.
Simple gophermap to HTML converter
#!/usr/bin/env perl
# Gopher2Html - Gophermap parser
# v1.0 (c) 2021 by Tobija Žuntar
use warnings;
use strict;
use feature qw(switch);
no warnings qw(experimental::smartmatch);
sub parse_line {
my ($line) = @_;
my $start = substr($line, 0, 1);
my $finalstr = " <p>";
given($start) {
when('0') { # Type 0 - Text Document
my $content = substr($line, 1);
my @spl = split(/\t/, $content);
if (@spl > 1) {
chomp($spl[1]);
$finalstr .= "<a href=\"$spl[1]\">[FILE] <strong>$spl[0]</strong></a>";
} else { $finalstr .= $line; } # it's not a tag
break;
} when('1') { # Type 1 - Another Gophermap
my $content = substr($line, 1);
my @spl = split(/\t/, $content);
if (@spl == 2) { # Local gophermap
my $f = $spl[1];
chomp($f);
if (substr($f, 0, 1) eq '/') {
$f = substr($spl[1], 1) . '/index.html';
} else { $f .= '/index.html'; }
$finalstr .= "<a href=\"$f\">[DIR] <strong>$spl[0]</strong></a>";
} elsif (@spl == 4) { # Another gopher server
my $path = '/';
if ($spl[1] ne '/') { $path .= $spl[1]; }
$finalstr .= "<a href=\"gopher://$spl[2]:$spl[3]$path\">"
. "[DIR] <strong>$spl[0]</strong></a>";
} else { $finalstr .= $line; }
break;
} when('I') { # Type I - Image
my $content = substr($line, 1);
my @spl = split(/\t/, $content);
if (@spl > 1) {
chomp($spl[1]);
$finalstr .= "<figure>
<img src=\"$spl[1]\" alt=\"$spl[0]\"/>
<figcaption>$spl[0]</figcaption>
</figure>";
} else { $finalstr .= $line; }
break;
} when('h') { # Type h - HTML
my $content = substr($line, 1);
my @spl = split(/\t/, $content);
if (@spl > 1) {
chomp($spl[1]);
$finalstr .= '<a href="'
. substr($spl[1], 4)
."\">[HTML] <strong>$spl[0]</strong></a>";
} else { $finalstr .= $line; }
break;
} when('!') { # Type ! - Escape
my $content = substr($line, 1);
chomp($content);
$finalstr .= $content;
break;
} default { # Plain text but maintain the spacing
if ($line eq "\n") { $line = '&nbsp;'; }
$line =~ s/\s(?=\s)/&nbsp;/g;
chomp($line);
$finalstr .= $line;
}
}
return $finalstr . "</p>\n";
}
sub html_header {
my ($file, $title) = @_;
open(FH_HTML, '>', $file) or die $!;
print FH_HTML "<!DOCTYPE html>
<html lang=\"en\">
<head>
<title>$title</title>
<meta charset=\"utf-8\"/>
<style>* { font-family: monospace; }
img { width: 50\%; }</style>
<body>";
close(FH_HTML);
}
sub html_footer {
my ($file) = @_;
open(FH_HTML, '>>', $file) or die $!;
print FH_HTML "</body></html>";
close(FH_HTML);
}
my $gophermap = 'gophermap';
if (@ARGV > 0) { $gophermap = $ARGV[0]; }
open(FH, '<', $gophermap) or die $!;
my @lines = ();
while (<FH>) { push @lines, parse_line($_); }
close(FH);
my $html = 'index.html';
my $title = 'Index';
if ($gophermap ne 'gophermap') {
$html = "$gophermap.html";
$title = "$gophermap"
}
html_header($html, $title);
open(FH_HTML, '>>', $html) or die $!;
print FH_HTML join('', @lines);
close(FH_HTML);
html_footer($html, $title);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment