use IkiWiki;
use Encode;
-sub linkify ($$$) { #{{{
- my $lpage=shift; # the page containing the links
- my $page=shift; # the page the link will end up on (different for inline)
- my $content=shift;
-
- $content =~ s{(\\?)$config{wiki_link_regexp}}{
- $2 ? ( $1 ? "[[$2|$3]]" : htmllink($lpage, $page, titlepage($3), 0, 0, pagetitle($2)))
- : ( $1 ? "[[$3]]" : htmllink($lpage, $page, titlepage($3)))
- }eg;
-
- return $content;
-} #}}}
-
-sub htmlize ($$) { #{{{
- my $type=shift;
- my $content=shift;
-
- if (exists $hooks{htmlize}{$type}) {
- $content=$hooks{htmlize}{$type}{call}->($content);
- }
- else {
- error("htmlization of $type not supported");
- }
-
- run_hooks(sanitize => sub {
- $content=shift->($content);
- });
-
- return $content;
-} #}}}
-
sub backlinks ($) { #{{{
my $page=shift;
return @ret;
} #}}}
-my @preprocessing;
-sub preprocess ($$$) { #{{{
- my $page=shift; # the page the data comes from
- my $destpage=shift; # the page the data will appear in (different for inline)
- my $content=shift;
-
- my $handle=sub {
- my $escape=shift;
- my $command=shift;
- my $params=shift;
- if (length $escape) {
- return "[[$command $params]]";
- }
- elsif (grep { $_ eq $page } @preprocessing) {
- # Avoid loops of preprocessed pages preprocessing
- # other pages that preprocess them, etc.
- return "[[$command would cause preprocessing loop]]";
- }
- elsif (exists $hooks{preprocess}{$command}) {
- # Note: preserve order of params, some plugins may
- # consider it significant.
- my @params;
- while ($params =~ /(?:(\w+)=)?(?:"""(.*?)"""|"([^"]+)"|(\S+))(?:\s+|$)/sg) {
- my $key=$1;
- my $val;
- if (defined $2) {
- $val=$2;
- $val=~s/\r\n/\n/mg;
- $val=~s/^\n+//g;
- $val=~s/\n+$//g;
- }
- elsif (defined $3) {
- $val=$3;
- }
- elsif (defined $4) {
- $val=$4;
- }
-
- if (defined $key) {
- push @params, $key, $val;
- }
- else {
- push @params, $val, '';
- }
- }
- push @preprocessing, $page;
- my $ret=$hooks{preprocess}{$command}{call}->(
- @params,
- page => $page,
- destpage => $destpage,
- );
- pop @preprocessing;
- return $ret;
- }
- else {
- return "[[$command not processed]]";
- }
- };
-
- $content =~ s{(\\?)\[\[(\w+)\s+((?:(?:\w+=)?(?:""".*?"""|"[^"]+"|[^\s\]]+)\s*)*)\]\]}{$handle->($1, $2, $3)}seg;
- return $content;
-} #}}}
-
-sub add_depends ($$) { #{{{
- my $page=shift;
- my $pagespec=shift;
-
- if (! exists $depends{$page}) {
- $depends{$page}=$pagespec;
- }
- else {
- $depends{$page}=pagespec_merge($depends{$page}, $pagespec);
- }
-} # }}}
-
sub genpage ($$$) { #{{{
my $page=shift;
my $content=shift;
$content=$template->output;
run_hooks(format => sub {
- $content=shift->($content);
+ $content=shift->(
+ page => $page,
+ content => $content,
+ );
});
return $content;
} #}}}
-sub check_overwrite ($$) { #{{{
- # Important security check. Make sure to call this before saving
- # any files to the source directory.
- my $dest=shift;
- my $src=shift;
-
- if (! exists $renderedfiles{$src} && -e $dest && ! $config{rebuild}) {
- error("$dest already exists and was not rendered from $src before");
- }
-} #}}}
-
-sub displaytime ($) { #{{{
- my $time=shift;
-
- eval q{use POSIX};
- # strftime doesn't know about encodings, so make sure
- # its output is properly treated as utf8
- return decode_utf8(POSIX::strftime(
- $config{timeformat}, localtime($time)));
-} #}}}
-
sub mtime ($) { #{{{
my $file=shift;
}
} #}}}
-sub filter ($$) {
- my $page=shift;
- my $content=shift;
-
- run_hooks(filter => sub {
- $content=shift->(page => $page, content => $content);
- });
-
- return $content;
-}
-
sub render ($) { #{{{
my $file=shift;
my $content=readfile($srcfile);
my $page=pagename($file);
delete $depends{$page};
+ will_render($page, htmlpage($page), 1);
$content=filter($page, $content);
$content=preprocess($page, $page, $content);
$content=linkify($page, $page, $content);
- $content=htmlize($type, $content);
+ $content=htmlize($page, $type, $content);
- check_overwrite("$config{destdir}/".htmlpage($page), $page);
writefile(htmlpage($page), $config{destdir},
genpage($page, $content, mtime($srcfile)));
$oldpagemtime{$page}=time;
- $renderedfiles{$page}=htmlpage($page);
}
else {
my $content=readfile($srcfile, 1);
$links{$file}=[];
delete $depends{$file};
- check_overwrite("$config{destdir}/$file", $file);
+ will_render($file, $file, 1);
writefile($file, $config{destdir}, $content, 1);
$oldpagemtime{$file}=time;
- $renderedfiles{$file}=$file;
}
} #}}}
if (! $exists{$page}) {
debug("removing old page $page");
push @del, $pagesources{$page};
- prune($config{destdir}."/".$renderedfiles{$page});
- delete $renderedfiles{$page};
+ $renderedfiles{$page}=[];
$oldpagemtime{$page}=0;
+ prune($config{destdir}."/".$_)
+ foreach @{$oldrenderedfiles{$page}};
delete $pagesources{$page};
}
}
}
}
+ # Remove no longer rendered files.
+ foreach my $src (keys %rendered) {
+ my $page=pagename($src);
+ foreach my $file (@{$oldrenderedfiles{$page}}) {
+ if (! grep { $_ eq $file } @{$renderedfiles{$page}}) {
+ debug("removing $file, no longer rendered by $page");
+ prune($config{destdir}."/".$file);
+ }
+ }
+ }
+
if (@del) {
run_hooks(delete => sub { shift->(@del) });
}
}
} #}}}
+sub commandline_render () { #{{{
+ loadplugins();
+ checkconfig();
+ lockwiki();
+ loadindex();
+ unlockwiki();
+
+ my $srcfile=possibly_foolish_untaint($config{render});
+ my $file=$srcfile;
+ $file=~s/\Q$config{srcdir}\E\/?//;
+
+ my $type=pagetype($file);
+ die "ikiwiki: cannot render $srcfile\n" unless defined $type;
+ my $content=readfile($srcfile);
+ my $page=pagename($file);
+ $pagesources{$page}=$file;
+ $content=filter($page, $content);
+ $content=preprocess($page, $page, $content);
+ $content=linkify($page, $page, $content);
+ $content=htmlize($page, $type, $content);
+
+ print genpage($page, $content, mtime($srcfile));
+ exit 0;
+} #}}}
+
1