Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- #
- # tool.pl, generates the strata website
- # (https://strata.neocities.org)
- #
- # MIT-licensed, version 0.1 from 2018,
- # written by Jonas "Lil' Strats" Kirschfeld
- #
- # Don't forget to install from CPAN:
- # - Data::Printer
- # - DateTime::Format::Strptime
- # - Path::Tiny
- # - Template::Toolkit
- use strict;
- use warnings;
- use autodie;
- use utf8;
- use v5.24.0;
- use Data::Printer {
- filters => {
- 'DateTime' => sub { "[DT:] $_[0]" },
- 'Path::Tiny' => sub { "[PT:] $_[0]" }
- },
- };
- use DateTime;
- use DateTime::Format::Strptime;
- use Path::Tiny qw@path@;
- use Template;
- sub DIR {
- {
- INPUT => {
- JOURNAL => path('./input/journal'),
- TEMPLATES => path('./input/templates'),
- },
- OUTPUT => {
- JOURNAL => path('./journal/')
- }
- }
- }
- sub WRAPPER { path('base.tt2') }
- sub TZ { 'Europe/Berlin' }
- package DateTime {
- sub mp_strats {
- # Evil monkey-patching:
- # returns something like "01/feb/18 12:25 a.m."
- my ($self, $arg) = @_;
- $arg //= '';
- my $strf = $self->strftime('%d/%b/%y');
- return lc $strf if $arg eq 'short';
- $strf .= $self->strftime(' / %I:%M ');
- $strf .= $self->strftime('%p') =~ s@(\w)@$1\.@gr;
- return lc $strf;
- }
- }
- sub render_template {
- my ($fn_in, $fn_out, $vars) = @_;
- state $tt = Template->new(
- {
- INCLUDE_PATH => DIR->{INPUT}{TEMPLATES},
- ENCODING => 'utf8',
- WRAPPER => WRAPPER->stringify
- }
- ) || die $Template::ERROR, "\n";
- return $tt->process(
- $fn_in, $vars, $fn_out, {binmode => ':utf8'}
- ) || die $tt->error, "\n";
- }
- sub parse_meta {
- my ($meta) = @_;
- my %map;
- for my $line (split(qr@\n@, $meta)) {
- my ($k, $v) = split(qr@: @, $line, 2);
- $map{$k} = $v;
- }
- return %map;
- }
- sub parse_timestamp {
- my ($ts) = @_;
- state $strp = DateTime::Format::Strptime->new(
- pattern => '%F %R',
- time_zone => TZ,
- );
- return $strp->parse_datetime($ts);
- }
- sub parse_slug {
- my ($path) = @_;
- $path =~ qr@/\d+-\d+-\d+-(?<slug>.*?).txt$@;
- return $+{slug};
- }
- sub make_entry_path {
- # returns e.g. "journal/jan18/heh.html" as Path::Tiny
- my (%entry) = $_[0]->%*;
- return DIR
- ->{OUTPUT}{JOURNAL}
- ->child(lc $entry{date}->strftime('%b%y'))
- ->child($entry{slug} . '.html');
- }
- sub make_entry {
- # returns an entry hashref
- my ($path) = @_;
- my ($meta, $content) =
- split(qr@\n\n...\n\n@, $path->slurp_utf8);
- my %entry = (parse_meta($meta));
- $entry{date} = parse_timestamp($entry{date});
- $entry{slug} = parse_slug($path);
- $entry{content} = $content;
- $entry{path} = make_entry_path(\%entry);
- return \%entry;
- }
- sub build_journal {
- # Fetch entries
- my @entries =
- sort { DateTime->compare($b->{date}, $a->{date}) }
- map { make_entry $_ }
- DIR->{INPUT}{JOURNAL}->children(qr@.txt$@);
- # Render each entry page
- my $template = path('journal/entry.tt2');
- for my $entry (@entries) {
- print "[journal] writing ", $entry->{path}, "\n";
- $entry->{path}->parent->mkpath;
- my %vars = (entry => $entry);
- render_template($template->stringify,
- $entry->{path}->stringify, \%vars);
- }
- # Render index
- $template = path('index.tt2');
- print "[journal] writing index \n";
- my %vars = (entries => \@entries);
- render_template($template->stringify,
- 'index.html', \%vars);
- }
- sub build {
- build_journal();
- }
- sub main {
- build();
- }
- main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement