package SCSite::PageSet;
-use IO::All;
use Text::MultiMarkdown 'markdown';
use HTML::Zoom;
use Sub::Quote;
use Syntax::Keyword::Gather;
use SCSite::Page;
-use Moo;
+use IO::All;
use Try::Tiny;
+use JSON;
+use Moo;
+
+{
+ my $j = JSON->new;
+ sub _json { $j }
+}
has top_dir => (is => 'ro', lazy => 1, builder => 'base_dir');
has base_dir => (is => 'ro', required => 1);
if @poss > 1;
return undef unless @poss;
$self->_inflate(
- $type, $self->rel_path->catdir($spec->{path}), $poss[0]->all
+ $type, $self->rel_path->catdir($spec->{path}), $poss[0]
);
}
sub _inflate {
- my ($self, $type, $path, $data) = @_;
- try { $self->${\"_inflate_${type}"}($path, $data) }
- catch {
- die "Error inflating ${path} as ${type}: $_\n\nData was: ${data}";
+ my ($self, $type, $path, $io) = @_;
+ (my $cache_name = $io->name) =~ s/\/([^\/]+)$/\/.htcache.$1.json/;
+ my $cache = io($cache_name);
+ if (-f $cache_name) {
+ if ($cache->mtime >= $io->mtime) {
+ return $self->_new_page($path, $self->_json->decode($cache->all));
+ }
+ }
+ my $raw = $io->all;
+ try {
+ my $extracted = $self->${\"_extract_from_${type}"}($raw);
+ $cache->print($self->_json->encode($extracted));
+ $self->_new_page($path, $extracted);
+ } catch {
+ die "Error inflating ${path} as ${type}: $_\n\nData was: ${raw}";
}
}
$self->_inflate(
$type,
$slash->catdir(File::Spec->abs2rel($path, $self->top_dir->name)),
- $_->all
+ $_
);
} map {
$_->filter(sub { $_->filename =~ /${\$self->_types_re}$/ })
sub _types_re { qw/\.(html|md)/ }
-sub _inflate_html {
- my ($self, $path, $html) = @_;
- $self->_new_page($path, $self->_extract_from_html($html));
-}
-
sub _extract_from_html {
my ($self, $html) = @_;
HTML::Zoom->from_html($html)
}
}
-sub _inflate_md {
- my ($self, $path, $md) = @_;
- $self->_new_page($path, $self->_extract_from_md($md));
-}
-
sub _extract_from_md {
my ($self, $md) = @_;
$self->_extract_from_html(markdown($md, { document_format => 'complete' }));