#!/usr/bin/env plackup # vim:syntax=perl: # - serves all files in the current directory as static files # - however, all .mkd files are converted to HTML via Text::MultiMarkdown # - if there's an index.mkd file in a directory, that's displayed instead of the directory listing # - if /markdown.css exists, it will apply to all .mkd files # TODO: # - figure out a way to have every page include some .js, and then have some standard bits of jQuery included # - (optional) figure out a way to get it to stop requesting the .css on EVERY page-load use strict; use warnings; use Plack::App::Directory; use Plack::Util; use Plack::MIME; use Text::MultiMarkdown; use Encode; use Data::Dumper; Plack::MIME->add_type(".mkd" => "text/x-markdown"); my $app = sub { my ($env) = @_; ##==== pre-filter # add "index.mkd" if a directory was requested, and there's an index.mkd inside it # (however, the directory listing can still be retrieved by putting a double-slash on the end of the URL if (-d "./$env->{PATH_INFO}" && !($env->{PATH_INFO} =~ s/\/\/$/\//) && -e "./$env->{PATH_INFO}/index.mkd") { $env->{PATH_INFO} .= "/index.mkd"; } # add ".mkd" suffix, if that would fix a 404-missing-file, but only when the .mkd'd path actually exists if (! -e "./$env->{PATH_INFO}" && -e "./$env->{PATH_INFO}.mkd") { $env->{PATH_INFO} .= ".mkd"; } ##==== have Plack::App::Directory and Plack::App::File do their thing my $res = Plack::App::Directory->new(root => ".")->to_app->($env); ##==== post-filter Plack::Util::response_cb($res, sub { my $res = shift; my $ct = Plack::Util::header_get( $res->[1], 'Content-Type' ); if ($ct =~ m#^text/x-markdown(?:;.*)?#) { # do markup=>HTML conversion my $markup = join '', $res->[2]->getlines(); prepend_metadata($markup, "css: /markdown.css") if (-e "markdown.css"); my $html = Text::MultiMarkdown::markdown($markup, { use_wikilinks => 1, document_format => 'complete', }); $res->[2] = [ $html ]; Plack::Util::header_set( $res->[1], 'Content-Type' => 'text/html; charset=utf-8' ); Plack::Util::header_set( $res->[1], 'Content-Length' => length(Encode::encode_utf8($html)) ); } return; }); }; sub prepend_metadata { my ($mkd, $metadata) = @_; $mkd = "\n$mkd" unless ($mkd =~ /^([a-zA-Z0-9][0-9a-zA-Z _-]+?):/s); $_[0] = "$metadata\n$mkd"; }