#!/usr/bin/env plackup # vim:syntax=perl: # This is a wiki that: # - uses flat-files as a storage system # - uses server-side (SSH+vim) page-editing only; there is no web-based editing (it should only be used when there is a limited group of authors) # - provides no page versioning / history / diffing # # Details: # - the markup language is MultiMarkdown # - serves all files in the current directory as static files # - *.mkd files are converted to HTML via Text::MultiMarkdown # - ".mkd" and "index.mkd" will be appended when appropriate. These are all the same page: # http://localhost:5000/ # http://localhost:5000/index # http://localhost:5000/index.mkd # TODO: # - make the title: attribute automatically add a page-header # (or should we just wrap the entire thing in a Template of some sort?) # (and replace the section with a proper template?) # - we should differentiate between internal and external links # see: http://www.mediawiki.org/wiki/Help:Links#External_link_icons # - URL auto-linking still isn't properly working... investigate if peg-multimarkdown might solve these issues # - disable CamelCase auto-linking # - add the ability to have an automatic table-of-contents, like Mediawiki does use strict; use warnings; use Plack::App::Directory; use Plack::Util; use Plack::MIME; use Text::MultiMarkdown; use Encode; use Regexp::Common qw /URI/; use Data::Dumper; our $head_insert = do {local $/; }; Plack::MIME->add_type(".mkd" => "text/x-markdown"); ################### #### Plack app #### ################### my $app = sub { my ($env) = @_; #return plack_dumper($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 my $is_force_dirlist = ($env->{PATH_INFO} =~ s/\/\/$/\// || $env->{REQUEST_URI} =~ /\/\/$/); if ($env->{PATH_INFO} =~ /\/$/ && -d "./$env->{PATH_INFO}" && !$is_force_dirlist && -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); #return plack_dumper($res); ##==== post-filter my $override; # to output debugging info, assign something to this (eg. the output of plack_dumper()) $res = 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(?:;.*)?#) { my $markdown = join '', $res->[2]->getlines(); my $wiki_root_url = $env->{SCRIPT_NAME} . '/'; my $html = multimarkdown_to_html($markdown, $wiki_root_url); $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)) ); } elsif ($is_force_dirlist) { # when we're forcibly displaying a directory list, the "parent directory" link otherwise doesn't go to the right place $res->[2][0] =~ s#[1], 'Content-Length' ); } return; }); return $override ? $override : $res; }; sub multimarkdown_to_html { my ($markdown, $wiki_root_url) = @_; # auto-wikilink bare URLs #$markdown =~ s#(? 1, # enable MediaWiki-style links document_format => 'complete', #base_url => $baseurl, }); $html =~ s/(]*>)/$1\n$head_insert/s; # wikilinks should be relative to the wiki-root, not the webserver-root $html =~ s# in every .mkd => .html conversion vv #### __DATA__