X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/9982862925627d4714ed8b61d8b591950ed5aaa5..84a0b15eb68917829267bacac005f2bcefee914a:/IkiWiki.pm
diff --git a/IkiWiki.pm b/IkiWiki.pm
index bbe1ad055..1433af99b 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -20,7 +20,7 @@ use Exporter q{import};
our @EXPORT = qw(hook debug error htmlpage template template_depends
deptype add_depends pagespec_match pagespec_match_list bestlink
htmllink readfile writefile pagetype srcfile pagename
- displaytime will_render gettext ngettext urlto targetpage
+ displaytime strftime_utf8 will_render gettext ngettext urlto targetpage
add_underlay pagetitle titlepage linkpage newpagefile
inject add_link add_autofile
%config %links %pagestate %wikistate %renderedfiles
@@ -237,8 +237,8 @@ sub getsetup () {
html5 => {
type => "boolean",
default => 0,
- description => "generate HTML5? (experimental)",
- advanced => 1,
+ description => "generate HTML5?",
+ advanced => 0,
safe => 1,
rebuild => 1,
},
@@ -305,9 +305,9 @@ sub getsetup () {
rebuild => 0,
},
umask => {
- type => "integer",
- example => "022",
- description => "force ikiwiki to use a particular umask",
+ type => "string",
+ example => "public",
+ description => "force ikiwiki to use a particular umask (keywords public, group or private, or a number)",
advanced => 1,
safe => 0, # paranoia
rebuild => 0,
@@ -336,6 +336,14 @@ sub getsetup () {
safe => 0, # paranoia
rebuild => 0,
},
+ timezone => {
+ type => "string",
+ default => "",
+ example => "US/Eastern",
+ description => "time zone name",
+ safe => 1,
+ rebuild => 1,
+ },
include => {
type => "string",
default => undef,
@@ -477,7 +485,7 @@ sub getsetup () {
},
setuptype => {
type => "internal",
- default => "Standard",
+ default => "Yaml",
description => "perl class to use to dump setup file",
safe => 0,
rebuild => 0,
@@ -497,7 +505,6 @@ sub defaultconfig () {
foreach my $key (keys %s) {
push @ret, $key, $s{$key}->{default};
}
- use Data::Dumper;
return @ret;
}
@@ -529,6 +536,12 @@ sub checkconfig () {
$ENV{$val}=$config{ENV}{$val};
}
}
+ if (defined $config{timezone} && length $config{timezone}) {
+ $ENV{TZ}=$config{timezone};
+ }
+ else {
+ $config{timezone}=$ENV{TZ};
+ }
if ($config{w3mmode}) {
eval q{use Cwd q{abs_path}};
@@ -574,7 +587,23 @@ sub checkconfig () {
unless exists $config{wikistatedir} && defined $config{wikistatedir};
if (defined $config{umask}) {
- umask(possibly_foolish_untaint($config{umask}));
+ my $u = possibly_foolish_untaint($config{umask});
+
+ if ($u =~ m/^\d+$/) {
+ umask($u);
+ }
+ elsif ($u eq 'private') {
+ umask(077);
+ }
+ elsif ($u eq 'group') {
+ umask(027);
+ }
+ elsif ($u eq 'public') {
+ umask(022);
+ }
+ else {
+ error(sprintf(gettext("unsupported umask setting %s"), $u));
+ }
}
run_hooks(checkconfig => sub { shift->() });
@@ -810,17 +839,23 @@ sub srcfile ($;$) {
return (srcfile_stat(@_))[0];
}
-sub add_underlay ($) {
+sub add_literal_underlay ($) {
my $dir=shift;
- if ($dir !~ /^\//) {
- $dir="$config{underlaydirbase}/$dir";
- }
-
if (! grep { $_ eq $dir } @{$config{underlaydirs}}) {
unshift @{$config{underlaydirs}}, $dir;
}
+}
+
+sub add_underlay ($) {
+ my $dir = shift;
+
+ if ($dir !~ /^\//) {
+ $dir="$config{underlaydirbase}/$dir";
+ }
+ add_literal_underlay($dir);
+ # why does it return 1? we just don't know
return 1;
}
@@ -1007,7 +1042,7 @@ sub bestlink ($$) {
sub isinlinableimage ($) {
my $file=shift;
- return $file =~ /\.(png|gif|jpg|jpeg)$/i;
+ return $file =~ /\.(png|gif|jpg|jpeg|svg)$/i;
}
sub pagetitle ($;$) {
@@ -1057,6 +1092,11 @@ sub cgiurl (@) {
join("&", map $_."=".uri_escape_utf8($params{$_}), keys %params);
}
+sub cgiurl_abs (@) {
+ eval q{use URI};
+ URI->new_abs(cgiurl(@_), $config{cgiurl});
+}
+
sub baseurl (;$) {
my $page=shift;
@@ -1068,6 +1108,16 @@ sub baseurl (;$) {
return $page;
}
+sub urlabs ($$) {
+ my $url=shift;
+ my $urlbase=shift;
+
+ return $url unless defined $urlbase && length $urlbase;
+
+ eval q{use URI};
+ URI->new_abs($url, $urlbase)->as_string;
+}
+
sub abs2rel ($$) {
# Work around very innefficient behavior in File::Spec if abs2rel
# is passed two relative paths. It's much faster if paths are
@@ -1103,9 +1153,19 @@ sub formattime ($;$) {
$format=$config{timeformat};
}
+ return strftime_utf8($format, localtime($time));
+}
+
+my $strftime_encoding;
+sub strftime_utf8 {
# strftime doesn't know about encodings, so make sure
- # its output is properly treated as utf8
- return decode_utf8(POSIX::strftime($format, localtime($time)));
+ # its output is properly treated as utf8.
+ # Note that this does not handle utf-8 in the format string.
+ ($strftime_encoding) = POSIX::setlocale(&POSIX::LC_TIME) =~ m#\.([^@]+)#
+ unless defined $strftime_encoding;
+ $strftime_encoding
+ ? Encode::decode($strftime_encoding, POSIX::strftime(@_))
+ : POSIX::strftime(@_);
}
sub date_3339 ($) {
@@ -1152,7 +1212,7 @@ sub urlto ($;$$) {
}
if (! defined $from) {
- my $u = $local_url;
+ my $u = $local_url || '';
$u =~ s{/$}{};
return $u.beautify_urlpath("/".$to);
}
@@ -1208,7 +1268,7 @@ sub htmllink ($$$;@) {
$cgilink = " "create",
- page => lc($link),
+ page => $link,
from => $lpage
)."\" rel=\"nofollow\">?";
}
@@ -1363,10 +1423,15 @@ sub preprocess ($$$;$$) {
|
"([^"]*?)" # 3: single-quoted value
|
- (\S+) # 4: unquoted value
+ '''(.*?)''' # 4: triple-single-quote
+ |
+ <<([a-zA-Z]+)\n # 5: heredoc start
+ (.*?)\n\5 # 6: heredoc value
+ |
+ (\S+) # 7: unquoted value
)
(?:\s+|$) # delimiter to next param
- }sgx) {
+ }msgx) {
my $key=$1;
my $val;
if (defined $2) {
@@ -1381,6 +1446,12 @@ sub preprocess ($$$;$$) {
elsif (defined $4) {
$val=$4;
}
+ elsif (defined $7) {
+ $val=$7;
+ }
+ elsif (defined $6) {
+ $val=$6;
+ }
if (defined $key) {
push @params, $key, $val;
@@ -1410,6 +1481,8 @@ sub preprocess ($$$;$$) {
if ($@) {
my $error=$@;
chomp $error;
+ eval q{use HTML::Entities};
+ $error = encode_entities($error);
$ret="[[!$command ".
gettext("Error").": $error"."]]";
}
@@ -1449,6 +1522,11 @@ sub preprocess ($$$;$$) {
|
"[^"]*?" # single-quoted value
|
+ '''.*?''' # triple-single-quote
+ |
+ <<([a-zA-Z]+)\n # 5: heredoc start
+ (?:.*?)\n\5 # heredoc value
+ |
[^"\s\]]+ # unquoted value
)
\s* # whitespace or end
@@ -1472,6 +1550,11 @@ sub preprocess ($$$;$$) {
|
"[^"]*?" # single-quoted value
|
+ '''.*?''' # triple-single-quote
+ |
+ <<([a-zA-Z]+)\n # 5: heredoc start
+ (?:.*?)\n\5 # heredoc value
+ |
[^"\s\]]+ # unquoted value
)
\s* # whitespace or end
@@ -1906,39 +1989,6 @@ sub template ($;@) {
template_depends(shift, undef, @_);
}
-sub misctemplate ($$;@) {
- my $title=shift;
- my $content=shift;
- my %params=@_;
-
- my $template=template("page.tmpl");
-
- my $page="";
- if (exists $params{page}) {
- $page=delete $params{page};
- }
- run_hooks(pagetemplate => sub {
- shift->(
- page => $page,
- destpage => $page,
- template => $template,
- );
- });
- templateactions($template, "");
-
- $template->param(
- dynamic => 1,
- title => $title,
- wikiname => $config{wikiname},
- content => $content,
- baseurl => baseurl(),
- html5 => $config{html5},
- %params,
- );
-
- return $template->output;
-}
-
sub templateactions ($$) {
my $template=shift;
my $page=shift;
@@ -2033,7 +2083,7 @@ sub rcs_recentchanges ($) {
$hooks{rcs}{rcs_recentchanges}{call}->(@_);
}
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
$hooks{rcs}{rcs_diff}{call}->(@_);
}
@@ -2614,8 +2664,14 @@ sub match_link ($$;@) {
}
sub match_backlink ($$;@) {
- my $ret=match_link($_[1], $_[0], @_);
- $ret->influences($_[1] => $IkiWiki::DEPEND_LINKS);
+ my $page=shift;
+ my $testpage=shift;
+ my %params=@_;
+ if ($testpage eq '.') {
+ $testpage = $params{'location'}
+ }
+ my $ret=match_link($testpage, $page, @_);
+ $ret->influences($testpage => $IkiWiki::DEPEND_LINKS);
return $ret;
}
@@ -2775,6 +2831,7 @@ sub cmp_title {
IkiWiki::pagetitle(IkiWiki::basename($b))
}
+sub cmp_path { IkiWiki::pagetitle($a) cmp IkiWiki::pagetitle($b) }
sub cmp_mtime { $IkiWiki::pagemtime{$b} <=> $IkiWiki::pagemtime{$a} }
sub cmp_age { $IkiWiki::pagectime{$b} <=> $IkiWiki::pagectime{$a} }