Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.49 KB | None | 0 0
  1. #!/usr/bin/env perl
  2. #
  3. # tool.pl, generates the strata website
  4. # (https://strata.neocities.org)
  5. #
  6. # MIT-licensed, version 0.1 from 2018,
  7. # written by Jonas "Lil' Strats" Kirschfeld
  8. #
  9. # Don't forget to install from CPAN:
  10. #   - Data::Printer
  11. #   - DateTime::Format::Strptime
  12. #   - Path::Tiny
  13. #   - Template::Toolkit
  14.  
  15. use strict;
  16. use warnings;
  17. use autodie;
  18. use utf8;
  19. use v5.24.0;
  20.  
  21. use Data::Printer {
  22.   filters => {
  23.     'DateTime'   => sub { "[DT:] $_[0]" },
  24.     'Path::Tiny' => sub { "[PT:] $_[0]" }
  25.   },
  26. };
  27. use DateTime;
  28. use DateTime::Format::Strptime;
  29. use Path::Tiny qw@path@;
  30. use Template;
  31.  
  32. sub DIR {
  33.   {
  34.     INPUT => {
  35.       JOURNAL => path('./input/journal'),
  36.       TEMPLATES => path('./input/templates'),
  37.     },
  38.     OUTPUT => {
  39.       JOURNAL => path('./journal/')
  40.     }
  41.   }
  42. }
  43. sub WRAPPER { path('base.tt2') }
  44. sub TZ { 'Europe/Berlin' }
  45.  
  46. package DateTime {
  47.   sub mp_strats {
  48.     # Evil monkey-patching:
  49.     # returns something like "01/feb/18 12:25 a.m."
  50.  
  51.     my ($self, $arg) = @_;
  52.     $arg //= '';
  53.    
  54.     my $strf = $self->strftime('%d/%b/%y');
  55.     return lc $strf if $arg eq 'short';
  56.  
  57.     $strf .= $self->strftime(' / %I:%M ');
  58.     $strf .= $self->strftime('%p') =~ s@(\w)@$1\.@gr;
  59.     return lc $strf;
  60.   }
  61. }
  62.  
  63. sub render_template {
  64.   my ($fn_in, $fn_out, $vars) = @_;
  65.  
  66.   state $tt = Template->new(
  67.     {
  68.       INCLUDE_PATH => DIR->{INPUT}{TEMPLATES},
  69.       ENCODING => 'utf8',
  70.       WRAPPER => WRAPPER->stringify
  71.     }
  72.   ) || die $Template::ERROR, "\n";
  73.  
  74.   return $tt->process(
  75.     $fn_in, $vars, $fn_out, {binmode => ':utf8'}
  76.   ) || die $tt->error, "\n";
  77. }
  78.  
  79. sub parse_meta {
  80.   my ($meta) = @_;
  81.  
  82.   my %map;
  83.   for my $line (split(qr@\n@, $meta)) {
  84.     my ($k, $v) = split(qr@: @, $line, 2);
  85.     $map{$k} = $v;
  86.   }
  87.   return %map;
  88. }
  89.  
  90. sub parse_timestamp {
  91.   my ($ts) = @_;
  92.  
  93.   state $strp = DateTime::Format::Strptime->new(
  94.     pattern => '%F %R',
  95.     time_zone => TZ,
  96.   );
  97.  
  98.   return $strp->parse_datetime($ts);
  99. }
  100.  
  101. sub parse_slug {
  102.   my ($path) = @_;
  103.  
  104.   $path =~ qr@/\d+-\d+-\d+-(?<slug>.*?).txt$@;
  105.   return $+{slug};
  106. }
  107.  
  108. sub make_entry_path {
  109.   # returns e.g. "journal/jan18/heh.html" as Path::Tiny
  110.  
  111.   my (%entry) = $_[0]->%*;
  112.  
  113.   return DIR
  114.     ->{OUTPUT}{JOURNAL}
  115.     ->child(lc $entry{date}->strftime('%b%y'))
  116.     ->child($entry{slug} . '.html');
  117. }
  118.  
  119. sub make_entry {
  120.   # returns an entry hashref
  121.  
  122.   my ($path) = @_;
  123.   my ($meta, $content) =
  124.       split(qr@\n\n...\n\n@, $path->slurp_utf8);
  125.  
  126.   my %entry = (parse_meta($meta));
  127.   $entry{date} = parse_timestamp($entry{date});
  128.   $entry{slug} = parse_slug($path);
  129.   $entry{content} = $content;
  130.   $entry{path} = make_entry_path(\%entry);
  131.   return \%entry;
  132. }
  133.  
  134. sub build_journal {
  135.   # Fetch entries
  136.   my @entries =
  137.     sort { DateTime->compare($b->{date}, $a->{date}) }
  138.     map { make_entry $_ }
  139.     DIR->{INPUT}{JOURNAL}->children(qr@.txt$@);
  140.  
  141.   # Render each entry page
  142.   my $template = path('journal/entry.tt2');
  143.   for my $entry (@entries) {
  144.     print "[journal] writing ", $entry->{path}, "\n";
  145.     $entry->{path}->parent->mkpath;
  146.    
  147.     my %vars = (entry => $entry);
  148.     render_template($template->stringify,
  149.                     $entry->{path}->stringify, \%vars);
  150.   }
  151.  
  152.   # Render index
  153.   $template = path('index.tt2');
  154.   print "[journal] writing index \n";
  155.   my %vars = (entries => \@entries);
  156.   render_template($template->stringify,
  157.                   'index.html', \%vars);
  158. }
  159.  
  160. sub build {
  161.   build_journal();
  162. }
  163.  
  164. sub main {
  165.   build();
  166. }
  167.  
  168. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement