aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2012-03-18 15:31:41 +0000
committerSimon McVittie <smcv@debian.org>2012-03-18 15:31:41 +0000
commit4e54fa1144065b7ff99e88e6c61ff1fdcf6175c9 (patch)
tree6759b80b8722ea532385c9a3ccc74897b784967d /IkiWiki
parentd70ba7cff3fc6cc78ea2f8eb0713212478ab6ba7 (diff)
parent0a9bb3edc2a9819ba87de1b6e57155120b6aba44 (diff)
downloadikiwiki-4e54fa1144065b7ff99e88e6c61ff1fdcf6175c9.tar
ikiwiki-4e54fa1144065b7ff99e88e6c61ff1fdcf6175c9.tar.gz
Merge tag '3.20120202' into trail3-integrated
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/Plugin/attachment.pm2
-rw-r--r--IkiWiki/Plugin/calendar.pm15
-rw-r--r--[-rwxr-xr-x]IkiWiki/Plugin/comments.pm3
-rw-r--r--IkiWiki/Plugin/cvs.pm168
-rw-r--r--IkiWiki/Plugin/editpage.pm2
-rw-r--r--IkiWiki/Plugin/graphviz.pm114
-rw-r--r--IkiWiki/Plugin/highlight.pm2
-rw-r--r--IkiWiki/Plugin/img.pm8
-rw-r--r--IkiWiki/Plugin/mdwn.pm26
-rw-r--r--IkiWiki/Plugin/recentchangesdiff.pm12
-rw-r--r--IkiWiki/Plugin/tag.pm2
-rw-r--r--IkiWiki/Receive.pm9
-rw-r--r--IkiWiki/Setup/Standard.pm5
-rw-r--r--IkiWiki/Setup/Yaml.pm12
14 files changed, 246 insertions, 134 deletions
diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm
index fd4096edf..5a180cd5c 100644
--- a/IkiWiki/Plugin/attachment.pm
+++ b/IkiWiki/Plugin/attachment.pm
@@ -272,6 +272,7 @@ sub attachments_save {
my @attachments;
my $dir=attachment_holding_location($form->field('page'));
foreach my $filename (glob("$dir/*")) {
+ $filename=Encode::decode_utf8($filename);
next unless -f $filename;
my $destdir=$config{srcdir}."/".
linkpage(IkiWiki::possibly_foolish_untaint(
@@ -345,6 +346,7 @@ sub attachment_list ($) {
my $dir=attachment_holding_location($page);
my $heldmsg=gettext("this attachment is not yet saved");
foreach my $file (glob("$dir/*")) {
+ $file=Encode::decode_utf8($file);
next unless -f $file;
my $base=IkiWiki::basename($file);
my $f=$loc.$base;
diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
index c7d2b7c01..fc497b3c7 100644
--- a/IkiWiki/Plugin/calendar.pm
+++ b/IkiWiki/Plugin/calendar.pm
@@ -22,7 +22,6 @@ use warnings;
use strict;
use IkiWiki 3.00;
use Time::Local;
-use POSIX ();
my $time=time;
my @now=localtime($time);
@@ -123,10 +122,10 @@ sub format_month (@) {
}
# Find out month names for this, next, and previous months
- my $monthabbrev=POSIX::strftime("%b", @monthstart);
- my $monthname=POSIX::strftime("%B", @monthstart);
- my $pmonthname=POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900)));
- my $nmonthname=POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900)));
+ my $monthabbrev=strftime_utf8("%b", @monthstart);
+ my $monthname=strftime_utf8("%B", @monthstart);
+ my $pmonthname=strftime_utf8("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900)));
+ my $nmonthname=strftime_utf8("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900)));
my $archivebase = 'archives';
$archivebase = $config{archivebase} if defined $config{archivebase};
@@ -182,7 +181,7 @@ EOF
my %dowabbr;
for my $dow ($week_start_day..$week_start_day+6) {
my @day=localtime(timelocal(0,0,0,$start_day++,$params{month}-1,$params{year}-1900));
- my $downame = POSIX::strftime("%A", @day);
+ my $downame = strftime_utf8("%A", @day);
my $dowabbr = substr($downame, 0, 1);
$downame{$dow % 7}=$downame;
$dowabbr{$dow % 7}=$dowabbr;
@@ -329,8 +328,8 @@ EOF
for (my $month = 1; $month <= 12; $month++) {
my @day=localtime(timelocal(0,0,0,15,$month-1,$params{year}-1900));
my $murl;
- my $monthname = POSIX::strftime("%B", @day);
- my $monthabbr = POSIX::strftime("%b", @day);
+ my $monthname = strftime_utf8("%B", @day);
+ my $monthabbr = strftime_utf8("%b", @day);
$calendar.=qq{\t<tr>\n} if ($month % $params{months_per_row} == 1);
my $tag;
my $mtag=sprintf("%02d", $month);
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index 3ad2a0e13..91a482ed6 100755..100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -9,7 +9,6 @@ use warnings;
use strict;
use IkiWiki 3.00;
use Encode;
-use POSIX qw(strftime);
use constant PREVIEW => "Preview";
use constant POST_COMMENT => "Post comment";
@@ -460,7 +459,7 @@ sub editcomment ($$) {
}
$content .= " subject=\"$subject\"\n";
- $content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
+ $content .= " date=\"" . strftime_utf8('%Y-%m-%dT%H:%M:%SZ', gmtime) . "\"\n";
my $editcontent = $form->field('editcontent');
$editcontent="" if ! defined $editcontent;
diff --git a/IkiWiki/Plugin/cvs.pm b/IkiWiki/Plugin/cvs.pm
index 71566d212..0a6cbfaf6 100644
--- a/IkiWiki/Plugin/cvs.pm
+++ b/IkiWiki/Plugin/cvs.pm
@@ -35,10 +35,14 @@ use IkiWiki;
use File::chdir;
+
+# GENERAL PLUGIN API CALLS
+
sub import {
- hook(type => "genwrapper", id => "cvs", call => \&genwrapper);
hook(type => "checkconfig", id => "cvs", call => \&checkconfig);
hook(type => "getsetup", id => "cvs", call => \&getsetup);
+ hook(type => "genwrapper", id => "cvs", call => \&genwrapper);
+
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
@@ -52,17 +56,6 @@ sub import {
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
}
-sub genwrapper () {
- return <<EOF;
- {
- int j;
- for (j = 1; j < argc; j++)
- if (strstr(argv[j], "New directory") != NULL)
- exit(0);
- }
-EOF
-}
-
sub checkconfig () {
if (! defined $config{cvspath}) {
$config{cvspath}="ikiwiki";
@@ -132,39 +125,22 @@ sub getsetup () {
},
}
-sub cvs_info ($$) {
- my $field=shift;
- my $file=shift;
-
- local $CWD = $config{srcdir};
-
- my $info=`cvs status $file`;
- my ($ret)=$info=~/^\s*$field:\s*(\S+)/m;
- return $ret;
+sub genwrapper () {
+ return <<EOF;
+ {
+ int j;
+ for (j = 1; j < argc; j++)
+ if (strstr(argv[j], "New directory") != NULL)
+ exit(0);
+ }
+EOF
}
-sub cvs_runcvs(@) {
- my @cmd = @_;
- unshift @cmd, 'cvs', '-Q';
-
- local $CWD = $config{srcdir};
-
- open(my $savedout, ">&STDOUT");
- open(STDOUT, ">", "/dev/null");
- my $ret = system(@cmd);
- open(STDOUT, ">&", $savedout);
- return ($ret == 0) ? 1 : 0;
-}
-
-sub cvs_is_controlling {
- my $dir=shift;
- $dir=$config{srcdir} unless defined($dir);
- return (-d "$dir/CVS") ? 1 : 0;
-}
+# VCS PLUGIN API CALLS
sub rcs_update () {
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
cvs_runcvs('update', '-dP');
}
@@ -175,7 +151,7 @@ sub rcs_prepedit ($) {
# The file is relative to the srcdir.
my $file=shift;
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
# For cvs, return the revision of the file when
# editing begins.
@@ -183,31 +159,13 @@ sub rcs_prepedit ($) {
return defined $rev ? $rev : "";
}
-sub commitmessage (@) {
- my %params=@_;
-
- if (defined $params{session}) {
- if (defined $params{session}->param("name")) {
- return "web commit by ".
- $params{session}->param("name").
- (length $params{message} ? ": $params{message}" : "");
- }
- elsif (defined $params{session}->remote_addr()) {
- return "web commit from ".
- $params{session}->remote_addr().
- (length $params{message} ? ": $params{message}" : "");
- }
- }
- return $params{message};
-}
-
sub rcs_commit (@) {
# Tries to commit the page; returns undef on _success_ and
# a version of the page with the rcs's conflict markers on failure.
# The file is relative to the srcdir.
my %params=@_;
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
# Check to see if the page has been changed by someone
# else since rcs_prepedit was called.
@@ -250,9 +208,6 @@ sub rcs_add ($) {
my $parent=IkiWiki::dirname($file);
my @files_to_add = ($file);
- eval q{use File::MimeInfo};
- error($@) if $@;
-
until ((length($parent) == 0) || cvs_is_controlling("$config{srcdir}/$parent")){
push @files_to_add, $parent;
$parent = IkiWiki::dirname($parent);
@@ -261,15 +216,8 @@ sub rcs_add ($) {
while ($file = pop @files_to_add) {
if (@files_to_add == 0) {
# file
- my $filemime = File::MimeInfo::default($file);
- if (defined($filemime) && $filemime eq 'text/plain') {
- cvs_runcvs('add', $file) ||
- warn("cvs add $file failed\n");
- }
- else {
- cvs_runcvs('add', '-kb', $file) ||
- warn("cvs add binary $file failed\n");
- }
+ cvs_runcvs('add', cvs_keyword_subst_args($file)) ||
+ warn("cvs add $file failed\n");
}
else {
# directory
@@ -283,7 +231,7 @@ sub rcs_remove ($) {
# filename is relative to the root of the srcdir
my $file=shift;
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
cvs_runcvs('rm', '-f', $file) ||
warn("cvs rm $file failed\n");
@@ -293,7 +241,7 @@ sub rcs_rename ($$) {
# filenames relative to the root of the srcdir
my ($src, $dest)=@_;
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
local $CWD = $config{srcdir};
@@ -309,7 +257,7 @@ sub rcs_recentchanges ($) {
my $num = shift;
my @ret;
- return unless cvs_is_controlling;
+ return unless cvs_is_controlling();
eval q{use Date::Parse};
error($@) if $@;
@@ -493,4 +441,74 @@ sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for cvs\n"; # TODO
}
+
+# INTERNAL SUPPORT ROUTINES
+
+sub commitmessage (@) {
+ my %params=@_;
+
+ if (defined $params{session}) {
+ if (defined $params{session}->param("name")) {
+ return "web commit by ".
+ $params{session}->param("name").
+ (length $params{message} ? ": $params{message}" : "");
+ }
+ elsif (defined $params{session}->remote_addr()) {
+ return "web commit from ".
+ $params{session}->remote_addr().
+ (length $params{message} ? ": $params{message}" : "");
+ }
+ }
+ return $params{message};
+}
+
+sub cvs_info ($$) {
+ my $field=shift;
+ my $file=shift;
+
+ local $CWD = $config{srcdir};
+
+ my $info=`cvs status $file`;
+ my ($ret)=$info=~/^\s*$field:\s*(\S+)/m;
+ return $ret;
+}
+
+sub cvs_is_controlling {
+ my $dir=shift;
+ $dir=$config{srcdir} unless defined($dir);
+ return (-d "$dir/CVS") ? 1 : 0;
+}
+
+sub cvs_keyword_subst_args ($) {
+ my $file = shift;
+
+ local $CWD = $config{srcdir};
+
+ eval q{use File::MimeInfo};
+ error($@) if $@;
+ my $filemime = File::MimeInfo::default($file);
+ # if (-T $file) {
+
+ if (defined($filemime) && $filemime eq 'text/plain') {
+ return ($file);
+ }
+ else {
+ return ('-kb', $file);
+ }
+}
+
+sub cvs_runcvs(@) {
+ my @cmd = @_;
+ unshift @cmd, 'cvs', '-Q';
+
+ local $CWD = $config{srcdir};
+
+ open(my $savedout, ">&STDOUT");
+ open(STDOUT, ">", "/dev/null");
+ my $ret = system(@cmd);
+ open(STDOUT, ">&", $savedout);
+
+ return ($ret == 0) ? 1 : 0;
+}
+
1
diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm
index a5c29a352..54051c58c 100644
--- a/IkiWiki/Plugin/editpage.pm
+++ b/IkiWiki/Plugin/editpage.pm
@@ -231,7 +231,7 @@ sub cgi_editpage ($$) {
if ! $form->submitted && lc($page) ne $page;
}
elsif (lc $page eq lc $config{discussionpage}) {
- @page_locs=$best_loc=$page="$from/".lc($page);
+ @page_locs=$best_loc="$from/".lc($page);
}
else {
my $dir=$from."/";
diff --git a/IkiWiki/Plugin/graphviz.pm b/IkiWiki/Plugin/graphviz.pm
index 4ed8b89f1..b9f997e04 100644
--- a/IkiWiki/Plugin/graphviz.pm
+++ b/IkiWiki/Plugin/graphviz.pm
@@ -10,7 +10,8 @@ use IPC::Open2;
sub import {
hook(type => "getsetup", id => "graphviz", call => \&getsetup);
- hook(type => "preprocess", id => "graph", call => \&graph);
+ hook(type => "needsbuild", id => "version", call => \&needsbuild);
+ hook(type => "preprocess", id => "graph", call => \&graph, scan => 1);
}
sub getsetup () {
@@ -26,66 +27,117 @@ my %graphviz_programs = (
"dot" => 1, "neato" => 1, "fdp" => 1, "twopi" => 1, "circo" => 1
);
+sub needsbuild {
+ my $needsbuild=shift;
+ foreach my $page (keys %pagestate) {
+ if (exists $pagestate{$page}{graph} &&
+ exists $pagesources{$page} &&
+ grep { $_ eq $pagesources{$page} } @$needsbuild) {
+ # remove state, will be re-added if
+ # the graph is still there during the rebuild
+ delete $pagestate{$page}{graph};
+ }
+ }
+ return $needsbuild;
+}
+
sub render_graph (\%) {
my %params = %{(shift)};
-
- my $src = "$params{type} g {\n";
- $src .= "charset=\"utf-8\";\n";
+
+ my $src = "charset=\"utf-8\";\n";
$src .= "ratio=compress;\nsize=\"".($params{width}+0).", ".($params{height}+0)."\";\n"
if defined $params{width} and defined $params{height};
$src .= $params{src};
$src .= "}\n";
-
- # Use the sha1 of the graphviz code as part of its filename.
+
+ # Use the sha1 of the graphviz code as part of its filename,
+ # and as a unique identifier for its imagemap.
eval q{use Digest::SHA};
error($@) if $@;
- my $dest=$params{page}."/graph-".
- IkiWiki::possibly_foolish_untaint(Digest::SHA::sha1_hex($src)).
- ".png";
+ my $sha=IkiWiki::possibly_foolish_untaint(Digest::SHA::sha1_hex($params{type}.$src));
+ $src = "$params{type} graph$sha {\n".$src;
+
+ my $dest=$params{page}."/graph-".$sha.".png";
will_render($params{page}, $dest);
- if (! -e "$config{destdir}/$dest") {
+ my $map=$pagestate{$params{destpage}}{graph}{$sha};
+ if (! -e "$config{destdir}/$dest" || ! defined $map) {
+ # Use ikiwiki's function to create the image file, this makes
+ # sure needed subdirs are there and does some sanity checking.
+ writefile($dest, $config{destdir}, "");
+
my $pid;
my $sigpipe=0;
$SIG{PIPE}=sub { $sigpipe=1 };
- $pid=open2(*IN, *OUT, "$params{prog} -Tpng");
+ $pid=open2(*IN, *OUT, "$params{prog} -Tpng -o '$config{destdir}/$dest' -Tcmapx");
# open2 doesn't respect "use open ':utf8'"
+ binmode (IN, ':utf8');
binmode (OUT, ':utf8');
print OUT $src;
close OUT;
- my $png;
- {
- local $/ = undef;
- $png = <IN>;
- }
+ local $/ = undef;
+ $map=$pagestate{$params{destpage}}{graph}{$sha}=<IN>;
close IN;
waitpid $pid, 0;
$SIG{PIPE}="DEFAULT";
- error gettext("failed to run graphviz") if $sigpipe;
-
- if (! $params{preview}) {
- writefile($dest, $config{destdir}, $png, 1);
- }
- else {
- # in preview mode, embed the image in a data uri
- # to avoid temp file clutter
- eval q{use MIME::Base64};
- error($@) if $@;
- return "<img src=\"data:image/png;base64,".
- encode_base64($png)."\" />";
- }
+ error gettext("failed to run graphviz") if ($sigpipe || $?);
}
- return "<img src=\"".urlto($dest, $params{destpage})."\" />\n";
+ return "<img src=\"".urlto($dest, $params{destpage}).
+ "\" usemap=\"#graph$sha\" />\n".
+ $map;
}
sub graph (@) {
my %params=@_;
- $params{src} = "" unless defined $params{src};
+
+ # Support wikilinks in the graph source.
+ my $src=$params{src};
+ $src="" unless defined $src;
+ $src=IkiWiki::linkify($params{page}, $params{destpage}, $params{src});
+ return unless defined wantarray; # scan mode short-circuit
+ if ($src ne $params{src}) {
+ # linkify makes html links, but graphviz wants plain
+ # urls. This is, frankly a hack: Process source as html,
+ # throw out everything inside tags that is not a href.
+ my $s;
+ my $nested=0;
+ use HTML::Parser;
+ error $@ if $@;
+ my $p=HTML::Parser->new(api_version => 3);
+ $p->handler(start => sub {
+ my %attrs=%{shift()};
+ if (exists $attrs{href}) {
+ if ($s=~/href\s*=\s*"$/) {
+ $s.=$attrs{href};
+ }
+ elsif ($s=~/href\s*=\s*$/) {
+ $s.="\"$attrs{href}\"";
+ }
+ else {
+ $s.="href=\"$attrs{href}\"";
+ }
+ }
+ $nested++;
+ }, "attr");
+ $p->handler(end => sub {
+ $nested--;
+ });
+ $p->handler(default => sub {
+ $s.=join("", @_) unless $nested;
+ }, "text");
+ $p->parse($src);
+ $p->eof;
+ $params{src}=$s;
+ }
+ else {
+ $params{src}=$src;
+ }
+
$params{type} = "digraph" unless defined $params{type};
$params{prog} = "dot" unless defined $params{prog};
error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}};
diff --git a/IkiWiki/Plugin/highlight.pm b/IkiWiki/Plugin/highlight.pm
index 33d136fbf..4e86207f1 100644
--- a/IkiWiki/Plugin/highlight.pm
+++ b/IkiWiki/Plugin/highlight.pm
@@ -52,7 +52,7 @@ sub getsetup () {
sub checkconfig () {
eval q{use highlight};
- if (highlight::DataDir->can('new')){
+ if (highlight::DataDir->can('new')) {
$data_dir=new highlight::DataDir();
$data_dir->searchDataDir("");
} else {
diff --git a/IkiWiki/Plugin/img.pm b/IkiWiki/Plugin/img.pm
index b98e843d4..b92e24cc0 100644
--- a/IkiWiki/Plugin/img.pm
+++ b/IkiWiki/Plugin/img.pm
@@ -118,7 +118,6 @@ sub preprocess (@) {
error sprintf(gettext("failed to read %s: %s"), $outfile, $r) if $r;
}
else {
- ($dwidth, $dheight)=($w, $h);
$r = $im->Resize(geometry => "${w}x${h}");
error sprintf(gettext("failed to resize: %s"), $r) if $r;
@@ -132,9 +131,10 @@ sub preprocess (@) {
$imglink = $file;
}
}
-
- $dwidth = $im->Get("width") unless defined $dwidth;
- $dheight = $im->Get("height") unless defined $dheight;
+
+ # always get the true size of the resized image
+ $dwidth = $im->Get("width");
+ $dheight = $im->Get("height");
}
}
else {
diff --git a/IkiWiki/Plugin/mdwn.pm b/IkiWiki/Plugin/mdwn.pm
index b892eabee..430194bff 100644
--- a/IkiWiki/Plugin/mdwn.pm
+++ b/IkiWiki/Plugin/mdwn.pm
@@ -25,6 +25,13 @@ sub getsetup () {
safe => 1,
rebuild => 1,
},
+ nodiscount => {
+ type => "boolean",
+ example => 0,
+ description => "disable use of markdown discount?",
+ safe => 1,
+ rebuild => 1,
+ },
}
my $markdown_sub;
@@ -50,6 +57,25 @@ sub htmlize (@) {
}
}
}
+ if (! defined $markdown_sub &&
+ (! exists $config{nodiscount} || ! $config{nodiscount})) {
+ eval q{use Text::Markdown::Discount};
+ if (! $@) {
+ $markdown_sub=sub {
+ my $t=shift;
+ # Workaround for discount binding bug
+ # https://rt.cpan.org/Ticket/Display.html?id=73657
+ return "" if $t=~/^\s*$/;
+ # Workaround for discount's eliding
+ # of <style> blocks.
+ # https://rt.cpan.org/Ticket/Display.html?id=74016
+ $t=~s/<style/<elyts/ig;
+ my $r=Text::Markdown::Discount::markdown($t);
+ $r=~s/<elyts/<style/ig;
+ return $r;
+ }
+ }
+ }
if (! defined $markdown_sub) {
eval q{use Text::Markdown};
if (! $@) {
diff --git a/IkiWiki/Plugin/recentchangesdiff.pm b/IkiWiki/Plugin/recentchangesdiff.pm
index 71297572d..418822793 100644
--- a/IkiWiki/Plugin/recentchangesdiff.pm
+++ b/IkiWiki/Plugin/recentchangesdiff.pm
@@ -31,13 +31,21 @@ sub pagetemplate (@) {
my @lines=IkiWiki::rcs_diff($params{rev}, $maxlines+1);
if (@lines) {
my $diff;
+ my $trunc=0;
if (@lines > $maxlines) {
- $diff=join("", @lines[0..($maxlines-1)])."\n".
- gettext("(Diff truncated)");
+ $diff=join("", @lines[0..($maxlines-1)]);
+ $trunc=1;
}
else {
$diff=join("", @lines);
}
+ if (length $diff > 102400) {
+ $diff=substr($diff, 0, 10240);
+ $trunc=1;
+ }
+ if ($trunc) {
+ $diff.="\n".gettext("(Diff truncated)");
+ }
# escape html
$diff = encode_entities($diff);
# escape links and preprocessor stuff
diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm
index 096c92616..605f41599 100644
--- a/IkiWiki/Plugin/tag.pm
+++ b/IkiWiki/Plugin/tag.pm
@@ -201,7 +201,7 @@ sub pagetemplate (@) {
if (defined $tags && %$tags) {
eval q{use HTML::Entities};
$template->param(categories =>
- [map { category => HTML::Entities::encode_entities(tagname($_)) },
+ [map { category => HTML::Entities::encode_entities_numeric(tagname($_)) },
sort keys %$tags]);
}
}
diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm
index c73adfbbb..5908e09f9 100644
--- a/IkiWiki/Receive.pm
+++ b/IkiWiki/Receive.pm
@@ -35,10 +35,17 @@ EOF
}
"u != $uid";
} @{$config{untrusted_committers}}).
- ") exit(0);\n";
+ ") {\n";
$ret.=<<"EOF";
+ /* Trusted user.
+ * Consume all stdin before exiting, as git may
+ * otherwise be unhappy. */
+ char buf[256];
+ while (read(0, &buf, 256) != 0) {}
+ exit(0);
+ }
asprintf(&s, "CALLER_UID=%i", u);
newenviron[i++]=s;
}
diff --git a/IkiWiki/Setup/Standard.pm b/IkiWiki/Setup/Standard.pm
index c85069304..ea7d763bb 100644
--- a/IkiWiki/Setup/Standard.pm
+++ b/IkiWiki/Setup/Standard.pm
@@ -14,7 +14,10 @@ sub import {
sub gendump ($@) {
my $class=shift;
- "#!/usr/bin/perl",
+ my $thisperl = eval q{use Config; $Config{perlpath}};
+ error($@) if $@;
+
+ "#!$thisperl",
"#",
(map { "# $_" } @_),
"use IkiWiki::Setup::Standard {",
diff --git a/IkiWiki/Setup/Yaml.pm b/IkiWiki/Setup/Yaml.pm
index 6da93bb64..6bf20f480 100644
--- a/IkiWiki/Setup/Yaml.pm
+++ b/IkiWiki/Setup/Yaml.pm
@@ -11,10 +11,8 @@ sub loaddump ($$) {
my $class=shift;
my $content=shift;
- eval q{use YAML::Any};
- eval q{use YAML} if $@;
+ eval q{use YAML::XS};
die $@ if $@;
- $YAML::Syck::ImplicitUnicode=1;
IkiWiki::Setup::merge(Load(encode_utf8($content)));
}
@@ -35,12 +33,12 @@ sub dumpline ($$$$) {
my $type=shift;
my $prefix=shift;
- eval q{use YAML::Old};
- eval q{use YAML} if $@;
+ eval q{use YAML::XS};
die $@ if $@;
- $YAML::UseHeader=0;
+ $YAML::XS::QuoteNumericStrings=0;
- my $dump=Dump({$key => $value});
+ my $dump=decode_utf8(Dump({$key => $value}));
+ $dump=~s/^---\n//; # yaml header, we don't want
chomp $dump;
if (length $prefix) {
$dump=join("\n", map { $prefix.$_ } split(/\n/, $dump));