diff --git a/Bundle/IkiWiki.pm b/Bundle/IkiWiki.pm index 74832323a..769791d30 100644 --- a/Bundle/IkiWiki.pm +++ b/Bundle/IkiWiki.pm @@ -16,17 +16,17 @@ perl -MCPAN -e 'install Bundle::IkiWiki' =head1 CONTENTS -XML::Simple Text::Markdown -Date::Parse -HTML::Template HTML::Scrubber -CGI +HTML::Template +HTML::Parser +URI +XML::Simple +Date::Parse CGI::FormBuilder CGI::Session Mail::Sendmail -HTML::Parser -URI +CGI Data::Dumper =head1 AUTHOR diff --git a/Bundle/IkiWiki/Extras.pm b/Bundle/IkiWiki/Extras.pm index abf596f00..40b36e7c8 100644 --- a/Bundle/IkiWiki/Extras.pm +++ b/Bundle/IkiWiki/Extras.pm @@ -31,6 +31,11 @@ Text::Textile Text::WikiFormat XML::Feed Net::Amazon::S3 +Text::WikiCreole +Term::ReadLine::Gnu +HTML::Tree +Authen::Passphrase +Sort::Naturally =head1 AUTHOR diff --git a/IkiWiki.pm b/IkiWiki.pm index 633c51381..ee07258ec 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -21,11 +21,12 @@ our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match bestlink htmllink readfile writefile pagetype srcfile pagename displaytime will_render gettext urlto targetpage add_underlay pagetitle titlepage linkpage newpagefile + inject %config %links %pagestate %wikistate %renderedfiles %pagesources %destsources); -our $VERSION = 2.00; # plugin interface version, next is ikiwiki version +our $VERSION = 3.00; # plugin interface version, next is ikiwiki version our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE -my $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE +our $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE # Optimisation. use Memoize; @@ -33,7 +34,7 @@ memoize("abs2rel"); memoize("pagespec_translate"); memoize("file_pruned"); -sub getsetup () { #{{{ +sub getsetup () { wikiname => { type => "string", default => "wiki", @@ -99,7 +100,7 @@ sub getsetup () { #{{{ type => "string", default => '', example => "/var/www/wiki/ikiwiki.cgi", - description => "cgi wrapper to generate", + description => "filename of cgi wrapper to generate", safe => 0, # file rebuild => 0, }, @@ -119,7 +120,7 @@ sub getsetup () { #{{{ }, default_plugins => { type => "internal", - default => [qw{mdwn link inline htmlscrubber passwordauth + default => [qw{mdwn link inline meta htmlscrubber passwordauth openid signinedit lockedit conditional recentchanges parentlinks editpage}], description => "plugins to enable by default", @@ -173,7 +174,7 @@ sub getsetup () { #{{{ verbose => { type => "boolean", example => 1, - description => "display verbose messages when building?", + description => "display verbose messages?", safe => 1, rebuild => 0, }, @@ -193,7 +194,7 @@ sub getsetup () { #{{{ }, prefix_directives => { type => "boolean", - default => 0, + default => 1, description => "use '!'-prefixed preprocessor directives?", safe => 0, # changing requires manual transition rebuild => 1, @@ -276,13 +277,20 @@ sub getsetup () { #{{{ }, umask => { type => "integer", - description => "", example => "022", description => "force ikiwiki to use a particular umask", advanced => 1, safe => 0, # paranoia rebuild => 0, }, + wrappergroup => { + type => "string", + example => "ikiwiki", + description => "group for wrappers to run in", + advanced => 1, + safe => 0, # paranoia + rebuild => 0, + }, libdir => { type => "string", default => "", @@ -381,6 +389,13 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, + test_receive => { + type => "internal", + default => 0, + description => "running in receive test mode", + safe => 0, + rebuild => 0, + }, getctime => { type => "internal", default => 0, @@ -395,6 +410,13 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, + wikistatedir => { + type => "internal", + default => undef, + description => "path to the .ikiwiki directory holding ikiwiki state", + safe => 0, + rebuild => 0, + }, setupfile => { type => "internal", default => undef, @@ -403,15 +425,15 @@ sub getsetup () { #{{{ rebuild => 0, }, allow_symlinks_before_srcdir => { - type => "string", + type => "boolean", default => 0, description => "allow symlinks in the path leading to the srcdir (potentially insecure)", safe => 0, rebuild => 0, }, -} #}}} +} -sub defaultconfig () { #{{{ +sub defaultconfig () { my %s=getsetup(); my @ret; foreach my $key (keys %s) { @@ -419,9 +441,9 @@ sub defaultconfig () { #{{{ } use Data::Dumper; return @ret; -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { # locale stuff; avoid LC_ALL since it overrides everything if (defined $ENV{LC_ALL}) { $ENV{LANG} = $ENV{LC_ALL}; @@ -459,7 +481,7 @@ sub checkconfig () { #{{{ } $config{wikistatedir}="$config{srcdir}/.ikiwiki" - unless exists $config{wikistatedir}; + unless exists $config{wikistatedir} && defined $config{wikistatedir}; if (defined $config{umask}) { umask(possibly_foolish_untaint($config{umask})); @@ -468,9 +490,9 @@ sub checkconfig () { #{{{ run_hooks(checkconfig => sub { shift->() }); return 1; -} #}}} +} -sub listplugins () { #{{{ +sub listplugins () { my %ret; foreach my $dir (@INC, $config{libdir}) { @@ -488,9 +510,9 @@ sub listplugins () { #{{{ } return keys %ret; -} #}}} +} -sub loadplugins () { #{{{ +sub loadplugins () { if (defined $config{libdir} && length $config{libdir}) { unshift @INC, possibly_foolish_untaint($config{libdir}); } @@ -511,15 +533,15 @@ sub loadplugins () { #{{{ run_hooks(getopt => sub { shift->() }); if (grep /^-/, @ARGV) { - print STDERR "Unknown option: $_\n" + print STDERR "Unknown option (or missing parameter): $_\n" foreach grep /^-/, @ARGV; usage(); } return 1; -} #}}} +} -sub loadplugin ($) { #{{{ +sub loadplugin ($) { my $plugin=shift; return if grep { $_ eq $plugin} @{$config{disable_plugins}}; @@ -545,9 +567,9 @@ sub loadplugin ($) { #{{{ } $loaded_plugins{$plugin}=1; return 1; -} #}}} +} -sub error ($;$) { #{{{ +sub error ($;$) { my $message=shift; my $cleaner=shift; log_message('err' => $message) if $config{syslog}; @@ -555,15 +577,15 @@ sub error ($;$) { #{{{ $cleaner->(); } die $message."\n"; -} #}}} +} -sub debug ($) { #{{{ +sub debug ($) { return unless $config{verbose}; return log_message(debug => @_); -} #}}} +} my $log_open=0; -sub log_message ($$) { #{{{ +sub log_message ($$) { my $type=shift; if ($config{syslog}) { @@ -583,56 +605,63 @@ sub log_message ($$) { #{{{ else { return print STDERR "@_\n"; } -} #}}} +} -sub possibly_foolish_untaint ($) { #{{{ +sub possibly_foolish_untaint ($) { my $tainted=shift; my ($untainted)=$tainted=~/(.*)/s; return $untainted; -} #}}} +} -sub basename ($) { #{{{ +sub basename ($) { my $file=shift; $file=~s!.*/+!!; return $file; -} #}}} +} -sub dirname ($) { #{{{ +sub dirname ($) { my $file=shift; $file=~s!/*[^/]+$!!; return $file; -} #}}} +} -sub pagetype ($) { #{{{ - my $page=shift; - - if ($page =~ /\.([^.]+)$/) { - return $1 if exists $hooks{htmlize}{$1}; - } - return; -} #}}} - -sub isinternal ($) { #{{{ +sub isinternal ($) { my $page=shift; return exists $pagesources{$page} && $pagesources{$page} =~ /\._([^.]+)$/; -} #}}} +} -sub pagename ($) { #{{{ +sub pagetype ($) { + my $file=shift; + + if ($file =~ /\.([^.]+)$/) { + return $1 if exists $hooks{htmlize}{$1}; + } + my $base=basename($file); + if (exists $hooks{htmlize}{$base} && + $hooks{htmlize}{$base}{noextension}) { + return $base; + } + return; +} + +sub pagename ($) { my $file=shift; my $type=pagetype($file); my $page=$file; - $page=~s/\Q.$type\E*$// if defined $type && !$hooks{htmlize}{$type}{keepextension}; + $page=~s/\Q.$type\E*$// + if defined $type && !$hooks{htmlize}{$type}{keepextension} + && !$hooks{htmlize}{$type}{noextension}; if ($config{indexpages} && $page=~/(.*)\/index$/) { $page=$1; } return $page; -} #}}} +} -sub newpagefile ($$) { #{{{ +sub newpagefile ($$) { my $page=shift; my $type=shift; @@ -642,27 +671,31 @@ sub newpagefile ($$) { #{{{ else { return $page."/index.".$type; } -} #}}} +} -sub targetpage ($$) { #{{{ +sub targetpage ($$;$) { my $page=shift; my $ext=shift; + my $filename=shift; - if (! $config{usedirs} || $page eq 'index') { + if (defined $filename) { + return $page."/".$filename.".".$ext; + } + elsif (! $config{usedirs} || $page eq 'index') { return $page.".".$ext; } else { return $page."/index.".$ext; } -} #}}} +} -sub htmlpage ($) { #{{{ +sub htmlpage ($) { my $page=shift; return targetpage($page, $config{htmlext}); -} #}}} +} -sub srcfile_stat { #{{{ +sub srcfile_stat { my $file=shift; my $nothrow=shift; @@ -672,26 +705,27 @@ sub srcfile_stat { #{{{ } error("internal error: $file cannot be found in $config{srcdir} or underlay") unless $nothrow; return; -} #}}} +} -sub srcfile ($;$) { #{{{ +sub srcfile ($;$) { return (srcfile_stat(@_))[0]; -} #}}} +} -sub add_underlay ($) { #{{{ +sub add_underlay ($) { my $dir=shift; - if ($dir=~/^\//) { - unshift @{$config{underlaydirs}}, $dir; + if ($dir !~ /^\//) { + $dir="$config{underlaydir}/../$dir"; } - else { - unshift @{$config{underlaydirs}}, "$config{underlaydir}/../$dir"; + + if (! grep { $_ eq $dir } @{$config{underlaydirs}}) { + unshift @{$config{underlaydirs}}, $dir; } return 1; -} #}}} +} -sub readfile ($;$$) { #{{{ +sub readfile ($;$$) { my $file=shift; my $binary=shift; my $wantfd=shift; @@ -705,11 +739,15 @@ sub readfile ($;$$) { #{{{ binmode($in) if ($binary); return \*$in if $wantfd; my $ret=<$in>; + # check for invalid utf-8, and toss it back to avoid crashes + if (! utf8::valid($ret)) { + $ret=encode_utf8($ret); + } close $in || error("failed to read $file: $!"); return $ret; -} #}}} +} -sub prep_writefile ($$) { #{{{ +sub prep_writefile ($$) { my $file=shift; my $destdir=shift; @@ -733,9 +771,9 @@ sub prep_writefile ($$) { #{{{ } return 1; -} #}}} +} -sub writefile ($$$;$$) { #{{{ +sub writefile ($$$;$$) { my $file=shift; # can include subdirs my $destdir=shift; # directory to put file in my $content=shift; @@ -763,10 +801,10 @@ sub writefile ($$$;$$) { #{{{ error("failed renaming $newfile to $destdir/$file: $!", $cleanup); return 1; -} #}}} +} my %cleared; -sub will_render ($$;$) { #{{{ +sub will_render ($$;$) { my $page=shift; my $dest=shift; my $clear=shift; @@ -790,9 +828,9 @@ sub will_render ($$;$) { #{{{ $destsources{$dest}=$page; return 1; -} #}}} +} -sub bestlink ($$) { #{{{ +sub bestlink ($$) { my $page=shift; my $link=shift; @@ -828,15 +866,15 @@ sub bestlink ($$) { #{{{ #print STDERR "warning: page $page, broken link: $link\n"; return ""; -} #}}} +} -sub isinlinableimage ($) { #{{{ +sub isinlinableimage ($) { my $file=shift; return $file =~ /\.(png|gif|jpg|jpeg)$/i; -} #}}} +} -sub pagetitle ($;$) { #{{{ +sub pagetitle ($;$) { my $page=shift; my $unescaped=shift; @@ -848,31 +886,31 @@ sub pagetitle ($;$) { #{{{ } return $page; -} #}}} +} -sub titlepage ($) { #{{{ +sub titlepage ($) { my $title=shift; # support use w/o %config set my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_"; $title=~s/([^$chars]|_)/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $title; -} #}}} +} -sub linkpage ($) { #{{{ +sub linkpage ($) { my $link=shift; my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_"; $link=~s/([^$chars])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $link; -} #}}} +} -sub cgiurl (@) { #{{{ +sub cgiurl (@) { my %params=@_; return $config{cgiurl}."?". join("&", map $_."=".uri_escape_utf8($params{$_}), keys %params); -} #}}} +} -sub baseurl (;$) { #{{{ +sub baseurl (;$) { my $page=shift; return "$config{url}/" if ! defined $page; @@ -881,9 +919,9 @@ sub baseurl (;$) { #{{{ $page=~s/[^\/]+$//; $page=~s/[^\/]+\//..\//g; return $page; -} #}}} +} -sub abs2rel ($$) { #{{{ +sub abs2rel ($$) { # Work around very innefficient behavior in File::Spec if abs2rel # is passed two relative paths. It's much faster if paths are # absolute! (Debian bug #376658; fixed in debian unstable now) @@ -894,9 +932,16 @@ sub abs2rel ($$) { #{{{ my $ret=File::Spec->abs2rel($path, $base); $ret=~s/^// if defined $ret; return $ret; -} #}}} +} -sub displaytime ($;$) { #{{{ +sub displaytime ($;$) { + # Plugins can override this function to mark up the time to + # display. + return ''.formattime(@_).''; +} + +sub formattime ($;$) { + # Plugins can override this function to format the time. my $time=shift; my $format=shift; if (! defined $format) { @@ -906,25 +951,25 @@ sub displaytime ($;$) { #{{{ # strftime doesn't know about encodings, so make sure # its output is properly treated as utf8 return decode_utf8(POSIX::strftime($format, localtime($time))); -} #}}} +} -sub beautify_urlpath ($) { #{{{ +sub beautify_urlpath ($) { my $url=shift; + # Ensure url is not an empty link, and if necessary, + # add ./ to avoid colon confusion. + if ($url !~ /^\// && $url !~ /^\.\.?\//) { + $url="./$url"; + } + if ($config{usedirs}) { $url =~ s!/index.$config{htmlext}$!/!; } - # Ensure url is not an empty link, and - # if it's relative, make that explicit to avoid colon confusion. - if ($url !~ /^\//) { - $url="./$url"; - } - return $url; -} #}}} +} -sub urlto ($$;$) { #{{{ +sub urlto ($$;$) { my $to=shift; my $from=shift; my $absolute=shift; @@ -944,9 +989,9 @@ sub urlto ($$;$) { #{{{ my $link = abs2rel($to, dirname(htmlpage($from))); return beautify_urlpath($link); -} #}}} +} -sub htmllink ($$$;@) { #{{{ +sub htmllink ($$$;@) { my $lpage=shift; # the page doing the linking my $page=shift; # the page that will contain the link (different for inline) my $link=shift; @@ -1009,9 +1054,9 @@ sub htmllink ($$$;@) { #{{{ } return "$linktext"; -} #}}} +} -sub userlink ($) { #{{{ +sub userlink ($) { my $user=shift; my $oiduser=eval { openiduser($user) }; @@ -1026,9 +1071,9 @@ sub userlink ($) { #{{{ length $config{userdir} ? $config{userdir}."/".$user : $user ), noimageinline => 1); } -} #}}} +} -sub htmlize ($$$$) { #{{{ +sub htmlize ($$$$) { my $page=shift; my $destpage=shift; my $type=shift; @@ -1063,9 +1108,9 @@ sub htmlize ($$$$) { #{{{ } return $content; -} #}}} +} -sub linkify ($$$) { #{{{ +sub linkify ($$$) { my $page=shift; my $destpage=shift; my $content=shift; @@ -1079,11 +1124,11 @@ sub linkify ($$$) { #{{{ }); return $content; -} #}}} +} our %preprocessing; our $preprocess_preview=0; -sub preprocess ($$$;$$) { #{{{ +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; @@ -1236,9 +1281,9 @@ sub preprocess ($$$;$$) { #{{{ $content =~ s{$regex}{$handle->($1, $2, $3, $4)}eg; return $content; -} #}}} +} -sub filter ($$$) { #{{{ +sub filter ($$$) { my $page=shift; my $destpage=shift; my $content=shift; @@ -1249,16 +1294,79 @@ sub filter ($$$) { #{{{ }); return $content; -} #}}} +} -sub indexlink () { #{{{ +sub indexlink () { return "$config{wikiname}"; -} #}}} +} + +sub check_canedit ($$$;$) { + my $page=shift; + my $q=shift; + my $session=shift; + my $nonfatal=shift; + + my $canedit; + run_hooks(canedit => sub { + return if defined $canedit; + my $ret=shift->($page, $q, $session); + if (defined $ret) { + if ($ret eq "") { + $canedit=1; + } + elsif (ref $ret eq 'CODE') { + $ret->() unless $nonfatal; + $canedit=0; + } + elsif (defined $ret) { + error($ret) unless $nonfatal; + $canedit=0; + } + } + }); + return defined $canedit ? $canedit : 1; +} + +sub check_content (@) { + my %params=@_; + + return 1 if ! exists $hooks{checkcontent}; # optimisation + + if (exists $pagesources{$params{page}}) { + my @diff; + my %old=map { $_ => 1 } + split("\n", readfile(srcfile($pagesources{$params{page}}))); + foreach my $line (split("\n", $params{content})) { + push @diff, $line if ! exists $old{$_}; + } + $params{content}=join("\n", @diff); + } + + my $ok; + run_hooks(checkcontent => sub { + return if defined $ok; + my $ret=shift->(%params); + if (defined $ret) { + if ($ret eq "") { + $ok=1; + } + elsif (ref $ret eq 'CODE') { + $ret->() unless $params{nonfatal}; + $ok=0; + } + elsif (defined $ret) { + error($ret) unless $params{nonfatal}; + $ok=0; + } + } + + }); + return defined $ok ? $ok : 1; +} my $wikilock; -sub lockwiki (;$) { #{{{ - my $wait=@_ ? shift : 1; +sub lockwiki () { # Take an exclusive lock on the wiki to prevent multiple concurrent # run issues. The lock will be dropped on program exit. if (! -d $config{wikistatedir}) { @@ -1266,32 +1374,21 @@ sub lockwiki (;$) { #{{{ } open($wikilock, '>', "$config{wikistatedir}/lockfile") || error ("cannot write to $config{wikistatedir}/lockfile: $!"); - if (! flock($wikilock, 2 | 4)) { # LOCK_EX | LOCK_NB - if ($wait) { - debug("wiki seems to be locked, waiting for lock"); - my $wait=600; # arbitrary, but don't hang forever to - # prevent process pileup - for (1..$wait) { - return if flock($wikilock, 2 | 4); - sleep 1; - } - error("wiki is locked; waited $wait seconds without lock being freed (possible stuck process or stale lock?)"); - } - else { - return 0; - } + if (! flock($wikilock, 2)) { # LOCK_EX + error("failed to get lock"); } return 1; -} #}}} +} -sub unlockwiki () { #{{{ +sub unlockwiki () { + POSIX::close($ENV{IKIWIKI_CGILOCK_FD}) if exists $ENV{IKIWIKI_CGILOCK_FD}; return close($wikilock) if $wikilock; return; -} #}}} +} my $commitlock; -sub commit_hook_enabled () { #{{{ +sub commit_hook_enabled () { open($commitlock, '+>', "$config{wikistatedir}/commitlock") || error("cannot write to $config{wikistatedir}/commitlock: $!"); if (! flock($commitlock, 1 | 4)) { # LOCK_SH | LOCK_NB to test @@ -1300,23 +1397,23 @@ sub commit_hook_enabled () { #{{{ } close($commitlock) || error("failed closing commitlock: $!"); return 1; -} #}}} +} -sub disable_commit_hook () { #{{{ +sub disable_commit_hook () { open($commitlock, '>', "$config{wikistatedir}/commitlock") || error("cannot write to $config{wikistatedir}/commitlock: $!"); if (! flock($commitlock, 2)) { # LOCK_EX error("failed to get commit lock"); } return 1; -} #}}} +} -sub enable_commit_hook () { #{{{ +sub enable_commit_hook () { return close($commitlock) if $commitlock; return; -} #}}} +} -sub loadindex () { #{{{ +sub loadindex () { %oldrenderedfiles=%pagectime=(); if (! $config{rebuild}) { %pagesources=%pagemtime=%oldlinks=%links=%depends= @@ -1376,9 +1473,9 @@ sub loadindex () { #{{{ $destsources{$_}=$page foreach @{$renderedfiles{$page}}; } return close($in); -} #}}} +} -sub saveindex () { #{{{ +sub saveindex () { run_hooks(savestate => sub { shift->() }); my %hookids; @@ -1434,18 +1531,18 @@ sub saveindex () { #{{{ error("failed renaming $newfile to $config{wikistatedir}/indexdb", $cleanup); return 1; -} #}}} +} -sub template_file ($) { #{{{ +sub template_file ($) { my $template=shift; foreach my $dir ($config{templatedir}, "$installdir/share/ikiwiki/templates") { return "$dir/$template" if -e "$dir/$template"; } return; -} #}}} +} -sub template_params (@) { #{{{ +sub template_params (@) { my $filename=template_file(shift); if (! defined $filename) { @@ -1464,14 +1561,14 @@ sub template_params (@) { #{{{ @_ ); return wantarray ? @ret : {@ret}; -} #}}} +} -sub template ($;@) { #{{{ +sub template ($;@) { require HTML::Template; return HTML::Template->new(template_params(@_)); -} #}}} +} -sub misctemplate ($$;@) { #{{{ +sub misctemplate ($$;@) { my $title=shift; my $pagebody=shift; @@ -1488,9 +1585,9 @@ sub misctemplate ($$;@) { #{{{ shift->(page => "", destpage => "", template => $template); }); return $template->output; -}#}}} +} -sub hook (@) { # {{{ +sub hook (@) { my %param=@_; if (! exists $param{type} || ! ref $param{call} || ! exists $param{id}) { @@ -1501,109 +1598,86 @@ sub hook (@) { # {{{ $hooks{$param{type}}{$param{id}}=\%param; return 1; -} # }}} +} -sub run_hooks ($$) { # {{{ +sub run_hooks ($$) { # Calls the given sub for each hook of the given type, # passing it the hook function to call. my $type=shift; my $sub=shift; if (exists $hooks{$type}) { - my @deferred; + my (@first, @middle, @last); foreach my $id (keys %{$hooks{$type}}) { - if ($hooks{$type}{$id}{last}) { - push @deferred, $id; - next; + if ($hooks{$type}{$id}{first}) { + push @first, $id; + } + elsif ($hooks{$type}{$id}{last}) { + push @last, $id; + } + else { + push @middle, $id; } - $sub->($hooks{$type}{$id}{call}); } - foreach my $id (@deferred) { + foreach my $id (@first, @middle, @last) { $sub->($hooks{$type}{$id}{call}); } } return 1; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { $hooks{rcs}{rcs_update}{call}->(@_); -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { $hooks{rcs}{rcs_prepedit}{call}->(@_); -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { $hooks{rcs}{rcs_commit}{call}->(@_); -} #}}} +} -sub rcs_commit_staged ($$$) { #{{{ +sub rcs_commit_staged ($$$) { $hooks{rcs}{rcs_commit_staged}{call}->(@_); -} #}}} +} -sub rcs_add ($) { #{{{ +sub rcs_add ($) { $hooks{rcs}{rcs_add}{call}->(@_); -} #}}} +} -sub rcs_remove ($) { #{{{ +sub rcs_remove ($) { $hooks{rcs}{rcs_remove}{call}->(@_); -} #}}} +} -sub rcs_rename ($$) { #{{{ +sub rcs_rename ($$) { $hooks{rcs}{rcs_rename}{call}->(@_); -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { $hooks{rcs}{rcs_recentchanges}{call}->(@_); -} #}}} +} -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { $hooks{rcs}{rcs_diff}{call}->(@_); -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { $hooks{rcs}{rcs_getctime}{call}->(@_); -} #}}} +} -sub globlist_to_pagespec ($) { #{{{ - my @globlist=split(' ', shift); +sub rcs_receive () { + $hooks{rcs}{rcs_receive}{call}->(); +} - my (@spec, @skip); - foreach my $glob (@globlist) { - if ($glob=~/^!(.*)/) { - push @skip, $glob; - } - else { - push @spec, $glob; - } - } - - my $spec=join(' or ', @spec); - if (@skip) { - my $skip=join(' and ', @skip); - if (length $spec) { - $spec="$skip and ($spec)"; - } - else { - $spec=$skip; - } - } - return $spec; -} #}}} - -sub is_globlist ($) { #{{{ - my $s=shift; - return ( $s =~ /[^\s]+\s+([^\s]+)/ && $1 ne "and" && $1 ne "or" ); -} #}}} - -sub safequote ($) { #{{{ +sub safequote ($) { my $s=shift; $s=~s/[{}]//g; return "q{$s}"; -} #}}} +} -sub add_depends ($$) { #{{{ +sub add_depends ($$) { my $page=shift; my $pagespec=shift; @@ -1617,9 +1691,9 @@ sub add_depends ($$) { #{{{ } return 1; -} # }}} +} -sub file_pruned ($$) { #{{{ +sub file_pruned ($$) { require File::Spec; my $file=File::Spec->canonpath(shift); my $base=File::Spec->canonpath(shift); @@ -1627,9 +1701,9 @@ sub file_pruned ($$) { #{{{ my $regexp='('.join('|', @{$config{wiki_file_prune_regexps}}).')'; return $file =~ m/$regexp/ && $file ne $base; -} #}}} +} -sub gettext { #{{{ +sub gettext { # Only use gettext in the rare cases it's needed. if ((exists $ENV{LANG} && length $ENV{LANG}) || (exists $ENV{LC_ALL} && length $ENV{LC_ALL}) || @@ -1650,39 +1724,50 @@ sub gettext { #{{{ else { return shift; } -} #}}} +} -sub yesno ($) { #{{{ +sub yesno ($) { my $val=shift; - return (defined $val && lc($val) eq gettext("yes")); -} #}}} + return (defined $val && (lc($val) eq gettext("yes") || lc($val) eq "yes" || $val eq "1")); +} -sub pagespec_merge ($$) { #{{{ +sub inject { + # Injects a new function into the symbol table to replace an + # exported function. + my %params=@_; + + # This is deep ugly perl foo, beware. + no strict; + no warnings; + if (! defined $params{parent}) { + $params{parent}='::'; + $params{old}=\&{$params{name}}; + $params{name}=~s/.*:://; + } + my $parent=$params{parent}; + foreach my $ns (grep /^\w+::/, keys %{$parent}) { + $ns = $params{parent} . $ns; + inject(%params, parent => $ns) unless $ns eq '::main::'; + *{$ns . $params{name}} = $params{call} + if exists ${$ns}{$params{name}} && + \&{${$ns}{$params{name}}} == $params{old}; + } + use strict; + use warnings; +} + +sub pagespec_merge ($$) { my $a=shift; my $b=shift; return $a if $a eq $b; - - # Support for old-style GlobLists. - if (is_globlist($a)) { - $a=globlist_to_pagespec($a); - } - if (is_globlist($b)) { - $b=globlist_to_pagespec($b); - } - return "($a) or ($b)"; -} #}}} +} -sub pagespec_translate ($) { #{{{ +sub pagespec_translate ($) { my $spec=shift; - # Support for old-style GlobLists. - if (is_globlist($spec)) { - $spec=globlist_to_pagespec($spec); - } - # Convert spec to perl code. my $code=""; while ($spec=~m{ @@ -1715,7 +1800,7 @@ sub pagespec_translate ($) { #{{{ $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@_)"; } else { - $code.=' 0'; + $code.="IkiWiki::FailReason->new(".safequote(qq{unknown function in pagespec "$word"}).")"; } } else { @@ -1724,14 +1809,14 @@ sub pagespec_translate ($) { #{{{ } if (! length $code) { - $code=0; + $code="IkiWiki::FailReason->new('empty pagespec')"; } no warnings; return eval 'sub { my $page=shift; '.$code.' }'; -} #}}} +} -sub pagespec_match ($$;@) { #{{{ +sub pagespec_match ($$;@) { my $page=shift; my $spec=shift; my @params=@_; @@ -1742,69 +1827,76 @@ sub pagespec_match ($$;@) { #{{{ } my $sub=pagespec_translate($spec); - return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") if $@; + return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") + if $@ || ! defined $sub; return $sub->($page, @params); -} #}}} +} -sub pagespec_valid ($) { #{{{ +sub pagespec_valid ($) { my $spec=shift; my $sub=pagespec_translate($spec); return ! $@; -} #}}} - -sub glob2re ($) { #{{{ +} + +sub glob2re ($) { my $re=quotemeta(shift); $re=~s/\\\*/.*/g; $re=~s/\\\?/./g; return $re; -} #}}} +} package IkiWiki::FailReason; -use overload ( #{{{ +use overload ( '""' => sub { ${$_[0]} }, '0+' => sub { 0 }, '!' => sub { bless $_[0], 'IkiWiki::SuccessReason'}, fallback => 1, -); #}}} +); -sub new { #{{{ +sub new { my $class = shift; my $value = shift; return bless \$value, $class; -} #}}} +} package IkiWiki::SuccessReason; -use overload ( #{{{ +use overload ( '""' => sub { ${$_[0]} }, '0+' => sub { 1 }, '!' => sub { bless $_[0], 'IkiWiki::FailReason'}, fallback => 1, -); #}}} +); -sub new { #{{{ +sub new { my $class = shift; my $value = shift; return bless \$value, $class; -}; #}}} +}; package IkiWiki::PageSpec; -sub match_glob ($$;@) { #{{{ +sub derel ($$) { + my $path=shift; + my $from=shift; + + if ($path =~ m!^\./!) { + $from=~s#/?[^/]+$## if defined $from; + $path=~s#^\./##; + $path="$from/$path" if length $from; + } + + return $path; +} + +sub match_glob ($$;@) { my $page=shift; my $glob=shift; my %params=@_; - my $from=exists $params{location} ? $params{location} : ''; - - # relative matching - if ($glob =~ m!^\./!) { - $from=~s#/?[^/]+$##; - $glob=~s#^\./##; - $glob="$from/$glob" if length $from; - } + $glob=derel($glob, $params{location}); my $regexp=IkiWiki::glob2re($glob); if ($page=~/^$regexp$/i) { @@ -1818,26 +1910,20 @@ sub match_glob ($$;@) { #{{{ else { return IkiWiki::FailReason->new("$glob does not match $page"); } -} #}}} +} -sub match_internal ($$;@) { #{{{ +sub match_internal ($$;@) { return match_glob($_[0], $_[1], @_, internal => 1) -} #}}} +} -sub match_link ($$;@) { #{{{ +sub match_link ($$;@) { my $page=shift; my $link=lc(shift); my %params=@_; + $link=derel($link, $params{location}); my $from=exists $params{location} ? $params{location} : ''; - # relative matching - if ($link =~ m!^\.! && defined $from) { - $from=~s#/?[^/]+$##; - $link=~s#^\./##; - $link="$from/$link" if length $from; - } - my $links = $IkiWiki::links{$page}; return IkiWiki::FailReason->new("$page has no links") unless $links && @{$links}; my $bestlink = IkiWiki::bestlink($from, $link); @@ -1849,18 +1935,25 @@ sub match_link ($$;@) { #{{{ else { return IkiWiki::SuccessReason->new("$page links to page $p matching $link") if match_glob($p, $link, %params); + $p=~s/^\///; + $link=~s/^\///; + return IkiWiki::SuccessReason->new("$page links to page $p matching $link") + if match_glob($p, $link, %params); } } return IkiWiki::FailReason->new("$page does not link to $link"); -} #}}} +} -sub match_backlink ($$;@) { #{{{ +sub match_backlink ($$;@) { return match_link($_[1], $_[0], @_); -} #}}} +} -sub match_created_before ($$;@) { #{{{ +sub match_created_before ($$;@) { my $page=shift; my $testpage=shift; + my %params=@_; + + $testpage=derel($testpage, $params{location}); if (exists $IkiWiki::pagectime{$testpage}) { if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) { @@ -1873,11 +1966,14 @@ sub match_created_before ($$;@) { #{{{ else { return IkiWiki::FailReason->new("$testpage has no ctime"); } -} #}}} +} -sub match_created_after ($$;@) { #{{{ +sub match_created_after ($$;@) { my $page=shift; my $testpage=shift; + my %params=@_; + + $testpage=derel($testpage, $params{location}); if (exists $IkiWiki::pagectime{$testpage}) { if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) { @@ -1890,36 +1986,36 @@ sub match_created_after ($$;@) { #{{{ else { return IkiWiki::FailReason->new("$testpage has no ctime"); } -} #}}} +} -sub match_creation_day ($$;@) { #{{{ +sub match_creation_day ($$;@) { if ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift) { return IkiWiki::SuccessReason->new('creation_day matched'); } else { return IkiWiki::FailReason->new('creation_day did not match'); } -} #}}} +} -sub match_creation_month ($$;@) { #{{{ +sub match_creation_month ($$;@) { if ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift) { return IkiWiki::SuccessReason->new('creation_month matched'); } else { return IkiWiki::FailReason->new('creation_month did not match'); } -} #}}} +} -sub match_creation_year ($$;@) { #{{{ +sub match_creation_year ($$;@) { if ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) { return IkiWiki::SuccessReason->new('creation_year matched'); } else { return IkiWiki::FailReason->new('creation_year did not match'); } -} #}}} +} -sub match_user ($$;@) { #{{{ +sub match_user ($$;@) { shift; my $user=shift; my %params=@_; @@ -1937,9 +2033,9 @@ sub match_user ($$;@) { #{{{ else { return IkiWiki::FailReason->new("user is $params{user}, not $user"); } -} #}}} +} -sub match_admin ($$;@) { #{{{ +sub match_admin ($$;@) { shift; shift; my %params=@_; @@ -1957,9 +2053,9 @@ sub match_admin ($$;@) { #{{{ else { return IkiWiki::FailReason->new("user is not an admin"); } -} #}}} +} -sub match_ip ($$;@) { #{{{ +sub match_ip ($$;@) { shift; my $ip=shift; my %params=@_; @@ -1974,6 +2070,6 @@ sub match_ip ($$;@) { #{{{ else { return IkiWiki::FailReason->new("IP is $params{ip}, not $ip"); } -} #}}} +} 1 diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm index dac522eea..04f24b04f 100644 --- a/IkiWiki/CGI.pm +++ b/IkiWiki/CGI.pm @@ -9,7 +9,7 @@ use IkiWiki::UserInfo; use open qw{:utf8 :std}; use Encode; -sub printheader ($) { #{{{ +sub printheader ($) { my $session=shift; if ($config{sslcookie}) { @@ -19,9 +19,9 @@ sub printheader ($) { #{{{ print $session->header(-charset => 'utf-8', -cookie => $session->cookie(-httponly => 1)); } -} #}}} +} -sub showform ($$$$;@) { #{{{ +sub showform ($$$$;@) { my $form=shift; my $buttons=shift; my $session=shift; @@ -38,7 +38,7 @@ sub showform ($$$$;@) { #{{{ print misctemplate($form->title, $form->render(submit => $buttons), @_); } -sub redirect ($$) { #{{{ +sub redirect ($$) { my $q=shift; my $url=shift; if (! $config{w3mmode}) { @@ -48,9 +48,9 @@ sub redirect ($$) { #{{{ print "Content-type: text/plain\n"; print "W3m-control: GOTO $url\n\n"; } -} #}}} +} -sub decode_cgi_utf8 ($) { #{{{ +sub decode_cgi_utf8 ($) { # decode_form_utf8 method is needed for 5.10 if ($] < 5.01) { my $cgi = shift; @@ -58,9 +58,9 @@ sub decode_cgi_utf8 ($) { #{{{ $cgi->param($f, map { decode_utf8 $_ } $cgi->param($f)); } } -} #}}} +} -sub decode_form_utf8 ($) { #{{{ +sub decode_form_utf8 ($) { if ($] >= 5.01) { my $form = shift; foreach my $f ($form->field) { @@ -70,11 +70,11 @@ sub decode_form_utf8 ($) { #{{{ ); } } -} #}}} +} # Check if the user is signed in. If not, redirect to the signin form and # save their place to return to later. -sub needsignin ($$) { #{{{ +sub needsignin ($$) { my $q=shift; my $session=shift; @@ -85,9 +85,9 @@ sub needsignin ($$) { #{{{ cgi_savesession($session); exit; } -} #}}} +} -sub cgi_signin ($$) { #{{{ +sub cgi_signin ($$) { my $q=shift; my $session=shift; @@ -127,9 +127,9 @@ sub cgi_signin ($$) { #{{{ } showform($form, $buttons, $session, $q); -} #}}} +} -sub cgi_postsignin ($$) { #{{{ +sub cgi_postsignin ($$) { my $q=shift; my $session=shift; @@ -142,11 +142,16 @@ sub cgi_postsignin ($$) { #{{{ exit; } else { - error(gettext("login failed, perhaps you need to turn on cookies?")); + if ($config{sslcookie} && ! $q->https()) { + error(gettext("probable misconfiguration: sslcookie is set, but you are attepting to login via http, not https")); + } + else { + error(gettext("login failed, perhaps you need to turn on cookies?")); + } } -} #}}} +} -sub cgi_prefs ($$) { #{{{ +sub cgi_prefs ($$) { my $q=shift; my $session=shift; @@ -203,25 +208,9 @@ sub cgi_prefs ($$) { #{{{ my $user_name=$session->param("name"); - # XXX deprecated, should be removed eventually - $form->field(name => "banned_users", size => 50, fieldset => "admin"); - if (! is_admin($user_name)) { - $form->field(name => "banned_users", type => "hidden"); - } if (! $form->submitted) { $form->field(name => "email", force => 1, value => userinfo_get($user_name, "email")); - if (is_admin($user_name)) { - my $value=join(" ", get_banned_users()); - if (length $value) { - $form->field(name => "banned_users", force => 1, - value => join(" ", get_banned_users()), - comment => "deprecated; please move to banned_users in setup file"); - } - else { - $form->field(name => "banned_users", type => "hidden"); - } - } } if ($form->submitted eq 'Logout') { @@ -239,48 +228,48 @@ sub cgi_prefs ($$) { #{{{ error("failed to set email"); } - # XXX deprecated, should be removed eventually - if (is_admin($user_name)) { - set_banned_users(grep { ! is_admin($_) } - split(' ', - $form->field("banned_users"))) || - error("failed saving changes"); - if (! length $form->field("banned_users")) { - $form->field(name => "banned_users", type => "hidden"); - } - } - $form->text(gettext("Preferences saved.")); } showform($form, $buttons, $session, $q); -} #}}} +} -sub check_banned ($$) { #{{{ +sub cgi_custom_failure ($$) { + my $header=shift; + my $message=shift; + + print $header; + print $message; + + # Internet Explod^Hrer won't show custom 404 responses + # unless they're >= 512 bytes + print ' ' x 512; + + exit; +} + +sub check_banned ($$) { my $q=shift; my $session=shift; my $name=$session->param("name"); if (defined $name) { - # XXX banned in userinfo is deprecated, should be removed - # eventually, and only banned_users be checked. - if (userinfo_get($session->param("name"), "banned") || - grep { $name eq $_ } @{$config{banned_users}}) { - print $q->header(-status => "403 Forbidden"); + if (grep { $name eq $_ } @{$config{banned_users}}) { $session->delete(); - print gettext("You are banned."); cgi_savesession($session); - exit; + cgi_custom_failure( + $q->header(-status => "403 Forbidden"), + gettext("You are banned.")); } } } -sub cgi_getsession ($) { #{{{ +sub cgi_getsession ($) { my $q=shift; - eval q{use CGI::Session}; + eval q{use CGI::Session; use HTML::Entities}; error($@) if $@; - CGI::Session->name("ikiwiki_session_".encode_utf8($config{wikiname})); + CGI::Session->name("ikiwiki_session_".encode_entities($config{wikiname})); my $oldmask=umask(077); my $session = eval { @@ -294,18 +283,34 @@ sub cgi_getsession ($) { #{{{ umask($oldmask); return $session; -} #}}} +} -sub cgi_savesession ($) { #{{{ +# To guard against CSRF, the user's session id (sid) +# can be stored on a form. This function will check +# (for logged in users) that the sid on the form matches +# the session id in the cookie. +sub checksessionexpiry ($$) { + my $q=shift; + my $session = shift; + + if (defined $session->param("name")) { + my $sid=$q->param('sid'); + if (! defined $sid || $sid ne $session->id) { + error(gettext("Your login session has expired.")); + } + } +} + +sub cgi_savesession ($) { my $session=shift; # Force session flush with safe umask. my $oldmask=umask(077); $session->flush; umask($oldmask); -} #}}} +} -sub cgi (;$$) { #{{{ +sub cgi (;$$) { my $q=shift; my $session=shift; @@ -331,7 +336,7 @@ sub cgi (;$$) { #{{{ error("\"do\" parameter missing"); } } - + # Need to lock the wiki before getting a session. lockwiki(); loadindex(); @@ -375,16 +380,16 @@ sub cgi (;$$) { #{{{ else { error("unknown do parameter"); } -} #}}} +} # Does not need to be called directly; all errors will go through here. -sub cgierror ($) { #{{{ +sub cgierror ($) { my $message=shift; print "Content-type: text/html\n\n"; print misctemplate(gettext("Error"), "

".gettext("Error").": $message

"); die $@; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/404.pm b/IkiWiki/Plugin/404.pm new file mode 100644 index 000000000..bae9e15d1 --- /dev/null +++ b/IkiWiki/Plugin/404.pm @@ -0,0 +1,78 @@ +#!/usr/bin/perl +# Copyright © 2009 Simon McVittie +# Licensed under the GNU GPL, version 2, or any later version published by the +# Free Software Foundation +package IkiWiki::Plugin::404; + +use warnings; +use strict; +use IkiWiki 3.00; + +sub import { + hook(type => "cgi", id => '404', call => \&cgi); + IkiWiki::loadplugin("goto"); +} + +sub getsetup () { + return + plugin => { + # not really a matter of safety, but enabling/disabling + # through a web interface is useless - it needs web + # server admin action too + safe => 0, + rebuild => 0, + } +} + +sub cgi_page_from_404 ($$$) { + my $path = shift; + my $baseurl = shift; + my $usedirs = shift; + + # fail if missing from environment or whatever + return undef unless defined $path; + return undef unless defined $baseurl; + + # with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or + # /~fred/foo/bar/index.html + # with usedirs off, path is like /~fred/foo/bar.html + # baseurl is like 'http://people.example.com/~fred' + + # convert baseurl to ~fred + unless ($baseurl =~ s{^https?://[^/]+/?}{}) { + return undef; + } + + # convert path to /~fred/foo/bar + if ($usedirs) { + $path =~ s/\/*(?:index\.$config{htmlext})?$//; + } + else { + $path =~ s/\.$config{htmlext}$//; + } + + # remove /~fred/ + unless ($path =~ s{^/*\Q$baseurl\E/*}{}) { + return undef; + } + + # special case for the index + unless ($path) { + return 'index'; + } + + return $path; +} + +sub cgi ($) { + my $cgi=shift; + + if (exists $ENV{REDIRECT_STATUS} && + $ENV{REDIRECT_STATUS} eq '404') { + my $page = cgi_page_from_404($ENV{REDIRECT_URL}, + $config{url}, $config{usedirs}); + IkiWiki::Plugin::goto::cgi_goto($cgi, $page); + } +} + +1; diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm index 26c5cc9ae..e1baae666 100644 --- a/IkiWiki/Plugin/aggregate.pm +++ b/IkiWiki/Plugin/aggregate.pm @@ -4,7 +4,7 @@ package IkiWiki::Plugin::aggregate; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Parser; use HTML::Tagset; use HTML::Entities; @@ -14,7 +14,7 @@ use open qw{:utf8 :std}; my %feeds; my %guids; -sub import { #{{{ +sub import { hook(type => "getopt", id => "aggregate", call => \&getopt); hook(type => "getsetup", id => "aggregate", call => \&getsetup); hook(type => "checkconfig", id => "aggregate", call => \&checkconfig); @@ -26,9 +26,9 @@ sub import { #{{{ if (exists $config{aggregate_webtrigger} && $config{aggregate_webtrigger}) { hook(type => "cgi", id => "aggregate", call => \&cgi); } -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); @@ -36,9 +36,9 @@ sub getopt () { #{{{ "aggregate" => \$config{aggregate}, "aggregateinternal!" => \$config{aggregateinternal}, ); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -46,7 +46,7 @@ sub getsetup () { #{{{ }, aggregateinternal => { type => "boolean", - example => 0, + example => 1, description => "enable aggregation to internal pages?", safe => 0, # enabling needs manual transition rebuild => 0, @@ -58,16 +58,20 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} + +sub checkconfig () { + if (! defined $config{aggregateinternal}) { + $config{aggregateinternal}=1; + } -sub checkconfig () { #{{{ if ($config{aggregate} && ! ($config{post_commit} && IkiWiki::commit_hook_enabled())) { launchaggregation(); } -} #}}} +} -sub cgi ($) { #{{{ +sub cgi ($) { my $cgi=shift; if (defined $cgi->param('do') && @@ -90,9 +94,9 @@ sub cgi ($) { #{{{ } exit 0; } -} #}}} +} -sub launchaggregation () { #{{{ +sub launchaggregation () { # See if any feeds need aggregation. loadstate(); my @feeds=needsaggregate(); @@ -135,16 +139,16 @@ sub launchaggregation () { #{{{ unlockaggregate(); return 1; -} #}}} +} # Pages with extension _aggregated have plain html markup, pass through. -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; return $params{content}; -} #}}} +} # Used by ikiwiki-transition aggregateinternal. -sub migrate_to_internal { #{{{ +sub migrate_to_internal { if (! lockaggregate()) { error("an aggregation process is currently running"); } @@ -190,9 +194,9 @@ sub migrate_to_internal { #{{{ IkiWiki::unlockwiki; unlockaggregate(); -} #}}} +} -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; loadstate(); @@ -206,9 +210,9 @@ sub needsbuild (@) { #{{{ markunseen($feed->{sourcepage}); } } -} # }}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; foreach my $required (qw{name url}) { @@ -245,6 +249,7 @@ sub preprocess (@) { #{{{ $feed->{template}=$params{template} . ".tmpl"; delete $feed->{unseen}; $feed->{lastupdate}=0 unless defined $feed->{lastupdate}; + $feed->{lasttry}=$feed->{lastupdate} unless defined $feed->{lasttry}; $feed->{numposts}=0 unless defined $feed->{numposts}; $feed->{newposts}=0 unless defined $feed->{newposts}; $feed->{message}=gettext("new feed") unless defined $feed->{message}; @@ -265,9 +270,9 @@ sub preprocess (@) { #{{{ ($feed->{newposts} ? "; ".$feed->{newposts}. " ".gettext("new") : ""). ")"; -} # }}} +} -sub delete (@) { #{{{ +sub delete (@) { my @files=@_; # Remove feed data for removed pages. @@ -275,9 +280,9 @@ sub delete (@) { #{{{ my $page=pagename($file); markunseen($page); } -} #}}} +} -sub markunseen ($) { #{{{ +sub markunseen ($) { my $page=shift; foreach my $id (keys %feeds) { @@ -285,11 +290,11 @@ sub markunseen ($) { #{{{ $feeds{$id}->{unseen}=1; } } -} #}}} +} my $state_loaded=0; -sub loadstate () { #{{{ +sub loadstate () { return if $state_loaded; $state_loaded=1; if (-e "$config{wikistatedir}/aggregate") { @@ -323,9 +328,9 @@ sub loadstate () { #{{{ close IN; } -} #}}} +} -sub savestate () { #{{{ +sub savestate () { return unless $state_loaded; garbage_collect(); my $newfile="$config{wikistatedir}/aggregate.new"; @@ -342,7 +347,8 @@ sub savestate () { #{{{ push @line, "tag=$_" foreach @{$data->{tags}}; } else { - push @line, "$field=".$data->{$field}; + push @line, "$field=".$data->{$field} + if defined $data->{$field}; } } print OUT join(" ", @line)."\n" || error("write $newfile: $!", $cleanup); @@ -350,9 +356,9 @@ sub savestate () { #{{{ close OUT || error("save $newfile: $!", $cleanup); rename($newfile, "$config{wikistatedir}/aggregate") || error("rename $newfile: $!", $cleanup); -} #}}} +} -sub garbage_collect () { #{{{ +sub garbage_collect () { foreach my $name (keys %feeds) { # remove any feeds that were not seen while building the pages # that used to contain them @@ -375,9 +381,9 @@ sub garbage_collect () { #{{{ delete $guid->{md5}; } } -} #}}} +} -sub mergestate () { #{{{ +sub mergestate () { # Load the current state in from disk, and merge into it # values from the state in memory that might have changed # during aggregation. @@ -390,8 +396,8 @@ sub mergestate () { #{{{ # fields. foreach my $name (keys %myfeeds) { if (exists $feeds{$name}) { - foreach my $field (qw{message lastupdate numposts - newposts error}) { + foreach my $field (qw{message lastupdate lasttry + numposts newposts error}) { $feeds{$name}->{$field}=$myfeeds{$name}->{$field}; } } @@ -407,15 +413,15 @@ sub mergestate () { #{{{ $guids{$guid}=$myguids{$guid}; } } -} #}}} +} -sub clearstate () { #{{{ +sub clearstate () { %feeds=(); %guids=(); $state_loaded=0; -} #}}} +} -sub expire () { #{{{ +sub expire () { foreach my $feed (values %feeds) { next unless $feed->{expireage} || $feed->{expirecount}; my $count=0; @@ -444,24 +450,24 @@ sub expire () { #{{{ } } } -} #}}} +} -sub needsaggregate () { #{{{ +sub needsaggregate () { return values %feeds if $config{rebuild}; return grep { time - $_->{lastupdate} >= $_->{updateinterval} } values %feeds; -} #}}} +} -sub aggregate (@) { #{{{ +sub aggregate (@) { eval q{use XML::Feed}; error($@) if $@; eval q{use URI::Fetch}; error($@) if $@; foreach my $feed (@_) { - $feed->{lastupdate}=time; + $feed->{lasttry}=time; $feed->{newposts}=0; - $feed->{message}=sprintf(gettext("processed ok at %s"), - displaytime($feed->{lastupdate})); + $feed->{message}=sprintf(gettext("last checked %s"), + displaytime($feed->{lasttry})); $feed->{error}=0; debug(sprintf(gettext("checking feed %s ..."), $feed->{name})); @@ -483,6 +489,10 @@ sub aggregate (@) { #{{{ debug($feed->{message}); next; } + + # lastupdate is only set if we were able to contact the server + $feed->{lastupdate}=$feed->{lasttry}; + if ($res->status == URI::Fetch::URI_GONE()) { $feed->{message}=gettext("feed not found"); $feed->{error}=1; @@ -496,15 +506,19 @@ sub aggregate (@) { #{{{ # that contains invalid UTF-8 sequences. Convert # feed to ascii to try to work around. $feed->{message}.=" ".sprintf(gettext("(invalid UTF-8 stripped from feed)")); - $content=Encode::decode_utf8($content, 0); - $f=eval{XML::Feed->parse(\$content)}; + $f=eval { + $content=Encode::decode_utf8($content, 0); + XML::Feed->parse(\$content) + }; } if ($@) { # Another possibility is badly escaped entities. $feed->{message}.=" ".sprintf(gettext("(feed entities escaped)")); $content=~s/\&(?!amp)(\w+);/&$1;/g; - $content=Encode::decode_utf8($content, 0); - $f=eval{XML::Feed->parse(\$content)}; + $f=eval { + $content=Encode::decode_utf8($content, 0); + XML::Feed->parse(\$content) + }; } if ($@) { $feed->{message}=gettext("feed crashed XML::Feed!")." ($@)"; @@ -520,10 +534,15 @@ sub aggregate (@) { #{{{ } foreach my $entry ($f->entries) { - my $content=$content=$entry->content->body; + # XML::Feed doesn't work around XML::Atom's bizarre + # API, so we will. Real unicode strings? Yes please. + # See [[bugs/Aggregated_Atom_feeds_are_double-encoded]] + local $XML::Atom::ForceUnicode = 1; + + my $c=$entry->content; # atom feeds may have no content, only a summary - if (! defined $content && ref $entry->summary) { - $content=$entry->summary->body; + if (! defined $c && ref $entry->summary) { + $c=$entry->summary; } add_page( @@ -531,15 +550,16 @@ sub aggregate (@) { #{{{ copyright => $f->copyright, title => defined $entry->title ? decode_entities($entry->title) : "untitled", link => $entry->link, - content => defined $content ? $content : "", + content => (defined $c && defined $c->body) ? $c->body : "", guid => defined $entry->id ? $entry->id : time."_".$feed->{name}, ctime => $entry->issued ? ($entry->issued->epoch || time) : time, + base => (defined $c && $c->can("base")) ? $c->base : undef, ); } } -} #}}} +} -sub add_page (@) { #{{{ +sub add_page (@) { my %params=@_; my $feed=$params{feed}; @@ -605,7 +625,8 @@ sub add_page (@) { #{{{ my $template=template($feed->{template}, blind_cache => 1); $template->param(title => $params{title}) if defined $params{title} && length($params{title}); - $template->param(content => htmlescape(htmlabs($params{content}, $feed->{feedurl}))); + $template->param(content => wikiescape(htmlabs($params{content}, + defined $params{base} ? $params{base} : $feed->{feedurl}))); $template->param(name => $feed->{name}); $template->param(url => $feed->{url}); $template->param(copyright => $params{copyright}) @@ -625,23 +646,25 @@ sub add_page (@) { #{{{ # Store it in pagectime for expiry code to use also. $IkiWiki::pagectime{$guid->{page}}=$mtime; } -} #}}} + else { + # Dummy value for expiry code. + $IkiWiki::pagectime{$guid->{page}}=time; + } +} -sub htmlescape ($) { #{{{ +sub wikiescape ($) { # escape accidental wikilinks and preprocessor stuff - my $html=shift; - $html=~s/(?new_abs($url, $urlbase)->as_string; -} #}}} +} -sub htmlabs ($$) { #{{{ +sub htmlabs ($$) { # Convert links in html from relative to absolute. # Note that this is a heuristic, which is not specified by the rss # spec and may not be right for all feeds. Also, see Debian @@ -677,15 +700,15 @@ sub htmlabs ($$) { #{{{ $p->eof; return $ret; -} #}}} +} -sub htmlfn ($) { #{{{ +sub htmlfn ($) { return shift().".".($config{aggregateinternal} ? "_aggregated" : $config{htmlext}); -} #}}} +} my $aggregatelock; -sub lockaggregate () { #{{{ +sub lockaggregate () { # Take an exclusive lock to prevent multiple concurrent aggregators. # Returns true if the lock was aquired. if (! -d $config{wikistatedir}) { @@ -698,11 +721,11 @@ sub lockaggregate () { #{{{ return 0; } return 1; -} #}}} +} -sub unlockaggregate () { #{{{ +sub unlockaggregate () { return close($aggregatelock) if $aggregatelock; return; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/amazon_s3.pm b/IkiWiki/Plugin/amazon_s3.pm index 597539c13..10bf358e4 100644 --- a/IkiWiki/Plugin/amazon_s3.pm +++ b/IkiWiki/Plugin/amazon_s3.pm @@ -4,7 +4,7 @@ package IkiWiki::Plugin::amazon_s3; use warnings; no warnings 'redefine'; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use IkiWiki::Render; use Net::Amazon::S3; @@ -16,13 +16,13 @@ BEGIN { } }; -sub import { #{{{ +sub import { hook(type => "getopt", id => "amazon_s3", call => \&getopt); hook(type => "getsetup", id => "amazon_s3", call => \&getsetup); hook(type => "checkconfig", id => "amazon_s3", call => \&checkconfig); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); @@ -38,9 +38,9 @@ sub getopt () { #{{{ debug(gettext("done")); exit(0); }); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, @@ -88,9 +88,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub checkconfig { #{{{ +sub checkconfig { foreach my $field (qw{amazon_s3_key_id amazon_s3_key_file amazon_s3_bucket}) { if (! exists $config{$field} || ! defined $config{$field}) { @@ -101,11 +101,11 @@ sub checkconfig { #{{{ ! defined $config{amazon_s3_prefix}) { $config{amazon_s3_prefix}="wiki/"; } -} #}}} +} { my $bucket; -sub getbucket { #{{{ +sub getbucket { return $bucket if defined $bucket; open(IN, "<", $config{amazon_s3_key_file}) || error($config{amazon_s3_key_file}.": ".$!); @@ -138,11 +138,11 @@ sub getbucket { #{{{ } return $bucket; -} #}}} +} } # Given a file, return any S3 keys associated with it. -sub file2keys ($) { #{{{ +sub file2keys ($) { my $file=shift; my @keys; @@ -162,14 +162,14 @@ sub file2keys ($) { #{{{ } } return @keys; -} #}}} +} package IkiWiki; use File::MimeInfo; use Encode; # This is a wrapper around the real writefile. -sub writefile ($$$;$$) { #{{{ +sub writefile ($$$;$$) { my $file=shift; my $destdir=shift; my $content=shift; @@ -225,10 +225,10 @@ sub writefile ($$$;$$) { #{{{ } return $ret; -} #}}} +} # This is a wrapper around the real prune. -sub prune ($) { #{{{ +sub prune ($) { my $file=shift; my @keys=IkiWiki::Plugin::amazon_s3::file2keys($file); @@ -247,6 +247,6 @@ sub prune ($) { #{{{ } return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file); -} #}}} +} 1 diff --git a/IkiWiki/Plugin/anonok.pm b/IkiWiki/Plugin/anonok.pm index 2be983693..243b98920 100644 --- a/IkiWiki/Plugin/anonok.pm +++ b/IkiWiki/Plugin/anonok.pm @@ -3,14 +3,14 @@ package IkiWiki::Plugin::anonok; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "anonok", call => \&getsetup); hook(type => "canedit", id => "anonok", call => \&canedit); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -24,9 +24,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} -sub canedit ($$$) { #{{{ +sub canedit ($$$) { my $page=shift; my $cgi=shift; my $session=shift; @@ -45,6 +45,6 @@ sub canedit ($$$) { #{{{ else { return ""; } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index dcac3e820..087c315a9 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -3,17 +3,18 @@ package IkiWiki::Plugin::attachment; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { + add_underlay("javascript"); hook(type => "getsetup", id => "attachment", call => \&getsetup); hook(type => "checkconfig", id => "attachment", call => \&checkconfig); hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup); hook(type => "formbuilder", id => "attachment", call => \&formbuilder); IkiWiki::loadplugin("filecheck"); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -34,9 +35,9 @@ sub getsetup () { #{{{ safe => 0, # executed rebuild => 0, }, -} #}}} +} -sub check_canattach ($$;$) { #{{{ +sub check_canattach ($$;$) { my $session=shift; my $dest=shift; # where it's going to be put, under the srcdir my $file=shift; # the path to the attachment currently @@ -60,36 +61,19 @@ sub check_canattach ($$;$) { #{{{ ); } - # XXX deprecated, should be removed eventually - if ($allowed) { - foreach my $admin (@{$config{adminuser}}) { - my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments"); - if (defined $allowed_attachments && - length $allowed_attachments) { - $allowed=pagespec_match($dest, - $allowed_attachments, - file => $file, - user => $session->param("name"), - ip => $ENV{REMOTE_ADDR}, - ); - last if $allowed; - } - } - } - if (! $allowed) { error(gettext("prohibited by allowed_attachments")." ($allowed)"); } else { return 1; } -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { $config{cgi_disable_uploads}=0; -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; my $q=$params{cgi}; @@ -104,10 +88,10 @@ sub formbuilder_setup (@) { #{{{ $form->tmpl_param("field-upload" => ''); $form->tmpl_param("field-link" => ''); - # Add the javascript from the toggle plugin; - # the attachments interface uses it to toggle visibility. + # Add the toggle javascript; the attachments interface uses + # it to toggle visibility. require IkiWiki::Plugin::toggle; - $form->tmpl_param("javascript" => $IkiWiki::Plugin::toggle::javascript); + $form->tmpl_param("javascript" => IkiWiki::Plugin::toggle::include_javascript($params{page}, 1)); # Start with the attachments interface toggled invisible, # but if it was used, keep it open. if ($form->submitted ne "Upload Attachment" && @@ -119,42 +103,9 @@ sub formbuilder_setup (@) { #{{{ $form->tmpl_param("attachments-class" => "toggleable-open"); } } - elsif ($form->title eq "preferences") { - # XXX deprecated, should remove eventually - my $session=$params{session}; - my $user_name=$session->param("name"); +} - $form->field(name => "allowed_attachments", size => 50, - fieldset => "admin", - comment => "deprecated; please move to allowed_attachments in setup file", - ); - if (! IkiWiki::is_admin($user_name)) { - $form->field(name => "allowed_attachments", type => "hidden"); - } - if (! $form->submitted) { - my $value=IkiWiki::userinfo_get($user_name, "allowed_attachments"); - if (length $value) { - $form->field(name => "allowed_attachments", force => 1, - value => IkiWiki::userinfo_get($user_name, "allowed_attachments")); - } - else { - $form->field(name => "allowed_attachments", type => "hidden"); - } - } - if ($form->submitted && $form->submitted eq 'Save Preferences') { - if (defined $form->field("allowed_attachments")) { - IkiWiki::userinfo_set($user_name, "allowed_attachments", - $form->field("allowed_attachments")) || - error("failed to set allowed_attachments"); - if (! length $form->field("allowed_attachments")) { - $form->field(name => "allowed_attachments", type => "hidden"); - } - } - } - } -} #}}} - -sub formbuilder (@) { #{{{ +sub formbuilder (@) { my %params=@_; my $form=$params{form}; my $q=$params{cgi}; @@ -252,9 +203,9 @@ sub formbuilder (@) { #{{{ # Generate the attachment list only after having added any new # attachments. $form->tmpl_param("attachment_list" => [attachment_list($form->field('page'))]); -} # }}} +} -sub attachment_location ($) { #{{{ +sub attachment_location ($) { my $page=shift; # Put the attachment in a subdir of the page it's attached @@ -263,9 +214,9 @@ sub attachment_location ($) { #{{{ $page.="/" if length $page; return $page; -} #}}} +} -sub attachment_list ($) { #{{{ +sub attachment_list ($) { my $page=shift; my $loc=attachment_location($page); @@ -279,7 +230,6 @@ sub attachment_list ($) { #{{{ link => htmllink($page, $page, $f, noimageinline => 1), size => IkiWiki::Plugin::filecheck::humansize((stat(_))[7]), mtime => displaytime($IkiWiki::pagemtime{$f}), - mtime_raw => $IkiWiki::pagemtime{$f}, }; } } @@ -287,6 +237,6 @@ sub attachment_list ($) { #{{{ # Sort newer attachments to the top of the list, so a newly-added # attachment appears just before the form used to add it. return sort { $b->{mtime_raw} <=> $a->{mtime_raw} || $a->{link} cmp $b->{link} } @ret; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index d1b3edb1f..555856b11 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -3,23 +3,23 @@ package IkiWiki::Plugin::autoindex; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use Encode; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "autoindex", call => \&getsetup); hook(type => "refresh", id => "autoindex", call => \&refresh); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub genindex ($) { #{{{ +sub genindex ($) { my $page=shift; my $file=newpagefile($page, $config{default_pageext}); my $template=template("autoindex.tmpl"); @@ -28,9 +28,9 @@ sub genindex ($) { #{{{ if ($config{rcs}) { IkiWiki::rcs_add($file); } -} #}}} +} -sub refresh () { #{{{ +sub refresh () { eval q{use File::Find}; error($@) if $@; @@ -107,6 +107,6 @@ sub refresh () { #{{{ IkiWiki::enable_commit_hook(); } } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/blogspam.pm b/IkiWiki/Plugin/blogspam.pm new file mode 100644 index 000000000..cbd9859a5 --- /dev/null +++ b/IkiWiki/Plugin/blogspam.pm @@ -0,0 +1,116 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::blogspam; + +use warnings; +use strict; +use IkiWiki 3.00; + +my $defaulturl='http://test.blogspam.net:8888/'; + +sub import { + hook(type => "getsetup", id => "blogspam", call => \&getsetup); + hook(type => "checkcontent", id => "blogspam", call => \&checkcontent); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => 0, + }, + blogspam_pagespec => { + type => 'pagespec', + example => 'postcomment(*)', + description => 'PageSpec of pages to check for spam', + link => 'ikiwiki/PageSpec', + safe => 1, + rebuild => 0, + }, + blogspam_options => { + type => "string", + example => "blacklist=1.2.3.4,blacklist=8.7.6.5,max-links=10", + description => "options to send to blogspam server", + link => "http://blogspam.net/api/testComment.html#options", + safe => 1, + rebuild => 0, + }, + blogspam_server => { + type => "string", + default => $defaulturl, + description => "blogspam server XML-RPC url", + safe => 1, + rebuild => 0, + }, +} + +sub checkcontent (@) { + my %params=@_; + + eval q{ + use RPC::XML; + use RPC::XML::Client; + }; + if ($@) { + warn($@); + return undef; + } + + if (exists $config{blogspam_pagespec}) { + return undef + if ! pagespec_match($params{page}, $config{blogspam_pagespec}, + location => $params{page}); + } + + my $url=$defaulturl; + $url = $config{blogspam_server} if exists $config{blogspam_server}; + my $client = RPC::XML::Client->new($url); + + my @options = split(",", $config{blogspam_options}) + if exists $config{blogspam_options}; + + # Allow short comments and whitespace-only edits, unless the user + # has overridden min-words themselves. + push @options, "min-words=0" + unless grep /^min-words=/i, @options; + # Wiki pages can have a lot of urls, unless the user specifically + # wants to limit them. + push @options, "exclude=lotsaurls" + unless grep /^max-links/i, @options; + # Unless the user specified a size check, disable such checking. + push @options, "exclude=size" + unless grep /^(?:max|min)-size/i, @options; + # This test has absurd false positives on words like "alpha" + # and "buy". + push @options, "exclude=stopwords"; + + my %req=( + ip => $ENV{REMOTE_ADDR}, + comment => $params{content}, + subject => defined $params{subject} ? $params{subject} : "", + name => defined $params{author} ? $params{author} : "", + link => exists $params{url} ? $params{url} : "", + options => join(",", @options), + site => $config{url}, + version => "ikiwiki ".$IkiWiki::version, + ); + my $res = $client->send_request('testComment', \%req); + + if (! ref $res || ! defined $res->value) { + debug("failed to get response from blogspam server ($url)"); + return undef; + } + elsif ($res->value =~ /^SPAM:(.*)/) { + eval q{use Data::Dumper}; + debug("blogspam server reports ".$res->value.": ".Dumper(\%req)); + return gettext("Sorry, but that looks like spam to blogspam: ").$1; + } + elsif ($res->value ne 'OK') { + debug("blogspam server failure: ".$res->value); + return undef; + } + else { + return undef; + } +} + +1 diff --git a/IkiWiki/Plugin/brokenlinks.pm b/IkiWiki/Plugin/brokenlinks.pm index 37752dd3e..bf0d7560d 100644 --- a/IkiWiki/Plugin/brokenlinks.pm +++ b/IkiWiki/Plugin/brokenlinks.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::brokenlinks; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "brokenlinks", call => \&getsetup); hook(type => "preprocess", id => "brokenlinks", call => \&preprocess); -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{pages}="*" unless defined $params{pages}; @@ -61,6 +61,6 @@ sub preprocess (@) { #{{{ } sort @broken) ."\n"; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/bzr.pm b/IkiWiki/Plugin/bzr.pm index 101e91b93..883007367 100644 --- a/IkiWiki/Plugin/bzr.pm +++ b/IkiWiki/Plugin/bzr.pm @@ -7,7 +7,7 @@ use IkiWiki; use Encode; use open qw{:utf8 :std}; -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "bzr", call => \&checkconfig); hook(type => "getsetup", id => "bzr", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -20,18 +20,18 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (defined $config{bzr_wrapper} && length $config{bzr_wrapper}) { push @{$config{wrappers}}, { wrapper => $config{bzr_wrapper}, wrappermode => (defined $config{bzr_wrappermode} ? $config{bzr_wrappermode} : "06755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -65,9 +65,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub bzr_log ($) { #{{{ +sub bzr_log ($) { my $out = shift; my @infos = (); my $key = undef; @@ -99,20 +99,20 @@ sub bzr_log ($) { #{{{ close $out; return @infos; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { my @cmdline = ("bzr", "update", "--quiet", $config{srcdir}); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { return ""; -} #}}} +} -sub bzr_author ($$) { #{{{ +sub bzr_author ($$) { my ($user, $ipaddr) = @_; if (defined $user) { @@ -124,9 +124,9 @@ sub bzr_author ($$) { #{{{ else { return "Anonymous"; } -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { my ($file, $message, $rcstoken, $user, $ipaddr) = @_; $user = bzr_author($user, $ipaddr); @@ -143,7 +143,7 @@ sub rcs_commit ($$$;$$) { #{{{ } return undef; # success -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -164,27 +164,27 @@ sub rcs_commit_staged ($$$) { } return undef; # success -} #}}} +} -sub rcs_add ($) { # {{{ +sub rcs_add ($) { my ($file) = @_; my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file"); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_remove ($) { # {{{ +sub rcs_remove ($) { my ($file) = @_; my @cmdline = ("bzr", "rm", "--force", "--quiet", "$config{srcdir}/$file"); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_rename ($$) { # {{{ +sub rcs_rename ($$) { my ($src, $dest) = @_; my $parent = IkiWiki::dirname($dest); @@ -196,9 +196,9 @@ sub rcs_rename ($$) { # {{{ if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { my ($num) = @_; my @cmdline = ("bzr", "log", "-v", "--show-ids", "--limit", $num, @@ -246,16 +246,36 @@ sub rcs_recentchanges ($) { #{{{ rev => $info->{"revno"}, user => $user, committype => "bzr", - when => time - str2time($info->{"timestamp"}), + when => str2time($info->{"timestamp"}), message => [@message], pages => [@pages], }; } return @ret; -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_diff ($) { + my $taintedrev=shift; + my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint + + my $prevspec = "before:" . $rev; + my $revspec = "revno:" . $rev; + my @cmdline = ("bzr", "diff", "--old", $config{srcdir}, + "--new", $config{srcdir}, + "-r", $prevspec . ".." . $revspec); + open (my $out, "@cmdline |"); + + my @lines = <$out>; + if (wantarray) { + return @lines; + } + else { + return join("", @lines); + } +} + +sub rcs_getctime ($) { my ($file) = @_; # XXX filename passes through the shell here, should try to avoid @@ -274,6 +294,6 @@ sub rcs_getctime ($) { #{{{ my $ctime = str2time($log[0]->{"timestamp"}); return $ctime; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm index 6d536a91b..d473c8348 100644 --- a/IkiWiki/Plugin/calendar.pm +++ b/IkiWiki/Plugin/calendar.pm @@ -20,7 +20,7 @@ package IkiWiki::Plugin::calendar; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use Time::Local; use POSIX; @@ -29,13 +29,13 @@ my %linkcache; my $time=time; my @now=localtime($time); -sub import { #{{{ +sub import { hook(type => "getsetup", id => "calendar", call => \&getsetup); hook(type => "needsbuild", id => "calendar", call => \&needsbuild); hook(type => "preprocess", id => "calendar", call => \&preprocess); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -48,23 +48,23 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub is_leap_year (@) { #{{{ +sub is_leap_year (@) { my %params=@_; return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 == 0)); -} #}}} +} -sub month_days { #{{{ +sub month_days { my %params=@_; my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1]; if ($params{month} == 2 && is_leap_year(%params)) { $days_in_month++; } return $days_in_month; -} #}}} +} -sub format_month (@) { #{{{ +sub format_month (@) { my %params=@_; my $pagespec = $params{pages}; @@ -215,9 +215,9 @@ EOF add_depends($params{page}, join(" or ", @list)); return $calendar; -} #}}} +} -sub format_year (@) { #{{{ +sub format_year (@) { my %params=@_; my $pagespec = $params{pages}; @@ -318,9 +318,9 @@ EOF EOF return $calendar; -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{pages} = "*" unless defined $params{pages}; $params{type} = "month" unless defined $params{type}; @@ -397,7 +397,7 @@ sub preprocess (@) { #{{{ return "\n
$calendar
\n"; } #}} -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{calendar}{nextchange}) { @@ -415,6 +415,6 @@ sub needsbuild (@) { #{{{ } } } -} # }}} +} 1 diff --git a/IkiWiki/Plugin/camelcase.pm b/IkiWiki/Plugin/camelcase.pm index 7881becd5..74a8397d7 100644 --- a/IkiWiki/Plugin/camelcase.pm +++ b/IkiWiki/Plugin/camelcase.pm @@ -4,7 +4,7 @@ package IkiWiki::Plugin::camelcase; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; # This regexp is based on the one in Text::WikiFormat. my $link_regexp=qr{ @@ -22,40 +22,52 @@ my $link_regexp=qr{ ) }x; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "camelcase", call => \&getsetup); hook(type => "linkify", id => "camelcase", call => \&linkify); hook(type => "scan", id => "camelcase", call => \&scan); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, - }; -} #}}} + }, + camelcase_ignore => { + type => "string", + example => [], + description => "list of words to not turn into links", + safe => 1, + rebuild => undef, # might change links + }, +} -sub linkify (@) { #{{{ +sub linkify (@) { my %params=@_; my $page=$params{page}; my $destpage=$params{destpage}; $params{content}=~s{$link_regexp}{ - htmllink($page, $destpage, linkpage($1)) + ignored($1) ? $1 : htmllink($page, $destpage, linkpage($1)) }eg; return $params{content}; -} #}}} +} -sub scan (@) { #{{{ +sub scan (@) { my %params=@_; my $page=$params{page}; my $content=$params{content}; while ($content =~ /$link_regexp/g) { - push @{$links{$page}}, linkpage($1); + push @{$links{$page}}, linkpage($1) unless ignored($1) } } +sub ignored ($) { + my $word=lc shift; + grep { $word eq lc $_ } @{$config{'camelcase_ignore'}} +} + 1 diff --git a/IkiWiki/Plugin/color.pm b/IkiWiki/Plugin/color.pm index ac702ff02..20505893b 100644 --- a/IkiWiki/Plugin/color.pm +++ b/IkiWiki/Plugin/color.pm @@ -5,14 +5,14 @@ package IkiWiki::Plugin::color; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "preprocess", id => "color", call => \&preprocess); hook(type => "format", id => "color", call => \&format); -} #}}} +} -sub preserve_style ($$$) { #{{{ +sub preserve_style ($$$) { my $foreground = shift; my $background = shift; my $text = shift; @@ -37,18 +37,18 @@ sub preserve_style ($$$) { #{{{ return $preserved; -} #}}} +} -sub replace_preserved_style ($) { #{{{ +sub replace_preserved_style ($) { my $content = shift; $content =~ s!((color: ([a-z]+|\#[0-9a-f]{3,6})?)?((; )?(background-color: ([a-z]+|\#[0-9a-f]{3,6})?)?)?)!!g; $content =~ s!!!g; return $content; -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params = @_; # Preprocess the text to expand any preprocessor directives @@ -57,13 +57,13 @@ sub preprocess (@) { #{{{ IkiWiki::filter($params{page}, $params{destpage}, $params{text})); return preserve_style($params{foreground}, $params{background}, $params{text}); -} #}}} +} -sub format (@) { #{{{ +sub format (@) { my %params = @_; $params{content} = replace_preserved_style($params{content}); return $params{content}; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm new file mode 100644 index 000000000..98f9f8b3d --- /dev/null +++ b/IkiWiki/Plugin/comments.pm @@ -0,0 +1,840 @@ +#!/usr/bin/perl +# Copyright © 2006-2008 Joey Hess +# Copyright © 2008 Simon McVittie +# Licensed under the GNU GPL, version 2, or any later version published by the +# Free Software Foundation +package IkiWiki::Plugin::comments; + +use warnings; +use strict; +use IkiWiki 3.00; +use Encode; +use POSIX qw(strftime); + +use constant PREVIEW => "Preview"; +use constant POST_COMMENT => "Post comment"; +use constant CANCEL => "Cancel"; + +my $postcomment; +my %commentstate; + +sub import { + hook(type => "checkconfig", id => 'comments', call => \&checkconfig); + hook(type => "getsetup", id => 'comments', call => \&getsetup); + hook(type => "preprocess", id => '_comment', call => \&preprocess); + hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi); + hook(type => "htmlize", id => "_comment", call => \&htmlize); + hook(type => "pagetemplate", id => "comments", call => \&pagetemplate); + hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup); + # Load goto to fix up user page links for logged-in commenters + IkiWiki::loadplugin("goto"); + IkiWiki::loadplugin("inline"); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => 1, + }, + comments_pagespec => { + type => 'pagespec', + example => 'blog/* and !*/Discussion', + description => 'PageSpec of pages where comments are allowed', + link => 'ikiwiki/PageSpec', + safe => 1, + rebuild => 1, + }, + comments_closed_pagespec => { + type => 'pagespec', + example => 'blog/controversial or blog/flamewar', + description => 'PageSpec of pages where posting new comments is not allowed', + link => 'ikiwiki/PageSpec', + safe => 1, + rebuild => 1, + }, + comments_pagename => { + type => 'string', + default => 'comment_', + description => 'Base name for comments, e.g. "comment_" for pages like "sandbox/comment_12"', + safe => 0, # manual page moving required + rebuild => undef, + }, + comments_allowdirectives => { + type => 'boolean', + example => 0, + description => 'Interpret directives in comments?', + safe => 1, + rebuild => 0, + }, + comments_allowauthor => { + type => 'boolean', + example => 0, + description => 'Allow anonymous commenters to set an author name?', + safe => 1, + rebuild => 0, + }, + comments_commit => { + type => 'boolean', + example => 1, + description => 'commit comments to the VCS', + # old uncommitted comments are likely to cause + # confusion if this is changed + safe => 0, + rebuild => 0, + }, +} + +sub checkconfig () { + $config{comments_commit} = 1 + unless defined $config{comments_commit}; + $config{comments_pagespec} = '' + unless defined $config{comments_pagespec}; + $config{comments_closed_pagespec} = '' + unless defined $config{comments_closed_pagespec}; + $config{comments_pagename} = 'comment_' + unless defined $config{comments_pagename}; +} + +sub htmlize { + my %params = @_; + return $params{content}; +} + +# FIXME: copied verbatim from meta +sub safeurl ($) { + my $url=shift; + if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} && + defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) { + return $url=~/$IkiWiki::Plugin::htmlscrubber::safe_url_regexp/; + } + else { + return 1; + } +} + +sub preprocess { + my %params = @_; + my $page = $params{page}; + + my $format = $params{format}; + if (defined $format && ! exists $IkiWiki::hooks{htmlize}{$format}) { + error(sprintf(gettext("unsupported page format %s"), $format)); + } + + my $content = $params{content}; + if (! defined $content) { + error(gettext("comment must have content")); + } + $content =~ s/\\"/"/g; + + $content = IkiWiki::filter($page, $params{destpage}, $content); + + if ($config{comments_allowdirectives}) { + $content = IkiWiki::preprocess($page, $params{destpage}, + $content); + } + + # no need to bother with htmlize if it's just HTML + $content = IkiWiki::htmlize($page, $params{destpage}, $format, $content) + if defined $format; + + IkiWiki::run_hooks(sanitize => sub { + $content = shift->( + page => $page, + destpage => $params{destpage}, + content => $content, + ); + }); + + # set metadata, possibly overriding [[!meta]] directives from the + # comment itself + + my $commentuser; + my $commentip; + my $commentauthor; + my $commentauthorurl; + my $commentopenid; + if (defined $params{username}) { + $commentuser = $params{username}; + + my $oiduser = eval { IkiWiki::openiduser($commentuser) }; + + if (defined $oiduser) { + # looks like an OpenID + $commentauthorurl = $commentuser; + $commentauthor = $oiduser; + $commentopenid = $commentuser; + } + else { + $commentauthorurl = IkiWiki::cgiurl( + do => 'goto', + page => (length $config{userdir} + ? "$config{userdir}/$commentuser" + : "$commentuser")); + + $commentauthor = $commentuser; + } + } + else { + if (defined $params{ip}) { + $commentip = $params{ip}; + } + $commentauthor = gettext("Anonymous"); + } + + $commentstate{$page}{commentuser} = $commentuser; + $commentstate{$page}{commentopenid} = $commentopenid; + $commentstate{$page}{commentip} = $commentip; + $commentstate{$page}{commentauthor} = $commentauthor; + $commentstate{$page}{commentauthorurl} = $commentauthorurl; + if (! defined $pagestate{$page}{meta}{author}) { + $pagestate{$page}{meta}{author} = $commentauthor; + } + if (! defined $pagestate{$page}{meta}{authorurl}) { + $pagestate{$page}{meta}{authorurl} = $commentauthorurl; + } + + if ($config{comments_allowauthor}) { + if (defined $params{claimedauthor}) { + $pagestate{$page}{meta}{author} = $params{claimedauthor}; + } + + if (defined $params{url}) { + my $url=$params{url}; + + eval q{use URI::Heuristic}; + if (! $@) { + $url=URI::Heuristic::uf_uristr($url); + } + + if (safeurl($url)) { + $pagestate{$page}{meta}{authorurl} = $url; + } + } + } + else { + $pagestate{$page}{meta}{author} = $commentauthor; + $pagestate{$page}{meta}{authorurl} = $commentauthorurl; + } + + if (defined $params{subject}) { + $pagestate{$page}{meta}{title} = $params{subject}; + } + + if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) { + $pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1). + "#".page_to_id($params{page}); + } + + eval q{use Date::Parse}; + if (! $@) { + my $time = str2time($params{date}); + $IkiWiki::pagectime{$page} = $time if defined $time; + } + + return $content; +} + +sub sessioncgi ($$) { + my $cgi=shift; + my $session=shift; + + my $do = $cgi->param('do'); + if ($do eq 'comment') { + editcomment($cgi, $session); + } + elsif ($do eq 'commentmoderation') { + commentmoderation($cgi, $session); + } +} + +# Mostly cargo-culted from IkiWiki::plugin::editpage +sub editcomment ($$) { + my $cgi=shift; + my $session=shift; + + IkiWiki::decode_cgi_utf8($cgi); + + eval q{use CGI::FormBuilder}; + error($@) if $@; + + my @buttons = (POST_COMMENT, PREVIEW, CANCEL); + my $form = CGI::FormBuilder->new( + fields => [qw{do sid page subject editcontent type author url}], + charset => 'utf-8', + method => 'POST', + required => [qw{editcontent}], + javascript => 0, + params => $cgi, + action => $config{cgiurl}, + header => 0, + table => 0, + template => scalar IkiWiki::template_params('editcomment.tmpl'), + ); + + IkiWiki::decode_form_utf8($form); + IkiWiki::run_hooks(formbuilder_setup => sub { + shift->(title => "comment", form => $form, cgi => $cgi, + session => $session, buttons => \@buttons); + }); + IkiWiki::decode_form_utf8($form); + + my $type = $form->param('type'); + if (defined $type && length $type && $IkiWiki::hooks{htmlize}{$type}) { + $type = IkiWiki::possibly_foolish_untaint($type); + } + else { + $type = $config{default_pageext}; + } + my @page_types; + if (exists $IkiWiki::hooks{htmlize}) { + @page_types = grep { ! /^_/ } keys %{$IkiWiki::hooks{htmlize}}; + } + + $form->field(name => 'do', type => 'hidden'); + $form->field(name => 'sid', type => 'hidden', value => $session->id, + force => 1); + $form->field(name => 'page', type => 'hidden'); + $form->field(name => 'subject', type => 'text', size => 72); + $form->field(name => 'editcontent', type => 'textarea', rows => 10); + $form->field(name => "type", value => $type, force => 1, + type => 'select', options => \@page_types); + + $form->tmpl_param(username => $session->param('name')); + + if ($config{comments_allowauthor} and + ! defined $session->param('name')) { + $form->tmpl_param(allowauthor => 1); + $form->field(name => 'author', type => 'text', size => '40'); + $form->field(name => 'url', type => 'text', size => '40'); + } + else { + $form->tmpl_param(allowauthor => 0); + $form->field(name => 'author', type => 'hidden', value => '', + force => 1); + $form->field(name => 'url', type => 'hidden', value => '', + force => 1); + } + + # The untaint is OK (as in editpage) because we're about to pass + # it to file_pruned anyway + my $page = $form->field('page'); + $page = IkiWiki::possibly_foolish_untaint($page); + if (! defined $page || ! length $page || + IkiWiki::file_pruned($page, $config{srcdir})) { + error(gettext("bad page name")); + } + + my $baseurl = urlto($page, undef, 1); + + $form->title(sprintf(gettext("commenting on %s"), + IkiWiki::pagetitle($page))); + + $form->tmpl_param('helponformattinglink', + htmllink($page, $page, 'ikiwiki/formatting', + noimageinline => 1, + linktext => 'FormattingHelp'), + allowdirectives => $config{allow_directives}); + + if ($form->submitted eq CANCEL) { + # bounce back to the page they wanted to comment on, and exit. + # CANCEL need not be considered in future + IkiWiki::redirect($cgi, urlto($page, undef, 1)); + exit; + } + + if (not exists $pagesources{$page}) { + error(sprintf(gettext( + "page '%s' doesn't exist, so you can't comment"), + $page)); + } + + if (pagespec_match($page, $config{comments_closed_pagespec}, + location => $page)) { + error(sprintf(gettext( + "comments on page '%s' are closed"), + $page)); + } + + # Set a flag to indicate that we're posting a comment, + # so that postcomment() can tell it should match. + $postcomment=1; + IkiWiki::check_canedit($page, $cgi, $session); + $postcomment=0; + + my $location=unique_comment_location($page, $config{srcdir}); + + my $content = "[[!_comment format=$type\n"; + + # FIXME: handling of double quotes probably wrong? + if (defined $session->param('name')) { + my $username = $session->param('name'); + $username =~ s/"/"/g; + $content .= " username=\"$username\"\n"; + } + elsif (defined $ENV{REMOTE_ADDR}) { + my $ip = $ENV{REMOTE_ADDR}; + if ($ip =~ m/^([.0-9]+)$/) { + $content .= " ip=\"$1\"\n"; + } + } + + if ($config{comments_allowauthor}) { + my $author = $form->field('author'); + if (defined $author && length $author) { + $author =~ s/"/"/g; + $content .= " claimedauthor=\"$author\"\n"; + } + my $url = $form->field('url'); + if (defined $url && length $url) { + $url =~ s/"/"/g; + $content .= " url=\"$url\"\n"; + } + } + + my $subject = $form->field('subject'); + if (defined $subject && length $subject) { + $subject =~ s/"/"/g; + $content .= " subject=\"$subject\"\n"; + } + + $content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n"; + + my $editcontent = $form->field('editcontent') || ''; + $editcontent =~ s/\r\n/\n/g; + $editcontent =~ s/\r/\n/g; + $editcontent =~ s/"/\\"/g; + $content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n"; + + # This is essentially a simplified version of editpage: + # - the user does not control the page that's created, only the parent + # - it's always a create operation, never an edit + # - this means that conflicts should never happen + # - this means that if they do, rocks fall and everyone dies + + if ($form->submitted eq PREVIEW) { + my $preview=previewcomment($content, $location, $page, time); + IkiWiki::run_hooks(format => sub { + $preview = shift->(page => $page, + content => $preview); + }); + $form->tmpl_param(page_preview => $preview); + } + else { + $form->tmpl_param(page_preview => ""); + } + + if ($form->submitted eq POST_COMMENT && $form->validate) { + IkiWiki::checksessionexpiry($cgi, $session); + + $postcomment=1; + my $ok=IkiWiki::check_content(content => $form->field('editcontent'), + subject => $form->field('subject'), + $config{comments_allowauthor} ? ( + author => $form->field('author'), + url => $form->field('url'), + ) : (), + page => $location, + cgi => $cgi, + session => $session, + nonfatal => 1, + ); + $postcomment=0; + + if (! $ok) { + my $penddir=$config{wikistatedir}."/comments_pending"; + $location=unique_comment_location($page, $penddir); + writefile("$location._comment", $penddir, $content); + IkiWiki::printheader($session); + print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")), + "

". + gettext("Your comment will be posted after moderator review"). + "

"); + exit; + } + + # FIXME: could probably do some sort of graceful retry + # on error? Would require significant unwinding though + my $file = "$location._comment"; + writefile($file, $config{srcdir}, $content); + + my $conflict; + + if ($config{rcs} and $config{comments_commit}) { + my $message = gettext("Added a comment"); + if (defined $form->field('subject') && + length $form->field('subject')) { + $message = sprintf( + gettext("Added a comment: %s"), + $form->field('subject')); + } + + IkiWiki::rcs_add($file); + IkiWiki::disable_commit_hook(); + $conflict = IkiWiki::rcs_commit_staged($message, + $session->param('name'), $ENV{REMOTE_ADDR}); + IkiWiki::enable_commit_hook(); + IkiWiki::rcs_update(); + } + + # Now we need a refresh + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + + # this should never happen, unless a committer deliberately + # breaks it or something + error($conflict) if defined $conflict; + + # Jump to the new comment on the page. + # The trailing question mark tries to avoid broken + # caches and get the most recent version of the page. + IkiWiki::redirect($cgi, urlto($page, undef, 1). + "?updated#".page_to_id($location)); + + } + else { + IkiWiki::showform ($form, \@buttons, $session, $cgi, + forcebaseurl => $baseurl); + } + + exit; +} + +sub commentmoderation ($$) { + my $cgi=shift; + my $session=shift; + + IkiWiki::needsignin($cgi, $session); + if (! IkiWiki::is_admin($session->param("name"))) { + error(gettext("you are not logged in as an admin")); + } + + IkiWiki::decode_cgi_utf8($cgi); + + if (defined $cgi->param('sid')) { + IkiWiki::checksessionexpiry($cgi, $session); + + my $rejectalldefer=$cgi->param('rejectalldefer'); + + my %vars=$cgi->Vars; + my $added=0; + foreach my $id (keys %vars) { + if ($id =~ /(.*)\Q._comment\E$/) { + my $action=$cgi->param($id); + next if $action eq 'Defer' && ! $rejectalldefer; + + # Make sure that the id is of a legal + # pending comment before untainting. + my ($f)= $id =~ /$config{wiki_file_regexp}/; + if (! defined $f || ! length $f || + IkiWiki::file_pruned($f, $config{srcdir})) { + error("illegal file"); + } + + my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1)); + my $file="$config{wikistatedir}/comments_pending/". + IkiWiki::possibly_foolish_untaint($id); + + if ($action eq 'Accept') { + my $content=eval { readfile($file) }; + next if $@; # file vanished since form was displayed + my $dest=unique_comment_location($page, $config{srcdir})."._comment"; + writefile($dest, $config{srcdir}, $content); + if ($config{rcs} and $config{comments_commit}) { + IkiWiki::rcs_add($dest); + } + $added++; + } + + # This removes empty subdirs, so the + # .ikiwiki/comments_pending dir will + # go away when all are moderated. + require IkiWiki::Render; + IkiWiki::prune($file); + } + } + + if ($added) { + my $conflict; + if ($config{rcs} and $config{comments_commit}) { + my $message = gettext("Comment moderation"); + IkiWiki::disable_commit_hook(); + $conflict=IkiWiki::rcs_commit_staged($message, + $session->param('name'), $ENV{REMOTE_ADDR}); + IkiWiki::enable_commit_hook(); + IkiWiki::rcs_update(); + } + + # Now we need a refresh + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + + error($conflict) if defined $conflict; + } + } + + my @comments=map { + my ($id, $ctime)=@{$_}; + my $file="$config{wikistatedir}/comments_pending/$id"; + my $content=readfile($file); + my $preview=previewcomment($content, $id, + IkiWiki::dirname($_), $ctime); + { + id => $id, + view => $preview, + } + } sort { $b->[1] <=> $a->[1] } comments_pending(); + + my $template=template("commentmoderation.tmpl"); + $template->param( + sid => $session->id, + comments => \@comments, + ); + IkiWiki::printheader($session); + my $out=$template->output; + IkiWiki::run_hooks(format => sub { + $out = shift->(page => "", content => $out); + }); + print IkiWiki::misctemplate(gettext("comment moderation"), $out); + exit; +} + +sub formbuilder_setup (@) { + my %params=@_; + + my $form=$params{form}; + if ($form->title eq "preferences" && + IkiWiki::is_admin($params{session}->param("name"))) { + push @{$params{buttons}}, "Comment Moderation"; + if ($form->submitted && $form->submitted eq "Comment Moderation") { + commentmoderation($params{cgi}, $params{session}); + } + } +} + +sub comments_pending () { + my $dir="$config{wikistatedir}/comments_pending/"; + return unless -d $dir; + + my @ret; + eval q{use File::Find}; + error($@) if $@; + find({ + no_chdir => 1, + wanted => sub { + $_=decode_utf8($_); + if (IkiWiki::file_pruned($_, $dir)) { + $File::Find::prune=1; + } + elsif (! -l $_ && ! -d _) { + $File::Find::prune=0; + my ($f)=/$config{wiki_file_regexp}/; # untaint + if (defined $f && $f =~ /\Q._comment\E$/) { + my $ctime=(stat($f))[10]; + $f=~s/^\Q$dir\E\/?//; + push @ret, [$f, $ctime]; + } + } + } + }, $dir); + + return @ret; +} + +sub previewcomment ($$$) { + my $content=shift; + my $location=shift; + my $page=shift; + my $time=shift; + + my $preview = IkiWiki::htmlize($location, $page, '_comment', + IkiWiki::linkify($location, $page, + IkiWiki::preprocess($location, $page, + IkiWiki::filter($location, $page, $content), 0, 1))); + + my $template = template("comment.tmpl"); + $template->param(content => $preview); + $template->param(ctime => displaytime($time)); + + IkiWiki::run_hooks(pagetemplate => sub { + shift->(page => $location, + destpage => $page, + template => $template); + }); + + $template->param(have_actions => 0); + + return $template->output; +} + +sub commentsshown ($) { + my $page=shift; + + return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)", + location => $page) && + pagespec_match($page, $config{comments_pagespec}, + location => $page); +} + +sub commentsopen ($) { + my $page = shift; + + return length $config{cgiurl} > 0 && + (! length $config{comments_closed_pagespec} || + ! pagespec_match($page, $config{comments_closed_pagespec}, + location => $page)); +} + +sub pagetemplate (@) { + my %params = @_; + + my $page = $params{page}; + my $template = $params{template}; + my $shown = ($template->query(name => 'commentslink') || + $template->query(name => 'commentsurl') || + $template->query(name => 'atomcommentsurl') || + $template->query(name => 'comments')) && + commentsshown($page); + + if ($template->query(name => 'comments')) { + my $comments = undef; + if ($shown) { + $comments = IkiWiki::preprocess_inline( + pages => "internal($page/$config{comments_pagename}*)", + template => 'comment', + show => 0, + reverse => 'yes', + page => $page, + destpage => $params{destpage}, + feedfile => 'comments', + emptyfeeds => 'no', + ); + } + + if (defined $comments && length $comments) { + $template->param(comments => $comments); + } + + if ($shown && commentsopen($page)) { + my $addcommenturl = IkiWiki::cgiurl(do => 'comment', + page => $page); + $template->param(addcommenturl => $addcommenturl); + } + } + + if ($template->query(name => 'commentsurl')) { + if ($shown) { + $template->param(commentsurl => + urlto($page, undef, 1).'#comments'); + } + } + + if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) { + if ($shown) { + # This will 404 until there are some comments, but I + # think that's probably OK... + $template->param(atomcommentsurl => + urlto($page, undef, 1).'comments.atom'); + } + } + + if ($template->query(name => 'commentslink')) { + # XXX Would be nice to say how many comments there are in + # the link. But, to update the number, blog pages + # would have to update whenever comments of any inlines + # page are added, which is not currently done. + if ($shown) { + $template->param(commentslink => + htmllink($page, $params{destpage}, $page, + linktext => gettext("Comments"), + anchor => "comments", + noimageinline => 1)); + } + } + + # everything below this point is only relevant to the comments + # themselves + if (!exists $commentstate{$page}) { + return; + } + + if ($template->query(name => 'commentid')) { + $template->param(commentid => page_to_id($page)); + } + + if ($template->query(name => 'commentuser')) { + $template->param(commentuser => + $commentstate{$page}{commentuser}); + } + + if ($template->query(name => 'commentopenid')) { + $template->param(commentopenid => + $commentstate{$page}{commentopenid}); + } + + if ($template->query(name => 'commentip')) { + $template->param(commentip => + $commentstate{$page}{commentip}); + } + + if ($template->query(name => 'commentauthor')) { + $template->param(commentauthor => + $commentstate{$page}{commentauthor}); + } + + if ($template->query(name => 'commentauthorurl')) { + $template->param(commentauthorurl => + $commentstate{$page}{commentauthorurl}); + } + + if ($template->query(name => 'removeurl') && + IkiWiki::Plugin::remove->can("check_canremove") && + length $config{cgiurl}) { + $template->param(removeurl => IkiWiki::cgiurl(do => 'remove', + page => $page)); + $template->param(have_actions => 1); + } +} + +sub unique_comment_location ($) { + my $page=shift; + my $dir=shift; + + my $location; + my $i = 0; + do { + $i++; + $location = "$page/$config{comments_pagename}$i"; + } while (-e "$dir/$location._comment"); + + return $location; +} + +sub page_to_id ($) { + # Converts a comment page name into a unique, legal html id + # addtibute value, that can be used as an anchor to link to the + # comment. + my $page=shift; + + eval q{use Digest::MD5 'md5_hex'}; + error($@) if $@; + + return "comment-".md5_hex($page); +} + +package IkiWiki::PageSpec; + +sub match_postcomment ($$;@) { + my $page = shift; + my $glob = shift; + + if (! $postcomment) { + return IkiWiki::FailReason->new("not posting a comment"); + } + return match_glob($page, $glob); +} + +1 diff --git a/IkiWiki/Plugin/conditional.pm b/IkiWiki/Plugin/conditional.pm index e787424aa..7445dbdad 100644 --- a/IkiWiki/Plugin/conditional.pm +++ b/IkiWiki/Plugin/conditional.pm @@ -3,23 +3,23 @@ package IkiWiki::Plugin::conditional; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use UNIVERSAL; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "conditional", call => \&getsetup); hook(type => "preprocess", id => "if", call => \&preprocess_if); -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess_if (@) { #{{{ +sub preprocess_if (@) { my %params=@_; foreach my $param (qw{test then}) { @@ -66,11 +66,11 @@ sub preprocess_if (@) { #{{{ } return IkiWiki::preprocess($params{page}, $params{destpage}, IkiWiki::filter($params{page}, $params{destpage}, $ret)); -} # }}} +} package IkiWiki::PageSpec; -sub match_enabled ($$;@) { #{{{ +sub match_enabled ($$;@) { shift; my $plugin=shift; @@ -81,12 +81,14 @@ sub match_enabled ($$;@) { #{{{ else { return IkiWiki::FailReason->new("$plugin is not enabled"); } -} #}}} +} -sub match_sourcepage ($$;@) { #{{{ +sub match_sourcepage ($$;@) { shift; my $glob=shift; my %params=@_; + + $glob=derel($glob, $params{location}); return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage}; if (match_glob($params{sourcepage}, $glob, @_)) { @@ -95,13 +97,15 @@ sub match_sourcepage ($$;@) { #{{{ else { return IkiWiki::FailReason->new("sourcepage does not match $glob"); } -} #}}} +} -sub match_destpage ($$;@) { #{{{ +sub match_destpage ($$;@) { shift; my $glob=shift; my %params=@_; + $glob=derel($glob, $params{location}); + return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage}; if (match_glob($params{destpage}, $glob, @_)) { return IkiWiki::SuccessReason->new("destpage matches $glob"); @@ -109,9 +113,9 @@ sub match_destpage ($$;@) { #{{{ else { return IkiWiki::FailReason->new("destpage does not match $glob"); } -} #}}} +} -sub match_included ($$;@) { #{{{ +sub match_included ($$;@) { shift; shift; my %params=@_; @@ -123,6 +127,6 @@ sub match_included ($$;@) { #{{{ else { return IkiWiki::FailReason->new("page $params{sourcepage} is not included"); } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/creole.pm b/IkiWiki/Plugin/creole.pm index 7c729300d..425e71043 100644 --- a/IkiWiki/Plugin/creole.pm +++ b/IkiWiki/Plugin/creole.pm @@ -5,22 +5,22 @@ package IkiWiki::Plugin::creole; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "creole", call => \&getsetup); hook(type => "htmlize", id => "creole", call => \&htmlize); -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; my $content = $params{content}; @@ -32,6 +32,6 @@ sub htmlize (@) { #{{{ creole_custombarelinks(); return creole_parse($content); -} # }}} +} 1 diff --git a/IkiWiki/Plugin/cutpaste.pm b/IkiWiki/Plugin/cutpaste.pm index 92667a1ef..417442f34 100644 --- a/IkiWiki/Plugin/cutpaste.pm +++ b/IkiWiki/Plugin/cutpaste.pm @@ -3,26 +3,26 @@ package IkiWiki::Plugin::cutpaste; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %savedtext; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "cutpaste", call => \&getsetup); hook(type => "preprocess", id => "cut", call => \&preprocess_cut, scan => 1); hook(type => "preprocess", id => "copy", call => \&preprocess_copy, scan => 1); hook(type => "preprocess", id => "paste", call => \&preprocess_paste); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess_cut (@) { #{{{ +sub preprocess_cut (@) { my %params=@_; foreach my $param (qw{id text}) { @@ -35,9 +35,9 @@ sub preprocess_cut (@) { #{{{ $savedtext{$params{page}}->{$params{id}} = $params{text}; return "" if defined wantarray; -} # }}} +} -sub preprocess_copy (@) { #{{{ +sub preprocess_copy (@) { my %params=@_; foreach my $param (qw{id text}) { @@ -51,9 +51,9 @@ sub preprocess_copy (@) { #{{{ return IkiWiki::preprocess($params{page}, $params{destpage}, IkiWiki::filter($params{page}, $params{destpage}, $params{text})) if defined wantarray; -} # }}} +} -sub preprocess_paste (@) { #{{{ +sub preprocess_paste (@) { my %params=@_; foreach my $param (qw{id}) { @@ -71,6 +71,6 @@ sub preprocess_paste (@) { #{{{ return IkiWiki::preprocess($params{page}, $params{destpage}, IkiWiki::filter($params{page}, $params{destpage}, $savedtext{$params{page}}->{$params{id}})); -} # }}} +} 1; diff --git a/IkiWiki/Plugin/ddate.pm b/IkiWiki/Plugin/ddate.pm index 6c36de0a6..bb77ce59f 100644 --- a/IkiWiki/Plugin/ddate.pm +++ b/IkiWiki/Plugin/ddate.pm @@ -2,22 +2,22 @@ # Discordian date support fnord ikiwiki. package IkiWiki::Plugin::ddate; -use IkiWiki 2.00; +use IkiWiki 3.00; no warnings; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "ddate", call => \&getsetup); -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub IkiWiki::displaytime ($;$) { #{{{ +sub IkiWiki::formattime ($;$) { my $time=shift; my $format=shift; if (! defined $format) { @@ -36,6 +36,6 @@ sub IkiWiki::displaytime ($;$) { #{{{ my $dt = DateTime->from_epoch(epoch => $time); my $dd = DateTime::Calendar::Discordian->from_object(object => $dt); return $dd->strftime($format); -} #}}} +} 5 diff --git a/IkiWiki/Plugin/editdiff.pm b/IkiWiki/Plugin/editdiff.pm index f5d7837fc..7df6a9ffb 100644 --- a/IkiWiki/Plugin/editdiff.pm +++ b/IkiWiki/Plugin/editdiff.pm @@ -4,25 +4,25 @@ package IkiWiki::Plugin::editdiff; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Entities; use IPC::Open2; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "editdiff", call => \&getsetup); hook(type => "formbuilder_setup", id => "editdiff", call => \&formbuilder_setup); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub diff ($$) { #{{{ +sub diff ($$) { my $orig=shift; my $content=shift; @@ -50,9 +50,9 @@ sub diff ($$) { #{{{ return "couldn't run diff\n" if $sigpipe; return "
".encode_entities($ret)."
"; -} #}}} +} -sub formbuilder_setup { #{{{ +sub formbuilder_setup { my %params=@_; my $form=$params{form}; @@ -72,6 +72,6 @@ sub formbuilder_setup { #{{{ my $diff = diff(srcfile($pagesources{$page}), $content); $form->tmpl_param("page_preview", $diff); } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 30c93df20..0068a6b11 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -6,19 +6,19 @@ use strict; use IkiWiki; use open qw{:utf8 :std}; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "editpage", call => \&getsetup); hook(type => "refresh", id => "editpage", call => \&refresh); hook(type => "sessioncgi", id => "editpage", call => \&IkiWiki::cgi_editpage); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} sub refresh () { if (exists $wikistate{editpage} && exists $wikistate{editpage}{previews}) { @@ -51,37 +51,10 @@ sub refresh () { # Back to ikiwiki namespace for the rest, this code is very much # internal to ikiwiki even though it's separated into a plugin, -# and other plugins use the functions below. +# and other plugins use the function below. package IkiWiki; -sub check_canedit ($$$;$) { #{{{ - my $page=shift; - my $q=shift; - my $session=shift; - my $nonfatal=shift; - - my $canedit; - run_hooks(canedit => sub { - return if defined $canedit; - my $ret=shift->($page, $q, $session); - if (defined $ret) { - if ($ret eq "") { - $canedit=1; - } - elsif (ref $ret eq 'CODE') { - $ret->() unless $nonfatal; - $canedit=0; - } - elsif (defined $ret) { - error($ret) unless $nonfatal; - $canedit=0; - } - } - }); - return $canedit; -} #}}} - -sub cgi_editpage ($$) { #{{{ +sub cgi_editpage ($$) { my $q=shift; my $session=shift; @@ -105,7 +78,6 @@ sub cgi_editpage ($$) { #{{{ header => 0, table => 0, template => scalar template_params("editpage.tmpl"), - wikiname => $config{wikiname}, ); decode_form_utf8($form); @@ -122,7 +94,7 @@ sub cgi_editpage ($$) { #{{{ my $absolute=($page =~ s#^/+##); if (! defined $page || ! length $page || file_pruned($page, $config{srcdir})) { - error("bad page name"); + error(gettext("bad page name")); } my $baseurl = urlto($page, undef, 1); @@ -340,16 +312,7 @@ sub cgi_editpage ($$) { #{{{ else { # save page check_canedit($page, $q, $session); - - # The session id is stored on the form and checked to - # guard against CSRF. But only if the user is logged in, - # as anonok can allow anonymous edits. - if (defined $session->param("name")) { - my $sid=$q->param('sid'); - if (! defined $sid || $sid ne $session->id) { - error(gettext("Your login session has expired.")); - } - } + checksessionexpiry($q, $session, $q->param('sid')); my $exists=-e "$config{srcdir}/$file"; @@ -378,8 +341,17 @@ sub cgi_editpage ($$) { #{{{ showform($form, \@buttons, $session, $q, forcebaseurl => $baseurl); exit; } + + my $message=""; + if (defined $form->field('comments') && + length $form->field('comments')) { + $message=$form->field('comments'); + } my $content=$form->field('editcontent'); + check_content(content => $content, page => $page, + cgi => $q, session => $session, + subject => $message); run_hooks(editcontent => sub { $content=shift->( content => $content, @@ -413,12 +385,6 @@ sub cgi_editpage ($$) { #{{{ my $conflict; if ($config{rcs}) { - my $message=""; - if (defined $form->field('comments') && - length $form->field('comments')) { - $message=$form->field('comments'); - } - if (! $exists) { rcs_add($file); } @@ -462,6 +428,6 @@ sub cgi_editpage ($$) { #{{{ } exit; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/edittemplate.pm b/IkiWiki/Plugin/edittemplate.pm index 846b4e7c8..0bafc95d0 100644 --- a/IkiWiki/Plugin/edittemplate.pm +++ b/IkiWiki/Plugin/edittemplate.pm @@ -3,11 +3,11 @@ package IkiWiki::Plugin::edittemplate; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Template; use Encode; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "edittemplate", call => \&getsetup); hook(type => "needsbuild", id => "edittemplate", @@ -16,17 +16,17 @@ sub import { #{{{ call => \&preprocess); hook(type => "formbuilder", id => "edittemplate", call => \&formbuilder); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; foreach my $page (keys %pagestate) { @@ -40,9 +40,9 @@ sub needsbuild (@) { #{{{ } } } -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; return "" if $params{page} ne $params{destpage}; @@ -62,9 +62,9 @@ sub preprocess (@) { #{{{ return sprintf(gettext("edittemplate %s registered for %s"), htmllink($params{page}, $params{destpage}, $link), $params{match}); -} # }}} +} -sub formbuilder (@) { #{{{ +sub formbuilder (@) { my %params=@_; my $form=$params{form}; @@ -103,9 +103,9 @@ sub formbuilder (@) { #{{{ } } } -} #}}} +} -sub filltemplate ($$) { #{{{ +sub filltemplate ($$) { my $template_page=shift; my $page=shift; @@ -136,6 +136,6 @@ sub filltemplate ($$) { #{{{ $template->param(name => $page); return $template->output; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/embed.pm b/IkiWiki/Plugin/embed.pm index 2a1637392..a7d38358f 100644 --- a/IkiWiki/Plugin/embed.pm +++ b/IkiWiki/Plugin/embed.pm @@ -3,7 +3,7 @@ package IkiWiki::Plugin::embed; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my $attribr=qr/[^<>"]+/; @@ -43,35 +43,35 @@ my $safehtml=qr{( my @embedded; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "embed", call => \&getsetup); hook(type => "filter", id => "embed", call => \&filter); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub embed ($) { #{{{ +sub embed ($) { hook(type => "format", id => "embed", call => \&format) unless @embedded; push @embedded, shift; return "
"; -} #}}} +} -sub filter (@) { #{{{ +sub filter (@) { my %params=@_; $params{content} =~ s/$safehtml/embed($1)/eg; return $params{content}; -} # }}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; $params{content} =~ s/
<\/div>/$embedded[$1]/eg; return $params{content}; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/external.pm b/IkiWiki/Plugin/external.pm index ba6c7d8b9..066f15cf1 100644 --- a/IkiWiki/Plugin/external.pm +++ b/IkiWiki/Plugin/external.pm @@ -6,7 +6,7 @@ package IkiWiki::Plugin::external; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use RPC::XML; use RPC::XML::Parser; use IPC::Open2; @@ -14,7 +14,7 @@ use IO::Handle; my %plugins; -sub import { #{{{ +sub import { my $self=shift; my $plugin=shift; return unless defined $plugin; @@ -32,17 +32,17 @@ sub import { #{{{ $RPC::XML::ENCODING="utf-8"; rpc_call($plugins{$plugin}, "import"); -} #}}} +} -sub rpc_write ($$) { #{{{ +sub rpc_write ($$) { my $fh=shift; my $string=shift; $fh->print($string."\n"); $fh->flush; -} #}}} +} -sub rpc_call ($$;@) { #{{{ +sub rpc_call ($$;@) { my $plugin=shift; my $command=shift; @@ -131,12 +131,12 @@ sub rpc_call ($$;@) { #{{{ } return undef; -} #}}} +} package IkiWiki::RPC::XML; use Memoize; -sub getvar ($$$) { #{{{ +sub getvar ($$$) { my $plugin=shift; my $varname="IkiWiki::".shift; my $key=shift; @@ -145,9 +145,9 @@ sub getvar ($$$) { #{{{ my $ret=$varname->{$key}; use strict 'refs'; return $ret; -} #}}} +} -sub setvar ($$$;@) { #{{{ +sub setvar ($$$;@) { my $plugin=shift; my $varname="IkiWiki::".shift; my $key=shift; @@ -157,18 +157,18 @@ sub setvar ($$$;@) { #{{{ my $ret=$varname->{$key}=$value; use strict 'refs'; return $ret; -} #}}} +} -sub getstate ($$$$) { #{{{ +sub getstate ($$$$) { my $plugin=shift; my $page=shift; my $id=shift; my $key=shift; return $IkiWiki::pagestate{$page}{$id}{$key}; -} #}}} +} -sub setstate ($$$$;@) { #{{{ +sub setstate ($$$$;@) { my $plugin=shift; my $page=shift; my $id=shift; @@ -176,22 +176,22 @@ sub setstate ($$$$;@) { #{{{ my $value=shift; return $IkiWiki::pagestate{$page}{$id}{$key}=$value; -} #}}} +} -sub getargv ($) { #{{{ +sub getargv ($) { my $plugin=shift; return \@ARGV; -} #}}} +} -sub setargv ($@) { #{{{ +sub setargv ($@) { my $plugin=shift; my $array=shift; @ARGV=@$array; -} #}}} +} -sub inject ($@) { #{{{ +sub inject ($@) { # Bind a given perl function name to a particular RPC request. my $plugin=shift; my %params=@_; @@ -202,12 +202,20 @@ sub inject ($@) { #{{{ my $sub = sub { IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_) }; - eval qq{*$params{name}=\$sub}; - memoize($params{name}) if $params{memoize}; - return 1; -} #}}} + $sub=memoize($sub) if $params{memoize}; -sub hook ($@) { #{{{ + # This will add it to the symbol table even if not present. + no warnings; + eval qq{*$params{name}=\$sub}; + use warnings; + + # This will ensure that everywhere it was exported to sees + # the injected version. + IkiWiki::inject(name => $params{name}, call => $sub); + return 1; +} + +sub hook ($@) { # the call parameter is a function name to call, since XML RPC # cannot pass a function reference my $plugin=shift; @@ -219,13 +227,13 @@ sub hook ($@) { #{{{ IkiWiki::hook(%params, call => sub { IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_); }); -} #}}} +} -sub pagespec_match ($@) { #{{{ +sub pagespec_match ($@) { # convert pagespec_match's return object into a XML RPC boolean my $plugin=shift; return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_)); -} #}}} +} 1 diff --git a/IkiWiki/Plugin/favicon.pm b/IkiWiki/Plugin/favicon.pm index e9204dea9..6060914c5 100644 --- a/IkiWiki/Plugin/favicon.pm +++ b/IkiWiki/Plugin/favicon.pm @@ -5,22 +5,22 @@ package IkiWiki::Plugin::favicon; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "favicon", call => \&getsetup); hook(type => "pagetemplate", id => "favicon", call => \&pagetemplate); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $template=$params{template}; @@ -28,6 +28,6 @@ sub pagetemplate (@) { #{{{ if ($template->query(name => "favicon")) { $template->param(favicon => "favicon.ico"); } -} # }}} +} 1 diff --git a/IkiWiki/Plugin/filecheck.pm b/IkiWiki/Plugin/filecheck.pm index 27f764e3b..8575ee108 100644 --- a/IkiWiki/Plugin/filecheck.pm +++ b/IkiWiki/Plugin/filecheck.pm @@ -3,7 +3,7 @@ package IkiWiki::Plugin::filecheck; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %units=( #{{{ # size in bytes B => 1, @@ -37,9 +37,9 @@ my %units=( #{{{ # size in bytes # ikiwiki, if you find you need larger data quantities, either modify # yourself to add them, or travel back in time to 2008 and kill me. # -- Joey -); #}}} +); -sub parsesize ($) { #{{{ +sub parsesize ($) { my $size=shift; no warnings; @@ -51,10 +51,10 @@ sub parsesize ($) { #{{{ } } return $base; -} #}}} +} # This is provided for other plugins that want to convert back the other way. -sub humansize ($) { #{{{ +sub humansize ($) { my $size=shift; foreach my $unit (reverse sort { $units{$a} <=> $units{$b} || $b cmp $a } keys %units) { @@ -63,11 +63,11 @@ sub humansize ($) { #{{{ } } return $size; # near zero, or negative -} #}}} +} package IkiWiki::PageSpec; -sub match_maxsize ($$;@) { #{{{ +sub match_maxsize ($$;@) { my $page=shift; my $maxsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)}; if ($@) { @@ -86,9 +86,9 @@ sub match_maxsize ($$;@) { #{{{ else { return IkiWiki::SuccessReason->new("file not too large"); } -} #}}} +} -sub match_minsize ($$;@) { #{{{ +sub match_minsize ($$;@) { my $page=shift; my $minsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)}; if ($@) { @@ -107,9 +107,9 @@ sub match_minsize ($$;@) { #{{{ else { return IkiWiki::SuccessReason->new("file not too small"); } -} #}}} +} -sub match_mimetype ($$;@) { #{{{ +sub match_mimetype ($$;@) { my $page=shift; my $wanted=shift; @@ -140,9 +140,9 @@ sub match_mimetype ($$;@) { #{{{ else { return IkiWiki::SuccessReason->new("file MIME type is $mimetype"); } -} #}}} +} -sub match_virusfree ($$;@) { #{{{ +sub match_virusfree ($$;@) { my $page=shift; my $wanted=shift; @@ -182,9 +182,9 @@ sub match_virusfree ($$;@) { #{{{ else { return IkiWiki::SuccessReason->new("file seems virusfree ($reason)"); } -} #}}} +} -sub match_ispage ($$;@) { #{{{ +sub match_ispage ($$;@) { my $filename=shift; if (defined IkiWiki::pagetype($filename)) { @@ -193,4 +193,4 @@ sub match_ispage ($$;@) { #{{{ else { return IkiWiki::FailReason->new("file is not a wiki page"); } -} #}}} +} diff --git a/IkiWiki/Plugin/format.pm b/IkiWiki/Plugin/format.pm new file mode 100644 index 000000000..bbe3aa9fe --- /dev/null +++ b/IkiWiki/Plugin/format.pm @@ -0,0 +1,30 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::format; + +use warnings; +use strict; +use IkiWiki 3.00; + +sub import { + hook(type => "preprocess", id => "format", call => \&preprocess); +} + +sub preprocess (@) { + my $format=$_[0]; + shift; shift; + my $text=$_[0]; + shift; shift; + my %params=@_; + + if (! defined $format || ! defined $text) { + error(gettext("must specify format and text")); + } + elsif (! exists $IkiWiki::hooks{htmlize}{$format}) { + error(sprintf(gettext("unsupported page format %s"), $format)); + } + + return IkiWiki::htmlize($params{page}, $params{destpage}, $format, + IkiWiki::preprocess($params{page}, $params{destpage}, $text)); +} + +1 diff --git a/IkiWiki/Plugin/fortune.pm b/IkiWiki/Plugin/fortune.pm index 456b63e9f..17e57dea1 100644 --- a/IkiWiki/Plugin/fortune.pm +++ b/IkiWiki/Plugin/fortune.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::fortune; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "fortune", call => \&getsetup); hook(type => "preprocess", id => "fortune", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { $ENV{PATH}="$ENV{PATH}:/usr/games:/usr/local/games"; my $f = `fortune 2>/dev/null`; @@ -29,6 +29,6 @@ sub preprocess (@) { #{{{ else { return "
$f
\n"; } -} # }}} +} 1 diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index 14b0ab285..68b114a73 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -9,8 +9,9 @@ use open qw{:utf8 :std}; my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums my $dummy_commit_msg = 'dummy commit'; # message to skip in recent changes +my $no_chdir=0; -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "git", call => \&checkconfig); hook(type => "getsetup", id => "git", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -23,24 +24,34 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} + hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive); +} -sub checkconfig () { #{{{ +sub checkconfig () { if (! defined $config{gitorigin_branch}) { $config{gitorigin_branch}="origin"; } if (! defined $config{gitmaster_branch}) { $config{gitmaster_branch}="master"; } - if (defined $config{git_wrapper} && length $config{git_wrapper}) { + if (defined $config{git_wrapper} && + length $config{git_wrapper}) { push @{$config{wrappers}}, { wrapper => $config{git_wrapper}, wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"), }; } -} #}}} + if (defined $config{git_test_receive_wrapper} && + length $config{git_test_receive_wrapper}) { + push @{$config{wrappers}}, { + test_receive => 1, + wrapper => $config{git_test_receive_wrapper}, + wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"), + }; + } +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -60,6 +71,20 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, + git_test_receive_wrapper => { + type => "string", + example => "/git/wiki.git/hooks/pre-receive", + description => "git pre-receive hook to generate", + safe => 0, # file + rebuild => 0, + }, + untrusted_committers => { + type => "string", + example => [], + description => "unix users whose commits should be checked by the pre-receive hook", + safe => 0, + rebuild => 0, + }, historyurl => { type => "string", example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=history;f=[[file]]", @@ -69,8 +94,8 @@ sub getsetup () { #{{{ }, diffurl => { type => "string", - example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_parent]];f=[[file]]", - description => "gitweb url to show a diff ([[sha1_to]], [[sha1_from]], [[sha1_parent]], and [[file]] substituted)", + example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]", + description => "gitweb url to show a diff ([[file]], [[sha1_to]], [[sha1_from]], [[sha1_commit]], and [[sha1_parent]] substituted)", safe => 1, rebuild => 1, }, @@ -88,9 +113,9 @@ sub getsetup () { #{{{ safe => 0, # paranoia rebuild => 0, }, -} #}}} +} -sub safe_git (&@) { #{{{ +sub safe_git (&@) { # Start a child process safely without resorting /bin/sh. # Return command output or success state (in scalar context). @@ -103,15 +128,25 @@ sub safe_git (&@) { #{{{ if (!$pid) { # In child. # Git commands want to be in wc. - chdir $config{srcdir} - or error("Cannot chdir to $config{srcdir}: $!"); + if (! $no_chdir) { + chdir $config{srcdir} + or error("Cannot chdir to $config{srcdir}: $!"); + } exec @cmdline or error("Cannot exec '@cmdline': $!"); } # In parent. + # git output is probably utf-8 encoded, but may contain + # other encodings or invalidly encoded stuff. So do not rely + # on the normal utf-8 IO layer, decode it by hand. + binmode($OUT); + my @lines; while (<$OUT>) { + $_=decode_utf8($_, 0); + chomp; + push @lines, $_; } @@ -125,9 +160,9 @@ sub safe_git (&@) { #{{{ sub run_or_die ($@) { safe_git(\&error, @_) } sub run_or_cry ($@) { safe_git(sub { warn @_ }, @_) } sub run_or_non ($@) { safe_git(undef, @_) } -#}}} -sub merge_past ($$$) { #{{{ + +sub merge_past ($$$) { # Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'. # Git merge commands work with the committed changes, except in the # implicit case of '-m' of git checkout(1). So we should invent a @@ -219,9 +254,9 @@ sub merge_past ($$$) { #{{{ error("Git merge failed!\n$failure\n") if $failure; return $conflict; -} #}}} +} -sub parse_diff_tree ($@) { #{{{ +sub parse_diff_tree ($@) { # Parse the raw diff tree chunk and return the info hash. # See git-diff-tree(1) for the syntax. @@ -320,6 +355,9 @@ sub parse_diff_tree ($@) { #{{{ 'file' => decode("utf8", $file), 'sha1_from' => $sha1_from[0], 'sha1_to' => $sha1_to, + 'mode_from' => $mode_from[0], + 'mode_to' => $mode_to, + 'status' => $status, }; } next; @@ -328,17 +366,17 @@ sub parse_diff_tree ($@) { #{{{ } return \%ci; -} #}}} +} -sub git_commit_info ($;$) { #{{{ - # Return an array of commit info hashes of num commits (default: 1) +sub git_commit_info ($;$) { + # Return an array of commit info hashes of num commits # starting from the given sha1sum. - my ($sha1, $num) = @_; - $num ||= 1; + my @opts; + push @opts, "--max-count=$num" if defined $num; - my @raw_lines = run_or_die('git', 'log', "--max-count=$num", + my @raw_lines = run_or_die('git', 'log', @opts, '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c', '-r', $sha1, '--', '.'); my ($prefix) = run_or_die('git', 'rev-parse', '--show-prefix'); @@ -351,11 +389,10 @@ sub git_commit_info ($;$) { #{{{ warn "Cannot parse commit info for '$sha1' commit" if !@ci; return wantarray ? @ci : $ci[0]; -} #}}} +} -sub git_sha1 (;$) { #{{{ +sub git_sha1 (;$) { # Return head sha1sum (of given file). - my $file = shift || q{--}; # Ignore error since a non-existing file might be given. @@ -365,26 +402,25 @@ sub git_sha1 (;$) { #{{{ ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now } else { debug("Empty sha1sum for '$file'.") } return defined $sha1 ? $sha1 : q{}; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { # Update working directory. if (length $config{gitorigin_branch}) { run_or_cry('git', 'pull', $config{gitorigin_branch}); } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { # Return the commit sha1sum of the file when editing begins. # This will be later used in rcs_commit if a merge is required. - my ($file) = @_; return git_sha1($file); -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { # Try to commit the page; returns undef on _success_ and # a version of the page with the rcs's conflict markers on # failure. @@ -403,7 +439,7 @@ sub rcs_commit ($$$;$$) { #{{{ rcs_add($file); return rcs_commit_staged($message, $user, $ipaddr); -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -413,7 +449,7 @@ sub rcs_commit_staged ($$$) { # Set the commit author and email to the web committer. my %env=%ENV; if (defined $user || defined $ipaddr) { - my $u=defined $user ? $user : $ipaddr; + my $u=encode_utf8(defined $user ? $user : $ipaddr); $ENV{GIT_AUTHOR_NAME}=$u; $ENV{GIT_AUTHOR_EMAIL}="$u\@web"; } @@ -444,29 +480,29 @@ sub rcs_commit_staged ($$$) { return undef; # success } -sub rcs_add ($) { # {{{ +sub rcs_add ($) { # Add file to archive. my ($file) = @_; run_or_cry('git', 'add', $file); -} #}}} +} -sub rcs_remove ($) { # {{{ +sub rcs_remove ($) { # Remove file from archive. my ($file) = @_; run_or_cry('git', 'rm', '-f', $file); -} #}}} +} -sub rcs_rename ($$) { # {{{ +sub rcs_rename ($$) { my ($src, $dest) = @_; run_or_cry('git', 'mv', '-f', $src, $dest); -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { # List of recent changes. my ($num) = @_; @@ -475,7 +511,7 @@ sub rcs_recentchanges ($) { #{{{ error($@) if $@; my @rets; - foreach my $ci (git_commit_info('HEAD', $num)) { + foreach my $ci (git_commit_info('HEAD', $num || 1)) { # Skip redundant commits. next if ($ci->{'comment'} && @{$ci->{'comment'}}[0] eq $dummy_commit_msg); @@ -493,6 +529,7 @@ sub rcs_recentchanges ($) { #{{{ $diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go; $diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go; $diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go; + $diffurl =~ s/\[\[sha1_commit\]\]/$sha1/go; push @pages, { page => pagename($file), @@ -533,9 +570,9 @@ sub rcs_recentchanges ($) { #{{{ } return @rets; -} #}}} +} -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { my $rev=shift; my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint my @lines; @@ -550,19 +587,112 @@ sub rcs_diff ($) { #{{{ else { return join("", @lines); } -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { my $file=shift; # Remove srcdir prefix $file =~ s/^\Q$config{srcdir}\E\/?//; - my $sha1 = git_sha1($file); - my $ci = git_commit_info($sha1); + my @sha1s = run_or_non('git', 'rev-list', 'HEAD', '--', $file); + my $ci = git_commit_info($sha1s[$#sha1s], 1); my $ctime = $ci->{'author_epoch'}; debug("ctime for '$file': ". localtime($ctime)); return $ctime; -} #}}} +} + +sub rcs_receive () { + # The wiki may not be the only thing in the git repo. + # Determine if it is in a subdirectory by examining the srcdir, + # and its parents, looking for the .git directory. + my $subdir=""; + my $dir=$config{srcdir}; + while (! -d "$dir/.git") { + $subdir=IkiWiki::basename($dir)."/".$subdir; + $dir=IkiWiki::dirname($dir); + if (! length $dir) { + error("cannot determine root of git repo"); + } + } + + my @rets; + while (<>) { + chomp; + my ($oldrev, $newrev, $refname) = split(' ', $_, 3); + + # only allow changes to gitmaster_branch + if ($refname !~ /^refs\/heads\/\Q$config{gitmaster_branch}\E$/) { + error sprintf(gettext("you are not allowed to change %s"), $refname); + } + + # Avoid chdir when running git here, because the changes + # are in the master git repo, not the srcdir repo. + # The pre-recieve hook already puts us in the right place. + $no_chdir=1; + my @changes=git_commit_info($oldrev."..".$newrev); + $no_chdir=0; + + foreach my $ci (@changes) { + foreach my $detail (@{ $ci->{'details'} }) { + my $file = $detail->{'file'}; + + # check that all changed files are in the + # subdir + if (length $subdir && + ! ($file =~ s/^\Q$subdir\E//)) { + error sprintf(gettext("you are not allowed to change %s"), $file); + } + + my ($action, $mode, $path); + if ($detail->{'status'} =~ /^[M]+\d*$/) { + $action="change"; + $mode=$detail->{'mode_to'}; + } + elsif ($detail->{'status'} =~ /^[AM]+\d*$/) { + $action="add"; + $mode=$detail->{'mode_to'}; + } + elsif ($detail->{'status'} =~ /^[DAM]+\d*/) { + $action="remove"; + $mode=$detail->{'mode_from'}; + } + else { + error "unknown status ".$detail->{'status'}; + } + + # test that the file mode is ok + if ($mode !~ /^100[64][64][64]$/) { + error sprintf(gettext("you cannot act on a file with mode %s"), $mode); + } + if ($action eq "change") { + if ($detail->{'mode_from'} ne $detail->{'mode_to'}) { + error gettext("you are not allowed to change file modes"); + } + } + + # extract attachment to temp file + if (($action eq 'add' || $action eq 'change') && + ! pagetype($file)) { + eval q{use File::Temp}; + die $@ if $@; + my $fh; + ($fh, $path)=File::Temp::tempfile("XXXXXXXXXX", UNLINK => 1); + if (system("git show ".$detail->{sha1_to}." > '$path'") != 0) { + error("failed writing temp file"); + } + } + + push @rets, { + file => $file, + action => $action, + path => $path, + }; + } + } + } + + return reverse @rets; +} 1 diff --git a/IkiWiki/Plugin/goodstuff.pm b/IkiWiki/Plugin/goodstuff.pm index ed1f4ddfc..451cd6f84 100644 --- a/IkiWiki/Plugin/goodstuff.pm +++ b/IkiWiki/Plugin/goodstuff.pm @@ -4,13 +4,12 @@ package IkiWiki::Plugin::goodstuff; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my @bundle=qw{ brokenlinks img map - meta more orphans pagecount @@ -23,21 +22,22 @@ my @bundle=qw{ template toc toggle + repolist }; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "goodstuff", call => \&getsetup); foreach my $plugin (@bundle) { IkiWiki::loadplugin($plugin); } -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} 1 diff --git a/IkiWiki/Plugin/google.pm b/IkiWiki/Plugin/google.pm index 92b9b29eb..4bba5775c 100644 --- a/IkiWiki/Plugin/google.pm +++ b/IkiWiki/Plugin/google.pm @@ -3,26 +3,26 @@ package IkiWiki::Plugin::google; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use URI; my $host; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "google", call => \&getsetup); hook(type => "checkconfig", id => "google", call => \&checkconfig); hook(type => "pagetemplate", id => "google", call => \&pagetemplate); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (! length $config{url}) { error(sprintf(gettext("Must specify %s when using the google search plugin"), "url")); } @@ -31,10 +31,10 @@ sub checkconfig () { #{{{ error(gettext("Failed to parse url, cannot determine domain name")); } $host=$uri->host; -} #}}} +} my $form; -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; my $template=$params{template}; @@ -49,6 +49,6 @@ sub pagetemplate (@) { #{{{ $template->param(searchform => $form); } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/googlecalendar.pm b/IkiWiki/Plugin/googlecalendar.pm deleted file mode 100644 index 81a3ad677..000000000 --- a/IkiWiki/Plugin/googlecalendar.pm +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/perl -package IkiWiki::Plugin::googlecalendar; - -use warnings; -use strict; -use IkiWiki 2.00; - -sub import { #{{{ - hook(type => "getsetup", id => "googlecalendar", - call => \&getsetup); - hook(type => "preprocess", id => "googlecalendar", - call => \&preprocess); - hook(type => "format", id => "googlecalendar", - call => \&format); -} # }}} - -sub getsetup () { #{{{ - return - plugin => { - safe => 1, - rebuild => undef, - }, -} #}}} - -sub preprocess (@) { #{{{ - my %params=@_; - - # Parse the html, looking for the url to embed for the calendar. - # Avoid XSS attacks.. - my ($url)=$params{html}=~m#iframe\s+src="http://www\.google\.com/calendar/embed\?([^"<>]+)"#; - if (! defined $url || ! length $url) { - error gettext("failed to find url in html") - } - my ($height)=$params{html}=~m#height="(\d+)"#; - my ($width)=$params{html}=~m#width="(\d+)"#; - - return "
"; -} # }}} - -sub format (@) { #{{{ - my %params=@_; - - $params{content}=~s/
<\/div>/gencal($1,$2,$3)/eg; - - return $params{content}; -} # }}} - -sub gencal ($$$) { #{{{ - my $url=shift; - my $height=shift; - my $width=shift; - return qq{}; -} #}}} - -1 diff --git a/IkiWiki/Plugin/goto.pm b/IkiWiki/Plugin/goto.pm new file mode 100644 index 000000000..3f40c5859 --- /dev/null +++ b/IkiWiki/Plugin/goto.pm @@ -0,0 +1,75 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::goto; + +use warnings; +use strict; +use IkiWiki 3.00; + +sub import { + hook(type => "cgi", id => 'goto', call => \&cgi); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => 0, + } +} + +# cgi_goto(CGI, [page]) +# Redirect to a specified page, or display "not found". If not specified, +# the page param from the CGI object is used. +sub cgi_goto ($;$) { + my $q = shift; + my $page = shift; + + if (!defined $page) { + $page = IkiWiki::decode_utf8($q->param("page")); + + if (!defined $page) { + error("missing page parameter"); + } + } + + IkiWiki::loadindex(); + + # If the page is internal (like a comment), see if it has a + # permalink. Comments do. + if (IkiWiki::isinternal($page) && + defined $pagestate{$page}{meta}{permalink}) { + IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink}); + } + + my $link = bestlink("", $page); + + if (! length $link) { + IkiWiki::cgi_custom_failure( + $q->header(-status => "404 Not Found"), + IkiWiki::misctemplate(gettext("missing page"), + "

". + sprintf(gettext("The page %s does not exist."), + htmllink("", "", $page)). + "

") + ) + } + else { + IkiWiki::redirect($q, urlto($link, undef, 1)); + } + + exit; +} + +sub cgi ($) { + my $cgi=shift; + my $do = $cgi->param('do'); + + if (defined $do && ($do eq 'goto' || $do eq 'commenter' || + $do eq 'recentchanges_link')) { + # goto is the preferred name for this; recentchanges_link and + # commenter are for compatibility with any saved URLs + cgi_goto($cgi); + } +} + +1; diff --git a/IkiWiki/Plugin/graphviz.pm b/IkiWiki/Plugin/graphviz.pm index 20b419413..32e994d6b 100644 --- a/IkiWiki/Plugin/graphviz.pm +++ b/IkiWiki/Plugin/graphviz.pm @@ -5,27 +5,27 @@ package IkiWiki::Plugin::graphviz; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use IPC::Open2; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "graphviz", call => \&getsetup); hook(type => "preprocess", id => "graph", call => \&graph); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} my %graphviz_programs = ( "dot" => 1, "neato" => 1, "fdp" => 1, "twopi" => 1, "circo" => 1 ); -sub render_graph (\%) { #{{{ +sub render_graph (\%) { my %params = %{(shift)}; my $src = "$params{type} g {\n"; @@ -45,7 +45,7 @@ sub render_graph (\%) { #{{{ if (! -e "$config{destdir}/$dest") { my $pid; - my $sigpipe=0;; + my $sigpipe=0; $SIG{PIPE}=sub { $sigpipe=1 }; $pid=open2(*IN, *OUT, "$params{prog} -Tpng"); @@ -84,9 +84,9 @@ sub render_graph (\%) { #{{{ else { return "\n"; } -} #}}} +} -sub graph (@) { #{{{ +sub graph (@) { my %params=@_; $params{src} = "" unless defined $params{src}; $params{type} = "digraph" unless defined $params{type}; @@ -94,6 +94,6 @@ sub graph (@) { #{{{ error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}}; return render_graph(%params); -} # }}} +} 1 diff --git a/IkiWiki/Plugin/haiku.pm b/IkiWiki/Plugin/haiku.pm index eb8b786e8..5a062a276 100644 --- a/IkiWiki/Plugin/haiku.pm +++ b/IkiWiki/Plugin/haiku.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::haiku; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "haiku", call => \&getsetup); hook(type => "preprocess", id => "haiku", call => \&preprocess); -} # }}} +} -sub getsetup { #{{{ +sub getsetup { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; my $haiku; @@ -54,6 +54,6 @@ sub preprocess (@) { #{{{ $haiku=~s/\n/
\n/mg; return "\n\n

$haiku

\n\n"; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/hnb.pm b/IkiWiki/Plugin/hnb.pm index 40e4f9452..bd2177a06 100644 --- a/IkiWiki/Plugin/hnb.pm +++ b/IkiWiki/Plugin/hnb.pm @@ -10,23 +10,23 @@ package IkiWiki::Plugin::hnb; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use File::Temp qw(:mktemp); -sub import { #{{{ +sub import { hook(type => "getsetup", id => "hnb", call => \&getsetup); hook(type => "htmlize", id => "hnb", call => \&htmlize); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params = @_; # hnb outputs version number etc. every time to STDOUT, so @@ -52,6 +52,6 @@ sub htmlize (@) { #{{{ $ret =~ s/.*//si; return $ret; -} #}}} +} 1; diff --git a/IkiWiki/Plugin/html.pm b/IkiWiki/Plugin/html.pm index b75207578..a7d5e8ce9 100644 --- a/IkiWiki/Plugin/html.pm +++ b/IkiWiki/Plugin/html.pm @@ -4,9 +4,9 @@ package IkiWiki::Plugin::html; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "html", call => \&getsetup); hook(type => "htmlize", id => "html", call => \&htmlize); hook(type => "htmlize", id => "htm", call => \&htmlize); @@ -14,19 +14,19 @@ sub import { #{{{ # ikiwiki defaults to skipping .html files as a security measure; # make it process them so this plugin can take effect $config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ]; -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; return $params{content}; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/htmlbalance.pm b/IkiWiki/Plugin/htmlbalance.pm new file mode 100644 index 000000000..26f8e494b --- /dev/null +++ b/IkiWiki/Plugin/htmlbalance.pm @@ -0,0 +1,58 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::htmlbalance; + +# htmlbalance: Parse and re-serialize HTML to ensure balanced tags +# +# Copyright 2008 Simon McVittie +# Licensed under the GNU GPL, version 2, or any later version published by the +# Free Software Foundation + +use warnings; +use strict; +use IkiWiki 3.00; +use HTML::Entities; + +sub import { + hook(type => "getsetup", id => "htmlbalance", call => \&getsetup); + hook(type => "sanitize", id => "htmlbalance", call => \&sanitize); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => undef, + }, +} + +sub sanitize (@) { + my %params=@_; + my $ret = ''; + + eval q{use HTML::TreeBuilder}; + error $@ if $@; + my $tree = HTML::TreeBuilder->new(); + $tree->ignore_unknown(0); + $tree->ignore_ignorable_whitespace(0); + $tree->no_space_compacting(1); + $tree->p_strict(1); + $tree->store_comments(0); + $tree->store_declarations(0); + $tree->store_pis(0); + $tree->parse_content($params{content}); + my @nodes = $tree->disembowel(); + foreach my $node (@nodes) { + if (ref $node) { + $ret .= $node->as_XML(); + chomp $ret; + $node->delete(); + } + else { + $ret .= encode_entities($node); + } + } + $tree->delete(); + return $ret; +} + +1 diff --git a/IkiWiki/Plugin/htmlscrubber.pm b/IkiWiki/Plugin/htmlscrubber.pm index 7398c8478..a249cdf7a 100644 --- a/IkiWiki/Plugin/htmlscrubber.pm +++ b/IkiWiki/Plugin/htmlscrubber.pm @@ -3,13 +3,13 @@ package IkiWiki::Plugin::htmlscrubber; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; # This regexp matches urls that are in a known safe scheme. # Feel free to use it from other plugins. our $safe_url_regexp; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "htmlscrubber", call => \&getsetup); hook(type => "sanitize", id => "htmlscrubber", call => \&sanitize); @@ -33,9 +33,9 @@ sub import { #{{{ # data is a special case. Allow data:image/*, but # disallow data:text/javascript and everything else. $safe_url_regexp=qr/^(?:(?:$uri_schemes):|data:image\/|[^:]+(?:$|\/))/i; -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -49,9 +49,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => undef, }, -} #}}} +} -sub sanitize (@) { #{{{ +sub sanitize (@) { my %params=@_; if (exists $config{htmlscrubber_skip} && @@ -62,10 +62,10 @@ sub sanitize (@) { #{{{ } return scrubber()->scrub($params{content}); -} # }}} +} my $_scrubber; -sub scrubber { #{{{ +sub scrubber { return $_scrubber if defined $_scrubber; eval q{use HTML::Scrubber}; @@ -111,6 +111,6 @@ sub scrubber { #{{{ }], ); return $_scrubber; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/htmltidy.pm b/IkiWiki/Plugin/htmltidy.pm index 9ba5e9592..6f3379ef4 100644 --- a/IkiWiki/Plugin/htmltidy.pm +++ b/IkiWiki/Plugin/htmltidy.pm @@ -9,23 +9,23 @@ package IkiWiki::Plugin::htmltidy; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use IPC::Open2; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "tidy", call => \&getsetup); hook(type => "sanitize", id => "tidy", call => \&sanitize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub sanitize (@) { #{{{ +sub sanitize (@) { my %params=@_; my $pid; @@ -49,6 +49,6 @@ sub sanitize (@) { #{{{ return "" if $sigpipe || ! defined $ret; return $ret; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/httpauth.pm b/IkiWiki/Plugin/httpauth.pm index fc0cffb1e..1816c9d74 100644 --- a/IkiWiki/Plugin/httpauth.pm +++ b/IkiWiki/Plugin/httpauth.pm @@ -4,28 +4,28 @@ package IkiWiki::Plugin::httpauth; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "httpauth", call => \&getsetup); hook(type => "auth", id => "httpauth", call => \&auth); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub auth ($$) { #{{{ +sub auth ($$) { my $cgi=shift; my $session=shift; if (defined $cgi->remote_user()) { $session->param("name", $cgi->remote_user()); } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/img.pm b/IkiWiki/Plugin/img.pm index 7b89ab673..d295b833b 100644 --- a/IkiWiki/Plugin/img.pm +++ b/IkiWiki/Plugin/img.pm @@ -5,24 +5,24 @@ package IkiWiki::Plugin::img; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %imgdefaults; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "img", call => \&getsetup); hook(type => "preprocess", id => "img", call => \&preprocess, scan => 1); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my ($image) = $_[0] =~ /$config{wiki_file_regexp}/; # untaint my %params=@_; @@ -119,9 +119,9 @@ sub preprocess (@) { #{{{ } my $imgtag=''.(exists $params{alt} ? $params{alt} : '').
 		' "getopt", id => "inline", call => \&getopt); hook(type => "getsetup", id => "inline", call => \&getsetup); hook(type => "checkconfig", id => "inline", call => \&checkconfig); @@ -22,15 +22,14 @@ sub import { #{{{ call => \&IkiWiki::preprocess_inline); hook(type => "pagetemplate", id => "inline", call => \&IkiWiki::pagetemplate_inline); - hook(type => "format", id => "inline", call => \&format); + hook(type => "format", id => "inline", call => \&format, first => 1); # Hook to change to do pinging since it's called late. # This ensures each page only pings once and prevents slow # pings interrupting page builds. - hook(type => "change", id => "inline", - call => \&IkiWiki::pingurl); -} # }}} + hook(type => "change", id => "inline", call => \&IkiWiki::pingurl); +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); @@ -43,9 +42,9 @@ sub getopt () { #{{{ push @{$config{pingurl}}, $_[1]; }, ); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -86,9 +85,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (($config{rss} || $config{atom}) && ! length $config{url}) { error(gettext("Must specify url to wiki with --url when using --rss or --atom")); } @@ -101,9 +100,9 @@ sub checkconfig () { #{{{ if (! exists $config{pingurl}) { $config{pingurl}=[]; } -} #}}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; # Fill in the inline content generated earlier. This is actually an @@ -112,9 +111,9 @@ sub format (@) { #{{{ delete @inline[$1,] }eg; return $params{content}; -} #}}} +} -sub sessioncgi ($$) { #{{{ +sub sessioncgi ($$) { my $q=shift; my $session=shift; @@ -149,7 +148,7 @@ package IkiWiki; my %toping; my %feedlinks; -sub preprocess_inline (@) { #{{{ +sub preprocess_inline (@) { my %params=@_; if (! exists $params{pages}) { @@ -161,6 +160,7 @@ sub preprocess_inline (@) { #{{{ my $atom=(($config{atom} || $config{allowatom}) && exists $params{atom}) ? yesno($params{atom}) : $config{atom}; my $quick=exists $params{quick} ? yesno($params{quick}) : 0; my $feeds=exists $params{feeds} ? yesno($params{feeds}) : !$quick; + my $emptyfeeds=exists $params{emptyfeeds} ? yesno($params{emptyfeeds}) : 1; my $feedonly=yesno($params{feedonly}); if (! exists $params{show} && ! $archive) { $params{show}=10; @@ -194,6 +194,13 @@ sub preprocess_inline (@) { #{{{ if (exists $params{sort} && $params{sort} eq 'title') { @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list; } + elsif (exists $params{sort} && $params{sort} eq 'title_natural') { + eval q{use Sort::Naturally}; + if ($@) { + error(gettext("Sort::Naturally needed for title_natural sort")); + } + @list=sort { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) } @list; + } elsif (exists $params{sort} && $params{sort} eq 'mtime') { @list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list; } @@ -201,7 +208,7 @@ sub preprocess_inline (@) { #{{{ @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list; } else { - return sprintf(gettext("unknown sort type %s"), $params{sort}); + error sprintf(gettext("unknown sort type %s"), $params{sort}); } if (yesno($params{reverse})) { @@ -232,29 +239,51 @@ sub preprocess_inline (@) { #{{{ # that if they are removed or otherwise changed, the inline will be # sure to be updated. add_depends($params{page}, join(" or ", $#list >= $#feedlist ? @list : @feedlist)); - - my $feednum=""; - - my $feedid=join("\0", map { $_."\0".$params{$_} } sort keys %params); - if (exists $knownfeeds{$feedid}) { - $feednum=$knownfeeds{$feedid}; + + if ($feeds && exists $params{feedpages}) { + @feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist; } - else { - if (exists $page_numfeeds{$params{destpage}}) { - if ($feeds) { - $feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}}; + + my ($feedbase, $feednum); + if ($feeds) { + # Ensure that multiple feeds on a page go to unique files. + + # Feedfile can lead to conflicts if usedirs is not enabled, + # so avoid supporting it in that case. + delete $params{feedfile} if ! $config{usedirs}; + # Tight limits on legal feedfiles, to avoid security issues + # and conflicts. + if (defined $params{feedfile}) { + if ($params{feedfile} =~ /\// || + $params{feedfile} !~ /$config{wiki_file_regexp}/) { + error("illegal feedfile"); } + $params{feedfile}=possibly_foolish_untaint($params{feedfile}); + } + $feedbase=targetpage($params{destpage}, "", $params{feedfile}); + + my $feedid=join("\0", $feedbase, map { $_."\0".$params{$_} } sort keys %params); + if (exists $knownfeeds{$feedid}) { + $feednum=$knownfeeds{$feedid}; } else { - $feednum=$knownfeeds{$feedid}=""; - if ($feeds) { - $page_numfeeds{$params{destpage}}=1; + if (exists $page_numfeeds{$params{destpage}}{$feedbase}) { + if ($feeds) { + $feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}}{$feedbase}; + } + } + else { + $feednum=$knownfeeds{$feedid}=""; + if ($feeds) { + $page_numfeeds{$params{destpage}}{$feedbase}=1; + } } } } - my $rssurl=basename(rsspage($params{destpage}).$feednum) if $feeds && $rss; - my $atomurl=basename(atompage($params{destpage}).$feednum) if $feeds && $atom; + my $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $rss; + my $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $atom; + my $ret=""; if (length $config{cgiurl} && ! $params{preview} && (exists $params{rootpage} || @@ -285,8 +314,12 @@ sub preprocess_inline (@) { #{{{ gettext("Add a new post titled:")); } $ret.=$formtemplate->output; + + # The post form includes the feed buttons, so + # emptyfeeds cannot be hidden. + $emptyfeeds=1; } - elsif ($feeds && !$params{preview}) { + elsif ($feeds && !$params{preview} && ($emptyfeeds || @feedlist)) { # Add feed buttons. my $linktemplate=template("feedlink.tmpl", blind_cache => 1); $linktemplate->param(rssurl => $rssurl) if $rss; @@ -298,7 +331,7 @@ sub preprocess_inline (@) { #{{{ require HTML::Template; my @params=IkiWiki::template_params($params{template}.".tmpl", blind_cache => 1); if (! @params) { - return sprintf(gettext("nonexistant template %s"), $params{template}); + error sprintf(gettext("nonexistant template %s"), $params{template}); } my $template=HTML::Template->new(@params) unless $raw; @@ -314,6 +347,7 @@ sub preprocess_inline (@) { #{{{ $template->param(content => $content); } $template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage})); + $template->param(inlinepage => $page); $template->param(title => pagetitle(basename($page))); $template->param(ctime => displaytime($pagectime{$page}, $params{timeformat})); $template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat})); @@ -363,30 +397,26 @@ sub preprocess_inline (@) { #{{{ } } - if ($feeds) { - if (exists $params{feedpages}) { - @feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist; - } - + if ($feeds && ($emptyfeeds || @feedlist)) { if ($rss) { - my $rssp=rsspage($params{destpage}).$feednum; + my $rssp=$feedbase."rss".$feednum; will_render($params{destpage}, $rssp); if (! $params{preview}) { writefile($rssp, $config{destdir}, genfeed("rss", $config{url}."/".$rssp, $desc, $params{guid}, $params{destpage}, @feedlist)); $toping{$params{destpage}}=1 unless $config{rebuild}; - $feedlinks{$params{destpage}}=qq{}; + $feedlinks{$params{destpage}}.=qq{}; } } if ($atom) { - my $atomp=atompage($params{destpage}).$feednum; + my $atomp=$feedbase."atom".$feednum; will_render($params{destpage}, $atomp); if (! $params{preview}) { writefile($atomp, $config{destdir}, genfeed("atom", $config{url}."/".$atomp, $desc, $params{guid}, $params{destpage}, @feedlist)); $toping{$params{destpage}}=1 unless $config{rebuild}; - $feedlinks{$params{destpage}}=qq{}; + $feedlinks{$params{destpage}}.=qq{}; } } } @@ -394,18 +424,18 @@ sub preprocess_inline (@) { #{{{ return $ret if $raw || $nested; push @inline, $ret; return "
\n\n"; -} #}}} +} -sub pagetemplate_inline (@) { #{{{ +sub pagetemplate_inline (@) { my %params=@_; my $page=$params{page}; my $template=$params{template}; $template->param(feedlinks => $feedlinks{$page}) if exists $feedlinks{$page} && $template->query(name => "feedlinks"); -} #}}} +} -sub get_inline_content ($$) { #{{{ +sub get_inline_content ($$) { my $page=shift; my $destpage=shift; @@ -424,9 +454,9 @@ sub get_inline_content ($$) { #{{{ else { return ""; } -} #}}} +} -sub date_822 ($) { #{{{ +sub date_822 ($) { my $time=shift; my $lc_time=POSIX::setlocale(&POSIX::LC_TIME); @@ -434,9 +464,9 @@ sub date_822 ($) { #{{{ my $ret=POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time)); POSIX::setlocale(&POSIX::LC_TIME, $lc_time); return $ret; -} #}}} +} -sub date_3339 ($) { #{{{ +sub date_3339 ($) { my $time=shift; my $lc_time=POSIX::setlocale(&POSIX::LC_TIME); @@ -444,9 +474,9 @@ sub date_3339 ($) { #{{{ my $ret=POSIX::strftime("%Y-%m-%dT%H:%M:%SZ", gmtime($time)); POSIX::setlocale(&POSIX::LC_TIME, $lc_time); return $ret; -} #}}} +} -sub absolute_urls ($$) { #{{{ +sub absolute_urls ($$) { # sucky sub because rss sucks my $content=shift; my $baseurl=shift; @@ -467,17 +497,9 @@ sub absolute_urls ($$) { #{{{ $content=~s/( date_3339($pagemtime{$p}), ); - if (exists $pagestate{$p} && - exists $pagestate{$p}{meta}{guid}) { - $itemtemplate->param(guid => $pagestate{$p}{meta}{guid}); + if (exists $pagestate{$p}) { + if (exists $pagestate{$p}{meta}{guid}) { + $itemtemplate->param(guid => $pagestate{$p}{meta}{guid}); + } + + if (exists $pagestate{$p}{meta}{updated}) { + $itemtemplate->param(mdate_822 => date_822($pagestate{$p}{meta}{updated})); + $itemtemplate->param(mdate_3339 => date_3339($pagestate{$p}{meta}{updated})); + } } if ($itemtemplate->query(name => "enclosure")) { @@ -562,9 +590,9 @@ sub genfeed ($$$$$@) { #{{{ }); return $template->output; -} #}}} +} -sub pingurl (@) { #{{{ +sub pingurl (@) { return unless @{$config{pingurl}} && %toping; eval q{require RPC::XML::Client}; @@ -610,6 +638,6 @@ sub pingurl (@) { #{{{ } exit 0; # daemon done -} #}}} +} 1 diff --git a/IkiWiki/Plugin/link.pm b/IkiWiki/Plugin/link.pm index 0638d4bdd..b79273f96 100644 --- a/IkiWiki/Plugin/link.pm +++ b/IkiWiki/Plugin/link.pm @@ -3,27 +3,27 @@ package IkiWiki::Plugin::link; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my $link_regexp; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "link", call => \&getsetup); hook(type => "checkconfig", id => "link", call => \&checkconfig); hook(type => "linkify", id => "link", call => \&linkify); hook(type => "scan", id => "link", call => \&scan); hook(type => "renamepage", id => "link", call => \&renamepage); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if ($config{prefix_directives}) { $link_regexp = qr{ \[\[(?=[^!]) # beginning of link @@ -58,9 +58,9 @@ sub checkconfig () { #{{{ \]\] # end of link }x, } -} #}}} +} -sub linkify (@) { #{{{ +sub linkify (@) { my %params=@_; my $page=$params{page}; my $destpage=$params{destpage}; @@ -78,9 +78,9 @@ sub linkify (@) { #{{{ }eg; return $params{content}; -} #}}} +} -sub scan (@) { #{{{ +sub scan (@) { my %params=@_; my $page=$params{page}; my $content=$params{content}; @@ -88,9 +88,9 @@ sub scan (@) { #{{{ while ($content =~ /(? "getsetup", id => "linkmap", call => \&getsetup); hook(type => "preprocess", id => "linkmap", call => \&preprocess); hook(type => "format", id => "linkmap", call => \&format); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} my $mapnum=0; my %maps; -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{pages}="*" unless defined $params{pages}; @@ -39,17 +39,17 @@ sub preprocess (@) { #{{{ $mapnum++; $maps{$mapnum}=\%params; return "
"; -} # }}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; $params{content}=~s/
<\/div>/genmap($1)/eg; return $params{content}; -} # }}} +} -sub genmap ($) { #{{{ +sub genmap ($) { my $mapnum=shift; return "" unless exists $maps{$mapnum}; my %params=%{$maps{$mapnum}}; @@ -106,6 +106,6 @@ sub genmap ($) { #{{{ error gettext("failed to run dot") if $sigpipe; return $ret; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/listdirectives.pm b/IkiWiki/Plugin/listdirectives.pm index fc8927ccb..d2cebca34 100644 --- a/IkiWiki/Plugin/listdirectives.pm +++ b/IkiWiki/Plugin/listdirectives.pm @@ -4,17 +4,17 @@ package IkiWiki::Plugin::listdirectives; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { add_underlay("directives"); hook(type => "getsetup", id => "listdirectives", call => \&getsetup); hook(type => "checkconfig", id => "listdirectives", call => \&checkconfig); hook(type => "needsbuild", id => "listdirectives", call => \&needsbuild); hook(type => "preprocess", id => "listdirectives", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -27,28 +27,27 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} my @fulllist; -my @earlylist; +my @shortlist; my $pluginstring; -sub checkconfig () { #{{{ +sub checkconfig () { if (! defined $config{directive_description_dir}) { $config{directive_description_dir} = "ikiwiki/directive"; } else { $config{directive_description_dir} =~ s/\/+$//; } +} - @earlylist = sort keys %{$IkiWiki::hooks{preprocess}}; -} #}}} - -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; @fulllist = sort keys %{$IkiWiki::hooks{preprocess}}; - $pluginstring = join(' ', @earlylist) . " : " . join(' ', @fulllist); + @shortlist = grep { ! $IkiWiki::hooks{preprocess}{$_}{shortcut} } @fulllist; + $pluginstring = join(' ', @shortlist) . " : " . join(' ', @fulllist); foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{listdirectives}{shown}) { @@ -64,9 +63,9 @@ sub needsbuild (@) { #{{{ } } } -} # }}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $pagestate{$params{destpage}}{listdirectives}{shown}=$pluginstring; @@ -77,7 +76,7 @@ sub preprocess (@) { #{{{ @pluginlist = @fulllist; } else { - @pluginlist = @earlylist; + @pluginlist = @shortlist; } my $result = '
    '; @@ -93,6 +92,6 @@ sub preprocess (@) { #{{{ $result .= "
"; return $result; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/lockedit.pm b/IkiWiki/Plugin/lockedit.pm index f6cac6cdd..0fa329251 100644 --- a/IkiWiki/Plugin/lockedit.pm +++ b/IkiWiki/Plugin/lockedit.pm @@ -3,16 +3,14 @@ package IkiWiki::Plugin::lockedit; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "lockedit", call => \&getsetup); hook(type => "canedit", id => "lockedit", call => \&canedit); - hook(type => "formbuilder_setup", id => "lockedit", - call => \&formbuilder_setup); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -26,9 +24,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} -sub canedit ($$) { #{{{ +sub canedit ($$) { my $page=shift; my $cgi=shift; my $session=shift; @@ -52,63 +50,7 @@ sub canedit ($$) { #{{{ } } - # XXX deprecated, should be removed eventually - foreach my $admin (@{$config{adminuser}}) { - if (pagespec_match($page, IkiWiki::userinfo_get($admin, "locked_pages"), - user => $session->param("name"), - ip => $ENV{REMOTE_ADDR}, - )) { - if (! defined $user || - ! IkiWiki::userinfo_get($session->param("name"), "regdate")) { - return sub { IkiWiki::needsignin($cgi, $session) }; - } - else { - return sprintf(gettext("%s is locked and cannot be edited"), - htmllink("", "", $page, noimageinline => 1)); - } - } - } - return undef; -} #}}} - -sub formbuilder_setup (@) { #{{{ - my %params=@_; - - # XXX deprecated, should be removed eventually - my $form=$params{form}; - if ($form->title eq "preferences") { - my $session=$params{session}; - my $cgi=$params{cgi}; - my $user_name=$session->param("name"); - - $form->field(name => "locked_pages", size => 50, - fieldset => "admin", - comment => "deprecated; please move to locked_pages in setup file" - ); - if (! IkiWiki::is_admin($user_name)) { - $form->field(name => "locked_pages", type => "hidden"); - } - if (! $form->submitted) { - my $value=IkiWiki::userinfo_get($user_name, "locked_pages"); - if (length $value) { - $form->field(name => "locked_pages", force => 1, value => $value); - } - else { - $form->field(name => "locked_pages", type => "hidden"); - } - } - if ($form->submitted && $form->submitted eq 'Save Preferences') { - if (defined $form->field("locked_pages")) { - IkiWiki::userinfo_set($user_name, "locked_pages", - $form->field("locked_pages")) || - error("failed to set locked_pages"); - if (! length $form->field("locked_pages")) { - $form->field(name => "locked_pages", type => "hidden"); - } - } - } - } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/map.pm b/IkiWiki/Plugin/map.pm index 18c584a30..328493116 100644 --- a/IkiWiki/Plugin/map.pm +++ b/IkiWiki/Plugin/map.pm @@ -9,22 +9,22 @@ package IkiWiki::Plugin::map; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "map", call => \&getsetup); hook(type => "preprocess", id => "map", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{pages}="*" unless defined $params{pages}; @@ -144,6 +144,6 @@ sub preprocess (@) { #{{{ } $map .= "
\n"; return $map; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/mdwn.pm b/IkiWiki/Plugin/mdwn.pm index 6c1d2ef3c..0e134c822 100644 --- a/IkiWiki/Plugin/mdwn.pm +++ b/IkiWiki/Plugin/mdwn.pm @@ -4,14 +4,14 @@ package IkiWiki::Plugin::mdwn; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "mdwn", call => \&getsetup); hook(type => "htmlize", id => "mdwn", call => \&htmlize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -24,10 +24,10 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} my $markdown_sub; -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; my $content = $params{content}; @@ -83,6 +83,6 @@ sub htmlize (@) { #{{{ $content=Encode::decode_utf8($content); return $content; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/mercurial.pm b/IkiWiki/Plugin/mercurial.pm index 7aceebcdb..11fdec529 100644 --- a/IkiWiki/Plugin/mercurial.pm +++ b/IkiWiki/Plugin/mercurial.pm @@ -7,7 +7,7 @@ use IkiWiki; use Encode; use open qw{:utf8 :std}; -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "mercurial", call => \&checkconfig); hook(type => "getsetup", id => "mercurial", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -20,18 +20,18 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (exists $config{mercurial_wrapper} && length $config{mercurial_wrapper}) { push @{$config{wrappers}}, { wrapper => $config{mercurial_wrapper}, wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -65,9 +65,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub mercurial_log ($) { #{{{ +sub mercurial_log ($) { my $out = shift; my @infos; @@ -111,20 +111,20 @@ sub mercurial_log ($) { #{{{ close $out; return @infos; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update"); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { return ""; -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { my ($file, $message, $rcstoken, $user, $ipaddr) = @_; if (defined $user) { @@ -149,7 +149,7 @@ sub rcs_commit ($$$;$$) { #{{{ } return undef; # success -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -159,28 +159,28 @@ sub rcs_commit_staged ($$$) { error("rcs_commit_staged not implemented for mercurial"); # TODO } -sub rcs_add ($) { # {{{ +sub rcs_add ($) { my ($file) = @_; my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file"); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } -} #}}} +} -sub rcs_remove ($) { # {{{ +sub rcs_remove ($) { my ($file) = @_; error("rcs_remove not implemented for mercurial"); # TODO -} #}}} +} -sub rcs_rename ($$) { # {{{ +sub rcs_rename ($$) { my ($src, $dest) = @_; error("rcs_rename not implemented for mercurial"); # TODO -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { my ($num) = @_; my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num, @@ -217,7 +217,7 @@ sub rcs_recentchanges ($) { #{{{ push @ret, { rev => $info->{"changeset"}, user => $user, - committype => "mercurial", + committype => "hg", when => str2time($info->{"date"}), message => [@message], pages => [@pages], @@ -225,18 +225,18 @@ sub rcs_recentchanges ($) { #{{{ } return @ret; -} #}}} +} -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { # TODO -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { my ($file) = @_; # XXX filename passes through the shell here, should try to avoid # that just in case - my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", '1', + my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "--style", "default", "$config{srcdir}/$file"); open (my $out, "@cmdline |"); @@ -249,8 +249,8 @@ sub rcs_getctime ($) { #{{{ eval q{use Date::Parse}; error($@) if $@; - my $ctime = str2time($log[0]->{"date"}); + my $ctime = str2time($log[$#log]->{"date"}); return $ctime; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index 8d444109f..4a22fed30 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -4,26 +4,26 @@ package IkiWiki::Plugin::meta; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %metaheaders; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "meta", call => \&getsetup); hook(type => "needsbuild", id => "meta", call => \&needsbuild); hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1); hook(type => "pagetemplate", id => "meta", call => \&pagetemplate); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{meta}) { @@ -38,16 +38,17 @@ sub needsbuild (@) { #{{{ } } -sub scrub ($) { #{{{ +sub scrub ($$) { if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) { - return IkiWiki::Plugin::htmlscrubber::sanitize(content => shift); + return IkiWiki::Plugin::htmlscrubber::sanitize( + content => shift, destpage => shift); } else { return shift; } -} #}}} +} -sub safeurl ($) { #{{{ +sub safeurl ($) { my $url=shift; if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} && defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) { @@ -56,9 +57,9 @@ sub safeurl ($) { #{{{ else { return 1; } -} #}}} +} -sub htmlize ($$$) { #{{{ +sub htmlize ($$$) { my $page = shift; my $destpage = shift; @@ -67,7 +68,7 @@ sub htmlize ($$$) { #{{{ IkiWiki::preprocess($page, $destpage, shift))); } -sub preprocess (@) { #{{{ +sub preprocess (@) { return "" unless @_; my %params=@_; my $key=shift; @@ -120,6 +121,20 @@ sub preprocess (@) { #{{{ $pagestate{$page}{meta}{authorurl}=$value if safeurl($value); # fallthrough } + elsif ($key eq 'date') { + eval q{use Date::Parse}; + if (! $@) { + my $time = str2time($value); + $IkiWiki::pagectime{$page}=$time if defined $time; + } + } + elsif ($key eq 'updated') { + eval q{use Date::Parse}; + if (! $@) { + my $time = str2time($value); + $pagestate{$page}{meta}{updated}=$time if defined $time; + } + } if (! defined wantarray) { # avoid collecting duplicate data during scan pass @@ -127,17 +142,10 @@ sub preprocess (@) { #{{{ } # Metadata collection that happens only during preprocessing pass. - if ($key eq 'date') { - eval q{use Date::Parse}; - if (! $@) { - my $time = str2time($value); - $IkiWiki::pagectime{$page}=$time if defined $time; - } - } - elsif ($key eq 'permalink') { + if ($key eq 'permalink') { if (safeurl($value)) { $pagestate{$page}{meta}{permalink}=$value; - push @{$metaheaders{$page}}, scrub(''); + push @{$metaheaders{$page}}, scrub('', $destpage); } } elsif ($key eq 'stylesheet') { @@ -206,7 +214,7 @@ sub preprocess (@) { #{{{ my $delay=int(exists $params{delay} ? $params{delay} : 0); my $redir=""; if (! $safe) { - $redir=scrub($redir); + $redir=scrub($redir, $destpage); } push @{$metaheaders{$page}}, $redir; } @@ -216,7 +224,7 @@ sub preprocess (@) { #{{{ join(" ", map { encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\"" } keys %params). - " />\n"); + " />\n", $destpage); } } elsif ($key eq 'robots') { @@ -225,13 +233,13 @@ sub preprocess (@) { #{{{ } else { push @{$metaheaders{$page}}, scrub(''); + '" content="'.encode_entities($value).'" />', $destpage); } return ""; -} # }}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; my $destpage=$params{destpage}; @@ -259,9 +267,9 @@ sub pagetemplate (@) { #{{{ $template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field})); } } -} # }}} +} -sub match { #{{{ +sub match { my $field=shift; my $page=shift; @@ -287,28 +295,28 @@ sub match { #{{{ else { return IkiWiki::FailReason->new("$page does not have a $field"); } -} #}}} +} package IkiWiki::PageSpec; -sub match_title ($$;@) { #{{{ +sub match_title ($$;@) { IkiWiki::Plugin::meta::match("title", @_); -} #}}} +} -sub match_author ($$;@) { #{{{ +sub match_author ($$;@) { IkiWiki::Plugin::meta::match("author", @_); -} #}}} +} -sub match_authorurl ($$;@) { #{{{ +sub match_authorurl ($$;@) { IkiWiki::Plugin::meta::match("authorurl", @_); -} #}}} +} -sub match_license ($$;@) { #{{{ +sub match_license ($$;@) { IkiWiki::Plugin::meta::match("license", @_); -} #}}} +} -sub match_copyright ($$;@) { #{{{ +sub match_copyright ($$;@) { IkiWiki::Plugin::meta::match("copyright", @_); -} #}}} +} 1 diff --git a/IkiWiki/Plugin/mirrorlist.pm b/IkiWiki/Plugin/mirrorlist.pm index aab60c435..737dcf767 100644 --- a/IkiWiki/Plugin/mirrorlist.pm +++ b/IkiWiki/Plugin/mirrorlist.pm @@ -3,14 +3,14 @@ package IkiWiki::Plugin::mirrorlist; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "mirrorlist", call => \&getsetup); hook(type => "pagetemplate", id => "mirrorlist", call => \&pagetemplate); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -23,9 +23,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $template=$params{template}; @@ -34,9 +34,9 @@ sub pagetemplate (@) { #{{{ $value.=mirrorlist($params{page}); $template->param(extrafooter => $value); } -} # }}} +} -sub mirrorlist ($) { #{{{ +sub mirrorlist ($) { my $page=shift; return "

". (keys %{$config{mirrorlist}} > 1 ? gettext("Mirrors") : gettext("Mirror")). @@ -49,6 +49,6 @@ sub mirrorlist ($) { #{{{ } keys %{$config{mirrorlist}} ). "

"; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/monotone.pm b/IkiWiki/Plugin/monotone.pm index f31a8606b..bdb564a71 100644 --- a/IkiWiki/Plugin/monotone.pm +++ b/IkiWiki/Plugin/monotone.pm @@ -10,7 +10,7 @@ use Date::Format qw(time2str); my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate sha1sums -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "monotone", call => \&checkconfig); hook(type => "getsetup", id => "monotone", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -23,9 +23,9 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (!defined($config{mtnrootdir})) { $config{mtnrootdir} = $config{srcdir}; } @@ -61,9 +61,9 @@ sub checkconfig () { #{{{ wrappermode => (defined $config{mtn_wrappermode} ? $config{mtn_wrappermode} : "06755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -117,9 +117,9 @@ sub getsetup () { #{{{ safe => 0, # path rebuild => 0, }, -} #}}} +} -sub get_rev () { #{{{ +sub get_rev () { my $sha1 = `mtn --root=$config{mtnrootdir} automate get_base_revision_id`; ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now @@ -128,9 +128,9 @@ sub get_rev () { #{{{ } return $sha1; -} #}}} +} -sub get_rev_auto ($) { #{{{ +sub get_rev_auto ($) { my $automator=shift; my @results = $automator->call("get_base_revision_id"); @@ -142,9 +142,9 @@ sub get_rev_auto ($) { #{{{ } return $sha1; -} #}}} +} -sub mtn_merge ($$$$) { #{{{ +sub mtn_merge ($$$$) { my $leftRev=shift; my $rightRev=shift; my $branch=shift; @@ -172,9 +172,9 @@ sub mtn_merge ($$$$) { #{{{ debug("merged $leftRev, $rightRev to make $mergeRev"); return $mergeRev; -} #}}} +} -sub commit_file_to_new_rev ($$$$$$$$) { #{{{ +sub commit_file_to_new_rev ($$$$$$$$) { my $automator=shift; my $wsfilename=shift; my $oldFileID=shift; @@ -219,9 +219,9 @@ sub commit_file_to_new_rev ($$$$$$$$) { #{{{ debug("Added certs for rev: $newRevID"); return $newRevID; -} #}}} +} -sub read_certs ($$) { #{{{ +sub read_certs ($$) { my $automator=shift; my $rev=shift; my @results = $automator->call("certs", $rev); @@ -239,9 +239,9 @@ sub read_certs ($$) { #{{{ } return @ret; -} #}}} +} -sub get_changed_files ($$) { #{{{ +sub get_changed_files ($$) { my $automator=shift; my $rev=shift; @@ -261,9 +261,9 @@ sub get_changed_files ($$) { #{{{ } return @ret; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { chdir $config{srcdir} or error("Cannot chdir to $config{srcdir}: $!"); @@ -278,9 +278,9 @@ sub rcs_update () { #{{{ if (system("mtn", "--root=$config{mtnrootdir}", "update", "--quiet") != 0) { debug("monotone update failed"); } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { my $file=shift; chdir $config{srcdir} @@ -289,9 +289,9 @@ sub rcs_prepedit ($) { #{{{ # For monotone, return the revision of the file when # editing begins. return get_rev(); -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +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. @@ -434,7 +434,7 @@ sub rcs_commit ($$$;$$) { #{{{ } return undef # success -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -466,7 +466,7 @@ sub rcs_commit_staged ($$$) { } } -sub rcs_add ($) { #{{{ +sub rcs_add ($) { my $file=shift; chdir $config{srcdir} @@ -476,9 +476,9 @@ sub rcs_add ($) { #{{{ $file) != 0) { error("Monotone add failed"); } -} #}}} +} -sub rcs_remove ($) { # {{{ +sub rcs_remove ($) { my $file = shift; chdir $config{srcdir} @@ -495,9 +495,9 @@ sub rcs_remove ($) { # {{{ $file) != 0) { error("Monotone remove failed"); } -} #}}} +} -sub rcs_rename ($$) { # {{{ +sub rcs_rename ($$) { my ($src, $dest) = @_; chdir $config{srcdir} @@ -507,9 +507,9 @@ sub rcs_rename ($$) { # {{{ $src, $dest) != 0) { error("Monotone rename failed"); } -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { my $num=shift; my @ret; @@ -525,13 +525,12 @@ sub rcs_recentchanges ($) { #{{{ my $child = open(MTNLOG, "-|"); if (! $child) { exec("mtn", "log", "--root=$config{mtnrootdir}", "--no-graph", - "--brief") || error("mtn log failed to run"); + "--brief", "--last=$num") || error("mtn log failed to run"); } - while (($num >= 0) and (my $line = )) { + while (my $line = ) { if ($line =~ m/^($sha1_pattern)/) { push @revs, $1; - $num -= 1; } } close MTNLOG || debug("mtn log exited $?"); @@ -560,7 +559,7 @@ sub rcs_recentchanges ($) { #{{{ if ($cert->{key} eq $config{mtnkey}) { $committype = "web"; } else { - $committype = "monotone"; + $committype = "mtn"; } } elsif ($cert->{name} eq "date") { $when = str2time($cert->{value}, 'UTC'); @@ -615,9 +614,9 @@ sub rcs_recentchanges ($) { #{{{ $automator->close(); return @ret; -} #}}} +} -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { my $rev=shift; my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint @@ -639,9 +638,9 @@ sub rcs_diff ($) { #{{{ else { return join("", @lines); } -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { my $file=shift; chdir $config{srcdir} @@ -691,6 +690,6 @@ sub rcs_getctime ($) { #{{{ $date=str2time($date, 'UTC'); debug("found ctime ".localtime($date)." for $file"); return $date; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/more.pm b/IkiWiki/Plugin/more.pm index 4484441c3..77d5fb077 100644 --- a/IkiWiki/Plugin/more.pm +++ b/IkiWiki/Plugin/more.pm @@ -3,24 +3,24 @@ package IkiWiki::Plugin::more; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my $linktext = gettext("more"); -sub import { #{{{ +sub import { hook(type => "getsetup", id => "more", call => \&getsetup); hook(type => "preprocess", id => "more", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{linktext} = $linktext unless defined $params{linktext}; diff --git a/IkiWiki/Plugin/norcs.pm b/IkiWiki/Plugin/norcs.pm index 58c26b633..bfe84c0e1 100644 --- a/IkiWiki/Plugin/norcs.pm +++ b/IkiWiki/Plugin/norcs.pm @@ -6,7 +6,7 @@ use warnings; use strict; use IkiWiki; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "norcs", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit); @@ -18,51 +18,51 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin rebuild => 0, }, -} #}}} +} -sub rcs_update () { #{{{ -} #}}} +sub rcs_update () { +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { return "" -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { my ($file, $message, $rcstoken, $user, $ipaddr) = @_; return undef # success -} #}}} +} -sub rcs_commit_staged ($$$) { #{{{ +sub rcs_commit_staged ($$$) { my ($message, $user, $ipaddr)=@_; return undef # success -} #}}} +} -sub rcs_add ($) { #{{{ -} #}}} +sub rcs_add ($) { +} -sub rcs_remove ($) { #{{{ -} #}}} +sub rcs_remove ($) { +} -sub rcs_rename ($$) { #{{{ -} #}}} +sub rcs_rename ($$) { +} -sub rcs_recentchanges ($) { #{{{ -} #}}} +sub rcs_recentchanges ($) { +} -sub rcs_diff ($) { #{{{ -} #}}} +sub rcs_diff ($) { +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { error gettext("getctime not implemented"); -} #}}} +} 1 diff --git a/IkiWiki/Plugin/opendiscussion.pm b/IkiWiki/Plugin/opendiscussion.pm index 96a74aee8..3da01efee 100644 --- a/IkiWiki/Plugin/opendiscussion.pm +++ b/IkiWiki/Plugin/opendiscussion.pm @@ -3,22 +3,22 @@ package IkiWiki::Plugin::opendiscussion; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "opendiscussion", call => \&getsetup); hook(type => "canedit", id => "opendiscussion", call => \&canedit); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub canedit ($$) { #{{{ +sub canedit ($$) { my $page=shift; my $cgi=shift; my $session=shift; @@ -26,6 +26,6 @@ sub canedit ($$) { #{{{ my $discussion=gettext("discussion"); return "" if $page=~/(\/|^)\Q$discussion\E$/; return undef; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm index f12cbdaa3..5424c57e2 100644 --- a/IkiWiki/Plugin/openid.pm +++ b/IkiWiki/Plugin/openid.pm @@ -4,24 +4,24 @@ package IkiWiki::Plugin::openid; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getopt", id => "openid", call => \&getopt); hook(type => "getsetup", id => "openid", call => \&getsetup); hook(type => "auth", id => "openid", call => \&auth); hook(type => "formbuilder_setup", id => "openid", call => \&formbuilder_setup, last => 1); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); GetOptions("openidsignup=s" => \$config{openidsignup}); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -34,9 +34,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; @@ -92,7 +92,7 @@ sub formbuilder_setup (@) { #{{{ } } -sub validate ($$$;$) { #{{{ +sub validate ($$$;$) { my $q=shift; my $session=shift; my $openid_url=shift; @@ -121,9 +121,9 @@ sub validate ($$$;$) { #{{{ # eventually bounce them back to auth() IkiWiki::redirect($q, $check_url); exit 0; -} #}}} +} -sub auth ($$) { #{{{ +sub auth ($$) { my $q=shift; my $session=shift; @@ -147,9 +147,9 @@ sub auth ($$) { #{{{ # myopenid.com affiliate support validate($q, $session, $q->param('openid_identifier')); } -} #}}} +} -sub getobj ($$) { #{{{ +sub getobj ($$) { my $q=shift; my $session=shift; @@ -178,26 +178,28 @@ sub getobj ($$) { #{{{ consumer_secret => sub { return shift()+$secret }, required_root => $config{cgiurl}, ); -} #}}} +} package IkiWiki; # This is not used by this plugin, but this seems the best place to put it. # Used elsewhere to pretty-display the name of an openid user. -sub openiduser ($) { #{{{ +sub openiduser ($) { my $user=shift; if ($user =~ m!^https?://! && eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) { my $oid=Net::OpenID::VerifiedIdentity->new(identity => $user); my $display=$oid->display; - # Convert "user.somehost.com" to "user [somehost.com]". + # Convert "user.somehost.com" to "user [somehost.com]" + # (also "user.somehost.co.uk") if ($display !~ /\[/) { - $display=~s/^(.*?)\.([^.]+\.[a-z]+)$/$1 [$2]/; + $display=~s/^([-a-zA-Z0-9]+?)\.([-.a-zA-Z0-9]+\.[a-z]+)$/$1 [$2]/; } # Convert "http://somehost.com/user" to "user [somehost.com]". + # (also "https://somehost.com/user/") if ($display !~ /\[/) { - $display=~s/^https?:\/\/(.+)\/([^\/]+)$/$2 [$1]/; + $display=~s/^https?:\/\/(.+)\/([^\/]+)\/?$/$2 [$1]/; } $display=~s!^https?://!!; # make sure this is removed eval q{use CGI 'escapeHTML'}; diff --git a/IkiWiki/Plugin/orphans.pm b/IkiWiki/Plugin/orphans.pm index 32cbc5dd5..605e6e43a 100644 --- a/IkiWiki/Plugin/orphans.pm +++ b/IkiWiki/Plugin/orphans.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::orphans; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "orphans", call => \&getsetup); hook(type => "preprocess", id => "orphans", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $params{pages}="*" unless defined $params{pages}; @@ -58,6 +58,6 @@ sub preprocess (@) { #{{{ "" } sort @orphans). "\n"; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/otl.pm b/IkiWiki/Plugin/otl.pm index ef76d6215..c68fcbbe3 100644 --- a/IkiWiki/Plugin/otl.pm +++ b/IkiWiki/Plugin/otl.pm @@ -4,25 +4,25 @@ package IkiWiki::Plugin::otl; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use open qw{:utf8 :std}; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "otl", call => \&getsetup); hook(type => "filter", id => "otl", call => \&filter); hook(type => "htmlize", id => "otl", call => \&htmlize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} -sub filter (@) { #{{{ +sub filter (@) { my %params=@_; # Munge up check boxes to look a little bit better. This is a hack. @@ -34,9 +34,9 @@ sub filter (@) { #{{{ $params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg; return $params{content}; -} # }}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; # Can't use open2 since otl2html doesn't play nice with buffering. @@ -95,6 +95,6 @@ sub htmlize (@) { #{{{ $ret=~s/.*//s; $ret=~s/ EODIV -} # }}} +} -sub format(@) { #{{{ +sub format(@) { my %params = @_; # If HTMLScrubber has removed the style attribute, then bring it back @@ -74,6 +74,6 @@ sub format(@) { #{{{ $params{content} =~ s!
($percentage_pattern)
!
$1
!g; return $params{content}; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/rawhtml.pm b/IkiWiki/Plugin/rawhtml.pm index 74ca13f3b..ad8a610c1 100644 --- a/IkiWiki/Plugin/rawhtml.pm +++ b/IkiWiki/Plugin/rawhtml.pm @@ -4,19 +4,19 @@ package IkiWiki::Plugin::rawhtml; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "rawhtml", call => \&getsetup); $config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ]; -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # changes file types }, -} #}}} +} 1 diff --git a/IkiWiki/Plugin/recentchanges.pm b/IkiWiki/Plugin/recentchanges.pm index eb23b184b..fa851e466 100644 --- a/IkiWiki/Plugin/recentchanges.pm +++ b/IkiWiki/Plugin/recentchanges.pm @@ -3,19 +3,21 @@ package IkiWiki::Plugin::recentchanges; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use Encode; +use HTML::Entities; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "recentchanges", call => \&getsetup); hook(type => "checkconfig", id => "recentchanges", call => \&checkconfig); hook(type => "refresh", id => "recentchanges", call => \&refresh); hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate); hook(type => "htmlize", id => "_change", call => \&htmlize); - hook(type => "cgi", id => "recentchanges", call => \&cgi); -} #}}} + # Load goto to fix up links from recentchanges + IkiWiki::loadplugin("goto"); +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -35,14 +37,14 @@ sub getsetup () { #{{{ safe => 1, rebuild => 0, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { $config{recentchangespage}='recentchanges' unless defined $config{recentchangespage}; $config{recentchangesnum}=100 unless defined $config{recentchangesnum}; -} #}}} +} -sub refresh ($) { #{{{ +sub refresh ($) { my %seen; # add new changes @@ -56,10 +58,10 @@ sub refresh ($) { #{{{ unlink($config{srcdir}.'/'.$pagesources{$page}); } } -} #}}} +} # Enable the recentchanges link on wiki pages. -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $template=$params{template}; my $page=$params{page}; @@ -70,48 +72,15 @@ sub pagetemplate (@) { #{{{ $template->param(recentchangesurl => urlto($config{recentchangespage}, $page)); $template->param(have_actions => 1); } -} #}}} - -# Pages with extension _change have plain html markup, pass through. -sub htmlize (@) { #{{{ - my %params=@_; - return $params{content}; -} #}}} - -sub cgi ($) { #{{{ - my $cgi=shift; - if (defined $cgi->param('do') && $cgi->param('do') eq "recentchanges_link") { - # This is a link from a change page to some - # other page. Since the change pages are only generated - # once, statically, links on them won't be updated if the - # page they link to is deleted, or newly created, or - # changes for whatever reason. So this CGI handles that - # dynamic linking stuff. - my $page=decode_utf8($cgi->param("page")); - if (!defined $page) { - error("missing page parameter"); - } - - IkiWiki::loadindex(); - - my $link=bestlink("", $page); - if (! length $link) { - print "Content-type: text/html\n\n"; - print IkiWiki::misctemplate(gettext(gettext("missing page")), - "

". - sprintf(gettext("The page %s does not exist."), - htmllink("", "", $page)). - "

"); - } - else { - IkiWiki::redirect($cgi, urlto($link, undef, 1)); - } - - exit; - } } -sub store ($$$) { #{{{ +# Pages with extension _change have plain html markup, pass through. +sub htmlize (@) { + my %params=@_; + return $params{content}; +} + +sub store ($$$) { my $change=shift; my $page="$config{recentchangespage}/change_".titlepage($change->{rev}); @@ -128,10 +97,10 @@ sub store ($$$) { #{{{ if (length $config{cgiurl}) { $_->{link} = " "recentchanges_link", + do => "goto", page => $_->{page} ). - "\">". + "\" rel=\"nofollow\">". pagetitle($_->{page}). "" } @@ -154,16 +123,18 @@ sub store ($$$) { #{{{ } elsif (length $config{cgiurl}) { $change->{authorurl} = IkiWiki::cgiurl( - do => "recentchanges_link", + do => "goto", page => (length $config{userdir} ? "$config{userdir}/" : "").$change->{author}, ); } - # escape wikilinks and preprocessor stuff in commit messages if (ref $change->{message}) { foreach my $field (@{$change->{message}}) { if (exists $field->{line}) { - $field->{line} =~ s/(?{line} = encode_entities($field->{line}); + # escape links and preprocessor stuff + $field->{line} = encode_entities($field->{line}, '\[\]'); } } } @@ -175,6 +146,10 @@ sub store ($$$) { #{{{ commitdate => displaytime($change->{when}, "%X %x"), wikiname => $config{wikiname}, ); + + $template->param(permalink => "$config{url}/$config{recentchangespage}/#change-".titlepage($change->{rev})) + if exists $config{url}; + IkiWiki::run_hooks(pagetemplate => sub { shift->(page => $page, destpage => $page, template => $template, rev => $change->{rev}); @@ -185,6 +160,6 @@ sub store ($$$) { #{{{ utime $change->{when}, $change->{when}, "$config{srcdir}/$file"; return $page; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/recentchangesdiff.pm b/IkiWiki/Plugin/recentchangesdiff.pm index 36acef72e..e3ba9b8d8 100644 --- a/IkiWiki/Plugin/recentchangesdiff.pm +++ b/IkiWiki/Plugin/recentchangesdiff.pm @@ -3,26 +3,27 @@ package IkiWiki::Plugin::recentchangesdiff; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; +use HTML::Entities; my $maxlines=200; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "recentchangesdiff", call => \&getsetup); hook(type => "pagetemplate", id => "recentchangesdiff", call => \&pagetemplate); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $template=$params{template}; if ($config{rcs} && exists $params{rev} && length $params{rev} && @@ -38,11 +39,13 @@ sub pagetemplate (@) { #{{{ else { $diff=join("", @lines); } + # escape html + $diff = encode_entities($diff); # escape links and preprocessor stuff - $diff =~ s/(?param(diff => $diff); } } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/relativedate.pm b/IkiWiki/Plugin/relativedate.pm new file mode 100644 index 000000000..3e33cd5c3 --- /dev/null +++ b/IkiWiki/Plugin/relativedate.pm @@ -0,0 +1,60 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::relativedate; + +use warnings; +no warnings 'redefine'; +use strict; +use IkiWiki 3.00; +use POSIX; +use Encode; + +sub import { + add_underlay("javascript"); + hook(type => "getsetup", id => "relativedate", call => \&getsetup); + hook(type => "format", id => "relativedate", call => \&format); + inject(name => "IkiWiki::displaytime", call => \&mydisplaytime); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => 1, + }, +} + +sub format (@) { + my %params=@_; + + if (! ($params{content}=~s!^()!$1.include_javascript($params{page})!em)) { + # no tag, probably in preview mode + $params{content}=include_javascript($params{page}, 1).$params{content}; + } + return $params{content}; +} + +sub include_javascript ($;$) { + my $page=shift; + my $absolute=shift; + + return ''."\n". + ''; +} + +sub mydisplaytime ($;$) { + my $time=shift; + my $format=shift; + + # This needs to be in a form that can be parsed by javascript. + # Being fairly human readable is also nice, as it will be exposed + # as the title if javascript is not available. + my $gmtime=decode_utf8(POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", + localtime($time))); + + return ''. + IkiWiki::formattime($time, $format).''; +} + +1 diff --git a/IkiWiki/Plugin/remove.pm b/IkiWiki/Plugin/remove.pm index 68bf9d1ee..ee5784f20 100644 --- a/IkiWiki/Plugin/remove.pm +++ b/IkiWiki/Plugin/remove.pm @@ -3,25 +3,25 @@ package IkiWiki::Plugin::remove; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "remove", call => \&getsetup); hook(type => "formbuilder_setup", id => "remove", call => \&formbuilder_setup); hook(type => "formbuilder", id => "remove", call => \&formbuilder); hook(type => "sessioncgi", id => "remove", call => \&sessioncgi); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub check_canremove ($$$) { #{{{ +sub check_canremove ($$$) { my $page=shift; my $q=shift; my $session=shift; @@ -41,7 +41,7 @@ sub check_canremove ($$$) { #{{{ error(sprintf(gettext("%s is not a file"), $file)); } - # Must be editiable. + # Must be editable. IkiWiki::check_canedit($page, $q, $session); # If a user can't upload an attachment, don't let them delete it. @@ -54,9 +54,9 @@ sub check_canremove ($$$) { #{{{ error("renaming of attachments is not allowed"); } } -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; my $q=$params{cgi}; @@ -67,9 +67,9 @@ sub formbuilder_setup (@) { #{{{ push @{$params{buttons}}, "Remove" if $form->field("do") eq "edit"; $form->tmpl_param("field-remove" => ''); } -} #}}} +} -sub confirmation_form ($$) { #{{{ +sub confirmation_form ($$) { my $q=shift; my $session=shift; @@ -90,9 +90,9 @@ sub confirmation_form ($$) { #{{{ $f->field(name => "do", type => "hidden", value => "remove", force => 1); return $f, ["Remove", "Cancel"]; -} #}}} +} -sub removal_confirm ($$@) { #{{{ +sub removal_confirm ($$@) { my $q=shift; my $session=shift; my $attachment=shift; @@ -122,9 +122,9 @@ sub removal_confirm ($$@) { #{{{ IkiWiki::showform($f, $buttons, $session, $q); exit 0; -} #}}} +} -sub postremove ($) { #{{{ +sub postremove ($) { my $session=shift; # Load saved form state and return to edit form. @@ -132,9 +132,9 @@ sub postremove ($) { #{{{ $session->clear("postremove"); IkiWiki::cgi_savesession($session); IkiWiki::cgi($postremove, $session); -} #}}} +} -sub formbuilder (@) { #{{{ +sub formbuilder (@) { my %params=@_; my $form=$params{form}; @@ -154,9 +154,9 @@ sub formbuilder (@) { #{{{ removal_confirm($q, $session, 1, @selected); } } -} #}}} +} -sub sessioncgi ($$) { #{{{ +sub sessioncgi ($$) { my $q=shift; if ($q->param("do") eq 'remove') { @@ -218,7 +218,7 @@ sub sessioncgi ($$) { #{{{ } } else { - IkiWiki::showform($form, $buttons, $session, $q); + removal_confirm($q, $session, 0, $q->param("page")); } exit 0; diff --git a/IkiWiki/Plugin/rename.pm b/IkiWiki/Plugin/rename.pm index 7e55e271c..41af3ca4d 100644 --- a/IkiWiki/Plugin/rename.pm +++ b/IkiWiki/Plugin/rename.pm @@ -3,25 +3,25 @@ package IkiWiki::Plugin::rename; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "rename", call => \&getsetup); hook(type => "formbuilder_setup", id => "rename", call => \&formbuilder_setup); hook(type => "formbuilder", id => "rename", call => \&formbuilder); hook(type => "sessioncgi", id => "rename", call => \&sessioncgi); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub check_canrename ($$$$$$) { #{{{ +sub check_canrename ($$$$$$) { my $src=shift; my $srcfile=shift; my $dest=shift; @@ -87,9 +87,9 @@ sub check_canrename ($$$$$$) { #{{{ IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile); } } -} #}}} +} -sub rename_form ($$$) { #{{{ +sub rename_form ($$$) { my $q=shift; my $session=shift; my $page=shift; @@ -111,7 +111,7 @@ sub rename_form ($$$) { #{{{ $f->field(name => "do", type => "hidden", value => "rename", force => 1); $f->field(name => "page", type => "hidden", value => $page, force => 1); - $f->field(name => "new_name", value => pagetitle($page), size => 60); + $f->field(name => "new_name", value => pagetitle($page, 1), size => 60); if (!$q->param("attachment")) { # insert the standard extensions my @page_types; @@ -145,9 +145,9 @@ sub rename_form ($$$) { #{{{ $f->field(name => "attachment", type => "hidden"); return $f, ["Rename", "Cancel"]; -} #}}} +} -sub rename_start ($$$$) { #{{{ +sub rename_start ($$$$) { my $q=shift; my $session=shift; my $attachment=shift; @@ -171,9 +171,9 @@ sub rename_start ($$$$) { #{{{ my ($f, $buttons)=rename_form($q, $session, $page); IkiWiki::showform($f, $buttons, $session, $q); exit 0; -} #}}} +} -sub postrename ($;$$$) { #{{{ +sub postrename ($;$$$) { my $session=shift; my $src=shift; my $dest=shift; @@ -204,9 +204,9 @@ sub postrename ($;$$$) { #{{{ } IkiWiki::cgi_editpage($postrename, $session); -} #}}} +} -sub formbuilder (@) { #{{{ +sub formbuilder (@) { my %params=@_; my $form=$params{form}; @@ -229,11 +229,11 @@ sub formbuilder (@) { #{{{ rename_start($q, $session, 1, $selected[0]); } } -} #}}} +} my $renamesummary; -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; my $q=$params{cgi}; @@ -248,9 +248,9 @@ sub formbuilder_setup (@) { #{{{ $form->tmpl_param(message => $renamesummary); } } -} #}}} +} -sub sessioncgi ($$) { #{{{ +sub sessioncgi ($$) { my $q=shift; if ($q->param("do") eq 'rename') { @@ -390,22 +390,8 @@ sub sessioncgi ($$) { #{{{ $template->param(error => $rename->{error}); if ($rename->{src} ne $rename->{dest}) { $template->param(brokenlinks_checked => 1); - $template->param(brokenlinks => [ - map { - { - page => htmllink($rename->{dest}, $rename->{dest}, $_, - noimageinline => 1) - } - } @{$rename->{brokenlinks}} - ]); - $template->param(fixedlinks => [ - map { - { - page => htmllink($rename->{dest}, $rename->{dest}, $_, - noimageinline => 1) - } - } @{$rename->{fixedlinks}} - ]); + $template->param(brokenlinks => linklist($rename->{dest}, $rename->{brokenlinks})); + $template->param(fixedlinks => linklist($rename->{dest}, $rename->{fixedlinks})); } $renamesummary.=$template->output; } @@ -418,9 +404,26 @@ sub sessioncgi ($$) { #{{{ exit 0; } -} #}}} +} + +sub linklist { + # generates a list of links in a form suitable for FormBuilder + my $dest=shift; + my $list=shift; + # converts a list of pages into a list of links + # in a form suitable for FormBuilder. -sub renamepage_hook ($$$$) { #{{{ + [map { + { + page => htmllink($dest, $dest, $_, + noimageinline => 1, + linktext => pagetitle($_), + ) + } + } @{$list}] +} + +sub renamepage_hook ($$$$) { my ($page, $src, $dest, $content)=@_; IkiWiki::run_hooks(renamepage => sub { @@ -433,9 +436,9 @@ sub renamepage_hook ($$$$) { #{{{ }); return $content; -}# }}} +} -sub do_rename ($$$) { #{{{ +sub do_rename ($$$) { my $rename=shift; my $q=shift; my $session=shift; @@ -460,9 +463,9 @@ sub do_rename ($$$) { #{{{ } } -} # }}} +} -sub fixlinks ($$$) { #{{{ +sub fixlinks ($$$) { my $rename=shift; my $session=shift; @@ -498,6 +501,6 @@ sub fixlinks ($$$) { #{{{ } return @fixedlinks; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/repolist.pm b/IkiWiki/Plugin/repolist.pm new file mode 100644 index 000000000..f69ec3988 --- /dev/null +++ b/IkiWiki/Plugin/repolist.pm @@ -0,0 +1,51 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::repolist; + +use warnings; +use strict; +use IkiWiki 3.00; + +sub import { + hook(type => "getsetup", id => "repolist", call => \&getsetup); + hook(type => "checkconfig", id => "repolist", call => \&checkconfig); +} + +sub getsetup () { + return + plugin => { + safe => 1, + rebuild => undef, + }, + repositories => { + type => "string", + example => ["svn://svn.example.org/wiki/trunk"], + description => "URIs of repositories containing the wiki's source", + safe => 1, + rebuild => undef, + }, +} + +my $relvcs; + +sub checkconfig () { + if (defined $config{rcs} && $config{repositories}) { + $relvcs=join("\n", map { + s/"//g; # avoid quotes just in case + qq{} + } @{$config{repositories}}); + + hook(type => "pagetemplate", id => "repolist", call => \&pagetemplate); + } +} + +sub pagetemplate (@) { + my %params=@_; + my $page=$params{page}; + my $template=$params{template}; + + if (defined $relvcs && $template->query(name => "relvcs")) { + $template->param(relvcs => $relvcs); + } +} + +1 diff --git a/IkiWiki/Plugin/search.pm b/IkiWiki/Plugin/search.pm index e40f4888c..d79e3170e 100644 --- a/IkiWiki/Plugin/search.pm +++ b/IkiWiki/Plugin/search.pm @@ -4,18 +4,18 @@ package IkiWiki::Plugin::search; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "search", call => \&getsetup); hook(type => "checkconfig", id => "search", call => \&checkconfig); hook(type => "pagetemplate", id => "search", call => \&pagetemplate); hook(type => "postscan", id => "search", call => \&index); hook(type => "delete", id => "search", call => \&delete); hook(type => "cgi", id => "search", call => \&cgi); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -28,9 +28,9 @@ sub getsetup () { #{{{ safe => 0, # external program rebuild => 0, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { foreach my $required (qw(url cgiurl)) { if (! length $config{$required}) { error(sprintf(gettext("Must specify %s when using the search plugin"), $required)); @@ -40,10 +40,10 @@ sub checkconfig () { #{{{ if (! defined $config{omega_cgi}) { $config{omega_cgi}="/usr/lib/cgi-bin/omega/omega"; } -} #}}} +} my $form; -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; my $template=$params{template}; @@ -58,11 +58,11 @@ sub pagetemplate (@) { #{{{ $template->param(searchform => $form); } -} #}}} +} my $scrubber; my $stemmer; -sub index (@) { #{{{ +sub index (@) { my %params=@_; setupfiles(); @@ -146,17 +146,17 @@ sub index (@) { #{{{ $doc->add_term($pageterm); $db->replace_document_by_term($pageterm, $doc); -} #}}} +} -sub delete (@) { #{{{ +sub delete (@) { my $db=xapiandb(); foreach my $page (@_) { my $pageterm=pageterm(pagename($page)); $db->delete_document_by_term($pageterm) if defined $pageterm; } -} #}}} +} -sub cgi ($) { #{{{ +sub cgi ($) { my $cgi=shift; if (defined $cgi->param('P')) { @@ -169,9 +169,9 @@ sub cgi ($) { #{{{ noimageinline => 1, linktext => "Help"); exec($config{omega_cgi}) || error("$config{omega_cgi} failed: $!"); } -} #}}} +} -sub pageterm ($) { #{{{ +sub pageterm ($) { my $page=shift; # 240 is the number used by omindex to decide when to hash an @@ -190,10 +190,10 @@ sub pageterm ($) { #{{{ else { return "U:".$page; } -} #}}} +} my $db; -sub xapiandb () { #{{{ +sub xapiandb () { if (! defined $db) { eval q{ use Search::Xapian; @@ -204,11 +204,11 @@ sub xapiandb () { #{{{ Search::Xapian::DB_CREATE_OR_OPEN()); } return $db; -} #}}} +} { my $setup=0; -sub setupfiles () { #{{{ +sub setupfiles () { if (! $setup and (! -e $config{wikistatedir}."/xapian" || $config{rebuild})) { writefile("omega.conf", $config{wikistatedir}."/xapian", "database_dir .\n". @@ -218,7 +218,7 @@ sub setupfiles () { #{{{ readfile(IkiWiki::template_file("searchquery.tmpl")))); $setup=1; } -} #}}} +} } 1 diff --git a/IkiWiki/Plugin/shortcut.pm b/IkiWiki/Plugin/shortcut.pm index 7bfce586f..1840a5722 100644 --- a/IkiWiki/Plugin/shortcut.pm +++ b/IkiWiki/Plugin/shortcut.pm @@ -3,33 +3,41 @@ package IkiWiki::Plugin::shortcut; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "shortcut", call => \&getsetup); - hook(type => "refresh", id => "shortcut", call => \&refresh); + hook(type => "checkconfig", id => "shortcut", call => \&checkconfig); hook(type => "preprocess", id => "shortcut", call => \&preprocess_shortcut); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub refresh () { #{{{ - # Preprocess the shortcuts page to get all the available shortcuts - # defined before other pages are rendered. - my $srcfile=srcfile("shortcuts.mdwn", 1); - if (! defined $srcfile) { - error(gettext("shortcut plugin will not work without a shortcuts.mdwn")); +sub checkconfig () { + if (defined $config{srcdir} && length $config{srcdir}) { + # Preprocess the shortcuts page to get all the available shortcuts + # defined before other pages are rendered. + my $srcfile=srcfile("shortcuts.".$config{default_pageext}, 1); + if (! defined $srcfile) { + $srcfile=srcfile("shortcuts.mdwn", 1); + } + if (! defined $srcfile) { + print STDERR sprintf(gettext("shortcut plugin will not work without %s"), + "shortcuts.".$config{default_pageext})."\n"; + } + else { + IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile)); + } } - IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile)); -} # }}} +} -sub preprocess_shortcut (@) { #{{{ +sub preprocess_shortcut (@) { my %params=@_; if (! defined $params{name} || ! defined $params{url}) { @@ -37,15 +45,16 @@ sub preprocess_shortcut (@) { #{{{ } hook(type => "preprocess", no_override => 1, id => $params{name}, + shortcut => 1, call => sub { shortcut_expand($params{url}, $params{desc}, @_) }); #translators: This is used to display what shortcuts are defined. #translators: First parameter is the name of the shortcut, the second #translators: is an URL. return sprintf(gettext("shortcut %s points to %s"), $params{name}, $params{url}); -} # }}} +} -sub shortcut_expand ($$@) { #{{{ +sub shortcut_expand ($$@) { my $url=shift; my $desc=shift; my %params=@_; @@ -82,6 +91,6 @@ sub shortcut_expand ($$@) { #{{{ } return "$desc"; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/sidebar.pm b/IkiWiki/Plugin/sidebar.pm index 9697e1198..41812e1c1 100644 --- a/IkiWiki/Plugin/sidebar.pm +++ b/IkiWiki/Plugin/sidebar.pm @@ -6,22 +6,22 @@ package IkiWiki::Plugin::sidebar; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "sidebar", call => \&getsetup); hook(type => "pagetemplate", id => "sidebar", call => \&pagetemplate); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, }, -} #}}} +} -sub sidebar_content ($) { #{{{ +sub sidebar_content ($) { my $page=shift; my $sidebar_page=bestlink($page, "sidebar") || return; @@ -42,9 +42,9 @@ sub sidebar_content ($) { #{{{ IkiWiki::filter($sidebar_page, $page, $content)))); } -} # }}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; @@ -56,6 +56,6 @@ sub pagetemplate (@) { #{{{ $template->param(sidebar => $content); } } -} # }}} +} 1 diff --git a/IkiWiki/Plugin/signinedit.pm b/IkiWiki/Plugin/signinedit.pm index ef7b9b428..032a0034c 100644 --- a/IkiWiki/Plugin/signinedit.pm +++ b/IkiWiki/Plugin/signinedit.pm @@ -3,23 +3,23 @@ package IkiWiki::Plugin::signinedit; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "signinedit", call => \&getsetup); hook(type => "canedit", id => "signinedit", call => \&canedit, last => 1); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 0, }, -} #}}} +} -sub canedit ($$$) { #{{{ +sub canedit ($$$) { my $page=shift; my $cgi=shift; my $session=shift; @@ -34,6 +34,6 @@ sub canedit ($$$) { #{{{ else { return ""; } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index f844ddb91..ea7d6e47f 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -6,9 +6,9 @@ package IkiWiki::Plugin::skeleton; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getopt", id => "skeleton", call => \&getopt); hook(type => "getsetup", id => "skeleton", call => \&getsetup); hook(type => "checkconfig", id => "skeleton", call => \&checkconfig); @@ -30,17 +30,18 @@ sub import { #{{{ hook(type => "auth", id => "skeleton", call => \&auth); hook(type => "sessioncgi", id => "skeleton", call => \&sessioncgi); hook(type => "canedit", id => "skeleton", call => \&canedit); + hook(type => "checkcontent", id => "skeleton", call => \&checkcontent); hook(type => "editcontent", id => "skeleton", call => \&editcontent); hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup); hook(type => "formbuilder", id => "skeleton", call => \&formbuilder); hook(type => "savestate", id => "skeleton", call => \&savestate); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { debug("skeleton plugin getopt"); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -53,155 +54,161 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { debug("skeleton plugin checkconfig"); -} #}}} +} -sub refresh () { #{{{ +sub refresh () { debug("skeleton plugin refresh"); -} #}}} +} -sub needsbuild () { #{{{ +sub needsbuild () { debug("skeleton plugin needsbuild"); -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; return "skeleton plugin result"; -} # }}} +} -sub filter (@) { #{{{ +sub filter (@) { my %params=@_; debug("skeleton plugin running as filter"); return $params{content}; -} # }}} +} -sub linkify (@) { #{{{ +sub linkify (@) { my %params=@_; debug("skeleton plugin running as linkify"); return $params{content}; -} # }}} +} -sub scan (@) { #{{{a +sub scan (@) { my %params=@_; debug("skeleton plugin running as scan"); -} # }}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; debug("skeleton plugin running as htmlize"); return $params{content}; -} # }}} +} -sub sanitize (@) { #{{{ +sub sanitize (@) { my %params=@_; debug("skeleton plugin running as a sanitizer"); return $params{content}; -} # }}} +} -sub postscan (@) { #{{{ +sub postscan (@) { my %params=@_; debug("skeleton plugin running as postscan"); -} # }}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; debug("skeleton plugin running as a formatter"); return $params{content}; -} # }}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; my $template=$params{template}; debug("skeleton plugin running as a pagetemplate hook"); -} # }}} +} -sub templatefile (@) { #{{{ +sub templatefile (@) { my %params=@_; my $page=$params{page}; debug("skeleton plugin running as a templatefile hook"); -} # }}} +} -sub delete (@) { #{{{ +sub delete (@) { my @files=@_; debug("skeleton plugin told that files were deleted: @files"); -} #}}} +} -sub change (@) { #{{{ +sub change (@) { my @files=@_; debug("skeleton plugin told that changed files were rendered: @files"); -} #}}} +} -sub cgi ($) { #{{{ +sub cgi ($) { my $cgi=shift; debug("skeleton plugin running in cgi"); -} #}}} +} -sub auth ($$) { #{{{ +sub auth ($$) { my $cgi=shift; my $session=shift; debug("skeleton plugin running in auth"); -} #}}} +} -sub sessioncgi ($$) { #{{{ +sub sessioncgi ($$) { my $cgi=shift; my $session=shift; debug("skeleton plugin running in sessioncgi"); -} #}}} +} -sub canedit ($$$) { #{{{ +sub canedit ($$$) { my $page=shift; my $cgi=shift; my $session=shift; debug("skeleton plugin running in canedit"); -} #}}} +} -sub editcontent ($$$) { #{{{ +sub checkcontent (@) { + my %params=@_; + + debug("skeleton plugin running in checkcontent"); +} + +sub editcontent ($$$) { my %params=@_; debug("skeleton plugin running in editcontent"); return $params{content}; -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; debug("skeleton plugin running in formbuilder_setup"); -} # }}} +} -sub formbuilder (@) { #{{{ +sub formbuilder (@) { my %params=@_; debug("skeleton plugin running in formbuilder"); -} # }}} +} -sub savestate () { #{{{ +sub savestate () { debug("skeleton plugin running in savestate"); -} #}}} +} 1 diff --git a/IkiWiki/Plugin/smiley.pm b/IkiWiki/Plugin/smiley.pm index 2633b1ea1..0d77916d0 100644 --- a/IkiWiki/Plugin/smiley.pm +++ b/IkiWiki/Plugin/smiley.pm @@ -3,18 +3,18 @@ package IkiWiki::Plugin::smiley; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %smileys; my $smiley_regexp; -sub import { #{{{ +sub import { add_underlay("smiley"); hook(type => "getsetup", id => "smiley", call => \&getsetup); hook(type => "sanitize", id => "smiley", call => \&sanitize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -22,9 +22,9 @@ sub getsetup () { #{{{ # removes the smileys, which would break links rebuild => 1, }, -} #}}} +} -sub build_regexp () { #{{{ +sub build_regexp () { my $list=readfile(srcfile("smileys.mdwn")); while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) { my $smiley=$1; @@ -50,9 +50,9 @@ sub build_regexp () { #{{{ $smiley_regexp='('.join('|', map { quotemeta } reverse sort keys %smileys).')'; #debug($smiley_regexp); -} #}}} +} -sub sanitize (@) { #{{{ +sub sanitize (@) { my %params=@_; build_regexp() unless defined $smiley_regexp; @@ -87,14 +87,14 @@ MATCH: while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) { } else { # Replace the smiley with its expanded value. - substr($_, $spos, length($smiley))= - htmllink($params{page}, $params{destpage}, + my $link=htmllink($params{page}, $params{destpage}, $smileys{$smiley}, linktext => $smiley); - pos=$epos+1; + substr($_, $spos, length($smiley))=$link; + pos=$epos+length($link); } } return $_; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/sparkline.pm b/IkiWiki/Plugin/sparkline.pm index 901c2f683..458192695 100644 --- a/IkiWiki/Plugin/sparkline.pm +++ b/IkiWiki/Plugin/sparkline.pm @@ -3,7 +3,7 @@ package IkiWiki::Plugin::sparkline; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use IPC::Open2; my $match_num=qr/[-+]?[0-9]+(?:\.[0-9]+)?/; @@ -14,20 +14,20 @@ my %locmap=( left => 'TEXT_LEFT', ); -sub import { #{{{ +sub import { hook(type => "getsetup", id => "sparkline", call => \&getsetup); hook(type => "preprocess", id => "sparkline", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; my $php; @@ -130,7 +130,7 @@ sub preprocess (@) { #{{{ if (! -e "$config{destdir}/$fn") { my $pid; - my $sigpipe=0;; + my $sigpipe=0; $SIG{PIPE}=sub { $sigpipe=1 }; $pid=open2(*IN, *OUT, "php"); @@ -166,6 +166,6 @@ sub preprocess (@) { #{{{ } return 'graph'; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/svn.pm b/IkiWiki/Plugin/svn.pm index d738720be..fe55e7d08 100644 --- a/IkiWiki/Plugin/svn.pm +++ b/IkiWiki/Plugin/svn.pm @@ -6,7 +6,7 @@ use strict; use IkiWiki; use POSIX qw(setlocale LC_CTYPE); -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "svn", call => \&checkconfig); hook(type => "getsetup", id => "svn", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -19,9 +19,9 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (! defined $config{svnpath}) { $config{svnpath}="trunk"; } @@ -37,9 +37,9 @@ sub checkconfig () { #{{{ wrappermode => (defined $config{svn_wrappermode} ? $config{svn_wrappermode} : "04755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -87,7 +87,7 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} # svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do. sub find_lc_ctype() { @@ -107,27 +107,27 @@ sub find_lc_ctype() { # fallback to the current locale return $current; -} # }}} +} $ENV{LC_CTYPE} = $ENV{LC_CTYPE} || find_lc_ctype(); -sub svn_info ($$) { #{{{ +sub svn_info ($$) { my $field=shift; my $file=shift; my $info=`LANG=C svn info $file`; my ($ret)=$info=~/^$field: (.*)$/m; return $ret; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { if (-d "$config{srcdir}/.svn") { if (system("svn", "update", "--quiet", $config{srcdir}) != 0) { warn("svn update failed\n"); } } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { # Prepares to edit a file under revision control. Returns a token # that must be passed into rcs_commit when the file is ready # for committing. @@ -140,9 +140,9 @@ sub rcs_prepedit ($) { #{{{ my $rev=svn_info("Revision", "$config{srcdir}/$file"); return defined $rev ? $rev : ""; } -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +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. @@ -185,7 +185,7 @@ sub rcs_commit ($$$;$$) { #{{{ } } return undef # success -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -209,7 +209,7 @@ sub rcs_commit_staged ($$$) { return undef # success } -sub rcs_add ($) { #{{{ +sub rcs_add ($) { # filename is relative to the root of the srcdir my $file=shift; @@ -224,9 +224,9 @@ sub rcs_add ($) { #{{{ warn("svn add failed\n"); } } -} #}}} +} -sub rcs_remove ($) { #{{{ +sub rcs_remove ($) { # filename is relative to the root of the srcdir my $file=shift; @@ -235,9 +235,9 @@ sub rcs_remove ($) { #{{{ warn("svn rm failed\n"); } } -} #}}} +} -sub rcs_rename ($$) { #{{{ +sub rcs_rename ($$) { # filenames relative to the root of the srcdir my ($src, $dest)=@_; @@ -258,9 +258,9 @@ sub rcs_rename ($$) { #{{{ warn("svn rename failed\n"); } } -} #}}} +} -sub rcs_recentchanges ($) { #{{{ +sub rcs_recentchanges ($) { my $num=shift; my @ret; @@ -341,14 +341,14 @@ sub rcs_recentchanges ($) { #{{{ } return @ret; -} #}}} +} -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { my $rev=IkiWiki::possibly_foolish_untaint(int(shift)); return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`; -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { my $file=shift; my $svn_log_infoline=qr/^r\d+\s+\|\s+[^\s]+\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/; @@ -376,6 +376,6 @@ sub rcs_getctime ($) { #{{{ $date=str2time($date); debug("found ctime ".localtime($date)." for $file"); return $date; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/table.pm b/IkiWiki/Plugin/table.pm index e782fc238..96d63f455 100644 --- a/IkiWiki/Plugin/table.pm +++ b/IkiWiki/Plugin/table.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::table; use warnings; use strict; use Encode; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "table", call => \&getsetup); - hook(type => "preprocess", id => "table", call => \&preprocess); -} # }}} + hook(type => "preprocess", id => "table", call => \&preprocess, scan => 1); +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params =( format => 'auto', header => 'row', @@ -27,13 +27,31 @@ sub preprocess (@) { #{{{ ); if (exists $params{file}) { - if (! $pagesources{$params{file}}) { + if (! exists $pagesources{$params{file}}) { error gettext("cannot find file"); } $params{data} = readfile(srcfile($params{file})); add_depends($params{page}, $params{file}); } + if (! defined wantarray) { + # scan mode -- if the table uses an external file, need to + # scan that file too. + return unless exists $params{file}; + + IkiWiki::run_hooks(scan => sub { + shift->( + page => $params{page}, + content => $params{data}, + ); + }); + + # Preprocess in scan-only mode. + IkiWiki::preprocess($params{page}, $params{page}, $params{data}, 1); + + return; + } + if (lc $params{format} eq 'auto') { # first try the more simple format if (is_dsv_data($params{data})) { @@ -50,22 +68,18 @@ sub preprocess (@) { #{{{ defined $params{delimiter} ? $params{delimiter} : ",",); # linkify after parsing since html link quoting can # confuse CSV parsing - if (! exists $params{file}) { - @data=map { - [ map { - IkiWiki::linkify($params{page}, - $params{destpage}, $_); - } @$_ ] - } @data; - } + @data=map { + [ map { + IkiWiki::linkify($params{page}, + $params{destpage}, $_); + } @$_ ] + } @data; } elsif (lc $params{format} eq 'dsv') { # linkify before parsing since wikilinks can contain the # delimiter - if (! exists $params{file}) { - $params{data} = IkiWiki::linkify($params{page}, - $params{destpage}, $params{data}); - } + $params{data} = IkiWiki::linkify($params{page}, + $params{destpage}, $params{data}); @data=split_dsv($params{data}, defined $params{delimiter} ? $params{delimiter} : "|",); } @@ -102,16 +116,16 @@ sub preprocess (@) { #{{{ else { return $html; } -} #}}} +} -sub is_dsv_data ($) { #{{{ +sub is_dsv_data ($) { my $text = shift; my ($line) = split(/\n/, $text); return $line =~ m{.+\|}; } -sub split_csv ($$) { #{{{ +sub split_csv ($$) { my @text_lines = split(/\n/, shift); my $delimiter = shift; @@ -137,9 +151,9 @@ sub split_csv ($$) { #{{{ } return @data; -} #}}} +} -sub split_dsv ($$) { #{{{ +sub split_dsv ($$) { my @text_lines = split(/\n/, shift); my $delimiter = shift; $delimiter="|" unless defined $delimiter; @@ -150,9 +164,9 @@ sub split_dsv ($$) { #{{{ } return @data; -} #}}} +} -sub genrow ($@) { #{{{ +sub genrow ($@) { my %params=%{shift()}; my $elt = shift; my @data = @_; @@ -190,6 +204,6 @@ sub genrow ($@) { #{{{ push @ret, "\t\t"; return @ret; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 158657507..8fe9c6828 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -4,26 +4,26 @@ package IkiWiki::Plugin::tag; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; my %tags; -sub import { #{{{ +sub import { hook(type => "getopt", id => "tag", call => \&getopt); hook(type => "getsetup", id => "tag", call => \&getsetup); hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1); hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1); hook(type => "pagetemplate", id => "tag", call => \&pagetemplate); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); GetOptions("tagbase=s" => \$config{tagbase}); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -36,35 +36,30 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub tagpage ($) { #{{{ +sub tagpage ($) { my $tag=shift; if ($tag !~ m{^\.?/} && defined $config{tagbase}) { - $tag=$config{tagbase}."/".$tag; + $tag="/".$config{tagbase}."/".$tag; + $tag=~y#/#/#s; # squash dups } return $tag; -} #}}} +} -sub taglink ($$$;@) { #{{{ +sub taglink ($$$;@) { my $page=shift; my $destpage=shift; my $tag=shift; my %opts=@_; - my $link=tagpage($tag); + return htmllink($page, $destpage, tagpage($tag), %opts); +} - # Force tag creation links to create the tag under /tagbase, - # if there is a tagbase and this tag used it. - $link="/".$link if $tag ne $link; - - return htmllink($page, $destpage, $link, %opts); -} #}}} - -sub preprocess_tag (@) { #{{{ +sub preprocess_tag (@) { if (! @_) { return ""; } @@ -82,9 +77,9 @@ sub preprocess_tag (@) { #{{{ } return ""; -} # }}} +} -sub preprocess_taglink (@) { #{{{ +sub preprocess_taglink (@) { if (! @_) { return ""; } @@ -107,9 +102,9 @@ sub preprocess_taglink (@) { #{{{ grep { $_ ne 'page' && $_ ne 'destpage' && $_ ne 'preview' } keys %params); -} # }}} +} -sub pagetemplate (@) { #{{{ +sub pagetemplate (@) { my %params=@_; my $page=$params{page}; my $destpage=$params{destpage}; @@ -128,6 +123,14 @@ sub pagetemplate (@) { #{{{ sort keys %{$tags{$page}}]); } } -} # }}} +} + +package IkiWiki::PageSpec; + +sub match_tagged ($$;@) { + my $page = shift; + my $glob = shift; + return match_link($page, IkiWiki::Plugin::tag::tagpage($glob)); +} 1 diff --git a/IkiWiki/Plugin/template.pm b/IkiWiki/Plugin/template.pm index c980df48f..b6097bb49 100644 --- a/IkiWiki/Plugin/template.pm +++ b/IkiWiki/Plugin/template.pm @@ -4,24 +4,25 @@ package IkiWiki::Plugin::template; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Template; use Encode; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "template", call => \&getsetup); - hook(type => "preprocess", id => "template", call => \&preprocess); -} # }}} + hook(type => "preprocess", id => "template", call => \&preprocess, + scan => 1); +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; if (! exists $params{id}) { @@ -68,9 +69,13 @@ sub preprocess (@) { #{{{ } } + # This needs to run even in scan mode, in order to process + # links and other metadata includes via the template. + my $scan=! defined wantarray; + return IkiWiki::preprocess($params{page}, $params{destpage}, IkiWiki::filter($params{page}, $params{destpage}, - $template->output)); -} # }}} + $template->output), $scan); +} 1 diff --git a/IkiWiki/Plugin/testpagespec.pm b/IkiWiki/Plugin/testpagespec.pm index 9f9b50f01..440fca33b 100644 --- a/IkiWiki/Plugin/testpagespec.pm +++ b/IkiWiki/Plugin/testpagespec.pm @@ -3,22 +3,22 @@ package IkiWiki::Plugin::testpagespec; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "testpagespec", call => \&getsetup); hook(type => "preprocess", id => "testpagespec", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; foreach my $param (qw{match pagespec}) { @@ -37,6 +37,6 @@ sub preprocess (@) { #{{{ else { return "no match: $ret"; } -} # }}} +} 1 diff --git a/IkiWiki/Plugin/teximg.pm b/IkiWiki/Plugin/teximg.pm index 661d97b1f..dba5372b5 100644 --- a/IkiWiki/Plugin/teximg.pm +++ b/IkiWiki/Plugin/teximg.pm @@ -8,7 +8,7 @@ use strict; use Digest::MD5 qw(md5_hex); use File::Temp qw(tempdir); use HTML::Entities; -use IkiWiki 2.00; +use IkiWiki 3.00; my $default_prefix = < "getsetup", id => "teximg", call => \&getsetup); hook(type => "preprocess", id => "teximg", call => \&preprocess); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -52,9 +52,9 @@ sub getsetup () { #{{{ safe => 0, # Not sure how secure LaTeX is... rebuild => 1, }, -} #}}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params = @_; my $height = $params{height}; @@ -76,9 +76,9 @@ sub preprocess (@) { #{{{ else { error gettext("code includes disallowed latex commands") } -} #}}} +} -sub check_height ($) { #{{{ +sub check_height ($) { # Since latex doesn't support unlimited scaling this function # returns the closest supported size. my $height =shift; @@ -95,9 +95,9 @@ sub check_height ($) { #{{{ } } return $ret; -} #}}} +} -sub create ($$$) { #{{{ +sub create ($$$) { # This function calls the image generating function and returns # the for the generated image. my $code = shift; @@ -127,9 +127,9 @@ sub create ($$$) { #{{{ else { error qq{}.gettext("failed to generate image from code").""; } -} #}}} +} -sub gen_image ($$$$) { #{{{ +sub gen_image ($$$$) { # Actually creates the image. my $code = shift; my $height = shift; @@ -180,18 +180,18 @@ sub gen_image ($$$$) { #{{{ return 0; } -} #}}} +} -sub create_tmp_dir ($) { #{{{ +sub create_tmp_dir ($) { # Create a temp directory, it will be removed when ikiwiki exits. my $base = shift; my $template = $base.".XXXXXXXXXX"; my $tmpdir = tempdir($template, TMPDIR => 1, CLEANUP => 1); return $tmpdir; -} #}}} +} -sub check ($) { #{{{ +sub check ($) { # Check if the code is ok my $code = shift; @@ -219,6 +219,6 @@ sub check ($) { #{{{ } } return 1; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/textile.pm b/IkiWiki/Plugin/textile.pm index bbd282f0c..b604aa3c5 100644 --- a/IkiWiki/Plugin/textile.pm +++ b/IkiWiki/Plugin/textile.pm @@ -6,29 +6,29 @@ package IkiWiki::Plugin::textile; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use Encode; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "textile", call => \&getsetup); hook(type => "htmlize", id => "txtl", call => \&htmlize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; my $content = decode_utf8(encode_utf8($params{content})); eval q{use Text::Textile}; return $content if $@; return Text::Textile::textile($content); -} # }}} +} 1 diff --git a/IkiWiki/Plugin/tla.pm b/IkiWiki/Plugin/tla.pm index 0a5c161b2..f4b20a6ec 100644 --- a/IkiWiki/Plugin/tla.pm +++ b/IkiWiki/Plugin/tla.pm @@ -5,7 +5,7 @@ use warnings; use strict; use IkiWiki; -sub import { #{{{ +sub import { hook(type => "checkconfig", id => "tla", call => \&checkconfig); hook(type => "getsetup", id => "tla", call => \&getsetup); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); @@ -18,18 +18,18 @@ sub import { #{{{ hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (defined $config{tla_wrapper} && length $config{tla_wrapper}) { push @{$config{wrappers}}, { wrapper => $config{tla_wrapper}, wrappermode => (defined $config{tla_wrappermode} ? $config{tla_wrappermode} : "06755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # rcs plugin @@ -63,9 +63,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub quiet_system (@) { #{{{ +sub quiet_system (@) { # See Debian bug #385939. open (SAVEOUT, ">&STDOUT"); close STDOUT; @@ -75,17 +75,17 @@ sub quiet_system (@) { #{{{ open (STDOUT, ">&SAVEOUT"); close SAVEOUT; return $ret; -} #}}} +} -sub rcs_update () { #{{{ +sub rcs_update () { if (-d "$config{srcdir}/{arch}") { if (quiet_system("tla", "replay", "-d", $config{srcdir}) != 0) { warn("tla replay failed\n"); } } -} #}}} +} -sub rcs_prepedit ($) { #{{{ +sub rcs_prepedit ($) { my $file=shift; if (-d "$config{srcdir}/{arch}") { @@ -94,9 +94,9 @@ sub rcs_prepedit ($) { #{{{ my $rev=`tla tree-id $config{srcdir}`; return defined $rev ? $rev : ""; } -} #}}} +} -sub rcs_commit ($$$;$$) { #{{{ +sub rcs_commit ($$$;$$) { my $file=shift; my $message=shift; my $rcstoken=shift; @@ -135,7 +135,7 @@ sub rcs_commit ($$$;$$) { #{{{ } } return undef # success -} #}}} +} sub rcs_commit_staged ($$$) { # Commits all staged changes. Changes can be staged using rcs_add, @@ -145,7 +145,7 @@ sub rcs_commit_staged ($$$) { error("rcs_commit_staged not implemented for tla"); # TODO } -sub rcs_add ($) { #{{{ +sub rcs_add ($) { my $file=shift; if (-d "$config{srcdir}/{arch}") { @@ -153,19 +153,19 @@ sub rcs_add ($) { #{{{ warn("tla add failed\n"); } } -} #}}} +} -sub rcs_remove ($) { # {{{ +sub rcs_remove ($) { my $file = shift; error("rcs_remove not implemented for tla"); # TODO -} #}}} +} sub rcs_rename ($$) { # {{{a my ($src, $dest) = @_; error("rcs_rename not implemented for tla"); # TODO -} #}}} +} sub rcs_recentchanges ($) { my $num=shift; @@ -239,7 +239,7 @@ sub rcs_recentchanges ($) { return @ret; } -sub rcs_diff ($) { #{{{ +sub rcs_diff ($) { my $rev=shift; my $logs = `tla logs -d $config{srcdir}`; my @changesets = reverse split(/\n/, $logs); @@ -251,9 +251,9 @@ sub rcs_diff ($) { #{{{ my $revminusone = $changesets[$i+1]; return `tla diff -d $config{srcdir} $revminusone`; -} #}}} +} -sub rcs_getctime ($) { #{{{ +sub rcs_getctime ($) { my $file=shift; eval q{use Date::Parse}; error($@) if $@; @@ -281,6 +281,6 @@ sub rcs_getctime ($) { #{{{ my $date=str2time($sdate, 'UTC'); debug("found ctime ".localtime($date)." for $file"); return $date; -} #}}} +} 1 diff --git a/IkiWiki/Plugin/toc.pm b/IkiWiki/Plugin/toc.pm index dff9d9aa5..a585564e7 100644 --- a/IkiWiki/Plugin/toc.pm +++ b/IkiWiki/Plugin/toc.pm @@ -4,26 +4,26 @@ package IkiWiki::Plugin::toc; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Parser; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "toc", call => \&getsetup); hook(type => "preprocess", id => "toc", call => \&preprocess); hook(type => "format", id => "toc", call => \&format); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} my %tocpages; -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; if ($params{page} eq $params{destpage}) { @@ -40,9 +40,9 @@ sub preprocess (@) { #{{{ # right. return ""; } -} # }}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; my $content=$params{content}; diff --git a/IkiWiki/Plugin/toggle.pm b/IkiWiki/Plugin/toggle.pm index 610d38e3a..aae8cdf84 100644 --- a/IkiWiki/Plugin/toggle.pm +++ b/IkiWiki/Plugin/toggle.pm @@ -3,80 +3,27 @@ package IkiWiki::Plugin::toggle; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -# Here's the javascript that makes this possible. A key feature is the use -# of css to hide toggleables, to avoid any flashing on page load. The css -# is only emitted after the javascript tests that it's going to be able to -# show the toggleables. -our $javascript=<<'EOF'; - -EOF - -sub import { #{{{ +sub import { + add_underlay("javascript"); hook(type => "getsetup", id => "toggle", call => \&getsetup); hook(type => "preprocess", id => "toggle", call => \&preprocess_toggle); hook(type => "preprocess", id => "toggleable", call => \&preprocess_toggleable); hook(type => "format", id => "toggle", call => \&format); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub genid ($$) { #{{{ +sub genid ($$) { my $page=shift; my $id=shift; @@ -88,16 +35,16 @@ sub genid ($$) { #{{{ $id="id$id"; } return $id; -} #}}} +} -sub preprocess_toggle (@) { #{{{ +sub preprocess_toggle (@) { my %params=(id => "default", text => "more", @_); my $id=genid($params{page}, $params{id}); return "$params{text}"; -} # }}} +} -sub preprocess_toggleable (@) { #{{{ +sub preprocess_toggleable (@) { my %params=(id => "default", text => "", open => "no", @_); # Preprocess the text to expand any preprocessor directives @@ -114,19 +61,29 @@ sub preprocess_toggleable (@) { #{{{ my ($indent)=$params{text}=~/( +)$/; $indent="" unless defined $indent; return "
\n\n$params{text}\n$indent
"; -} # }}} +} -sub format (@) { #{{{ +sub format (@) { my %params=@_; if ($params{content}=~s!(
\s*)
!$1!g) { $params{content}=~s/
//g; - if (! ($params{content}=~s!^!$javascript!m)) { + if (! ($params{content}=~s!^()!$1.include_javascript($params{page})!em)) { # no tag, probably in preview mode - $params{content}=$javascript.$params{content}; + $params{content}=include_javascript($params{page}, 1).$params{content}; } } return $params{content}; -} # }}} +} + +sub include_javascript ($;$) { + my $page=shift; + my $absolute=shift; + + return ''."\n". + ''; +} 1 diff --git a/IkiWiki/Plugin/txt.pm b/IkiWiki/Plugin/txt.pm index e4c9e5d6a..8599bdc8e 100644 --- a/IkiWiki/Plugin/txt.pm +++ b/IkiWiki/Plugin/txt.pm @@ -8,7 +8,7 @@ package IkiWiki::Plugin::txt; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; use HTML::Entities; my $findurl=0; @@ -24,13 +24,13 @@ sub import { } } -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, -} #}}} +} # We use filter to convert raw text to HTML # (htmlize is called after other plugins insert HTML) @@ -39,7 +39,7 @@ sub filter (@) { my $content = $params{content}; if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.txt$/) { - encode_entities($content); + encode_entities($content, "<>&"); if ($findurl) { my $finder = URI::Find->new(sub { my ($uri, $orig_uri) = @_; diff --git a/IkiWiki/Plugin/typography.pm b/IkiWiki/Plugin/typography.pm index 27089b390..f62be82bb 100644 --- a/IkiWiki/Plugin/typography.pm +++ b/IkiWiki/Plugin/typography.pm @@ -4,22 +4,22 @@ package IkiWiki::Plugin::typography; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getopt", id => "typography", call => \&getopt); hook(type => "getsetup", id => "typography", call => \&getsetup); IkiWiki::hook(type => "sanitize", id => "typography", call => \&sanitize); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); GetOptions("typographyattributes=s" => \$config{typographyattributes}); -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { eval q{use Text::Typography}; error($@) if $@; @@ -36,9 +36,9 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, -} #}}} +} -sub sanitize (@) { #{{{ +sub sanitize (@) { my %params=@_; eval q{use Text::Typography}; @@ -46,6 +46,6 @@ sub sanitize (@) { #{{{ my $attributes=defined $config{typographyattributes} ? $config{typographyattributes} : '3'; return Text::Typography::typography($params{content}, $attributes); -} # }}} +} 1 diff --git a/IkiWiki/Plugin/underlay.pm b/IkiWiki/Plugin/underlay.pm new file mode 100644 index 000000000..380d418fb --- /dev/null +++ b/IkiWiki/Plugin/underlay.pm @@ -0,0 +1,40 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::underlay; +# Copyright © 2008 Simon McVittie +# Licensed under the GNU GPL, version 2, or any later version published by the +# Free Software Foundation + +use warnings; +use strict; +use IkiWiki 3.00; + +sub import { + hook(type => "getsetup", id => "underlay", call => \&getsetup); + hook(type => "checkconfig", id => "underlay", call => \&checkconfig); +} + +sub getsetup () { + return + plugin => { + safe => 0, + rebuild => undef, + }, + add_underlays => { + type => "string", + default => [], + description => "extra underlay directories to add", + advanced => 1, + safe => 0, + rebuild => 1, + }, +} + +sub checkconfig () { + return unless exists $config{add_underlays}; + + foreach my $dir (@{$config{add_underlays}}) { + add_underlay($dir); + } +} + +1; diff --git a/IkiWiki/Plugin/version.pm b/IkiWiki/Plugin/version.pm index 18e9613ae..587cd55fa 100644 --- a/IkiWiki/Plugin/version.pm +++ b/IkiWiki/Plugin/version.pm @@ -4,23 +4,23 @@ package IkiWiki::Plugin::version; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "version", call => \&getsetup); hook(type => "needsbuild", id => "version", call => \&needsbuild); hook(type => "preprocess", id => "version", call => \&preprocess); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, rebuild => undef, }, -} #}}} +} -sub needsbuild (@) { #{{{ +sub needsbuild (@) { my $needsbuild=shift; foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{version}{shown}) { @@ -36,11 +36,11 @@ sub needsbuild (@) { #{{{ } } } -} # }}} +} -sub preprocess (@) { #{{{ +sub preprocess (@) { my %params=@_; $pagestate{$params{destpage}}{version}{shown}=$IkiWiki::version; -} # }}} +} 1 diff --git a/IkiWiki/Plugin/websetup.pm b/IkiWiki/Plugin/websetup.pm index 827ee3099..95d044c08 100644 --- a/IkiWiki/Plugin/websetup.pm +++ b/IkiWiki/Plugin/websetup.pm @@ -3,17 +3,17 @@ package IkiWiki::Plugin::websetup; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "websetup", call => \&getsetup); hook(type => "checkconfig", id => "websetup", call => \&checkconfig); hook(type => "sessioncgi", id => "websetup", call => \&sessioncgi); hook(type => "formbuilder_setup", id => "websetup", call => \&formbuilder_setup); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 1, @@ -33,15 +33,15 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, -} #}}} +} -sub checkconfig () { #{{{ +sub checkconfig () { if (! exists $config{websetup_show_unsafe}) { $config{websetup_show_unsafe}=1; } -} #}}} +} -sub formatexample ($$) { #{{{ +sub formatexample ($$) { my $example=shift; my $value=shift; @@ -54,9 +54,9 @@ sub formatexample ($$) { #{{{ else { return ""; } -} #}}} +} -sub showfields ($$$@) { #{{{ +sub showfields ($$$@) { my $form=shift; my $plugin=shift; my $enabled=shift; @@ -139,7 +139,7 @@ sub showfields ($$$@) { #{{{ my $value=$config{$key}; if ($info{safe} && (ref $value eq 'ARRAY' || ref $info{example} eq 'ARRAY')) { - $value=[@{$value}, "", ""]; # blank items for expansion + $value=[(ref $value eq 'ARRAY' ? @{$value} : ""), "", ""]; # blank items for expansion } if ($info{type} eq "string") { @@ -207,16 +207,16 @@ sub showfields ($$$@) { #{{{ } return %enabledfields; -} #}}} +} -sub enable_plugin ($) { #{{{ +sub enable_plugin ($) { my $plugin=shift; $config{disable_plugins}=[grep { $_ ne $plugin } @{$config{disable_plugins}}]; push @{$config{add_plugins}}, $plugin; } -sub disable_plugin ($) { #{{{ +sub disable_plugin ($) { my $plugin=shift; if (grep { $_ eq $plugin } @{$config{add_plugins}}) { @@ -227,7 +227,7 @@ sub disable_plugin ($) { #{{{ } } -sub showform ($$) { #{{{ +sub showform ($$) { my $cgi=shift; my $session=shift; @@ -441,9 +441,9 @@ sub showform ($$) { #{{{ } IkiWiki::showform($form, $buttons, $session, $cgi); -} #}}} +} -sub sessioncgi ($$) { #{{{ +sub sessioncgi ($$) { my $cgi=shift; my $session=shift; @@ -451,9 +451,9 @@ sub sessioncgi ($$) { #{{{ showform($cgi, $session); exit; } -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; @@ -464,6 +464,6 @@ sub formbuilder_setup (@) { #{{{ exit; } } -} #}}} +} 1 diff --git a/IkiWiki/Plugin/wikitext.pm b/IkiWiki/Plugin/wikitext.pm index c47ccb7b1..accb03bbe 100644 --- a/IkiWiki/Plugin/wikitext.pm +++ b/IkiWiki/Plugin/wikitext.pm @@ -4,29 +4,29 @@ package IkiWiki::Plugin::wikitext; use warnings; use strict; -use IkiWiki 2.00; +use IkiWiki 3.00; -sub import { #{{{ +sub import { hook(type => "getsetup", id => "wiki", call => \&getsetup); hook(type => "htmlize", id => "wiki", call => \&htmlize); -} # }}} +} -sub getsetup () { #{{{ +sub getsetup () { return plugin => { safe => 0, # format plugin rebuild => undef, }, -} #}}} +} -sub htmlize (@) { #{{{ +sub htmlize (@) { my %params=@_; my $content = $params{content}; eval q{use Text::WikiFormat}; return $content if $@; return Text::WikiFormat::format($content, undef, { implicit_links => 0 }); -} # }}} +} 1 diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm new file mode 100644 index 000000000..9ddd237ab --- /dev/null +++ b/IkiWiki/Plugin/wmd.pm @@ -0,0 +1,52 @@ +#!/usr/bin/perl +package IkiWiki::Plugin::wmd; + +use warnings; +use strict; +use IkiWiki 3.00; +use POSIX; +use Encode; + +sub import { + add_underlay("wmd"); + hook(type => "getsetup", id => "wmd", call => \&getsetup); + hook(type => "formbuilder_setup", id => "wmd", call => \&formbuilder_setup); +} + +sub getsetup () { + return + plugin => { + safe => 1, + }, +} + +sub formbuilder_setup (@) { + my %params=@_; + my $form=$params{form}; + + return if ! defined $form->field("do"); + + return unless $form->field("do") eq "edit" || + $form->field("do") eq "create" || + $form->field("do") eq "comment"; + + $form->tmpl_param("wmd_preview", "
\n". + include_javascript(undef, 1)); +} + +sub include_javascript ($;$) { + my $page=shift; + my $absolute=shift; + + my $wmdjs=urlto("wmd/wmd.js", $page, $absolute); + return <<"EOF" + + +EOF +} + +1 diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm new file mode 100644 index 000000000..37b6f2a62 --- /dev/null +++ b/IkiWiki/Receive.pm @@ -0,0 +1,135 @@ +#!/usr/bin/perl + +package IkiWiki::Receive; + +use warnings; +use strict; +use IkiWiki; + +sub getuser () { + my $user=(getpwuid(exists $ENV{CALLER_UID} ? $ENV{CALLER_UID} : $<))[0]; + if (! defined $user) { + error("cannot determine username for $<"); + } + return $user; +} + +sub trusted () { + my $user=getuser(); + return ! ref $config{untrusted_committers} || + ! grep { $_ eq $user } @{$config{untrusted_committers}}; +} + +sub gen_wrapper () { + # Test for commits from untrusted committers in the wrapper, to + # avoid loading ikiwiki at all for trusted commits. + + my $ret=<<"EOF"; + { + int u=getuid(); +EOF + $ret.="\t\tif ( ". + join("&&", map { + my $uid=getpwnam($_); + if (! defined $uid) { + error(sprintf(gettext("cannot determine id of untrusted committer %s"), $_)); + } + "u != $uid"; + } @{$config{untrusted_committers}}). + ") exit(0);\n"; + $ret.=<<"EOF"; + asprintf(&s, "CALLER_UID=%i", u); + newenviron[i++]=s; + } +EOF + return $ret; +} + +sub test () { + exit 0 if trusted(); + + IkiWiki::lockwiki(); + IkiWiki::loadindex(); + + # Dummy up a cgi environment to use when calling check_canedit + # and friends. + eval q{use CGI}; + error($@) if $@; + my $cgi=CGI->new; + $ENV{REMOTE_ADDR}='unknown' unless exists $ENV{REMOTE_ADDR}; + + # And dummy up a session object. + require IkiWiki::CGI; + my $session=IkiWiki::cgi_getsession($cgi); + $session->param("name", getuser()); + # Make sure whatever user was authed is in the + # userinfo db. + require IkiWiki::UserInfo; + if (! IkiWiki::userinfo_get($session->param("name"), "regdate")) { + IkiWiki::userinfo_setall($session->param("name"), { + email => "", + password => "", + regdate => time, + }) || error("failed adding user"); + } + + my %newfiles; + + foreach my $change (IkiWiki::rcs_receive()) { + # This untaint is safe because we check file_pruned and + # wiki_file_regexp. + my ($file)=$change->{file}=~/$config{wiki_file_regexp}/; + $file=IkiWiki::possibly_foolish_untaint($file); + if (! defined $file || ! length $file || + IkiWiki::file_pruned($file, $config{srcdir})) { + error(gettext("bad file name %s"), $file); + } + + my $type=pagetype($file); + my $page=pagename($file) if defined $type; + + if ($change->{action} eq 'add') { + $newfiles{$file}=1; + } + + if ($change->{action} eq 'change' || + $change->{action} eq 'add') { + if (defined $page) { + if (IkiWiki->can("check_canedit")) { + IkiWiki::check_canedit($page, $cgi, $session); + next; + } + } + else { + if (IkiWiki::Plugin::attachment->can("check_canattach")) { + IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path}); + next; + } + } + } + elsif ($change->{action} eq 'remove') { + # check_canremove tests to see if the file is present + # on disk. This will fail is a single commit adds a + # file and then removes it again. Avoid the problem + # by not testing the removal in such pairs of changes. + # (The add is still tested, just to make sure that + # no data is added to the repo that a web edit + # could add.) + next if $newfiles{$file}; + + if (IkiWiki::Plugin::remove->can("check_canremove")) { + IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session); + next; + } + } + else { + error "unknown action ".$change->{action}; + } + + error sprintf(gettext("you are not allowed to change %s"), $file); + } + + exit 0; +} + +1 diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index bc997ffb0..adae9f0d5 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -10,7 +10,7 @@ use Encode; my %backlinks; my $backlinks_calculated=0; -sub calculate_backlinks () { #{{{ +sub calculate_backlinks () { return if $backlinks_calculated; %backlinks=(); foreach my $page (keys %links) { @@ -22,9 +22,9 @@ sub calculate_backlinks () { #{{{ } } $backlinks_calculated=1; -} #}}} +} -sub backlinks ($) { #{{{ +sub backlinks ($) { my $page=shift; calculate_backlinks(); @@ -45,9 +45,9 @@ sub backlinks ($) { #{{{ push @links, { url => $href, page => pagetitle($p_trimmed) }; } return @links; -} #}}} +} -sub genpage ($$) { #{{{ +sub genpage ($$) { my $page=shift; my $content=shift; @@ -131,9 +131,9 @@ sub genpage ($$) { #{{{ }); return $content; -} #}}} +} -sub scan ($) { #{{{ +sub scan ($) { my $file=shift; my $type=pagetype($file); @@ -165,9 +165,9 @@ sub scan ($) { #{{{ else { will_render($file, $file, 1); } -} #}}} +} -sub fast_file_copy (@) { #{{{ +sub fast_file_copy (@) { my $srcfile=shift; my $destfile=shift; my $srcfd=shift; @@ -191,7 +191,7 @@ sub fast_file_copy (@) { #{{{ } } -sub render ($) { #{{{ +sub render ($) { my $file=shift; my $type=pagetype($file); @@ -233,9 +233,9 @@ sub render ($) { #{{{ fast_file_copy($srcfile, $file, $srcfd, @_); }); } -} #}}} +} -sub prune ($) { #{{{ +sub prune ($) { my $file=shift; unlink($file); @@ -243,14 +243,14 @@ sub prune ($) { #{{{ while (rmdir($dir)) { $dir=dirname($dir); } -} #}}} +} -sub refresh () { #{{{ +sub refresh () { # security check, avoid following symlinks in the srcdir path by default my $test=$config{srcdir}; while (length $test) { if (-l $test && ! $config{allow_symlinks_before_srcdir}) { - error(sprintf(gettext("symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to allow this")), $test); + error(sprintf(gettext("symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to allow this"), $test)); } unless ($test=~s/\/+$//) { $test=dirname($test); @@ -507,9 +507,9 @@ sub refresh () { #{{{ if (%rendered) { run_hooks(change => sub { shift->(keys %rendered) }); } -} #}}} +} -sub commandline_render () { #{{{ +sub commandline_render () { lockwiki(); loadindex(); unlockwiki(); @@ -528,9 +528,10 @@ sub commandline_render () { #{{{ $content=linkify($page, $page, $content); $content=htmlize($page, $page, $type, $content); $pagemtime{$page}=(stat($srcfile))[9]; + $pagectime{$page}=$pagemtime{$page} if ! exists $pagectime{$page}; print genpage($page, $content); exit 0; -} #}}} +} 1 diff --git a/IkiWiki/Setup.pm b/IkiWiki/Setup.pm index 77afdd608..6ee112096 100644 --- a/IkiWiki/Setup.pm +++ b/IkiWiki/Setup.pm @@ -10,7 +10,7 @@ use IkiWiki; use open qw{:utf8 :std}; use File::Spec; -sub load ($) { # {{{ +sub load ($) { my $setup=IkiWiki::possibly_foolish_untaint(shift); $config{setupfile}=File::Spec->rel2abs($setup); @@ -27,7 +27,7 @@ sub load ($) { # {{{ eval $code; error("$setup: ".$@) if $@; -} #}}} +} sub merge ($) { # Merge setup into existing config and untaint. @@ -71,9 +71,9 @@ sub merge ($) { wrappermode => (defined $config{cgi_wrappermode} ? $config{cgi_wrappermode} : "06755"), }; } -} #}}} +} -sub getsetup () { #{{{ +sub getsetup () { # Gets all available setup data from all plugins. Returns an # ordered list of [plugin, setup] pairs. my @ret; @@ -105,9 +105,9 @@ sub getsetup () { #{{{ $config{syslog}=$syslog; return @ret; -} #}}} +} -sub dump ($) { #{{{ +sub dump ($) { my $file=IkiWiki::possibly_foolish_untaint(shift); require IkiWiki::Setup::Standard; diff --git a/IkiWiki/Setup/Automator.pm b/IkiWiki/Setup/Automator.pm index 88e9f3d24..7d9eca3af 100644 --- a/IkiWiki/Setup/Automator.pm +++ b/IkiWiki/Setup/Automator.pm @@ -9,21 +9,22 @@ use IkiWiki; use IkiWiki::UserInfo; use Term::ReadLine; use File::Path; +use Encode; -sub ask ($$) { #{{{ +sub ask ($$) { my ($question, $default)=@_; my $r=Term::ReadLine->new("ikiwiki"); - $r->readline($question." ", $default); -} #}}} + $r->readline(encode_utf8($question)." ", $default); +} -sub prettydir ($) { #{{{ +sub prettydir ($) { my $dir=shift; $dir=~s/^\Q$ENV{HOME}\E\//~\//; return $dir; -} #}}} +} -sub import (@) { #{{{ +sub import (@) { my $this=shift; IkiWiki::Setup::merge({@_}); @@ -73,8 +74,18 @@ sub import (@) { #{{{ print "\n\nSetting up $config{wikiname} ...\n"; - # Set up the repository. + # Set up the srcdir. mkpath($config{srcdir}) || die "mkdir $config{srcdir}: $!"; + # Copy in example wiki. + if (exists $config{example}) { + # cp -R is POSIX + # Another reason not to use -a is so that pages such as blog + # posts will not have old creation dates on this new wiki. + system("cp -R $IkiWiki::installdir/share/ikiwiki/examples/$config{example}/* $config{srcdir}"); + delete $config{example}; + } + + # Set up the repository. delete $config{repository} if ! $config{rcs} || $config{rcs}=~/bzr|mercurial/; if ($config{rcs}) { my @params=($config{rcs}, $config{srcdir}); @@ -99,11 +110,20 @@ sub import (@) { #{{{ next if $admin=~/^http\?:\/\//; # openid # Prompt for password w/o echo. + my ($password, $password2); system('stty -echo 2>/dev/null'); local $|=1; print "\n\nCreating wiki admin $admin ...\n"; - print "Choose a password: "; - chomp(my $password=); + for (;;) { + print "Choose a password: "; + chomp($password=); + print "Confirm password: "; + chomp($password2=); + + last if $password2 eq $password; + + print "Password mismatch.\n\n"; + } print "\n\n\n"; system('stty sane 2>/dev/null'); @@ -142,6 +162,6 @@ sub import (@) { #{{{ print "To modify settings, edit ".prettydir($config{dumpsetup})." and then run:\n"; print " ikiwiki -setup ".prettydir($config{dumpsetup})."\n"; exit 0; -} #}}} +} 1 diff --git a/IkiWiki/Setup/Standard.pm b/IkiWiki/Setup/Standard.pm index 92f887f0c..951bcfc56 100644 --- a/IkiWiki/Setup/Standard.pm +++ b/IkiWiki/Setup/Standard.pm @@ -9,11 +9,11 @@ use warnings; use strict; use IkiWiki; -sub import { #{{{ +sub import { IkiWiki::Setup::merge($_[1]); -} #}}} +} -sub dumpline ($$$$) { #{{{ +sub dumpline ($$$$) { my $key=shift; my $value=shift; my $type=shift; @@ -26,6 +26,8 @@ sub dumpline ($$$$) { #{{{ local $Data::Dumper::Pad="\t"; local $Data::Dumper::Sortkeys=1; local $Data::Dumper::Quotekeys=0; + # only the perl version preserves utf-8 in output + local $Data::Dumper::Useperl=1; my $dumpedvalue; if (($type eq 'boolean' || $type eq 'integer') && $value=~/^[0-9]+$/) { @@ -53,9 +55,9 @@ sub dumpline ($$$$) { #{{{ } return "\t$prefix$key => $dumpedvalue,"; -} #}}} +} -sub dumpvalues ($@) { #{{{ +sub dumpvalues ($@) { my $setup=shift; my @ret; while (@_) { @@ -78,9 +80,9 @@ sub dumpvalues ($@) { #{{{ } } return @ret; -} #}}} +} -sub gendump ($) { #{{{ +sub gendump ($) { my $description=shift; my %setup=(%config); my @ret; @@ -110,6 +112,6 @@ sub gendump ($) { #{{{ push @ret, "}"; return @ret; -} #}}} +} 1 diff --git a/IkiWiki/UserInfo.pm b/IkiWiki/UserInfo.pm index dcf99da09..0bf100a95 100644 --- a/IkiWiki/UserInfo.pm +++ b/IkiWiki/UserInfo.pm @@ -7,12 +7,12 @@ use strict; use Storable; use IkiWiki; -sub userinfo_retrieve () { #{{{ +sub userinfo_retrieve () { my $userinfo=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") }; return $userinfo; -} #}}} +} -sub userinfo_store ($) { #{{{ +sub userinfo_store ($) { my $userinfo=shift; my $newfile="$config{wikistatedir}/userdb.new"; @@ -26,9 +26,9 @@ sub userinfo_store ($) { #{{{ } } return $ret; -} #}}} +} -sub userinfo_get ($$) { #{{{ +sub userinfo_get ($$) { my $user=shift; my $field=shift; @@ -39,9 +39,9 @@ sub userinfo_get ($$) { #{{{ return ""; } return $userinfo->{$user}->{$field}; -} #}}} +} -sub userinfo_set ($$$) { #{{{ +sub userinfo_set ($$$) { my $user=shift; my $field=shift; my $value=shift; @@ -54,9 +54,9 @@ sub userinfo_set ($$$) { #{{{ $userinfo->{$user}->{$field}=$value; return userinfo_store($userinfo); -} #}}} +} -sub userinfo_setall ($$) { #{{{ +sub userinfo_setall ($$) { my $user=shift; my $info=shift; @@ -66,32 +66,12 @@ sub userinfo_setall ($$) { #{{{ } $userinfo->{$user}=$info; return userinfo_store($userinfo); -} #}}} +} -sub is_admin ($) { #{{{ +sub is_admin ($) { my $user_name=shift; return grep { $_ eq $user_name } @{$config{adminuser}}; -} #}}} - -# XXX deprecated, should be removed eventually -sub get_banned_users () { #{{{ - my @ret; - my $userinfo=userinfo_retrieve(); - foreach my $user (keys %{$userinfo}) { - push @ret, $user if $userinfo->{$user}->{banned}; - } - return @ret; -} #}}} - -# XXX deprecated, should be removed eventually -sub set_banned_users (@) { #{{{ - my %banned=map { $_ => 1 } @_; - my $userinfo=userinfo_retrieve(); - foreach my $user (keys %{$userinfo}) { - $userinfo->{$user}->{banned} = $banned{$user}; - } - return userinfo_store($userinfo); -} #}}} +} 1 diff --git a/IkiWiki/Wrapper.pm b/IkiWiki/Wrapper.pm index 187314d16..6555fe625 100644 --- a/IkiWiki/Wrapper.pm +++ b/IkiWiki/Wrapper.pm @@ -8,7 +8,7 @@ use File::Spec; use Data::Dumper; use IkiWiki; -sub gen_wrapper () { #{{{ +sub gen_wrapper () { $config{srcdir}=File::Spec->rel2abs($config{srcdir}); $config{destdir}=File::Spec->rel2abs($config{destdir}); my $this=File::Spec->rel2abs($0); @@ -28,34 +28,84 @@ sub gen_wrapper () { #{{{ my @envsave; push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE - HTTP_COOKIE REMOTE_USER HTTPS} if $config{cgi}; + HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS + REDIRECT_URL} if $config{cgi}; my $envsave=""; foreach my $var (@envsave) { - $envsave.=<<"EOF" + $envsave.=<<"EOF"; if ((s=getenv("$var"))) addenv("$var", s); EOF } - + + my $test_receive=""; + if ($config{test_receive}) { + require IkiWiki::Receive; + $test_receive=IkiWiki::Receive::gen_wrapper(); + } + + my $check_commit_hook=""; + my $pre_exec=""; + if ($config{post_commit}) { + # Optimise checking !commit_hook_enabled() , + # so that ikiwiki does not have to be started if the + # hook is disabled. + # + # Note that perl's flock may be implemented using fcntl + # or lockf on some systems. If so, and if there is no + # interop between the locking systems, the true C flock will + # always succeed, and this optimisation won't work. + # The perl code will later correctly check the lock, + # so the right thing will still happen, though without + # the benefit of this optimisation. + $check_commit_hook=<<"EOF"; + { + int fd=open("$config{wikistatedir}/commitlock", O_CREAT | O_RDWR, 0666); + if (fd != -1) { + if (flock(fd, LOCK_SH | LOCK_NB) != 0) + exit(0); + close(fd); + } + } +EOF + } + elsif ($config{cgi}) { + # Avoid more than one ikiwiki cgi running at a time by + # taking a cgi lock. Since ikiwiki uses several MB of + # memory, a pile up of processes could cause thrashing + # otherwise. The fd of the lock is stored in + # IKIWIKI_CGILOCK_FD so unlockwiki can close it. + $pre_exec=<<"EOF"; + { + int fd=open("$config{wikistatedir}/cgilock", O_CREAT | O_RDWR, 0666); + if (fd != -1 && flock(fd, LOCK_EX) == 0) { + char *fd_s; + asprintf(&fd_s, "%i", fd); + setenv("IKIWIKI_CGILOCK_FD", fd_s, 1); + } + } +EOF + } + $Data::Dumper::Indent=0; # no newlines my $configstring=Data::Dumper->Dump([\%config], ['*config']); $configstring=~s/\\/\\\\/g; $configstring=~s/"/\\"/g; $configstring=~s/\n/\\n/g; - #translators: The first parameter is a filename, and the second is - #translators: a (probably not translated) error message. - open(OUT, ">$wrapper.c") || error(sprintf(gettext("failed to write %s: %s"), "$wrapper.c", $!));; - print OUT <<"EOF"; + writefile(basename("$wrapper.c"), dirname($wrapper), <<"EOF"); /* A wrapper for ikiwiki, can be safely made suid. */ #include #include +#include +#include #include #include #include +#include extern char **environ; -char *newenviron[$#envsave+5]; +char *newenviron[$#envsave+6]; int i=0; addenv(char *var, char *val) { @@ -67,8 +117,10 @@ addenv(char *var, char *val) { } int main (int argc, char **argv) { - /* Sanitize environment. */ char *s; + +$check_commit_hook +$test_receive $envsave newenviron[i++]="HOME=$ENV{HOME}"; newenviron[i++]="WRAPPED_OPTIONS=$configstring"; @@ -86,6 +138,7 @@ $envsave exit(1); } +$pre_exec execl("$this", "$this", NULL); perror("exec $this"); exit(1); @@ -118,6 +171,6 @@ EOF #translators: The parameter is a filename. printf(gettext("successfully generated %s"), $wrapper); print "\n"; -} #}}} +} 1 diff --git a/Makefile.PL b/Makefile.PL index 95e574c66..93f9e89e2 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -23,6 +23,9 @@ PROBABLE_INST_LIB=$(shell \\ fi \\ ) +# Additional configurable path variables. +W3M_CGI_BIN?=$(PREFIX)/lib/w3m/cgi-bin + tflag=$(shell if [ -n "$$NOTAINT" ] && [ "$$NOTAINT" != 1 ]; then printf -- "-T"; fi) extramodules=$(shell if [ "$$PROFILE" = 1 ]; then printf -- "-d:Profile"; fi) @@ -39,7 +42,7 @@ extra_build: ikiwiki.out ikiwiki.setup docwiki ./mdwn2man ikiwiki-makerepo 1 doc/ikiwiki-makerepo.mdwn > ikiwiki-makerepo.man ./mdwn2man ikiwiki-transition 1 doc/ikiwiki-transition.mdwn > ikiwiki-transition.man ./mdwn2man ikiwiki-update-wikilist 1 doc/ikiwiki-update-wikilist.mdwn > ikiwiki-update-wikilist.man - $(MAKE) -C po mo + $(MAKE) -C po docwiki: ikiwiki.out $(PERL) -Iblib/lib $(extramodules) $(tflag) ikiwiki.out -libdir . -setup docwiki.setup -refresh @@ -54,6 +57,7 @@ extra_install: for dir in `cd underlays && find . -follow -type d ! -regex '.*\.svn.*'`; do \ install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \ for file in `find underlays/$$dir -follow -maxdepth 1 -type f`; do \ + cp -aL $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir 2>/dev/null || \ install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \ done; \ done @@ -65,6 +69,15 @@ extra_install: install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/directives/ikiwiki/directive; \ fi \ done + + # Install example sites. + for dir in `cd doc/examples; find . -type d ! -regex '.*\.svn.*'`; do \ + install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$dir; \ + done + for file in `cd doc/examples; find . -type f ! -regex '.*\.svn.*'`; do \ + cp -aL doc/examples/$$file $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$file 2>/dev/null || \ + install -m 644 doc/examples/$$file $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$file; \ + done for dir in `find templates -follow -type d ! -regex '.*\.svn.*'`; do \ install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \ @@ -74,10 +87,10 @@ extra_install: done install -d $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins - for file in `find plugins -maxdepth 1 -type f ! -wholename plugins/.\* ! -name \*demo\* -name \*.py`; do \ + for file in `find plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* -name \*.py`; do \ install -m 644 $$file $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins; \ done - for file in `find plugins -maxdepth 1 -type f ! -wholename plugins/.\* ! -name \*demo\* ! -name \*.py ! -name \*.pyc`; do \ + for file in `find plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* ! -name \*.py ! -name \*.pyc`; do \ install -m 755 $$file $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins; \ done @@ -93,8 +106,8 @@ extra_install: install -d $(DESTDIR)$(PREFIX)/sbin install ikiwiki-mass-rebuild $(DESTDIR)$(PREFIX)/sbin - install -d $(DESTDIR)$(PREFIX)/lib/w3m/cgi-bin - install ikiwiki-w3m.cgi $(DESTDIR)$(PREFIX)/lib/w3m/cgi-bin + install -d $(DESTDIR)$(W3M_CGI_BIN) + install ikiwiki-w3m.cgi $(DESTDIR)$(W3M_CGI_BIN) install -d $(DESTDIR)$(PREFIX)/bin install ikiwiki.out $(DESTDIR)$(PREFIX)/bin/ikiwiki @@ -107,6 +120,7 @@ extra_install: -install -d $(DESTDIR)/etc/ikiwiki -install -m 0644 wikilist $(DESTDIR)/etc/ikiwiki -install -m 0644 auto.setup $(DESTDIR)/etc/ikiwiki + -install -m 0644 auto-blog.setup $(DESTDIR)/etc/ikiwiki } } diff --git a/auto-blog.setup b/auto-blog.setup new file mode 100644 index 000000000..3ef734b39 --- /dev/null +++ b/auto-blog.setup @@ -0,0 +1,49 @@ +#!/usr/bin/perl +# Ikiwiki setup automator -- blog version. +# +# This setup file causes ikiwiki to create a wiki, containing a blog, +# check it into revision control, generate a setup file for the new +# wiki, and set everything up. +# +# Just run: ikiwiki -setup /etc/ikiwiki/auto-blog.setup +# +# By default, it asks a few questions, and confines itself to the user's home +# directory. You can edit it to change what it asks questions about, or to +# modify the values to use site-specific settings. + +require IkiWiki::Setup::Automator; + +our $wikiname=IkiWiki::Setup::Automator::ask( + gettext("What will the blog be named?"), gettext("blog")); +our $rcs=IkiWiki::Setup::Automator::ask( + gettext("What revision control system to use?"), "git"); +our $admin=IkiWiki::Setup::Automator::ask( + gettext("What wiki user (or openid) will be admin?"), $ENV{USER}); +use Net::Domain q{hostfqdn}; +our $domain=hostfqdn() || ikiwiki::setup::automator::ask( + gettext("What is the domain name of the web server?"), ""); + +IkiWiki::Setup::Automator->import( + wikiname => $wikiname, + adminuser => [$admin], + rcs => $rcs, + srcdir => "$ENV{HOME}/$wikiname", + destdir => "$ENV{HOME}/public_html/$wikiname", + repository => "$ENV{HOME}/$wikiname.".($rcs eq "monotone" ? "mtn" : $rcs), + dumpsetup => "$ENV{HOME}/$wikiname.setup", + url => "http://$domain/~$ENV{USER}/$wikiname", + cgiurl => "http://$domain/~$ENV{USER}/$wikiname/ikiwiki.cgi", + cgi_wrapper => "$ENV{HOME}/public_html/$wikiname/ikiwiki.cgi", + adminemail => "$ENV{USER}\@$domain", + add_plugins => [qw{goodstuff websetup comments blogspam}], + disable_plugins => [qw{}], + libdir => "$ENV{HOME}/.ikiwiki", + rss => 1, + atom => 1, + syslog => 1, + + example => "blog", + comments_pagespec => "posts/* and !*/Discussion", + blogspam_pagespec => "postcomment(*)", + discussion => 0, +) diff --git a/auto.setup b/auto.setup index ef0f1723c..3da5e3a62 100644 --- a/auto.setup +++ b/auto.setup @@ -17,7 +17,7 @@ our $wikiname=IkiWiki::Setup::Automator::ask( our $rcs=IkiWiki::Setup::Automator::ask( gettext("What revision control system to use?"), "git"); our $admin=IkiWiki::Setup::Automator::ask( - gettext("What wiki user (or openid) will be wiki admin?"), $ENV{USER}); + gettext("What wiki user (or openid) will be admin?"), $ENV{USER}); use Net::Domain q{hostfqdn}; our $domain=hostfqdn() || ikiwiki::setup::automator::ask( gettext("What is the domain name of the web server?"), ""); @@ -40,6 +40,4 @@ IkiWiki::Setup::Automator->import( rss => 1, atom => 1, syslog => 1, - prefix_directives => 1, - hardlink => 1, ) diff --git a/debian/NEWS b/debian/NEWS index a7a145d9b..22513cc4a 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,3 +1,27 @@ +ikiwiki (3.01) unstable; urgency=low + + If your wiki uses git, and you have a `diffurl` configured in + its setup file, you should be aware that gitweb has stopped + supporting the url form commonly used for the `diffurl`. + + You can change your setup to use the newer gitweb url form: + + http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]] + + The changes from the old form are the addition of the `hpb` parameter, + and the change to the value used for the `hb` parameter. + + -- Joey Hess Mon, 05 Jan 2009 18:18:05 -0500 + +ikiwiki (3.00) unstable; urgency=low + + The 3.0 release of ikiwiki changes several defaults and finishes + some transitions. You will need to modify your wikis to work with + ikiwiki 3.0. A document explaining the process is available + in + + -- Joey Hess Tue, 23 Dec 2008 16:14:18 -0500 + ikiwiki (2.62) unstable; urgency=low TexImg standard preamble changed @@ -101,10 +125,7 @@ ikiwiki (2.40) unstable; urgency=low in their setup files. To convert your wiki to the new syntax, ikiwiki provides a new script - ikiwiki-transition. It will convert preprocessor directives in - all files given on the command line. To convert an entire wiki: - - find wikidir/ -type f -name '*.mdwn' -print0 | xargs -0 ikiwiki-transition prefix_directives + ikiwiki-transition. Even with prefix_directives disabled, ikiwiki now allows an optional '!' prefix on preprocessor directives (but still requires a space). Thus, a diff --git a/debian/changelog b/debian/changelog index ecef4f158..fab20985d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,295 @@ -ikiwiki (2.67) UNRELEASED; urgency=low +ikiwiki (3.09) unstable; urgency=low + + * inline: Add title_natural sort order, using Sort::Naturally + (chrysn) + * inline: Fix urls to feed when feedfile is used on an index page. + * git, mercurial: Fix --getctime to return file creation time, + not last commit time. + * Updated French translation (Jean-Luc Coulon). Closes: #521072 + * css: Add clear: both to inlinefooter. + * comments: Fix too loose test for comments pages that matched + normal pages with "comment_" in their name. Closes: #521322 + * comments: Fix anchor ids to be legal xhtml. Closes: #521339 + * Fix documentation of anonok_pagespec. Closes: #521793 + * Add missing suggests on libtext-textile-perl. Closes: #522039 + * recentchanges: change to using do=goto links for user links. + * Fix git test suite to use a bare repo. + + -- Joey Hess Sat, 04 Apr 2009 14:33:49 -0400 + +ikiwiki (3.08) unstable; urgency=low + + * git: Fix utf-8 encoding of author names. + * git: Manually decode git output from utf-8, avoids + warning messages on invalidly encoded output. + * Fix bug that caused weird things to appear as page types. + + -- Joey Hess Sun, 15 Mar 2009 17:54:47 -0400 + +ikiwiki (3.07) unstable; urgency=low + + * Updated German translation (Kai Wasserbäch). Closes: #518377 + * Updated French translation (Jean-Luc Coulon). Closes: #518510 + * wmd: New plugin contributed by William Uther to support the WMD + Wysiwym markdown editor. + * smiley: Avoid infinite loop in smiley expansion triggered + by the template scan mode change in version 3.05. Closes: #518805 + * template: When loading a template in scan mode, let preprocess + know it only needs to scan. + + -- Joey Hess Sun, 08 Mar 2009 19:00:46 -0400 + +ikiwiki (3.06) unstable; urgency=low + + * Setup automator: Fix bug in password comparison. Closes: #517654 + + -- Joey Hess Sun, 01 Mar 2009 15:02:30 -0500 + +ikiwiki (3.05) unstable; urgency=low + + * debhelper v7(.0.50); rules file minimisation. + * template: Load templates in scan mode. + This is potentially expensive, but is necessary so that meta and tag + directives, and other links on templates affect the page using the + template reliably. + * goto: Fix redirect to comments. + * Add noextension parameter to htmlize hooks to support, eg, Makefile. + * Add tagged() PageSpec. + * Updated German translation (Kai Wasserbäch). Closes: #516770 + * Setup automator: Prompt for password twice. Closes: #516973 + * bzr: Add missing rcs_diff. (liw) + * comments: Avoid showing comment moderation button in prefs to non-admins. + * goto: Fix typo that broke recentchanges_link compatibility. + + -- Joey Hess Fri, 27 Feb 2009 15:48:39 -0500 + +ikiwiki (3.04) unstable; urgency=low + + * 404: New plugin which lets you use the IkiWiki CGI script as + an Apache 404 handler, to give the behaviour of various other wiki + engines where visiting a nonexistent page provides you with a link + to create it. (smcv) + * Factor out redundant code into goto plugin. (smcv) + * Work around XML::Atom strangeness that results in double-encoded posts. + (smcv) + * Fix unusual --setup --post-commit command line option combo. + * Create any missing directory necessary to put the wrapper + file into. Closes: #514384 + * shortcut: If default_pageext is set, first look for + shortcuts.default_pageext. + * Allow comments, rename, remove, and attachment plugins to be used + even if the editpage plugin is disabled. + + -- Joey Hess Sat, 14 Feb 2009 02:27:14 -0500 + +ikiwiki (3.03) unstable; urgency=low + + * Avoid feeding decoded unicode to Term::ReadLine. Closes: 512169 + * blogspam: Log spam info on failure in debug mode. + * Remove nonstandard css. Closes: #512378 + * blogspam: Fix use of blogspam_options and blogspam_server config settings. + * comments: If comment content checks fail, store the comment + (in .ikiwiki/comments_pending) for moderator review. + * comments: Add a moderation web interface, which admins can + access via their Preferences page. + * git: Fix malformed utf8 received from git. + * meta: New "updated" metadata specifies a fake modification time for a + page, to be output into RSS and Atom feeds. (smcv) + * underlay: New plugin, allows pulling in additional files not + in version control. (smcv) + + -- Joey Hess Thu, 29 Jan 2009 14:36:58 -0500 + +ikiwiki (3.02) unstable; urgency=low + + * blogspam: New plugin, adding spam filtering for page editing / comment + posting using the BlogSpam.net API. + * Add auto-blog.setup, which will set up an ikiwiki instance tuned for use + in blogging. + * checkcontent: New hook, can be used to implement arbitrary content + filters, including spam filters. + * table: Fix misparsed links in external files. + * table: Find links in external files in scan pass. + * rename: Show full names of affected pages. + * comments: Fix cache avoidance hack. + * repolist: New plugin to support the rel=vcs-* microformat. + * goodstuff: Include repolist by default. (But it does nothing until + configured with the repository locations.) + * comments: Add support for removing comments via web interface. (smcv) + * Consistently allow use of relative paths in all PageSpecs + that take a page name parameter. Previously, match_created_before(), + match_created_after(), match_sourcepage(), and match_destpage() + did not support that, and the docs were not clear. + * pinger: Get whole url, don't just head, avoids problems on + the nostromo web server. + * Recommend libterm-readline-gnu-perl since that makes auto.setup + behave better. + + -- Joey Hess Sat, 17 Jan 2009 18:19:39 -0500 + +ikiwiki (3.01) unstable; urgency=low + + * ikiwiki-makerepo: Fix injecting of empty mercurial and bzr repositories. + Closes: #510518 + * Fix documentation about git hook to use right name. Closes: #510393 + * yesno: Always accept English even when localised. + * yesno: Also accept 1 and 0 as input. + * A recent change to gitweb removed support for the form of diffurl + that many ikiwiki setups use. Document how to use the new url form. + + -- Joey Hess Mon, 05 Jan 2009 18:53:50 -0500 + +ikiwiki (3.00) unstable; urgency=low + + * Remove support for GlobLists. + * Remove support for configuring allowed attachments, locked pages, + and banned users from the admin preferences page. These can only be + controlled via the setup file now. + * ikiwiki-transition moveprefs can be used to move the above + admin preferences into a setup file. + * prefix_directives and aggregate_internal are now turned on by default. + * ikiwiki-transition prefix_directives syntax changed + * googlecalendar: removed this deprecated plugin. Use htmlscrubber_skip + instead. + * embed: This plugin is deprecated, use htmlscrubber_skip instead. + Closes: ##462970. + * Version 3.00 of the plugin API. + * Replace blank OpenID placeholder logo with an unofficial OpenID + logo developed by Anna Hess. The official logo does not seem destined to + be free. + * comments: Add cache avoidance. + * htmlbalance: Demand-load HTML::TreeBuilder to avoid failing test suite + if it is not present. + * French translation update from Philippe Batailler. Closes: #510216 + * websetup: Avoid a crash when a new array setup item has been added in + a new ikiwiki release, and is thus not present in the setup file yet. + + -- Joey Hess Wed, 31 Dec 2008 15:17:47 -0500 + +ikiwiki (2.72) unstable; urgency=low + + * Avoid comments in recentchanges being broken links (smcv) + * Add deprecation warning for GlobLists, which will stop working in 3.0. + * camelcase: Add camelcase_ignore setting. + * googlecalendar: Add runtime deprecation warning. + * comments: Deal with users entering unqualified or partial urls. + * inline: Run format hook first, to ensure other format hooks can affect + inlined content. Closes: #509710 + + -- Joey Hess Sun, 28 Dec 2008 15:01:02 -0500 + +ikiwiki (2.71) unstable; urgency=low + + * comments: Blog-style comment support, contributed by Simon McVittie. + * htmlbalance: New plugin contributed by Simon McVittie. + * Change deb dependencies to list Text::Markdown before markdown (really + this time). + * Improve escaping of wikilinks and preprocessor directives in content + produced by aggregate and recentchanges. + * French translation update from Philippe Batailler. Closes: #506250 + * Spanish translation update from Victor Moral. + * Fix handling of wrappergroup option. + * Correct --dumpsetup to include the srcdir in the setup file. + * German translation update from Kai Wasserbäch. Closes: #507056 + * inline: Support emptyfeeds=no option to skip generating empty feeds. + * inline: Support feedfile option to change the filename of the feed + generated. + * meta: Pass info to htmlscrubber so htmlscrubber_skip can take effect. + * htmlbalance: don't compact whitespace, and set misc other options (smcv) + * rename: Fix double-escaping of page name in edit box. + * monotone: When getting the log, tell monotone how many entries + we want, rather than closing the pipe, which it dislikes. (thm) + * Coding style change: Remove explcit vim folding markers. + * aggregate: If a feed fails to be downloaded, try again immediatly + next time aggregation is run, even if the usual time has not passed. + Closes: #508622 (Michael Gold) + * meta: Process meta date during scan pass so that the date will always + affect sorting in inlines. + * Improve display of some openids (smcv) + + -- Joey Hess Sun, 21 Dec 2008 16:22:05 -0500 + +ikiwiki (2.70) unstable; urgency=low + + * Avoid crash on malformed utf-8 discovered by intrigeri. + + -- Joey Hess Wed, 12 Nov 2008 17:45:58 -0500 + +ikiwiki (2.69) unstable; urgency=low + + * Avoid multiple ikiwiki cgi processes piling up, eating all memory, + and thrashing, by making the cgi wrapper wait on a cgilock. + If you had to set apache's MaxClients low to avoid ikiwiki thrashing your + server, you can now turn it up to a high value. + * Stop busy-waiting in lockwiki, as this could delay ikiwiki from waking up + for up to one second. The bailout code is no longer needed after above + change. + * Remove support for unused optional wait parameter from lockwiki. + * aggregate: Try to query XML::Feed for the base url when derelevatising + links. Since this needs the just released XML::Feed 0.3, as well + as a not yet released XML::RSS, it will fall back to the old method + if no xml:base info is available. + * meta: Plugin is now enabled by default since the basewiki uses it. + * txt: Do not encode quotes when filtering the txt, as that broke + later parsing of any directives on the page. + * Fix the link() pagespec to match links that are internally recorded as + absolute. + * Add rel=nofollow to recentchanges_links for the same (weak) reasons it + was earlier added to edit links. + * tag: Normalize tagbase so leading/trailing slashes in it don't break + things. + * bzr: Fix dates for recentchanges. + + -- Joey Hess Tue, 11 Nov 2008 20:35:55 -0500 + +ikiwiki (2.68) unstable; urgency=low + + * Add support for checking pushes from untrusted git committers. This can be + used to set up anonymous git pushes, and other similar things. + * format: New plugin, allows embedding differently formatted text inside a + page (ie, otl inside a mdwn page, or syntax highlighted code inside a + page). + * relativedate: New javascript-alicious plugin that makes all dates display + relative, in a very nice way, if I say so myself. + * Optimise the no-op post-commit hook, to speed up web edits by a fraction + of a second. + * git: Allow [[sha1_commit]] to be used in the diffurl, to support cgit. + * shortcut: Fix display of shortcuts while previewing. + * Plugins that used to override displaytime should instead override + formattime. displaytime will call that, and may wrap markup around the + formatted time. + * Add an underlay for javascript, and add ikiwiki.js containing some utility + code. + * toggle: Stop embedding the full toggle code on each page using it, and + move it to toggle.js in the javascript underlay. + * recentchanges: Make feed links point back to anchors on the recentchanges + page. (JasonBlevins) + * Fix issue with utf-8 in wikiname breaking session cookies, by + entity-encoding the wikiname in the session cookie. + * Use the pure perl Data::Dumper when generating setup files to ensure that + utf-8 characters are written out as such, and not as the encoded perl + strings the C Data::Dumper produces. + * inline: Only the last feed link was put on the page, fix this to include + all feed links. So rss will be included along with atom, and pages with + multiple feeds will get links added for all feeds. + * tag: When tagbase is set, force the links created by tagging to point at + the toplevel tagbase, and not closer subpages. The html links already went + there, but internally the links were not recorded as absolute, which could + cause confusing backlinks etc. + * Add an inject function, that can be used by plugins that want to + replace one of ikiwiki's functions with their own version. + (This is a scary thing that grubs through the symbol table, and replaces + all exported occurances of a function with the injected version.) + * external: RPC functions can be injected to replace exported functions. + * Updated French translation. Closes: #502694 + * Updated Spanish translation from the ever vigilant Victor Moral. + * Updated Danish translation from Jonas Smedegaard. Closes: #503117 + * Preserve syslog setting when doing `ikiwiki -setup foo -dumpsetup bar` + * Several fixes to --render mode. + + -- Joey Hess Mon, 03 Nov 2008 16:31:11 -0500 + +ikiwiki (2.67) unstable; urgency=low * remove: Avoid $_ breakage. (Stupid, stupid perl.) * Updated Spanish translation from Victor Moral. @@ -13,8 +304,10 @@ ikiwiki (2.67) UNRELEASED; urgency=low * inline: Allow MTIME to be used in inlinepage.tmpl. * inline: Use the feed's description in the rss and atom links. Closes: #502113 + * aggregate: Avoid bug that caused immediate expiration of items + with a date in the future. - -- Joey Hess Mon, 06 Oct 2008 16:07:50 -0400 + -- Joey Hess Fri, 17 Oct 2008 13:13:41 -0400 ikiwiki (2.66) unstable; urgency=low diff --git a/debian/compat b/debian/compat index 7ed6ff82d..7f8f011eb 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -5 +7 diff --git a/debian/control b/debian/control index fdf2a3a36..a0769cbce 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: ikiwiki Section: web Priority: optional -Build-Depends: perl, debhelper (>= 5) +Build-Depends: perl, debhelper (>= 7.0.50) Build-Depends-Indep: dpkg-dev (>= 1.9.0), libxml-simple-perl, libtext-markdown-perl | markdown, libtimedate-perl, libhtml-template-perl, libhtml-scrubber-perl, wdg-html-validator, libhtml-parser-perl, liburi-perl, perlmagick Maintainer: Joey Hess Uploaders: Josh Triplett @@ -12,9 +12,9 @@ Vcs-Browser: http://git.ikiwiki.info/?p=ikiwiki Package: ikiwiki Architecture: all -Depends: ${perl:Depends}, markdown | libtext-markdown-perl, libhtml-scrubber-perl, libhtml-template-perl, libhtml-parser-perl, liburi-perl -Recommends: gcc | c-compiler, libc6-dev | libc-dev, subversion | git-core (>= 1:1.5.0) | tla | bzr (>= 0.91) | mercurial | monotone (>= 0.38), libxml-simple-perl, libnet-openid-consumer-perl, liblwpx-paranoidagent-perl, libtimedate-perl, libcgi-formbuilder-perl (>= 3.05), libcgi-session-perl (>= 4.14-1), libmail-sendmail-perl, libauthen-passphrase-perl -Suggests: viewvc | gitweb | viewcvs, libsearch-xapian-perl, xapian-omega (>= 1.0.5), librpc-xml-perl, libtext-wikiformat-perl, python, python-docutils, polygen, tidy, libxml-feed-perl, libmailtools-perl, perlmagick, libfile-mimeinfo-perl, libcrypt-ssleay-perl, liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl, libtext-csv-perl, libdigest-sha1-perl, graphviz, libnet-amazon-s3-perl, sparkline-php, texlive, dvipng +Depends: ${misc:Depends}, ${perl:Depends}, libtext-markdown-perl | markdown, libhtml-scrubber-perl, libhtml-template-perl, libhtml-parser-perl, liburi-perl +Recommends: gcc | c-compiler, libc6-dev | libc-dev, subversion | git-core (>= 1:1.5.0) | tla | bzr (>= 0.91) | mercurial | monotone (>= 0.38), libxml-simple-perl, libnet-openid-consumer-perl, liblwpx-paranoidagent-perl, libtimedate-perl, libcgi-formbuilder-perl (>= 3.05), libcgi-session-perl (>= 4.14-1), libmail-sendmail-perl, libauthen-passphrase-perl, libterm-readline-gnu-perl +Suggests: viewvc | gitweb | viewcvs, libsearch-xapian-perl, xapian-omega (>= 1.0.5), librpc-xml-perl, libtext-wikiformat-perl, python, python-docutils, polygen, tidy, libhtml-tree-perl, libxml-feed-perl, libmailtools-perl, perlmagick, libfile-mimeinfo-perl, libcrypt-ssleay-perl, liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl, libtext-csv-perl, libdigest-sha1-perl, graphviz, libnet-amazon-s3-perl, sparkline-php, texlive, dvipng, libtext-wikicreole-perl, libsort-naturally-perl, libtext-textile-perl Conflicts: ikiwiki-plugin-table Replaces: ikiwiki-plugin-table Provides: ikiwiki-plugin-table diff --git a/debian/copyright b/debian/copyright index f257234dd..67f0ac540 100644 --- a/debian/copyright +++ b/debian/copyright @@ -76,6 +76,10 @@ Files: htmltidy.pm Copyright: © 2006 Faidon Liambotis License: GPL-2+ +Files: htmlbalance.pm, underlay.pm +Copyright: © 2008 Simon McVittie +License: GPL-2+ + Files: polygen.pm, pagestats.pm, cutpaste.pm Copyright: © 2006 Enrico Zini License: GPL-2+ @@ -108,6 +112,20 @@ Files: google.pm Copyright: Copyright (C) 2008 Peter Simons License: GPL-2+ +Files: comments.pm +Copyright: + © 2006-2008 Joey Hess + © 2008 Simon McVittie +License: GPL-2+ + +Files: 404.pm +Copyright: © 2009 Simon McVittie +License: GPL-2+ + +Files: wmd.pm +Copyright: © 2009 William Uther +License: GPL-2+ + Files: doc/logo/* Copyright: © 2006 Recai Oktaş License: GPL-2+ diff --git a/debian/docs b/debian/docs new file mode 100644 index 000000000..1936cc1d4 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +html diff --git a/debian/link b/debian/link new file mode 100644 index 000000000..cb3793191 --- /dev/null +++ b/debian/link @@ -0,0 +1,2 @@ +usr/share/ikiwiki/examples usr/share/doc/ikiwiki/examples +usr/share/common-licenses/GPL-2 usr/share/doc/ikiwiki/html/GPL diff --git a/debian/preinst b/debian/preinst index c588901df..4158b2ae6 100755 --- a/debian/preinst +++ b/debian/preinst @@ -14,3 +14,7 @@ if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt 1.2; then fi fi fi +if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt 3.02; then + # replaced by symlink + rm -rf /usr/share/doc/ikiwiki/examples +fi diff --git a/debian/rules b/debian/rules index 25b1f57b6..0a7ce7a26 100755 --- a/debian/rules +++ b/debian/rules @@ -1,44 +1,19 @@ #!/usr/bin/make -f +%: + dh $@ -build: build-stamp -build-stamp: - dh_testdir - perl Makefile.PL PREFIX=/usr INSTALLDIRS=vendor - $(MAKE) -C po - $(MAKE) - $(MAKE) test - touch build-stamp +override_dh_auto_configure: + # keeps it out of /usr/local + dh_auto_configure -- PREFIX=/usr -clean: - dh_testdir - dh_testroot - rm -f build-stamp - perl Makefile.PL +override_dh_compress: + # avoid compressing files in the doc wiki + dh_compress -Xhtml + +override_dh_auto_clean: + # distclean moans about MANIFEST, this is quieter if [ -e Makefile ]; then $(MAKE) realclean; fi - dh_clean - -binary-arch: build - -binary-indep: build - dh_testdir - dh_testroot - dh_clean -k - $(MAKE) pure_install DESTDIR=$(shell pwd)/debian/ikiwiki - dh_installdocs html - dh_installexamples doc/examples/* - dh_link usr/share/common-licenses/GPL-2 usr/share/doc/ikiwiki/html/GPL - dh_installchangelogs - dh_compress -X html - dh_fixperms - dh_perl - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb # Not intended for use by anyone except the author. announcedir: @echo ${HOME}/src/ikiwiki/doc/news - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary diff --git a/doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn b/doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn new file mode 100644 index 000000000..fbdc58d5d --- /dev/null +++ b/doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn @@ -0,0 +1,22 @@ +The Atom feed from +get "double-encoded" (UTF-8 is decoded as Latin-1 and re-encoded as +UTF-8) when aggregated with IkiWiki on Debian unstable. The RSS 1.0 +and RSS 2.0 feeds from the same Planet are fine. All three files +are in fact correct UTF-8, but IkiWiki mis-parses the Atom. + +This turns out to be a bug in XML::Feed, or (depending on your point +of view) XML::Feed failing to work around a design flaw in XML::Atom. +When parsing RSS it returns Unicode strings, but when parsing Atom +it delegates to XML::Atom's behaviour, which by default is to strip +the UTF8 flag from strings that it outputs; as a result, they're +interpreted by IkiWiki as byte sequences corresponding to the UTF-8 +encoding. IkiWiki then treats these as if they were Latin-1 and +encodes them into UTF-8 for output. + +I've filed a bug against XML::Feed on CPAN requesting that it sets +the right magical variable to change this behaviour. IkiWiki can +also apply the same workaround (and doing so should be harmless even +when XML::Feed is fixed); please consider merging my 'atom' branch, +which does so. --[[smcv]] + +[[!tag patch done]] diff --git a/doc/bugs/Allow_overriding_of_symlink_restriction.mdwn b/doc/bugs/Allow_overriding_of_symlink_restriction.mdwn index 07badd646..efdd9004e 100644 --- a/doc/bugs/Allow_overriding_of_symlink_restriction.mdwn +++ b/doc/bugs/Allow_overriding_of_symlink_restriction.mdwn @@ -34,9 +34,9 @@ Is there a huge objection to this patch? index 990fcaa..0fb78ba 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm - @@ -260,13 +260,15 @@ sub prune ($) { #{{{ + @@ -260,13 +260,15 @@ sub prune ($) { - sub refresh () { #{{{ + sub refresh () { # security check, avoid following symlinks in the srcdir path - my $test=$config{srcdir}; - while (length $test) { @@ -108,7 +108,7 @@ like this being accepted before I bothered. use IkiWiki; +use File::Spec; - sub gen_wrapper () { #{{{ + sub gen_wrapper () { - $config{srcdir}=abs_path($config{srcdir}); - $config{destdir}=abs_path($config{destdir}); - my $this=abs_path($0); diff --git a/doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn b/doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn new file mode 100644 index 000000000..ef74deb91 --- /dev/null +++ b/doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn @@ -0,0 +1,59 @@ +Error received when clicking on the "edit" link: + +> `Error: [CGI::FormBuilder::AUTOLOAD] Fatal: Attempt to address +> non-existent field 'text' by name at +> /home/tealart/bin/share/perl/5.8.4/IkiWiki/CGI.pm line 112` + +Error received when following a "Create New Page" (eg. ?) link: + +> `Error: [CGI::FormBuilder::AUTOLOAD] Fatal: Attempt to address +> non-existent field 'param' by name at +> /home/tealart/bin/share/perl/5.8.4/IkiWiki/Plugin/editpage.pm line 122` + +I could probably find several other flavors of this error if I went +looking, but I trust you get the idea. + +The CGI starts to render (this isn't the "you forgot to set the +permissions/turn on the CGI" error) and then fails. + +Further details: + +- Running on shared hosting (dreamhost; but everything compiles, + dependencies installed, the site generates perfectly, other CGIs + work, the file permissions work). + +- It's running perl 5.8.4, but I did upgrade gettext to 0.17 + +- the server is running gcc v3.3.5 (at this point, this is the main + difference between the working system and my box.) + +- I've removed the locale declarations from both the config file and + the environment variable. + +- I've also modified the page template and have my templates in a non + standard location. The wiki compiles fine, with the template, but + might this be an issue? The CGI script doesn't (seem) to load under + the new template, but I'm not sure how to address this issue. + +- All of the required/suggested module dependencies are installed + (finally) to the latest version including (relevantly) + CGI::FormBuilder 3.0501. + +- I'm running ikiwiki v3.08. Did I mention that it works perfectly in + nearly every other way that I've managed to test thusfar? + +---- + +> I suspect that your perl is too old and is incompatible with the version of CGI::FormBuilder you have installed. +> +> Is so, it seems likely that the same error message can be reproduced by running a simple command like this at the command line: +> +> perl -e 'use warnings; use strict; use CGI::FormBuilder; my $form=CGI::FormBuilder->new; $form->text("boo")' +> +> --[[Joey]] + +> > nope, that command produces no output. :/ +> > +> > I considered downgrading CGI::FormBuilder but I saw evidence of previous versions being incompatible with ikiwiki so I decided against that. +> > +> > -- [[tychoish]] diff --git a/doc/bugs/Can__39__t_create_root_page.mdwn b/doc/bugs/Can__39__t_create_root_page.mdwn index 60cbcd530..91c2eae60 100644 --- a/doc/bugs/Can__39__t_create_root_page.mdwn +++ b/doc/bugs/Can__39__t_create_root_page.mdwn @@ -33,7 +33,7 @@ This type of page name (with leading slash) also gets created by the aggregate p index 99cead6..23d9616 100644 --- a/IkiWiki/CGI.pm +++ b/IkiWiki/CGI.pm - @@ -305,9 +305,11 @@ sub cgi_editpage ($$) { #{{{ + @@ -305,9 +305,11 @@ sub cgi_editpage ($$) { my $page=$form->field('page'); $page=possibly_foolish_untaint($page); if (! defined $page || ! length $page || @@ -46,7 +46,7 @@ This type of page name (with leading slash) also gets created by the aggregate p my $baseurl=$config{url}."/".htmlpage($page); - @@ -425,6 +427,7 @@ sub cgi_editpage ($$) { #{{{ + @@ -425,6 +427,7 @@ sub cgi_editpage ($$) { $from ne $form->field('from') || file_pruned($from, $config{srcdir}) || $from=~/^\// || diff --git a/doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn b/doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn new file mode 100644 index 000000000..6df3ccd9c --- /dev/null +++ b/doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn @@ -0,0 +1,5 @@ +When a page links to its own #comments anchor you get a link like +"index.html#comments" rather than "./#comments". Fixed in commit 0844bd0b +on my 'comments' branch. --[[smcv]] + +[[!tag patch done]] diff --git a/doc/bugs/Error:_Your_login_session_has_expired._.mdwn b/doc/bugs/Error:_Your_login_session_has_expired._.mdwn new file mode 100644 index 000000000..046d6e10d --- /dev/null +++ b/doc/bugs/Error:_Your_login_session_has_expired._.mdwn @@ -0,0 +1,44 @@ +I keep getting: + + Error: Your login session has expired. + +Whilst trying to edit http://hugh.vm.bytemark.co.uk/ikiwiki.cgi via OpenID. Any ideas? + + + iki@hugh:~$ dpkg -l | grep openid + ii libnet-openid-consumer-perl 0.14-4 library for consumers of OpenID iden + tities + iki@hugh:~$ + +> This error occurs if ikiwiki sees something that looks like a CSRF +> attack. It checks for such an attack by embedding your session id on the +> page edit form, and comparing that id with the session id used to post +> the form. +> +> So, somehow your session id has changed between opening the edit form and +> posting it. A few ways this could happen: +> +> * Genuine CSRF attack (unlikely) +> * If you logged out and back in, in another tab, while the edit form was +> open. +> * If `.ikiwiki/sessions.db` was deleted/corrupted while you were in the +> midst of the edit. +> * If some bug in CGI::Session caused your session not to be saved to the +> database somehow. +> * If your browser didn't preserve the session cookie across the edit +> process, for whatever local reason. +> * If you were using a modified version of `editpage.tmpl`, and +> it did not include `FIELD-SID`. +> * If you upgraded from an old version of ikiwiki, before `FIELD-SID` was +> added (<= 2.41), and had an edit form open from that old version, and +> tried to save it using the new. +> +> I don't see the problem editing the sandbox there myself, FWIW. +> (BTW, shouldn't you enable the meta plugin so RecentChanges displays +> better?) +> --[[joey]] + + +Thanks for you excellent analysis. The bug was due to old pre-3.0 **templates** laying about. After deleting them, ikiwiki defaults to its own templates. Clever. :-) + +[[bugs/done]] diff --git a/doc/bugs/Git:_web_commit_message_not_utf-8.mdwn b/doc/bugs/Git:_web_commit_message_not_utf-8.mdwn new file mode 100644 index 000000000..08247dded --- /dev/null +++ b/doc/bugs/Git:_web_commit_message_not_utf-8.mdwn @@ -0,0 +1,17 @@ +The message generated for web commits: + +> web commit by mädduck + +is not utf-8 encoded before passed to Git (which uses utf-8 as default encoding for commit messages). This causes a wrongly-encoded log entry, and makes ikiwiki spew warnings as it creates `recentchanges`: + + utf8 "\xF6" does not map to Unicode at /usr/share/perl5/IkiWiki/Rcs/git.pm line 36, <$OUT> line 57. + Malformed UTF-8 character (unexpected non-continuation byte 0x6e, immediately after start byte 0xf6) in pattern match (m//) at /usr/share/perl5/IkiWiki/Rcs/git.pm line 393. + utf8 "\xF6" does not map to Unicode at /usr/share/perl5/IkiWiki/Rcs/git.pm line 36, <$OUT> line 5. + +(This is version 2.53.3~bpo40+1 for lack of a newer backport for sarge) + +Please make sure that commit messages for Git are always utf-8. + +This is a change by user `mädduck` to trigger the error. + +> [[Fixed|done]] both on the commit and log sides. --[[Joey]] diff --git a/doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn b/doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn new file mode 100644 index 000000000..1d396c85b --- /dev/null +++ b/doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn @@ -0,0 +1,24 @@ +'make test' has the following errors: + +Can't locate Locale/gettext.pm in @INC (@INC contains: /home/turian/utils//lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /home/turian/utils//lib/perl5/site_perl/5.8.8 . /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8) at (eval 254) line 2. + +What's weird is that I already have gettext.pm: + /home/turian/utils/lib/perl5/lib/i386-linux-thread-multi/Locale/gettext.pm + +That directory should be part of @INC, because I have: + export PERL5LIB="$PERL5LIB:$UTILS/lib/perl5/lib/i386-linux-thread-multi/" +in my .bashrc. However, /home/turian/utils/lib/perl5/lib/i386-linux-thread-multi/ does not appear in that @INC line. + +How do I get the proper @INC locations set? + +> Nothing in ikiwiki touches whatever PERL5DIR setting you may have, +> so AFAICS, this must be some sort of local configuration problem. +> How do +> `/home/turian/utils//lib/perl5/site_perl/5.8.8/i386-linux-thread-multi` +> and `/home/turian/utils//lib/perl5/site_perl/5.8.8` get into the +> displayed `@INC`? The likely way seems to be that something in your +> system sets PERL5LIB to contain those directories, clobbering +> the earlier setting in your `.bashrc`. +> --[[Joey]] + +[[!tag done]] diff --git a/doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn b/doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn new file mode 100644 index 000000000..6b02c4186 --- /dev/null +++ b/doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn @@ -0,0 +1,23 @@ +In IkiWiki/Wrapper.pm, the gen_wrapper function finds out what srcdir and +destdir are set to in the config, but does not use them. + +Later in the sub, when a new wiki.cgi wrapper is being created when calling +ikiwiki --setup /path/to/setup, it will only work if cgi\_wrapper in the +config file is set to the full path. Otherwise, it creates wiki.cgi in the +current working directory. It works with the other wrapper it sets up in +my config - post\_update (using git), as that shows in the config with a +full path. + +One workaround would be to mention in the setup file that cgi_wrapper has +to be the full path, not just the file name, but that seems silly when +destdir is also specified in that file and that's where it should go, and +$config{destdir} is a known value in the Wrapper.pm file. + +> Nowhere in any documentation does +> it say that cgi\_wrapper is relative to the destdir. +> As noted in [[discussion]], there are web server setups +> that require the cgi be located elsewhere. +> [[done]] --[[Joey]] + +>> A comment in the generated setup file that all paths should be full +>> would prevent my (admittedly dumb) error without any drawbacks. diff --git a/doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn b/doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn new file mode 100644 index 000000000..870fa7a66 --- /dev/null +++ b/doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn @@ -0,0 +1,4 @@ +Just as a point of information, I do not put my cgi wrapper in the dest +directory. Instead I configure Apache to relate a specific URI to the cgi via +ScriptAlias. I would not like things to be changed so that the cgi was put in +the destdir, so I'd vote instead to comment in the `setup\_file`. -- [[Jon]] diff --git a/doc/bugs/Insecure_dependency_in_eval_while_running_with_-T_switch.mdwn b/doc/bugs/Insecure_dependency_in_eval_while_running_with_-T_switch.mdwn index 28b48e2c6..c3beb8219 100644 --- a/doc/bugs/Insecure_dependency_in_eval_while_running_with_-T_switch.mdwn +++ b/doc/bugs/Insecure_dependency_in_eval_while_running_with_-T_switch.mdwn @@ -53,7 +53,7 @@ I didn't apply your following old patch against `Ikiwiki.pm` file: + } + + return eval $newpagespec; - } #}}} + } package IkiWiki::PageSpec; @@ -83,7 +83,7 @@ to break the code I distribute in my backport ;) + my $ret=eval possibly_foolish_untaint(pagespec_translate($spec)); return IkiWiki::FailReason->new("syntax error") if $@; return $ret; - } #}}} + } >> Thanks a lot, Joey! It works :) >> diff --git a/doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn b/doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn new file mode 100644 index 000000000..0e40da551 --- /dev/null +++ b/doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn @@ -0,0 +1,11 @@ +I have been trying to include some meta info using the link setting something like the below + + meta link="http://www.example.com/" rel="command" name="Example" + +This gets removed by the htmlscrubber as you would expect. + +Setting htmlscrubber_skip to the pagespec should stop this getting scrubbed but it does not. + +Below is a patch to fix that. It seams to work but I am not sure of it is the correct thing to do. + +> [[done]], thanks for the patch --[[Joey]] diff --git a/doc/bugs/Monotone_rcs_support.mdwn b/doc/bugs/Monotone_rcs_support.mdwn index 3d1388312..8687e7983 100644 --- a/doc/bugs/Monotone_rcs_support.mdwn +++ b/doc/bugs/Monotone_rcs_support.mdwn @@ -11,7 +11,7 @@ diff --git a/IkiWiki/Rcs/monotone.pm b/IkiWiki/Rcs/monotone.pm index cde6029..34f8f96 100644 --- a/IkiWiki/Rcs/monotone.pm +++ b/IkiWiki/Rcs/monotone.pm -@@ -186,8 +186,9 @@ sub rcs_update () { #{{{ +@@ -186,8 +186,9 @@ sub rcs_update () { check_config(); if (defined($config{mtnsync}) && $config{mtnsync}) { diff --git a/doc/bugs/No_link_for_blog_items_when_filename_contains_a_colon.mdwn b/doc/bugs/No_link_for_blog_items_when_filename_contains_a_colon.mdwn index 019970899..bb3f92f9c 100644 --- a/doc/bugs/No_link_for_blog_items_when_filename_contains_a_colon.mdwn +++ b/doc/bugs/No_link_for_blog_items_when_filename_contains_a_colon.mdwn @@ -38,19 +38,19 @@ At the moment I see two possible solutions: +++ IkiWiki.pm 2008-07-21 20:41:35.000000000 +0200 @@ -477,13 +477,13 @@ - sub titlepage ($) { #{{{ + sub titlepage ($) { my $title=shift; - $title=~s/([^-[:alnum:]:+\/.])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; + $title=~s/([^-[:alnum:]+\/.])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $title; - } #}}} + } - sub linkpage ($) { #{{{ + sub linkpage ($) { my $link=shift; - $link=~s/([^-[:alnum:]:+\/._])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; + $link=~s/([^-[:alnum:]+\/._])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $link; - } #}}} + } What do you think about that? Does the patch have any side-effects I didn't see? diff --git a/doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn b/doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn new file mode 100644 index 000000000..0a1299993 --- /dev/null +++ b/doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn @@ -0,0 +1,25 @@ +If a PNG image matches the [[ikiwiki/PageSpec]] of an [[ikiwiki/directive/inline]] directive, the page throws the following error: + +> \[[!inline Error: Malformed UTF-8 character (fatal) at /usr/local/lib/perl5/site_perl/5.8.8/File/MimeInfo.pm line 120.]] + +Individual posts display fine, and moving the offending image outside the scope of the [[ikiwiki/directive/inline]] directive's PageSpec eliminates the error. + +> I tried to reproduce this with a random png and File::MimeInfo +> version 0.15, but could not. The png was included in the generated feed +> via an enclosure, as it should be; no warnings or errors. +> +> Looking at the source to File::MimeInfo and its changelog, +> I'm pretty sure that this problem was fixed in version +> 0.14: +>> - Fixed bug with malformed utf8 chars in default() method +> +> The code involved in that fix looks like this: +> +>> no warnings; # warnings can be thrown when input not ascii +>> if ($] < 5.008 or ! utf8::valid($line)) { +>> use bytes; # avoid invalid utf8 chars +> +> I guess that your locally installed version of File::MimeInfo is older than +> this. So closing this bug [[done]]. If you still see the problem with a current +> version of File::MimeInfo, please reopen and include where I can get a png file +> that triggers the problem. --[[Joey]] diff --git a/doc/bugs/Problem_with_toc.pm_plug-in.mdwn b/doc/bugs/Problem_with_toc.pm_plug-in.mdwn index 8ae347d42..6be5f89b5 100644 --- a/doc/bugs/Problem_with_toc.pm_plug-in.mdwn +++ b/doc/bugs/Problem_with_toc.pm_plug-in.mdwn @@ -9,7 +9,7 @@ Here is a patch for toc.pm for producing non-empty 'a' elements. --- IkiWiki/Plugin/toc.pm.orig Thu Jun 7 11:53:53 2007 +++ IkiWiki/Plugin/toc.pm Thu Jun 7 13:00:00 2007 - @@ -47,7 +47,7 @@ sub format (@) { #{{{ + @@ -47,7 +47,7 @@ sub format (@) { if ($tagname =~ /^h(\d+)$/i) { my $level=$1; my $anchor="index".++$anchors{$level}."h$level"; @@ -18,7 +18,7 @@ Here is a patch for toc.pm for producing non-empty 'a' elements. # Take the first header level seen as the topmost level, # even if there are higher levels seen later on. - @@ -90,6 +90,16 @@ sub format (@) { #{{{ + @@ -90,6 +90,16 @@ sub format (@) { "\n"; $p->handler(text => undef); }, "dtext"); diff --git a/doc/bugs/Problems_with_graphviz.pm_plug-in.mdwn b/doc/bugs/Problems_with_graphviz.pm_plug-in.mdwn index 9a26e505a..c9f698158 100644 --- a/doc/bugs/Problems_with_graphviz.pm_plug-in.mdwn +++ b/doc/bugs/Problems_with_graphviz.pm_plug-in.mdwn @@ -15,7 +15,7 @@ It also generates image URLs relative to the page being rendered, which means th --- IkiWiki/Plugin/graphviz.pm.orig 2007-07-27 11:35:05.000000000 +0200 +++ IkiWiki/Plugin/graphviz.pm 2007-07-27 11:36:02.000000000 +0200 - @@ -69,7 +69,12 @@ sub render_graph (\%) { #{{{ + @@ -69,7 +69,12 @@ sub render_graph (\%) { } } @@ -26,9 +26,9 @@ It also generates image URLs relative to the page being rendered, which means th + else { + return "\n"; + } - } #}}} + } - sub graph (@) { #{{{ + sub graph (@) { >> --[[HenrikBrixAndersen]] @@ -38,7 +38,7 @@ The patch below fixes these two issues. --- graphviz.pm.orig Thu Jun 7 15:45:16 2007 +++ graphviz.pm Fri Jun 8 12:03:38 2007 - @@ -41,7 +41,6 @@ sub render_graph (\%) { #{{{ + @@ -41,7 +41,6 @@ sub render_graph (\%) { $pid=open2(*IN, *OUT, "$params{prog} -Tpng"); # open2 doesn't respect "use open ':utf8'" @@ -46,7 +46,7 @@ The patch below fixes these two issues. binmode (OUT, ':utf8'); print OUT $src; - @@ -70,7 +69,12 @@ sub render_graph (\%) { #{{{ + @@ -70,7 +69,12 @@ sub render_graph (\%) { } } @@ -57,6 +57,6 @@ The patch below fixes these two issues. + else { + return "\n"; + } - } #}}} + } - sub graph (@) { #{{{ + sub graph (@) { diff --git a/doc/bugs/RecentChanges_broken_with_empty_svnpath.mdwn b/doc/bugs/RecentChanges_broken_with_empty_svnpath.mdwn index 836c39a71..c852df5e9 100644 --- a/doc/bugs/RecentChanges_broken_with_empty_svnpath.mdwn +++ b/doc/bugs/RecentChanges_broken_with_empty_svnpath.mdwn @@ -13,7 +13,7 @@ I can not see why this check is needed in the first place, so here's a patch for diff -upr ikiwiki-1.49.orig/IkiWiki/Rcs/svn.pm ikiwiki-1.49/IkiWiki/Rcs/svn.pm --- ikiwiki-1.49.orig/IkiWiki/Rcs/svn.pm Mon Apr 16 15:15:09 2007 +++ ikiwiki-1.49/IkiWiki/Rcs/svn.pm Mon Apr 16 15:15:47 2007 - @@ -176,7 +176,6 @@ sub rcs_recentchanges ($) { #{{{ + @@ -176,7 +176,6 @@ sub rcs_recentchanges ($) { } foreach (keys %{$logentry->{paths}}) { diff --git a/doc/bugs/SVG_files_not_recognized_as_images.mdwn b/doc/bugs/SVG_files_not_recognized_as_images.mdwn new file mode 100644 index 000000000..207edd426 --- /dev/null +++ b/doc/bugs/SVG_files_not_recognized_as_images.mdwn @@ -0,0 +1,29 @@ +In ikiwiki 2.66, SVG images are not recognized as images. In ikiwiki.pm, +the hardcoded list of image file extensions does not include ".svg", which +it probably should unless there's some other issue about rendering SVGs? + +The 'img' plugin also seems to not support SVGs. + +> SVG images can only be included via an ``, ``, or +> ` - """]] - -The iframe should be the one provided by google. Note that it's used in a -way that avoids cross-site scripting attacks, assuming you trust google's -content. diff --git a/doc/plugins/goto.mdwn b/doc/plugins/goto.mdwn new file mode 100644 index 000000000..9c401c5d2 --- /dev/null +++ b/doc/plugins/goto.mdwn @@ -0,0 +1,10 @@ +[[!template id=plugin name=goto author="[[Simon_McVittie|smcv]]"]] +[[!tag type/useful]] + +This plugin adds a `do=goto` mode for the IkiWiki CGI script. It's mainly +for internal use by the [[404]], [[comments]] and [[recentchanges]] +plugins, which enable it automatically. + +With this plugin enabled you can link to `ikiwiki.cgi?do=goto&page=some/where` +to make a link that will redirect to the page `/some/where` if it exists, or +offer a link to create it if it doesn't. diff --git a/doc/plugins/htmlbalance.mdwn b/doc/plugins/htmlbalance.mdwn new file mode 100644 index 000000000..f4e2298ee --- /dev/null +++ b/doc/plugins/htmlbalance.mdwn @@ -0,0 +1,9 @@ +[[!template id=plugin name=htmlbalance author="[[Simon_McVittie|smcv]]"]] +[[!tag type/html]] + +This plugin ensures that the HTML emitted by ikiwiki contains well-balanced +HTML tags, by parsing it with [[!cpan HTML::TreeBuilder]] and re-serializing it. This +acts as a lighter-weight alternative to [[plugins/htmltidy]]; it doesn't +ensure validity, but it does at least ensure that formatting from a +blog post pulled in by the [[ikiwiki/directive/inline]] directive doesn't +leak into the rest of the page. diff --git a/doc/plugins/htmlbalance/discussion.mdwn b/doc/plugins/htmlbalance/discussion.mdwn new file mode 100644 index 000000000..c66528a4f --- /dev/null +++ b/doc/plugins/htmlbalance/discussion.mdwn @@ -0,0 +1,10 @@ +Would it be possible to use [[!cpan HTML::Entities]] rather than +`XML::Atom::Util` for encoding entities? The former is already an ikiwiki +dependency (via [[!cpan HTML::Parser]]). + +> Now switched to HTML::Entities --[[Joey]] + +I also wonder if there's any benefit to using this plugin aside from with +aggregate. Perhaps a small one but aggregate seems like the main case.. +wondering if it would be better to just have aggregate balanace the html +automatically and do away with the separate plugin. --[[Joey]] diff --git a/doc/plugins/htmlscrubber.mdwn b/doc/plugins/htmlscrubber.mdwn index 7db372e1b..c59b46e14 100644 --- a/doc/plugins/htmlscrubber.mdwn +++ b/doc/plugins/htmlscrubber.mdwn @@ -32,10 +32,10 @@ other HTML-related functionality, such as whether [[meta]] allows potentially unsafe HTML tags. The `htmlscrubber_skip` configuration setting can be used to skip scrubbing -of some pages. Set it to a [[PageSpec]], such as "!*/Discussion", and pages -matching that can have all the evil CSS, JavsScript, and unsafe html -elements you like. One safe way to use this is to use [[lockedit]] to lock -those pages, so only admins can edit them. +of some pages. Set it to a [[ikiwiki/PageSpec]], such as "!*/Discussion", +and pages matching that can have all the evil CSS, JavsScript, and unsafe +html elements you like. One safe way to use this is to use [[lockedit]] to +lock those pages, so only admins can edit them. ---- diff --git a/doc/plugins/htmltidy.mdwn b/doc/plugins/htmltidy.mdwn index f675a01ae..580e56f59 100644 --- a/doc/plugins/htmltidy.mdwn +++ b/doc/plugins/htmltidy.mdwn @@ -7,4 +7,5 @@ emitted by ikiwiki. Besides being nicely formatted, this helps ensure that even if users enter suboptimal html, your wiki generates valid html. Note that since tidy is an external program, that is run each time a page -is built, this plugin will slow ikiwiki down somewhat. +is built, this plugin will slow ikiwiki down somewhat. [[plugins/htmlbalance]] +might provide a faster alternative. diff --git a/doc/plugins/img/discussion.mdwn b/doc/plugins/img/discussion.mdwn index 02d46e380..e1bb2d15b 100644 --- a/doc/plugins/img/discussion.mdwn +++ b/doc/plugins/img/discussion.mdwn @@ -5,3 +5,8 @@ logo link to \[[hurd/logo]] / instead of linking to the PNG image file. --[[tschwinge]] > Done, use link=somepage --[[Joey]] + +It would be handy if the `class` and `id` tags were passed through to the surrounding `table` in the case of `caption` being present. Would this break anything? --[[neale]] + +> Seems unlikely to break *too* much. I can imagine css that styles the img +> unexpectedly applying the table. --[[Joey]] diff --git a/doc/plugins/lockedit.mdwn b/doc/plugins/lockedit.mdwn index 71bf232ab..c8f64ea47 100644 --- a/doc/plugins/lockedit.mdwn +++ b/doc/plugins/lockedit.mdwn @@ -4,7 +4,7 @@ This plugin allows the administrator of a wiki to lock some pages, limiting who can edit them using the online interface. This doesn't prevent anyone who can commit to the underlying revision control system from editing the -pages, however. +pages, however. (Unless you set up [[tips/untrusted_git_push]].) The `locked_pages` setting configures what pages are locked. It is a [[ikiwiki/PageSpec]], so you have lots of control over what kind of pages @@ -17,6 +17,10 @@ One handy thing to do if you're using ikiwiki for your blog is to lock posts in your blog, while still letting them comment via the Discussion pages. +Alternatively, if you're using the [[comments]] plugin, you can lock +"!postcomment(*)" to allow users to comment on pages, but not edit anything +else. + Wiki administrators can always edit locked pages. The [[ikiwiki/PageSpec]] can specify that some pages are not locked for some users. For example, "important_page and !user(joey)" locks `important_page` while still diff --git a/doc/plugins/mdwn/discussion.mdwn b/doc/plugins/mdwn/discussion.mdwn new file mode 100644 index 000000000..4b05e7f4e --- /dev/null +++ b/doc/plugins/mdwn/discussion.mdwn @@ -0,0 +1,7 @@ +Unlike other format, ikiwiki is somehow depends +on mdwn, since the underlay dir +is written in mdwn. If you want to disable mdwn, +you need to overwrite the underlay +dir (set underlaydir in ikiwiki.setup +to your own underlay dir or replace underlay pages +in your $SRC). diff --git a/doc/plugins/meta.mdwn b/doc/plugins/meta.mdwn index afd554993..e49bdcc50 100644 --- a/doc/plugins/meta.mdwn +++ b/doc/plugins/meta.mdwn @@ -1,4 +1,4 @@ -[[!template id=plugin name=meta author="[[Joey]]"]] +[[!template id=plugin name=meta core=1 author="[[Joey]]"]] [[!tag type/meta]] This plugin provides the [[ikiwiki/directive/meta]] [[ikiwiki/directive]], diff --git a/doc/plugins/pagecount.mdwn b/doc/plugins/pagecount.mdwn index 6235963d3..a56027e60 100644 --- a/doc/plugins/pagecount.mdwn +++ b/doc/plugins/pagecount.mdwn @@ -6,5 +6,5 @@ This plugin provides the [[ikiwiki/directive/pagecount]] currently in the wiki. If it is turned on it can tell us that this wiki includes -[[!pagecount pages="* and !recentchanges"]] -pages, of which [[!pagecount pages="*/Discussion"]] are discussion pages. +[[!pagecount ]] pages, of which +[[!pagecount pages="*/Discussion"]] are discussion pages. diff --git a/doc/plugins/passwordauth/discussion.mdwn b/doc/plugins/passwordauth/discussion.mdwn index f4e7ae7a1..672970c21 100644 --- a/doc/plugins/passwordauth/discussion.mdwn +++ b/doc/plugins/passwordauth/discussion.mdwn @@ -9,3 +9,71 @@ the *Preferences -- Subscriptions*. --[[tschwinge]] >> Aha, then the problem is Firefox, which is automatically filling the >> *Password* field with its previous value, but not filling the >> *Confirm Password* one. --[[tschwinge]] + +## easy access to the userdb for apache auth? + +My use case is: + +* restricted ikiwiki +* read/edit only allowed from the local network (done with apache restrictions) +* edit only for people authenticated (done with vanilla ikiwiki passwordauth) + +I would like to allow people to read/edit the wiki from outside of the +local network, if and only if they already have an ikiwiki account. + +[[httpauth]] doesn't fit since it doesn't allow anonymous local users +to create their own account. I want a single, local, simple auth +database. + +My (naïve?) idea would be: + +* keep the [[passwordauth]] system +* provide a way for Apache to use the userdb for authentication if +people want to connect from outside + +I looked at the various auth modules for apache2. It seems that none +can use a "perl Storable data" file. So, I think some solutions could +be: + +* use a sqlite database instead of a perl Storable file + * can be used with + [mod_auth_dbd](http://httpd.apache.org/docs/2.2/mod/mod_authn_dbd.html) + * requires a change in ikiwiki module [[passwordauth]] +* use an external program to read the userdb and talk with + [mod_auth_external](http://unixpapa.com/mod_auth_external.html) + * requires the maintainance of this external auth proxy over ikiwiki + userdb format changes + * (I don't know perl) +* include this wrapper in ikiwiki + * something like `ikiwiki --auth user:pass:userdb` check the + `user:pass` pair in `userdb` and returns an Accept/Reject flag to + Apache + * requires a change in ikiwiki core + * still requires + [mod_auth_external](http://unixpapa.com/mod_auth_external.html) +* do it with Apache perl sections + * (I don't know perl) + +Any opinion/suggestion/solution to this is welcome and appreciated. + +-- +[[NicolasLimare]] + +For a similar use case, I've been intending to implement +[[todo/httpauth_feature_parity_with_passwordauth]], but your idea may +actually be the way to go. IMHO, the Perl sections idea is the +easiest to setup, but on the long run, I'd prefer ikiwiki to optionnally +use a userdb storage backend supported at least by Apache and lighttpd. +--[[intrigeri]] + +Tons of CPAN modules may help, but most of them are specific to `mod_perl`, +and AFAIK, ikiwiki is generally not run with `mod_perl`. It's not clear to me +wether these modules depend on the webapp to be run with `mod_perl` set +as the script handler, or only on `mod_perl` to be installed and loaded. + +* CPAN's `Apache::AuthenHook` allows to plug arbitrary Perl handlers as + Apache authentication providers. +* CPAN's `Apache::Authen::Program` (`mod_perl`) +* [http://www.openfusion.com.au/labs/mod_auth_tkt/](mod_auth_tkt) along with CPAN's + `Apache::AuthTkt` +--[[intrigeri]] diff --git a/doc/plugins/pingee.mdwn b/doc/plugins/pingee.mdwn index d012004f9..6156c235f 100644 --- a/doc/plugins/pingee.mdwn +++ b/doc/plugins/pingee.mdwn @@ -3,7 +3,7 @@ This plugin causes ikiwiki to listen for pings, typically delivered from another ikiwiki instance using the [[pinger]] plugin. When a ping is -recieved, ikiwiki will update the wiki, the same as if `ikiwiki --refresh` +received, ikiwiki will update the wiki, the same as if `ikiwiki --refresh` were ran at the command line. An url such as the following is used to trigger a ping: diff --git a/doc/plugins/prettydate.mdwn b/doc/plugins/prettydate.mdwn index 9a67f5dca..11ad4252f 100644 --- a/doc/plugins/prettydate.mdwn +++ b/doc/plugins/prettydate.mdwn @@ -1,5 +1,5 @@ [[!template id=plugin name=prettydate author="[[Joey]]"]] -[[!tag type/format]] +[[!tag type/date]] Enabling this plugin changes the dates displayed on pages in the wiki to a format that is nice and easy to read. Examples: "late Wednesday evening, diff --git a/doc/plugins/relativedate.mdwn b/doc/plugins/relativedate.mdwn new file mode 100644 index 000000000..3ada0864b --- /dev/null +++ b/doc/plugins/relativedate.mdwn @@ -0,0 +1,16 @@ +[[!template id=plugin name=relativedate author="[[Joey]]"]] +[[!tag type/date]] + +This plugin lets dates be displayed in relative form. Examples: "2 days ago", +"1 month and 3 days ago", "30 minutes ago". Hovering over the date will +cause a tooltip to pop up with the absolute date. + +This only works in browsers with javascript enabled; other browsers will +show the absolute date instead. Also, this plugin can be used with other +plugins like [[prettydate]] that change how the absolute date is displayed. + +If this plugin is enabled, you may also add relative dates to pages in the +wiki, by using html elements in the "relativedate" class. For example, this +will display as a relative date: + + Tue Jan 20 12:00:00 EDT 2009 diff --git a/doc/plugins/repolist.mdwn b/doc/plugins/repolist.mdwn new file mode 100644 index 000000000..9b3a7575e --- /dev/null +++ b/doc/plugins/repolist.mdwn @@ -0,0 +1,17 @@ +[[!template id=plugin name=repolist author="[[Joey]]"]] +[[!tag type/useful]] + +This plugin allows you to configure ikiwiki with the location of +[[rcs]] repositories for your wiki's source. This is done via the +"repositories" setting in the setup file. Once you tell it where the source +to your wiki can be downloaded from, this information can be published on +your wiki in various ways. + +This plugin supports the [rel-vcs-*](http://kitenet.net/~joey/rfc/rel-vcs/) +microformat, and uses it to embed the repository location information in +every wiki page. + +By using this plugin, you will make [[Joey]] very happy, as he will be able +to easily check out the source of your wiki, for purposes of debugging and +general curiosity. More generally, making it easy for others to find the +repository for your wiki is just a Plain Good Idea(TM). diff --git a/doc/plugins/rst.mdwn b/doc/plugins/rst.mdwn index 9355597ac..5e97e2d80 100644 --- a/doc/plugins/rst.mdwn +++ b/doc/plugins/rst.mdwn @@ -11,7 +11,7 @@ ikiwiki. Limitations include: * There are issues with inserting raw html into documents, as ikiwiki does with [[WikiLinks|ikiwiki/WikiLink]] and many - preprocessor [[directives|ikiwiki/directive]]. + [[directives|ikiwiki/directive]]. So while you may find this useful for importing old files into your wiki, using this as your main markup language in ikiwiki isn't recommended at diff --git a/doc/plugins/shortcut/discussion.mdwn b/doc/plugins/shortcut/discussion.mdwn index 8b1378917..4e11ce08c 100644 --- a/doc/plugins/shortcut/discussion.mdwn +++ b/doc/plugins/shortcut/discussion.mdwn @@ -1 +1,12 @@ +The plugin depends on [[mdwn]]. If you have +disabled [[mdwn]], to get [[shortcut]] work, you need +commit in a shortcuts.ext (ext is `rcs|creole|html|txt|etc`), +and edit/patch [[shortcut]]. + +Maybe use the `default_pageext` is better than hardcode .mdwn? + +--[[weakish]] + +> done, it will use `default_pageext` now --[[Joey]] + diff --git a/doc/plugins/tag.mdwn b/doc/plugins/tag.mdwn index 17bb086a1..8ff70a069 100644 --- a/doc/plugins/tag.mdwn +++ b/doc/plugins/tag.mdwn @@ -5,6 +5,9 @@ This plugin provides the [[ikiwiki/directive/tag]] and [[ikiwiki/directive/taglink]] [[directives|ikiwiki/directive]]. These directives allow tagging pages. +It also provides the `tagged()` [[ikiwiki/PageSpec]], which can be used to +match pages that are tagged with a specific tag. + [[!if test="enabled(tag)" then=""" This wiki has the tag plugin enabled, so you'll see a note below that this page is tagged with the "tags" tag. diff --git a/doc/plugins/tag/discussion.mdwn b/doc/plugins/tag/discussion.mdwn index 7e7b88bc5..b6dab5358 100644 --- a/doc/plugins/tag/discussion.mdwn +++ b/doc/plugins/tag/discussion.mdwn @@ -22,3 +22,9 @@ AOLMODE=true echo "I too would really like this feature, which would make cgi fr better" --[[DavidBremner]] Please make the actual text used a template some way or another. I may want `map` instead of `inline`. --[[madduck]] + + +See [[todo/auto-create tag pages according to a template]] + +-- Jeremy Schultz + diff --git a/doc/plugins/textile/discussion.mdwn b/doc/plugins/textile/discussion.mdwn deleted file mode 100644 index 945c9b46d..000000000 --- a/doc/plugins/textile/discussion.mdwn +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file diff --git a/doc/plugins/type/date.mdwn b/doc/plugins/type/date.mdwn new file mode 100644 index 000000000..eae1226da --- /dev/null +++ b/doc/plugins/type/date.mdwn @@ -0,0 +1 @@ +These plugins control how ikiwiki displays dates. diff --git a/doc/plugins/underlay.mdwn b/doc/plugins/underlay.mdwn new file mode 100644 index 000000000..09d096a6e --- /dev/null +++ b/doc/plugins/underlay.mdwn @@ -0,0 +1,14 @@ +[[!template id=plugin name=underlay author="[[Simon_McVittie|smcv]]"]] +[[!tag type/useful]] + +This plugin adds an `add_underlays` option to the `.setup` file. +Its value is a list of underlay directories whose content is added to the wiki. + +Multiple underlays are normally set up automatically by other plugins (for +instance, the images used by the [[plugins/smiley]] plugin), but they can also be +used as a way to pull in external files that you don't want in revision control, +like photos or software releases. + +Directories in `add_underlays` should usually be absolute. If relative, they're +interpreted as relative to the parent directory of the basewiki underlay, which +is probably not particularly useful in this context. diff --git a/doc/plugins/wmd.mdwn b/doc/plugins/wmd.mdwn new file mode 100644 index 000000000..dc9a30703 --- /dev/null +++ b/doc/plugins/wmd.mdwn @@ -0,0 +1,16 @@ +[[!template id=plugin name=wmd author="[[Will]]"]] +[[!tag type/chrome]] + +[WMD](http://wmd-editor.com/) is a What You See Is What You Mean editor for +[[mdwn]]. This plugin makes WMD be used for editing pages in the wiki. + +To use the plugin, you will need to install WMD. Download the [WMD +source](http://wmd-editor.com/downloads/wmd-1.0.1.zip). In that zip file +you'll find a few example html files, a readme and `wmd` directory. Create +a 'wmd' subdirectory in the ikiwiki `underlaydir` directory (ie `sudo mkdir +/usr/share/ikiwiki/wmd`). Move the `wmd` directory into the directory you +made. You should now have a `wmd/wmd/wmd.js` file as well as some other +javascript files and an images directory in the same place. + +Note that the WMD plugin does **not** handle ikiwiki directives. For this +reason the normal `preview` button remains. diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 1b78f5900..696bc6bc3 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -19,7 +19,7 @@ that can be fleshed out to make a useful plugin. `IkiWiki::Plugin::pagecount` is another simple example. All perl plugins should `use IkiWiki` to import the ikiwiki plugin interface. It's a good idea to include the version number of the plugin interface that your plugin -expects: `use IkiWiki 2.00`. +expects: `use IkiWiki 3.00`. An external plugin is an executable program. It can be written in any language. Its interface to ikiwiki is via XML RPC, which it reads from @@ -55,8 +55,8 @@ plugin, and a "call" parameter, which tells what function to call for the hook. An optional "last" parameter, if set to a true value, makes the hook run -after all other hooks of its type. Useful if the hook depends on some other -hook being run first. +after all other hooks of its type, and an optional "first" parameter makes +it run first. Useful if the hook depends on some other hook being run first. ## Types of hooks @@ -107,7 +107,7 @@ adding or removing files from it. This hook is called early in the process of building the wiki, and is used as a first pass scan of the page, to collect metadata about the page. It's -mostly used to scan the page for WikiLinks, and add them to `%links`. +mostly used to scan the page for [[WikiLinks|ikiwiki/WikiLink]], and add them to `%links`. Present in IkiWiki 2.40 and later. The function is passed named parameters "page" and "content". Its return @@ -168,7 +168,7 @@ htmlize the page) along with the rest of the page. hook(type => "linkify", id => "foo", call => \&linkify); -This hook is called to convert [[WikiLinks|WikiLink]] on the page into html +This hook is called to convert [[WikiLinks|ikiwiki/WikiLink]] on the page into html links. The function is passed named parameters "page", "destpage", and "content". It should return the linkified content. Present in IkiWiki 2.40 and later. @@ -189,14 +189,18 @@ The function is passed named parameters: "page" and "content" and should return the htmlized content. If `hook` is passed an optional "keepextension" parameter, set to a true -value, then this extension will not be stripped from the source filename when +value, then the extension will not be stripped from the source filename when generating the page. +If `hook` is passed an optional "noextension" parameter, set to a true +value, then the id parameter specifies not a filename extension, but +a whole filename that can be htmlized. This is useful for files +like `Makefile` that have no extension. + ### pagetemplate hook(type => "pagetemplate", id => "foo", call => \&pagetemplate); - [[Templates|wikitemplates]] are filled out for many different things in ikiwiki, like generating a page, or part of a blog page, or an rss feed, or a cgi. This hook allows modifying the variables available on those @@ -304,7 +308,7 @@ can check if the session object has a "name" parameter set. ### canedit - hook(type => "canedit", id => "foo", call => \&pagelocked); + hook(type => "canedit", id => "foo", call => \&canedit); This hook can be used to implement arbitrary access methods to control when a page can be edited using the web interface (commits from revision control @@ -322,6 +326,26 @@ This hook should avoid directly redirecting the user to a signin page, since it's sometimes used to test to see which pages in a set of pages a user can edit. +### checkcontent + + hook(type => "checkcontent", id => "foo", call => \&checkcontent); + +This hook is called to check the content a user has entered on a page, +before it is saved, and decide if it should be allowed. + +It is passed named parameters: `content`, `page`, `cgi`, and `session`. If +the content the user has entered is a comment, it may also be passed some +additional parameters: `author`, `url`, and `subject`. The `subject` +parameter may also be filled with the user's comment about the change. + +Note: When the user edits an existing wiki page, the passed `content` will +include only the lines that they added to the page, or modified. + +The hook should return `undef` on success. If the content is disallowed, it +should return a message stating what the problem is, or a function +that can be run to perform whatever action is necessary to allow the user +to post the content. + ### editcontent hook(type => "editcontent", id => "foo", call => \&editcontent); @@ -415,7 +439,7 @@ describes the plugin as a whole. For example: * `example` can be set to an example value. * `description` is a short description of the option. * `link` is a link to further information about the option. This can either - be a wikilink, or an url. + be a [[ikiwiki/WikiLink]], or an url. * `advanced` can be set to true if the option is more suitable for advanced users. * `safe` should be false if the option should not be displayed in unsafe @@ -432,7 +456,7 @@ describes the plugin as a whole. For example: To import the ikiwiki plugin interface: - use IkiWiki '2.00'; + use IkiWiki '3.00'; This will import several variables and functions into your plugin's namespace. These variables and functions are the ones most plugins need, @@ -487,7 +511,7 @@ use the following hashes, using a page name as the key: destination file. * `%pagesources` contains the name of the source file for each page. -Also, the %IkiWiki::version variable contains the version number for the +Also, the `%IkiWiki::version` variable contains the version number for the ikiwiki program. ### Library functions @@ -610,6 +634,16 @@ A failure to write the file will result in it dying with an error. If the destination directory doesn't exist, it will first be created. +The filename and directory are separate parameters because of +some security checks done to avoid symlink attacks. Before writing a file, +it checks to make sure there's not a symlink with its name, to avoid +following the symlink. If the filename parameter includes a subdirectory +to put the file in, it also checks if that subdirectory is a symlink, etc. +The directory parameter, however, is not checked for symlinks. So, +generally the directory parameter is a trusted toplevel directory like +the srcdir or destdir, and any subdirectories of this are included in the +filename parameter. + #### `will_render($$)` Given a page name and a destination file name (not including the base @@ -651,7 +685,7 @@ a wiki page name. #### `linkpage($)` This converts text that could have been entered by the user as a -[[WikiLink]] into a wiki page name. +[[ikiwiki/WikiLink]] into a wiki page name. #### `srcfile($;$)` @@ -697,11 +731,15 @@ This can be called when creating a new page, to determine what filename to save the page to. It's passed a page name, and its type, and returns the name of the file to create, relative to the srcdir. -#### `targetpage($$)` +#### `targetpage($$;$)` Passed a page and an extension, returns the filename that page will be rendered to. +Optionally, a third parameter can be passed, to specify the preferred +filename of the page. For example, `targetpage("foo", "rss", "feed")` +will yield something like `foo/feed.rss`. + ## Miscellaneous ### Internal use pages @@ -712,7 +750,7 @@ are collected together to form the RecentChanges page, for example. To make an internal use page, register a filename extension that starts with "_". Internal use pages cannot be edited with the web interface, -generally shouldn't contain wikilinks or preprocessor directives (use +generally shouldn't contain [[WikiLinks|ikiwiki/WikiLink]] or preprocessor directives (use either on them with extreme caution), and are not matched by regular PageSpecs glob patterns, but instead only by a special `internal()` [[ikiwiki/PageSpec]]. @@ -821,6 +859,30 @@ it up in the history. It's ok if this is not implemented, and throws an error. +#### `rcs_receive()` + +This is called when ikiwiki is running as a pre-receive hook (or +equivalent), and is testing if changes pushed into the RCS from an +untrusted user should be accepted. This is optional, and doesn't make +sense to implement for all RCSs. + +It should examine the incoming changes, and do any sanity +checks that are appropriate for the RCS to limit changes to safe file adds, +removes, and changes. If something bad is found, it should exit +nonzero, to abort the push. Otherwise, it should return a list of +files that were changed, in the form: + + { + file => # name of file that was changed + action => # either "add", "change", or "remove" + path => # temp file containing the new file content, only + # needed for "add"/"change", and only if the file + # is an attachment, not a page + } + +The list will then be checked to make sure that each change is one that +is allowed to be made via the web interface. + ### PageSpec plugins It's also possible to write plugins that add new functions to @@ -847,3 +909,82 @@ to a hash containing all the config items. They should also implement a By the way, to parse a ikiwiki setup file and populate `%config`, a program just needs to do something like: `use IkiWiki::Setup; IkiWiki::Setup::load($filename)` + +### Function overriding + +Sometimes using ikiwiki's pre-defined hooks is not enough. Your plugin +may need to replace one of ikiwiki's own functions with a modified version, +or wrap one of the functions. + +For example, your plugin might want to override `displaytime`, to change +the html markup used when displaying a date. Or it might want to override +`IkiWiki::formattime`, to change how a date is formatted. Or perhaps you +want to override `bestlink` and change how ikiwiki deals with [[WikiLinks|ikiwiki/WikiLink]]. + +By venturing into this territory, your plugin is becoming tightly tied to +ikiwiki's internals. And it might break if those internals change. But +don't let that stop you, if you're brave. + +Ikiwiki provides an `inject()` function, that is a powerful way to replace +any function with one of your own. This even allows you to inject a +replacement for an exported function, like `bestlink`. Everything that +imports that function will get your version instead. Pass it the name of +the function to replace, and a new function to call. + +For example, here's how to replace `displaytime` with a version using HTML 5 +markup: + + inject(name => 'IkiWiki::displaytime', call => sub { + return ""; + }); + +Here's how to wrap `bestlink` with a version that tries to handle +plural words: + + my $origbestlink=\&bestlink; + inject(name => 'IkiWiki::bestlink', call => \&mybestlink); + + sub deplural ($) { + my $word=shift; + $word =~ s/e?s$//; # just an example :-) + return $word; + } + + sub mybestlink ($$) { + my $page=shift; + my $link=shift; + my $ret=$origbestlink->($page, $link); + if (! length $ret) { + $ret=$origbestlink->($page, deplural($link)); + } + return $ret; + } + +### Javascript + +Some plugins use javascript to make ikiwiki look a bit more web-2.0-ish. + +All javascript code should be put in `.js` files in the `javascript` +underlay, and plugins using those files can enable use of the underlay by +calling `add_underlay("javascript");` in their `import` function. + +You'll have to arrange for ` + - + -EOF + + $form->field("do") eq "create" || + + $form->field("do") eq "comment"; + + + + my $useAPI = $config{wmd_use101api}?'true':'false'; + + my $ikiwikijs = urlto("ikiwiki.js", undef, 1); + + my $wmdIkiwikijs = urlto("wmd-ikiwiki.js", undef, 1); + + my $wmdjs = urlto("wmd.js", undef, 1); + + + + my $previewScripts = <<"EOS"; + + + + + + + + + +EOS + + + + $form->tmpl_param("wmd_preview", $previewScripts); + } + + 1 + diff --git a/doc/style.css b/doc/style.css + index a6e6734..36c2b13 + --- a/doc/style.css + +++ b/doc/style.css + @@ -76,9 +76,16 @@ div.tags { + float: right; + } + + +/* + #editcontent { + width: 100%; + } + +*/ + + + +#wmd-preview-container { + + width: 49%; + + float: right; + +} + + img { + border-style: none; + diff --git a/templates/editpage.tmpl b/templates/editpage.tmpl + index b1cf015..1d2f080 100644 + --- a/templates/editpage.tmpl + +++ b/templates/editpage.tmpl + @@ -15,6 +15,14 @@ Page type: + + + + + + +
+ +
+ +Live preview: + +
+ +
+ +
+ +
+
+ + Optional comment about this change:
diff --git a/doc/todo/mercurial.mdwn b/doc/todo/mercurial.mdwn index f0dbf9806..e71c8106a 100644 --- a/doc/todo/mercurial.mdwn +++ b/doc/todo/mercurial.mdwn @@ -14,6 +14,10 @@ It seems that with the current mercurial commit code, it will always blindly overwrite the current file with the web edited version, losing any other changes. +* `rcs_commit_staged`, `rcs_rename`, `rcs_remove`, and `rcs_diff` are not + implemented for mercurial, and so attachments, remove and rename plugins + and recentchangesdiff cannot be used with it. (These should be fairly + easy to add..) Posthook: in `$srcdir/.hg/hgrc`, I have the following @@ -29,6 +33,62 @@ This should update the working directory and run ikiwiki every time a change is > It can deadlock if the post-commit hook runs with --refresh in the > former case. --[[Joey]] +The problem with --post-commit is that if you delete some pages in $SRC, ikiwiki --setup setupfile --post-commit will not delete them in $DEST. --[[users/weakish]] + +> You should really be using a setup file that has `mercurial_wrapper` +> set, and running the wrapper generated by that from your hook. +> That will work. I think that the `--setup --post-commit` on the command +> line is currently broken and does the same expensive rebuild process as --setup +> alone (which doesn't delete files from $DEST either). Will fix that. +> (fixed) +> --[[Joey]] + +>> Mercurial doesn't support put hooks in .hg/hooks/* (like git). In Mercurial, the only way to run +>> your own hooks is specifying them in the hgrc file. (Or write a new extension.) +>> I guess use a very long command will work. +>> (e.g. ikiwiki --post-commit --a-lot-of-switches --set var=value $SRC $DEST) +>> (Fortunately ikiwiki supports --set var=value so without --setup works.) +>> +>> Alternative is always editing via cgi or pushing. Never work on the $SRC/repo directly. +>> --[[users/weakish]] + +>>> I don't see anything preventing you from using a setup file with +>>> `mercurial_wrapper => ".hg/ikiwiki-hook",` and then modifying the hgrc +>>> to run that wrapper. --[[Joey]] + +>> Thanks for pointing out this. I have some stupid misunderstanding on the +>> usage of mercurial_wrapper before. The wrapper works nicely! --[[weakish]] + +I add the following to .hg/hgrc:(I use changegroup since I don't think we need refresh per changeset, please point out if I am wrong.) + + [hooks] + changegroup = hg update >&2 && ikiwiki --setup path.to.setup.file --refresh + post-commit = path.to.the.mercurial.wrapper + +----- + +I have no idea when the deadlock will happen. --[[users/weakish]] + +> For the deadlock to occur, a edit has to be made via the web. +> +> Ikiwiki, +> running as a CGI, takes a lock on the wiki, and commits the edit, +> continuing to run in the background, with the lock still held. +> When the edit is committed, the hg hook runs, running `ikwiki --refresh`. +> Nearly the first thing that process does it try to lock the wiki.. +> which is already locked. This lock is taken in a blocking manner, +> thus the deadlock -- the cgi is waiting for the commit to finish before +> dropping the lock, and the commit is blocked waiting for the lock to be +> released. +> +> --post-commit avoids this problem by checking if the cgi is running +> and avoiding doing anything in that case. (While still handing the +> refresh if the commit was not made by the CGI.) +> So in that case, the commit finishes w/o ikiwiki doing anything, +> and the ikiwiki CGI handles the wiki refresh. +> --[[Joey]] + + *** I have a few notes on mercurial usage after trying it out for a while: diff --git a/doc/todo/meta_rcsid.mdwn b/doc/todo/meta_rcsid.mdwn index 81a2c1328..158edea6e 100644 --- a/doc/todo/meta_rcsid.mdwn +++ b/doc/todo/meta_rcsid.mdwn @@ -26,7 +26,7 @@ of CVS/SVN-style keywords (like '$Id$', etc.) from the source file in the page t my %copyright; +my %rcsid; - sub import { #{{{ + sub import { hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1); @@ -110,6 +111,9 @@ $meta{$page}.="\n"; diff --git a/doc/todo/missingparents.pm.mdwn b/doc/todo/missingparents.pm.mdwn index 0cc7137ba..c5f2ab535 100644 --- a/doc/todo/missingparents.pm.mdwn +++ b/doc/todo/missingparents.pm.mdwn @@ -82,15 +82,15 @@ Index: IkiWiki/Plugin/missingparents.pm +my %ownfiles; +my @pagespecs; + -+sub import { #{{{ ++sub import { + hook(type => "checkconfig", id => "missingparents", call => \&checkconfig); + hook(type => "needsdelete", id => "missingparents", call => \&needsdelete); + hook(type => "needsbuild", id => "missingparents", call => \&needsbuild); + hook(type => "savestate", id => "missingparents", call => \&savestate); + hook(type => "preprocess", id => "missingparents", call => \&preprocess_missingparents); -+} # }}} ++} + -+sub checkconfig () { #{{{ ++sub checkconfig () { + IkiWiki::preprocess("missingparents", "missingparents", + readfile(srcfile("missingparents.mdwn"))); + loadstate(); @@ -99,9 +99,9 @@ Index: IkiWiki/Plugin/missingparents.pm + unlink $config{srcdir}.'/'.$file; + } + } -+} #}}} ++} + -+sub preprocess_missingparents (@) { #{{{ ++sub preprocess_missingparents (@) { + my %params=@_; + + if (! defined $params{pages} || ! defined $params{generate}) { @@ -115,10 +115,10 @@ Index: IkiWiki/Plugin/missingparents.pm + #translators: is text for pages that match that pagespec. + return sprintf(gettext("missingparents in %s will be %s"), + '`'.$params{pages}.'`', '`\\'.$params{generate}.'`'); -+} # }}} ++} + +my $state_loaded=0; -+sub loadstate() { #{{{ ++sub loadstate() { + my $filename = "$config{wikistatedir}/missingparents"; + if (-e $filename) { + open (IN, $filename) || @@ -132,9 +132,9 @@ Index: IkiWiki/Plugin/missingparents.pm + + $state_loaded=1; + } -+} #}}} ++} + -+sub savestate() { #{{{ ++sub savestate() { + my $filename = "$config{wikistatedir}/missingparents.new"; + my $cleanup = sub { unlink ($filename) }; + open (OUT, ">$filename") || error("open $filename: $!", $cleanup); @@ -143,9 +143,9 @@ Index: IkiWiki/Plugin/missingparents.pm + } + rename($filename, "$config{wikistatedir}/missingparents") || + error("rename $filename: $!", $cleanup); -+} #}}} ++} + -+sub needsdelete (@) { #{{{ ++sub needsdelete (@) { + my $files=shift; + + my @mydel; @@ -167,9 +167,9 @@ Index: IkiWiki/Plugin/missingparents.pm + foreach my $page (@mydel){ + push @{$files}, $page; + } -+} #}}} ++} + -+sub check_matches($) { #{{{ ++sub check_matches($) { + my $page = shift; + return if $IkiWiki::pagesources{$page}; + @@ -183,9 +183,9 @@ Index: IkiWiki/Plugin/missingparents.pm + return $output; + } + return ""; -+} #}}} ++} + -+sub needsbuild ($) { #{{{ ++sub needsbuild ($) { + my $files=shift; + my @new; + @@ -209,7 +209,7 @@ Index: IkiWiki/Plugin/missingparents.pm + $ownfiles{$file} = 1; + push @{$files}, $file; + } -+} #}}} ++} + +1 Index: IkiWiki.pm @@ -227,18 +227,18 @@ Index: IkiWiki.pm our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE @@ -330,6 +336,30 @@ error("failed renaming $newfile to $destdir/$file: $!", $cleanup); - } #}}} + } -+sub newpage($$) { #{{{ ++sub newpage($$) { + my $file=shift; + my $page=shift; + + $pagemtime{$page} = $pagectime{$page} = time; + $pagesources{$page} = $file; + $pagecase{lc $page} = $page; -+} #}}} ++} + -+sub delpage($) { #{{{ ++sub delpage($) { + my $page=shift; + $links{$page}=[]; + $renderedfiles{$page}=[]; @@ -251,10 +251,10 @@ Index: IkiWiki.pm + delete $destsources{$_}; + } + } -+} #}}} ++} + my %cleared; - sub will_render ($$;$) { #{{{ + sub will_render ($$;$) { my $page=shift; diff --git a/doc/todo/modify_page_filename_in_plugin.mdwn b/doc/todo/modify_page_filename_in_plugin.mdwn index 7c0a909eb..a13c8b62f 100644 --- a/doc/todo/modify_page_filename_in_plugin.mdwn +++ b/doc/todo/modify_page_filename_in_plugin.mdwn @@ -6,11 +6,13 @@ The problem is that I occasionally have xxx.c and xxx.h in the same directory an My solution is to allow plugins to provide a hook that sets the pagename. --[[/users/bstpierre]] +> You might also find the solution to [[bugs/multiple_pages_with_same_name]] helps you. That patch is already applied. -- [[Will]] + --- /usr/share/perl5/IkiWiki.pm.ORIG 2008-10-03 14:12:50.000000000 -0400 +++ /usr/share/perl5/IkiWiki.pm 2008-10-07 11:57:26.000000000 -0400 @@ -196,11 +196,32 @@ - sub pagename ($) { #{{{ + sub pagename ($) { my $file=shift; my $type=pagetype($file); @@ -27,7 +29,7 @@ My solution is to allow plugins to provide a hook that sets the pagename. --[[/u $page=~s/\Q.$type\E*$// if defined $type; return $page; + } - } #}}} + } - sub htmlpage ($) { #{{{ + sub htmlpage ($) { diff --git a/doc/todo/natural_sorting.mdwn b/doc/todo/natural_sorting.mdwn new file mode 100644 index 000000000..5df17e95b --- /dev/null +++ b/doc/todo/natural_sorting.mdwn @@ -0,0 +1,21 @@ +[[!tag wishlist]] +[[!tag patch]] + +the inline plugin's sorting is plain lexical, thich may not be appropriate for +page titles if they have numeric components. the +[Sort::Naturally](http://search.cpan.org/dist/Sort-Naturally/) perl module +provides an algorithm for that. + +there is a +[patch](http://git.ikiwiki.info/?p=ikiwiki;a=commit;h=55b83cb7bd1cd7c60bb45dc22c3745dd80a63fed) +attached that makes the [[plugins/inline]] plugin use Sort::Naturally if sort +is set to "title_natural". + +the current patch uses `require Sort::Naturally`, so +[libsort-naturally-perl](http://packages.debian.org/libsort-naturally-perl) +does not become a dependency; it might be worth suggesting, though. + +> See also: [[inline:_numerical_ordering_by_title]] (I probably prefer your +> approach..) --[[Joey]] + +> [[applied|done]] diff --git a/doc/todo/need_global_renamepage_hook.mdwn b/doc/todo/need_global_renamepage_hook.mdwn new file mode 100644 index 000000000..b123340af --- /dev/null +++ b/doc/todo/need_global_renamepage_hook.mdwn @@ -0,0 +1,115 @@ +As documented in [[plugins/write]], the current `renamepage` hook is +heavily oriented towards updating links in pages' content: it is run +once per page linking to the renamed page. + +That's fine, but it can't be used to trigger more general actions on +page rename. E.g. it won't be run at all if the page being renamed is +an orphan one. + +This is a real issue for the [[plugins/contrib/po]] development: what +I'm about to achieve is: + +- when a master page is renamed, the plugin takes notice of it (using + the `rename` hook), and later renames the translation pages + accordingly (in the `change` hook) +- when a master page is deleted, the plugin deletes its translations + (using the `delete` hook) + +With the current `renamepage` hook behavior, combining these two goals +has an annoying drawback: a plugin can't notice an orphan master page +has been renamed, so instead of renaming (and preserving) its +translations, it considers the oldpage as deleted, and deletes its +translations. Game over. + +It may seem like a corner case, but I want to be very careful when +deleting files automatically in `srcdir`, which is not always under +version control. + +As a sad workaround, I can still disable any deletion in `srcdir` +when it is not under version control. But I think ikiwiki deserves +a global `renamepage` hook that would be run once per rename +operation. + +My proposal is thus: + +- keep the documented `renamepage` hook as it is +- use something inspired by the trick `preprocess` uses: when `hook` + is passed an optional "global" parameter, set to a true value, the + declared `renamepage` hook is run once per rename operation, and is + passed named parameters: `src`, `srcfile`, `dest` and `destfile`. + +I'm of course volunteering to implement this, or anything related that +would solve my problem. Hmmm? --[[intrigeri]] + +> I think it would be better to have a different hook that is called for +> renames, since the two hook actions are very different (unlike the +> preprocess hook, which does a very similar thing in scan mode). +> +> Just calling it `rename` seems like a reasonable name, by analogy with +> the `delete` and `change` hooks. +> +> It might make sense to rename `renamepage` to `renamelink` to make it +> clearer what it does. (I'm not very worried about this breaking things, at +> this point.) --[[Joey]] + +>> In my `po` branch, I renamed `renamepage` to `renamelink`, and +>> created a `rename` hook that is passed a reference to `@torename`. +>> --[[intrigeri]] + +>>> As Joey highlights it on [[plugins/contrib/po]], it's too late to +>>> merge such a change, as the 3.x plugin API is released and should +>>> not be broken. I will thus keep the existing `renamepage` as it +>>> is, and call `rename` the global hook I need. --[[intrigeri]] + +>>>> Done in my `po` branch. --[[intrigeri]] + +I think I see a problem in the rename hook. The hook is called +before the plugin adds any subpages to the set of pages to rename. +So, if the user choses to rename subpages, po will not notice +they are moving, and will not move their po files. + +Perhaps the hooks should be moved to come after subpages are added. +This would, though, mean that if the hook somehow decides to add +entirely other pages to the list, their subpages would not be +automatically added. + +I also have some qualms about the design of the hook. In particular, +passing the mutable array reference probably makes it impossible +to use from external plugins. Instead it could return any additional +rename hashes it wants to add. Or, if the ability to modify existing +hashes is desired, it could return the full set of hashes. + +--[[Joey]] + +> I fixed the last part, i.e. a rename hook function now returns the +> full set of hashes. As I also converted it to take named parameters, +> such a function still is passed a reference to the original array, +> though, because one can't build a hash containing an array of hashes +> as a value, without passing this array as a reference. +> +>> Sure. +> +> I'm not entirely sure about your first concern. Calling the hook +> before or after the subpages addition both have their own problems. +> +> What about running the hook before *and* after the subpages +> addition, with an additional `when` named parameter, so that +> a given hook function can choose to act only before or after, or both? +> +> --[[intrigeri]] +>> +>> Have you thought about making the hook be run once *per* file that is +>> selected to be renamed? This would even handle the case where two +>> plugins use the hook; plugin A would see when plugin B adds a new file +>> to be renamed. And the subpage renaming stuff could probably be moved +>> into the rename hook too. --[[Joey]] +>>> +>>> I've implemented this nice solution in my po branch, please review. +>>> I'm slowly coming back to do the last bits needed to get my po and +>>> meta branch merged. --[[intrigeri]] + +>>>> It looks good. I made some small changes to it in my own po branch. +>>>> Nothing significant really. If this were not tied up in the po branch, +>>>> I've have merged it to master already. --[[Joey]] + +>>>> Thanks, this is great :) --[[intrigeri]] diff --git a/doc/todo/overriding_displayed_modification_time.mdwn b/doc/todo/overriding_displayed_modification_time.mdwn new file mode 100644 index 000000000..160d31519 --- /dev/null +++ b/doc/todo/overriding_displayed_modification_time.mdwn @@ -0,0 +1,27 @@ +Some aggregators, like Planet, sort by mtime rather than ctime. This +means that posts with modified content come to the top (which seems odd +to me, but is presumably what the aggregator's author or operator +wants), + +> Hah! That's so charitable I hope you can deduct it from your taxes. ;-) +> --[[Joey]] + +but it also means that posts with insignificant edits (like +adding tags) come to the top too. Atom defines `` to be the date +of the last *significant* change, so it's fine that ikiwiki defaults to +using the mtime, but it would be good to have a way for the author to +say "that edit was insignificant, don't use that mtime". + +> Yes, this is a real limitiation of ikiwiki's atom support. --[[Joey]] + +See smcv's 'updated' branch for a basic implementation, which only affects +the Atom `` field or the RSS equivalent. + +Other places the updated metadata item could be used (opinions on whether +each should use it or not, please): + +* sorting by mtime in the inline directive +* displaying "last edited" on ordinary pages + +> Tending toward no for both, but willing to be convinced otherwise.. +> [[merged|done]] --[[Joey]] diff --git a/doc/todo/pagespec_relative_to_a_target.mdwn b/doc/todo/pagespec_relative_to_a_target.mdwn index f7b248670..4757988e0 100644 --- a/doc/todo/pagespec_relative_to_a_target.mdwn +++ b/doc/todo/pagespec_relative_to_a_target.mdwn @@ -57,7 +57,7 @@ diff -urNX ignorepats ikiwiki/IkiWiki/Plugin/relative.pm ikidev/IkiWiki/Plugin/r + +package IkiWiki::PageSpec; + -+sub match_relative($$;@) { #{{{ ++sub match_relative($$;@) { + my $parent = shift; + my $spec = shift; + my %params = @_; @@ -69,21 +69,21 @@ diff -urNX ignorepats ikiwiki/IkiWiki/Plugin/relative.pm ikidev/IkiWiki/Plugin/r + } + } + return IkiWiki::FailReason->new("$parent can't match $spec against anything"); -+} #}}} ++} + -+sub match_has_child($$;@) { #{{{ ++sub match_has_child($$;@) { + my $page = shift; + my $childname = shift; + my $spec; -+ if ($childname) { #{{{ ++ if ($childname) { + $spec = "$page/$childname or $page/*/$childname"; -+ } #}}} -+ else { #{{{ ++ } ++ else { + $spec = "$page/*"; -+ } #}}} ++ } + + return match_relative($page, $spec, @_); -+} #}}} ++} + +1 diff --git a/doc/todo/pingback_support.mdwn b/doc/todo/pingback_support.mdwn new file mode 100644 index 000000000..b10366bda --- /dev/null +++ b/doc/todo/pingback_support.mdwn @@ -0,0 +1,39 @@ +A "pingback" is a system whereby URLs you might reference in a blog post are +contacted by the blog publishing software at publishing time (i.e., once) so +that they might update a list of "pingbacks" to the URL. The originating +URL's blog software might then display a list of pingbacks, or an excerpt of +the text from your blog, perhaps interleaved with comments, etc. + +At a technical level, external URLs are extracted from your blog post by the +blogging software, fetched, inspected for information to determine whether the +remote server is configured to support pingbacks (look for link tags, or HTTP +headers) and the relevant pingback URL sent an XML-RPC packet. + +There are other technologies to achieve the same thing: trackbacks predate +pingbacks but are more vulnerable to spam due to design problems. + +The spec for pingbacks is at . + +I would like to somehow use pingbacks in conjunction with ikiwiki. I suppose +this could be achieved using a commit hook and some external software in which +case I will consider this done with an entry in [[tips]]; otherwise a +[[plugins|plugin]] to implement pingbacks would be great. + +-- [[Jon]] (Wed Jan 14 13:48:47 GMT 2009) + +> I think it's now possible to implement trackback and pingback receiving +> support in ikiwiki. One easy way to do it would be to hook it into the +> existing [[plugins/comments]] plugin -- each pingback/trackback that +> ikiwiki recieves would result in the creation if a new comment, which +> would be subject to the usual comment filtering (ie, blogspam) and +> moderation and would then show up amoung the other, regular comments on +> the page. +> +> (One wrinkle: would need to guard against duplicate pings. Maybe by +> checking existing comments for any that have the same url?) +> +> As for sending trackbacks and pingbacks, this could fairly easily be +> implemented using a `editcontent` hook. Since this hook is called +> whenever a page is posted or edited, and gets the changed content, it can +> simply scan it for urls (may have to htmlize first?), and send pings to +> all urls found. --[[Joey]] diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 132de4480..b3e3a7889 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -70,10 +70,6 @@ Suggestions of ideas for plugins: > web-server-specific code to list all users, and openid can't feasibly do so > at all. --[[JoshTriplett]] -* It would be nice to be able to have a button to show "Differences" (or - "Show Diff") when editing a page. Is that an option that can be enabled? - Using a plugin? - * For PlaceWiki I want to be able to do some custom plugins, including one that links together subpages about the same place created by different users. This seems to call for a plugin that applies to every page w/o any diff --git a/doc/todo/provide_inline_diffs_in_recentchanges.mdwn b/doc/todo/provide_inline_diffs_in_recentchanges.mdwn index 7724576f5..39a35d0c6 100644 --- a/doc/todo/provide_inline_diffs_in_recentchanges.mdwn +++ b/doc/todo/provide_inline_diffs_in_recentchanges.mdwn @@ -1,3 +1,8 @@ It would rock if I could view diffs from the web without going via feeds. I envision toggle-style buttons on the recentchanges page, or just links to the CGI, which then displays the diff... --[[madduck]] +> The diffs are actually there, enabled by the `recentchangesdiff` +> plugin, but they are hidden in the XHTML version by the stylesheet. +> You might try a user stylesheet with `div.diff { display: block }`. +> --[[JasonBlevins]] + [[!tag wishlist]] diff --git a/doc/todo/provide_sha1_for_git_diffurl.mdwn b/doc/todo/provide_sha1_for_git_diffurl.mdwn new file mode 100644 index 000000000..01aa512f8 --- /dev/null +++ b/doc/todo/provide_sha1_for_git_diffurl.mdwn @@ -0,0 +1,26 @@ +This [[patch]] allows for `\[[sha1]]` substitution in the `diffurl` +for git repositories. This is useful for use with [cgit][] which has +diffurls of the following form: + + /project.git/diff/\[[file]]?id=\[[sha1_commit]] + + [cgit]: http://hjemli.net/git/cgit/ + + diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm + index 5bef928..164210d 100644 + --- a/IkiWiki/Plugin/git.pm + +++ b/IkiWiki/Plugin/git.pm + @@ -518,6 +518,7 @@ sub rcs_recentchanges ($) { + + my $diffurl = defined $config{'diffurl'} ? $config{'diffurl'} : ""; + $diffurl =~ s/\[\[file\]\]/$file/go; + + $diffurl =~ s/\[\[sha1\]\]/$sha1/go; + $diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go; + $diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go; + $diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go; + +> [[done]], but I called it `sha1_commit` since I think that's what it's +> actually a sha1 of. --[[Joey]] + +>> I was at a loss for something more descriptive...I like that much +>> better :) Thanks! --[[JasonBlevins]] diff --git a/doc/todo/rcs_updates_needed_for_rename_and_remove.mdwn b/doc/todo/rcs_updates_needed.mdwn similarity index 54% rename from doc/todo/rcs_updates_needed_for_rename_and_remove.mdwn rename to doc/todo/rcs_updates_needed.mdwn index 2af659c3b..472a5800f 100644 --- a/doc/todo/rcs_updates_needed_for_rename_and_remove.mdwn +++ b/doc/todo/rcs_updates_needed.mdwn @@ -3,3 +3,8 @@ renaming and removing files using the web interface. The mercurial and tla [[rcs]] backends need implementions of these functions. (The maintainers of these backends have been mailed. --[[Joey]]) + +Also, currently git is the only VCS to have support for +[[untrusted_push|tips/untrusted_git_push]]. It _may_ be possible to +implement it for other DVCS, if they offer a hook that can be used to check +incoming pushes early. diff --git a/doc/todo/redirect_automatically_after_rename.mdwn b/doc/todo/redirect_automatically_after_rename.mdwn new file mode 100644 index 000000000..1cbb824d2 --- /dev/null +++ b/doc/todo/redirect_automatically_after_rename.mdwn @@ -0,0 +1,10 @@ +In some wikis, (e.g. Mediawiki) after [[renaming|plugins/rename]] +a page, the old page still exist but only redirect to the +new page. This is convenient since external sites may +have links pointing to the old url. + +If [[plugins/meta]] plugin is enabled, users can manually edit the +page, and put in '\[[!meta redir=newpage]]', but this is +not very convenient. + + diff --git a/doc/todo/relative_pagespec_deficiency.mdwn b/doc/todo/relative_pagespec_deficiency.mdwn new file mode 100644 index 000000000..4500581c7 --- /dev/null +++ b/doc/todo/relative_pagespec_deficiency.mdwn @@ -0,0 +1,8 @@ +While a relative pagespec like `./posts/*` will work, when used in a page +such as `bdale/blog`, you cannot do +`created_after(./posts/foo)` -- only `glob()` supports relative page +references. + +The other pagespec functions should too, where appropriate. + +[[done]] diff --git a/doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn b/doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn index dfeacbabd..c4e78ca0b 100644 --- a/doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn +++ b/doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn @@ -54,3 +54,7 @@ the templates. I'd prefer not having to touch Perl though... ----- Yes, Template::Toolkit is very powerful. But I think it's somehow overkill for a wiki. HTML::Template can keep things simple, though. --[weakish](http://weakish.int.eu.org/blog/) + +I'd have to agree that Template::Toolkit is overkill and personally I'm not a fan, but it is very popular (there is even a book) and the new version (3) is alleged to be much more nimble than current version. --[[ajt]] + +HTML::Template's HTML-like markup prevents me from editing templates in KompoZer or other WYSIWYG HTML editors. The editor tries to render the template markup rather than display it verbatim, and large parts of the template become invisible. A markup syntax that doesn't confuse editors (such as Template::Toolkit's "[% FOO %]") may promote template customization. The ability to replace the template engine would be within the spirit of ikiwiki's extensibility. --Rocco diff --git a/doc/todo/require_CAPTCHA_to_edit.mdwn b/doc/todo/require_CAPTCHA_to_edit.mdwn index 110b4167f..83ba07eb0 100644 --- a/doc/todo/require_CAPTCHA_to_edit.mdwn +++ b/doc/todo/require_CAPTCHA_to_edit.mdwn @@ -91,15 +91,15 @@ ignored. --- a/IkiWiki/Plugin/openid.pm +++ b/IkiWiki/Plugin/openid.pm -@@ -18,6 +18,7 @@ sub getopt () { #{{{ +@@ -18,6 +18,7 @@ sub getopt () { error($@) if $@; Getopt::Long::Configure('pass_through'); GetOptions("openidsignup=s" => \$config{openidsignup}); + GetOptions("openidneedscaptcha=s" => \$config{openidneedscaptcha}); - } #}}} + } - sub formbuilder_setup (@) { #{{{ -@@ -61,6 +62,7 @@ sub formbuilder_setup (@) { #{{{ + sub formbuilder_setup (@) { +@@ -61,6 +62,7 @@ sub formbuilder_setup (@) { # Skip all other required fields in this case. foreach my $field ($form->field) { next if $field eq "openid_url"; @@ -107,7 +107,7 @@ ignored. $form->field(name => $field, required => 0, validate => '/.*/'); } -@@ -96,6 +98,18 @@ sub validate ($$$;$) { #{{{ +@@ -96,6 +98,18 @@ sub validate ($$$;$) { } } @@ -152,19 +152,19 @@ use warnings; use strict; use IkiWiki 2.00; -sub import { #{{{ +sub import { hook(type => "formbuilder_setup", id => "recaptcha", call => \&formbuilder_setup); -} # }}} +} -sub getopt () { #{{{ +sub getopt () { eval q{use Getopt::Long}; error($@) if $@; Getopt::Long::Configure('pass_through'); GetOptions("reCaptchaPubKey=s" => \$config{reCaptchaPubKey}); GetOptions("reCaptchaPrivKey=s" => \$config{reCaptchaPrivKey}); -} #}}} +} -sub formbuilder_setup (@) { #{{{ +sub formbuilder_setup (@) { my %params=@_; my $form=$params{form}; @@ -274,7 +274,7 @@ EOTAGS }); } } -} # }}} +} # The following function is borrowed from # Captcha::reCAPTCHA by Andy Armstrong and are under the PERL Artistic License diff --git a/doc/todo/rewrite_ikiwiki_in_haskell.mdwn b/doc/todo/rewrite_ikiwiki_in_haskell.mdwn new file mode 100644 index 000000000..204c48cd7 --- /dev/null +++ b/doc/todo/rewrite_ikiwiki_in_haskell.mdwn @@ -0,0 +1,68 @@ +[[!tag wishlist blue-sky]] + +In the long term, I have been considering rewriting ikiwiki in haskell. +It's appealing for a lot of reasons, including: + +* No need to depend on a C compiler and have wrappers. Instead, ikiwiki + binaries could be built on demand to do the things wrappers are used for + now (cgi, post-commit, etc). +* Potentially much faster. One problem with the now very modular ikiwiki is + that it has to load up dozens of perl modules each time it runs, which + means both opening lots of files and evaluating them. A haskell version + could run from one pre-compiled file. Other speed efficienies are also + likely with haskell. For example, pandoc is apparently an order of + magnitude faster than perl markdown implementations. +* Many plugins could be written in pure functional code, with no side + effects. Not all of them, of course. +* It should be much easier to get ikiwiki to support parallel compilation + on multi-core systems using haskell. +* A rewrite would be an opportunity to utterly break compatability and + redo things based on experience. Since the haskell libraries used for + markdown, templates, etc, are unlikely to be very compatable with the perl + versions, and since perl plugins obviously wouldn't work, and perl setup + files wouldn't be practical to keep, a lot of things would unavoidably + change, and at that point changinge everything else I can think of + probably wouldn't hurt (much). + + - Re templates, it would be nice to have a template library that + doesn't use html-ish templating tags, since those are hard for users to + edit in html editors currently. + - This would be a chance to make WikiLinks with link texts read + "the right way round" (ie, vaguely wiki creole compatably). + - The data structures would probably be quite different. + - I might want to drop a lot of the command-line flags, either + requiring a setup file be used for those things, or leaving the + general-purpose `--set var=value` flag. + - Sometimes the current behavior of `--setup` seems confusing; it might + only cause a setup file to be read, and not force rebuild mode. + - Hard to say how the very high level plugin interface design would change, + but at the least some of the names of hooks could stand a rename, and + their parameter passing cleaned up. + +We know that a big, break-the-world rewrite like this can be a very +bad thing for a project to attempt. It would be possible to support +external plugins written in haskell today, without any rewrite; and a few +of the benefits could be obtained by, eg, making the mdwn plugin be a +haskell program that uses pandoc. I doubt that wouod be a good first step +to converting ikiwiki to haskell, because such a program would have very +different data structures and intercommuniucation than a pure haskell +version. + +Some other things to be scared about: + +* By picking perl, I made a lot of people annoyed (and probably turned + several people away from using ikiwiki). But over time there turned out + to be a lot of folks who knew perl already (even if rustily), and made + some *very* useful contributions. I doubt there's as large a pool of haskell + programmers, and it's probably harder for a python user to learn haskell + than perl if they want to contribute to ikiwiki. +* It might be harder for users of hosting services to install a haskell based + ikiwiki than the perl version. Such systems probably don't have ghc and + a bunch of haskell libraries. OTOH, it might be possible to build a + static binary at home and upload it, thus avoiding a messy installation + procedure entirely. +* I can barely code in haskell yet. I'm probably about 100x faster at + programming in perl. I need to get some more practical experience before + I´m fast and seasoned enough in haskell to attempt such a project. + (And so far, progress at learning has been slow and I have not managed + to write anything serious in haskell.) --[[Joey]] diff --git a/doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn b/doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn new file mode 100644 index 000000000..1edebe4e8 --- /dev/null +++ b/doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn @@ -0,0 +1,14 @@ +Ok, I have to admit, I have no idea if this is an April fool's joke or not. +Congratulations for demonstrating that April fools jokes can still be subtle +(whether intentionally or not!) -- [[Jon]] + +> Having said all that, have you looked at erlang? Have you heard of couchdb? +> I'd strongly recommend looking at that. -- [[Jon]] + +>> I've glanced at couchdb, but don't see how it would tie in with ikiwiki. +>> --[[Joey]] + + +>>> It doesn't really. I recently (re-)read about couchdb and thought that +>>> what it was trying to do had some comparisons with the thinking going on +>>> in [[todo/structured_page_data]]. -- [[Jon]] diff --git a/doc/todo/source_link.mdwn b/doc/todo/source_link.mdwn index 93791c81a..b051361a8 100644 --- a/doc/todo/source_link.mdwn +++ b/doc/todo/source_link.mdwn @@ -1,6 +1,6 @@ How about a direct link from the page header to the source of the latest version, to avoid the need to either use edit or navigate to the current version via the history link? - I'd like this too (and might try to implement it). -- [[jondowland]] + I'd like this too (and might try to implement it). -- [[users/jon]] I just implemented this. There is one [[patch]] to the default page template, and a new plugin. -- [[Will]] @@ -31,13 +31,13 @@ I just implemented this. There is one [[patch]] to the default page template, a use IkiWiki; use open qw{:utf8 :std}; - sub import { #{{{ + sub import { hook(type => "getsetup", id => "getsource", call => \&getsetup); hook(type => "pagetemplate", id => "getsource", call => \&pagetemplate); hook(type => "sessioncgi", id => "getsource", call => \&cgi_getsource); - } # }}} + } - sub getsetup () { #{{{ + sub getsetup () { return plugin => { safe => 1, @@ -50,9 +50,9 @@ I just implemented this. There is one [[patch]] to the default page template, a safe => 1, rebuild => 0, }, - } #}}} + } - sub pagetemplate (@) { #{{{ + sub pagetemplate (@) { my %params=@_; my $page=$params{page}; @@ -62,9 +62,9 @@ I just implemented this. There is one [[patch]] to the default page template, a $template->param(getsourceurl => IkiWiki::cgiurl(do => "getsource", page => $page)); $template->param(have_actions => 1); } - } # }}} + } - sub cgi_getsource ($$) { #{{{ + sub cgi_getsource ($$) { my $cgi=shift; my $session=shift; diff --git a/doc/todo/structured_page_data.mdwn b/doc/todo/structured_page_data.mdwn index 2a196ed23..22f67cc0a 100644 --- a/doc/todo/structured_page_data.mdwn +++ b/doc/todo/structured_page_data.mdwn @@ -257,21 +257,21 @@ in a large number of other cases. use CGI::FormBuilder; use IkiWiki 2.00; - sub import { #{{{ + sub import { hook(type => "getsetup", id => "form", call => \&getsetup); hook(type => "htmlize", id => "form", call => \&htmlize); hook(type => "sessioncgi", id => "form", call => \&cgi_submit); - } # }}} + } - sub getsetup () { #{{{ + sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, - } #}}} + } - sub makeFormFromYAML ($$$) { #{{{ + sub makeFormFromYAML ($$$) { my $page = shift; my $YAMLString = shift; my $q = shift; @@ -350,9 +350,9 @@ in a large number of other cases. # IkiWiki::decode_form_utf8($form); return $form; - } #}}} + } - sub htmlize (@) { #{{{ + sub htmlize (@) { my %params=@_; my $content = $params{content}; my $page = $params{page}; @@ -360,9 +360,9 @@ in a large number of other cases. my $form = makeFormFromYAML($page, $content, undef); return $form->render(submit => 'Update Form'); - } # }}} + } - sub cgi_submit ($$) { #{{{ + sub cgi_submit ($$) { my $q=shift; my $session=shift; @@ -425,11 +425,11 @@ in a large number of other cases. } exit; - } #}}} + } package IkiWiki::PageSpec; - sub match_form_eq ($$;@) { #{{{ + sub match_form_eq ($$;@) { my $page=shift; my $argSet=shift; my @args=split(/,/, $argSet); @@ -460,7 +460,7 @@ in a large number of other cases. } else { return IkiWiki::FailReason->new("field value does not match"); } - } #}}} + } 1 @@ -476,22 +476,22 @@ in a large number of other cases. my $inTable = 0; - sub import { #{{{ + sub import { hook(type => "getsetup", id => "data", call => \&getsetup); hook(type => "needsbuild", id => "data", call => \&needsbuild); hook(type => "preprocess", id => "data", call => \&preprocess, scan => 1); hook(type => "preprocess", id => "datatable", call => \&preprocess_table, scan => 1); # does this need scan? - } # }}} + } - sub getsetup () { #{{{ + sub getsetup () { return plugin => { safe => 1, rebuild => 1, # format plugin }, - } #}}} + } - sub needsbuild (@) { #{{{ + sub needsbuild (@) { my $needsbuild=shift; foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{data}) { @@ -506,7 +506,7 @@ in a large number of other cases. } } - sub preprocess (@) { #{{{ + sub preprocess (@) { my @argslist = @_; my %params=@argslist; @@ -546,9 +546,9 @@ in a large number of other cases. } return $html; - } # }}} + } - sub preprocess_table (@) { #{{{ + sub preprocess_table (@) { my %params=@_; my @lines; @@ -568,11 +568,11 @@ in a large number of other cases. push @lines, ''; return join("\n", @lines); - } #}}} + } package IkiWiki::PageSpec; - sub match_data_eq ($$;@) { #{{{ + sub match_data_eq ($$;@) { my $page=shift; my $argSet=shift; my @args=split(/,/, $argSet); @@ -592,9 +592,9 @@ in a large number of other cases. } else { return IkiWiki::FailReason->new("value does not match"); } - } #}}} + } - sub match_data_link ($$;@) { #{{{ + sub match_data_link ($$;@) { my $page=shift; my $argSet=shift; my @params=@_; @@ -618,6 +618,6 @@ in a large number of other cases. } return IkiWiki::FailReason->new("No data link on page $page with key $key matches glob $value"); - } #}}} + } 1 diff --git a/doc/todo/support_creole_markup.mdwn b/doc/todo/support_creole_markup.mdwn index b0ebf5b9e..5a1e1286d 100644 --- a/doc/todo/support_creole_markup.mdwn +++ b/doc/todo/support_creole_markup.mdwn @@ -12,7 +12,7 @@ And there is a perl module: Text::WikiCreole Syntax file for vim: http://www.peter-hoffmann.com/code/vim/ (Since a typical ikiwiki user usually use external editors. :)) -> Should be pretty easy to add a plugin to do it using [[cpan +> Should be pretty easy to add a plugin to do it using [[!cpan > Text::WikiCreole]]. --[[Joey]] [[done]] diff --git a/doc/todo/supporting_comments_via_disussion_pages.mdwn b/doc/todo/supporting_comments_via_disussion_pages.mdwn index e0495c8c2..aae0b3008 100644 --- a/doc/todo/supporting_comments_via_disussion_pages.mdwn +++ b/doc/todo/supporting_comments_via_disussion_pages.mdwn @@ -91,14 +91,14 @@ Each comment is processed to something like this: use strict; use IkiWiki '1.02'; - sub import { #{{{ + sub import { hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup); hook(type => "preprocess", id => "blogcomment", call => \&preprocess); - } # }}} + } - sub formbuilder_setup (@) { #{{{ + sub formbuilder_setup (@) { my %params=@_; my $cgi = $params{cgi}; my $form = $params{form}; @@ -138,9 +138,9 @@ Each comment is processed to something like this: $content.=qq{[[!blogcomment from="""$name""" timestamp="""$timestamp""" subject="""$subject""" text="""$comment"""]]\n\n}; $content=~s/\n/\r\n/g; $form->field(name => "editcontent", value => $content, force => 1); - } # }}} + } - sub preprocess (@) { #{{{ + sub preprocess (@) { my %params=@_; my ($text, $date, $from, $subject, $r); @@ -159,7 +159,7 @@ Each comment is processed to something like this: $r .= "\n" . $text . "\n"; return $r; - } # }}} + } 1; @@ -213,3 +213,8 @@ do you think so far? Known issues include: un-wikiish). --[[smcv]] + +I've updated smcvpostcomment and publicised it as [[plugins/contrib/comments]]. --[[smcv]] + +> While there is still room for improvement and entirely other approaches, +> I am calling this done since smcv's comments plugin is ready. --[[Joey]] diff --git a/doc/todo/syntax_highlighting.mdwn b/doc/todo/syntax_highlighting.mdwn new file mode 100644 index 000000000..b5d083ba5 --- /dev/null +++ b/doc/todo/syntax_highlighting.mdwn @@ -0,0 +1,133 @@ +There's been a lot of work on contrib syntax highlighting plugins. One should be +picked and added to ikiwiki core. + +Ideally, it should support both converting whole source files into wiki +pages, as well as doing syntax highlighting as a preprocessor directive +(which is either passed the text, or reads it from a file). + +## The big list of possibilities + +* [[plugins/contrib/highlightcode]] uses [[!cpan Syntax::Highlight::Engine::Kate]], + operates on whole source files only, has a few bugs (see + [here](http://u32.net/Highlight_Code_Plugin/), and needs to be updated to + support [[bugs/multiple_pages_with_same_name]]. +* [[!cpan IkiWiki-Plugin-syntax]] only operates as a directive. + Interestingly, it supports multiple highlighting backends, including Kate + and Vim. +* [[plugins/contrib/syntax]] only operates as a directive + ([[not_on_source_code_files|automatic_use_of_syntax_plugin_on_source_code_files]]), + and uses [[!cpan Text::VimColor]]. +* [[plugins/contrib/sourcehighlight]] uses src-highlight, and operates on + whole source files only. Needs to be updated to + support [[bugs/multiple_pages_with_same_name]]. +* [[sourcecode|todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion]] + also uses src-highlight, and operates on whole source files. + Updated to work with the fix for [[bugs/multiple_pages_with_same_name]]. Untested with files with no extension, e.g. `Makefile`. +* [[users/jasonblevins]]'s code plugin uses src-highlight, and supports both + while file and directive use. + +* [hlsimple](http://pivot.cs.unb.ca/git/?p=ikiplugins.git;a=blob_plain;f=IkiWiki/Plugin/hlsimple.pm;hb=HEAD) is a wrapper for the the perl module Syntax::Highlight::Engine::Simple. This is pure perl, pretty simple, uses css. It ought to be pretty fast (according to the author, and just because it is not external). +On the other hand, there are not many predefined languages yet. Defining language syntaxes is about as much +work as source-highlight, but in perl. I plan to package the base module for debian. Perhaps after the author +releases the 5 or 6 language definitions he has running on his web site, it might be suitable for inclusion in ikiwiki. [[DavidBremner]] + +## General problems + +* Using non-perl syntax highlighting backends is slow. I'd prefer either + using a perl module, or a multiple-backend solution that can use a perl + module as one option. (Or, if there's a great highlighter python module, + we could use an external plugin..) +* Currently no single plugin supports both modes of operation (directive + and whole source file to page). + + > This is now fixed by the [[ikiwiki/directive/format]] directive for all + > whole-source-file plugins, right? + +* Nothing seems to support + [[wiki-formatted_comments|wiki-formatted_comments_with_syntax_plugin]] + inside source files. Doing this probably means post-processing the + results of the highlighting engine, to find places where it's highlighted + comments, and then running them through the ikiwiki rendering pipeline. + This seems fairly doable with [[!cpan Syntax::Highlight::Engine::Kate]], + at least. +* The whole-file plugins tend to have a problem that things that look like + wikilinks in the source code get munged into links by ikiwiki, which can + have confusing results. Similar problem with preprocessor directives. + One approach that's also been requested for eg, + [[plugins/contrib/mediawiki]] is to allow controlling which linkification + types a page type can have on it. + + > The previous two points seem to be related. One thought: instead of + > getting the source from the `content` parameter, the plugin could + > re-load the page source. That would stop directives/links from + > being processed in the source. As noted above, comments + > could then be parsed for directives/links later. + > + > Would it be worth adding a `nodirectives` option when registering + > an htmlize hook that switches off directive and link processing before + > generating the html for a page? + +* The whole-file plugins all get confused if there is a `foo.c` and a `foo.h`. + This is trivially fixable now by passing the keepextension option when + registering the htmlize hooks, though. +* Whole-file plugins register a bunch of htmlize hooks. The wacky thing + about it is that, when creating a new page, you can then pick "c" or + "h" or "pl" etc from the dropdown that normally has "mdwn" etc in it. + Is this a bug, or a feature? (Even if a feature, plugins with many + extensions make the dropdown unusable.. One way to deal with that is have + a config setting that lists what extensions to offer highlighting for. + Most people won't need/want the dozens some engines support.) +* The per page highlighters can't handle creating wiki pages from + "Makefile", or other files without a significant extension. + Not clear how to fix this, as ikiwiki is very oriented toward file + extensions. The workaround is to use a directive on a wiki page, pulling + in the Makefile. + + > I wonder how hard it would be to make a patch whereby a file with + > no `.` in the name, and a name that matches a filetype, and where + > that filetype was registered `keepextension`, then the file is just + > chosen as the appropriate type. This would allow `Makefile` to + > work. + +like this: + + diff --git a/IkiWiki.pm b/IkiWiki.pm + index 8d728c9..1bd46a9 100644 + --- a/IkiWiki.pm + +++ b/IkiWiki.pm + @@ -618,6 +618,8 @@ sub pagetype ($) { + + if ($page =~ /\.([^.]+)$/) { + return $1 if exists $hooks{htmlize}{$1}; + + } elsif ($hooks{htmlize}{$page}{keepextension}) { + + return $page; + } + return; + } + +## format directive + +Rather than making syntax highlight plugins have to provide a preprocessor +directive as well as handling whole source files, perhaps a generic format +directive could be used: + + \[[!format pl """..."""]] + +That would run the text through the pl htmlizer, from the syntax hightligh +plugin. OTOH, if "rst" were given, it would run the text through the rst +htmlizer. So, more generic, allows mixing different types of markup on one +page, as well as syntax highlighting. Does require specifying the type of +format, instead of allowing it to be guessed (which some syntax highlighters +can do). (This directive is now implemented..) + +Hmm, this would also allow comments inside source files to have mdwn +embedded in them, without making the use of mdwn a special case, or needing +to postprocess the syntax highlighter output to find comments. + + /* \[[!format mdwn """ + + This is a comment in my C file. You can use mdwn in here. + + """]] */ + +Note that this assumes that directives are expanded in source files. diff --git a/doc/todo/syntax_highlighting/discussion.mdwn b/doc/todo/syntax_highlighting/discussion.mdwn new file mode 100644 index 000000000..7a4095c65 --- /dev/null +++ b/doc/todo/syntax_highlighting/discussion.mdwn @@ -0,0 +1,26 @@ +sourcehighlight is annoyingly slow, but it does support wiki directives +in comments. See [here](http://www.cs.unb.ca/~bremner/teaching/java_examples/snippet/ListMerge/) +for an example (tags). + +> I think that is just a result of it expanding directives, and wikilinks, +> everywhere in the file, which is generally a possible problem.. +> --[[Joey]] + +* * * * * + +I think having the option to choose source code page types from the +dropdown list is definitely a feature. This gives users an easy way +to contribute programs (say `.pl` files) or code snippets (like, for +example, the Elisp area of the EmacsWiki). Actually, would there any +other way to create a `.pl` file without write access to the +repository? --[[JasonBlevins]] + +> Well, you can upload them as an attachment if the wiki is configured to +> allow it. Having them in the drop down becomes a problem when there are +> so many wacky extensions in there that you can't find anything. +> --[[Joey]] + +>> I should just note that the +>> [[sourcecode|todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion]] +>> plugin only adds the file extensions listed in the config. This shouldn't cause +>> massive drop-down menu pollution. -- [[Will]] diff --git a/doc/todo/tag_pagespec_function.mdwn b/doc/todo/tag_pagespec_function.mdwn new file mode 100644 index 000000000..681a1f661 --- /dev/null +++ b/doc/todo/tag_pagespec_function.mdwn @@ -0,0 +1,34 @@ +Implementing tags in terms of links is clever, but it would be nice if it was +opaque in both directions: tagging and matching tags. Writing pagespecs to +find out which pages are tagged with a given name means that the pagespec is +tied to whatever the tagbase is. + +This patch adds a pagespec function 'tag' which lets you write pagespecs to +match tagged pages independent of whatever the tagbase is set to. + + -- [[users/Jon]] 2009/02/17 + +> So, this looks good, appreciate the patch. +> +> The only problem I see is it could be confusing if `tag(foo)` matched +> a page that just linked to the tag via a wikilink, w/o actually tagging it. +> +> One other thing, perhaps it should be called `tagged()`? --[[Joey]] + +[[!tag patch done]] + + --- a/plugins/IkiWiki/Plugin/tag.pm 2009-02-16 11:30:11.000000000 +0000 + +++ b/plugins/IkiWiki/Plugin/tag.pm 2009-02-17 15:40:03.000000000 +0000 + @@ -125,4 +125,12 @@ + } + } + + +package IkiWiki::PageSpec; + + + +sub match_tag ($$;@) { + + my $page = shift; + + my $glob = shift; + + return match_link($page, IkiWiki::Plugin::tag::tagpage($glob)); + +} + + + 1 diff --git a/doc/todo/tidy_git__39__s_ctime_debug_output.mdwn b/doc/todo/tidy_git__39__s_ctime_debug_output.mdwn index aaa040ec7..bfc130d69 100644 --- a/doc/todo/tidy_git__39__s_ctime_debug_output.mdwn +++ b/doc/todo/tidy_git__39__s_ctime_debug_output.mdwn @@ -10,6 +10,6 @@ + debug("ctime for '$file': ". localtime($ctime)); return $ctime; - } #}}} + } [[!tag patch done]] diff --git a/doc/todo/tla.mdwn b/doc/todo/tla.mdwn index 6ef8453f1..b6b082cfe 100644 --- a/doc/todo/tla.mdwn +++ b/doc/todo/tla.mdwn @@ -1,4 +1,7 @@ * Need to get post commit hook code working. * Need some example urls for web based diffs. +* `rcs_commit_staged`, `rcs_rename`, `rcs_remove`, are not + implemented for tla, and so attachments, remove and rename plugins + cannot be used with it. (These should be fairly easy to add..) [[!tag rcs/tla]] diff --git a/doc/todo/tmplvars_plugin.mdwn b/doc/todo/tmplvars_plugin.mdwn index f7d06a579..644cf23aa 100644 --- a/doc/todo/tmplvars_plugin.mdwn +++ b/doc/todo/tmplvars_plugin.mdwn @@ -11,12 +11,12 @@ A simple plugin to allow per-page customization of a template by passing paramat my %tmplvars; - sub import { #{{{ + sub import { hook(type => "preprocess", id => "tmplvars", call => \&preprocess); hook(type => "pagetemplate", id => "tmplvars", call => \&pagetemplate); - } # }}} + } - sub preprocess (@) { #{{{ + sub preprocess (@) { my %params=@_; if ($params{page} eq $params{destpage}) { @@ -34,9 +34,9 @@ A simple plugin to allow per-page customization of a template by passing paramat } } - } # }}} + } - sub pagetemplate (@) { #{{{ + sub pagetemplate (@) { my %params=@_; my $template = $params{template}; @@ -47,6 +47,6 @@ A simple plugin to allow per-page customization of a template by passing paramat } return undef; - } # }}} + } 1 diff --git a/doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn b/doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn new file mode 100644 index 000000000..547c7a80a --- /dev/null +++ b/doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn @@ -0,0 +1,3 @@ +It would be nice if the [[plugins/toc]] plugin let you specify a header level "ceiling" above which (or above and including which) the headers would not be incorporated into the toc. + +Currently, the levels=X parameter lets you tweak how deep it will go for small headers, but I'd like to chop off the h1's (as I use them for my page title) -- [[Jon]] diff --git a/doc/todo/tracking_bugs_with_dependencies.mdwn b/doc/todo/tracking_bugs_with_dependencies.mdwn index 3af0458bd..2832e37aa 100644 --- a/doc/todo/tracking_bugs_with_dependencies.mdwn +++ b/doc/todo/tracking_bugs_with_dependencies.mdwn @@ -194,9 +194,9 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W index 4e4da11..8b3cdfe 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm - @@ -1550,7 +1550,16 @@ sub globlist_to_pagespec ($) { #{{{ + @@ -1550,7 +1550,16 @@ sub globlist_to_pagespec ($) { - sub is_globlist ($) { #{{{ + sub is_globlist ($) { my $s=shift; - return ( $s =~ /[^\s]+\s+([^\s]+)/ && $1 ne "and" && $1 ne "or" ); + return ! ($s =~ / @@ -209,19 +209,19 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W + ) | + (\s and \s) | (\s or \s) # or we find 'and' or 'or' somewhere + /xs); - } #}}} + } - sub safequote ($) { #{{{ - @@ -1631,7 +1640,7 @@ sub pagespec_merge ($$) { #{{{ + sub safequote ($) { + @@ -1631,7 +1640,7 @@ sub pagespec_merge ($$) { return "($a) or ($b)"; - } #}}} + } - -sub pagespec_translate ($) { #{{{ - +sub pagespec_makeperl ($) { #{{{ + -sub pagespec_translate ($) { + +sub pagespec_makeperl ($) { my $spec=shift; # Support for old-style GlobLists. - @@ -1650,12 +1659,14 @@ sub pagespec_translate ($) { #{{{ + @@ -1650,12 +1659,14 @@ sub pagespec_translate ($) { | \) # ) | @@ -238,7 +238,7 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W my $word=$1; if (lc $word eq 'and') { $code.=' &&'; - @@ -1666,16 +1677,23 @@ sub pagespec_translate ($) { #{{{ + @@ -1666,16 +1677,23 @@ sub pagespec_translate ($) { elsif ($word eq "(" || $word eq ")" || $word eq "!") { $code.=' '.$word; } @@ -265,14 +265,14 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W } } - @@ -1683,8 +1701,18 @@ sub pagespec_translate ($) { #{{{ + @@ -1683,8 +1701,18 @@ sub pagespec_translate ($) { $code=0; } + return 'sub { my $page=shift; my %params = @_; '.$code.' }'; - +} #}}} + +} + - +sub pagespec_translate ($) { #{{{ + +sub pagespec_translate ($) { + my $spec=shift; + + my $code = pagespec_makeperl($spec); @@ -282,19 +282,19 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W no warnings; - return eval 'sub { my $page=shift; '.$code.' }'; + return eval $code; - } #}}} + } - sub pagespec_match ($$;@) { #{{{ - @@ -1699,7 +1727,7 @@ sub pagespec_match ($$;@) { #{{{ + sub pagespec_match ($$;@) { + @@ -1699,7 +1727,7 @@ sub pagespec_match ($$;@) { my $sub=pagespec_translate($spec); return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") if $@; - return $sub->($page, @params); + return $sub->($page, @params, specFuncs => {}); - } #}}} + } - sub pagespec_valid ($) { #{{{ - @@ -1748,11 +1776,78 @@ sub new { #{{{ + sub pagespec_valid ($) { + @@ -1748,11 +1776,78 @@ sub new { package IkiWiki::PageSpec; @@ -361,7 +361,7 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W + } +} + - sub match_glob ($$;@) { #{{{ + sub match_glob ($$;@) { my $page=shift; my $glob=shift; my %params=@_; @@ -373,9 +373,9 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W my $from=exists $params{location} ? $params{location} : ''; # relative matching - @@ -1782,11 +1877,12 @@ sub match_internal ($$;@) { #{{{ + @@ -1782,11 +1877,12 @@ sub match_internal ($$;@) { - sub match_link ($$;@) { #{{{ + sub match_link ($$;@) { my $page=shift; - my $link=lc(shift); + my $fulllink=shift; @@ -388,7 +388,7 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W # relative matching if ($link =~ m!^\.! && defined $from) { $from=~s#/?[^/]+$##; - @@ -1804,19 +1900,32 @@ sub match_link ($$;@) { #{{{ + @@ -1804,19 +1900,32 @@ sub match_link ($$;@) { } else { return IkiWiki::SuccessReason->new("$page links to page $p matching $link") @@ -397,9 +397,9 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W } } return IkiWiki::FailReason->new("$page does not link to $link"); - } #}}} + } - sub match_backlink ($$;@) { #{{{ + sub match_backlink ($$;@) { - return match_link($_[1], $_[0], @_); + my $page=shift; + my $backlink=shift; @@ -410,9 +410,9 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W + } + + return match_link($backlink, $page, @params); - } #}}} + } - sub match_created_before ($$;@) { #{{{ + sub match_created_before ($$;@) { my $page=shift; my $testpage=shift; + my @params=@_; @@ -423,8 +423,8 @@ account all comments above (which doesn't mean it is above reproach :) ). --[[W if (exists $IkiWiki::pagectime{$testpage}) { if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) { - @@ -1834,6 +1943,11 @@ sub match_created_before ($$;@) { #{{{ - sub match_created_after ($$;@) { #{{{ + @@ -1834,6 +1943,11 @@ sub match_created_before ($$;@) { + sub match_created_after ($$;@) { my $page=shift; my $testpage=shift; + my @params=@_; diff --git a/doc/todo/turn_edittemplate_verbosity_off_by_default.mdwn b/doc/todo/turn_edittemplate_verbosity_off_by_default.mdwn index 87e55685c..14bb43782 100644 --- a/doc/todo/turn_edittemplate_verbosity_off_by_default.mdwn +++ b/doc/todo/turn_edittemplate_verbosity_off_by_default.mdwn @@ -8,7 +8,7 @@ I think this (untested) patch might just do the trick: --- a/IkiWiki/Plugin/edittemplate.pm +++ b/IkiWiki/Plugin/edittemplate.pm - @@ -46,8 +46,13 @@ sub preprocess (@) { #{{{ + @@ -46,8 +46,13 @@ sub preprocess (@) { $pagestate{$params{page}}{edittemplate}{$params{match}}=$params{template}; @@ -21,9 +21,9 @@ I think this (untested) patch might just do the trick: + else { + return ''; + } - } # }}} + } - sub formbuilder (@) { #{{{ + sub formbuilder (@) { --[[madduck]] diff --git a/doc/todo/using_meta_titles_for_parentlinks.html b/doc/todo/using_meta_titles_for_parentlinks.html deleted file mode 100644 index 651b7fa0f..000000000 --- a/doc/todo/using_meta_titles_for_parentlinks.html +++ /dev/null @@ -1,116 +0,0 @@ -It is possible to set a Page-Title in the meta-plugin, but that one isn't -reused in parentlinks. This [[patch]] may fix it. - -
    -
  • I give pagetitle the full path to a page. -
  • I redefine the 'pagetitle'-sub to deal with it. -
  • to maintain compatibility for IkiWikis without the meta-plugin, i added a 'basename' to the Original-pagetitle. -
- -
-diff -c /usr/share/perl5/IkiWiki/Render.pm.distrib /usr/share/perl5/IkiWiki/Render.pm
-*** /usr/share/perl5/IkiWiki/Render.pm.distrib  Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Render.pm  Tue Aug 26 23:29:32 2008
-***************
-*** 102,108 ****
-        $template->param(
-                title => $page eq 'index' 
-                        ? $config{wikiname} 
-!                       : pagetitle(basename($page)),
-                wikiname => $config{wikiname},
-                content => $content,
-                backlinks => $backlinks,
---- 102,108 ----
-        $template->param(
-                title => $page eq 'index' 
-                        ? $config{wikiname} 
-!                       : pagetitle($page),
-                wikiname => $config{wikiname},
-                content => $content,
-                backlinks => $backlinks,
-
-diff -c /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm
-*** /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib      Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm      Tue Aug 26 23:19:43 2008
-***************
-*** 44,50 ****
-                        "height_$height" => 1,
-                };
-                $path.="/".$dir;
-!               $title=IkiWiki::pagetitle($dir);
-                $i++;
-        }
-        return @ret;
---- 44,50 ----
-                        "height_$height" => 1,
-                };
-                $path.="/".$dir;
-!               $title=IkiWiki::pagetitle($path);
-                $i++;
-        }
-        return @ret;
-
-diff -c /usr/share/perl5/IkiWiki.pm.distrib /usr/share/perl5/IkiWiki.pm
-*** /usr/share/perl5/IkiWiki.pm.distrib Wed Aug  6 07:48:34 2008
---- /usr/share/perl5/IkiWiki.pm Tue Aug 26 23:47:30 2008
-***************
-*** 792,797 ****
---- 792,799 ----
-        my $page=shift;
-        my $unescaped=shift;
-  
-+       $page=basename($page);
-+ 
-        if ($unescaped) {
-                $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
-    	}
-
-diff -c /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib /usr/share/perl5/IkiWiki/Plugin/meta.pm
-*** /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib     Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Plugin/meta.pm     Tue Aug 26 23:30:58 2008
-***************
-*** 3,8 ****
---- 3,9 ----
-  package IkiWiki::Plugin::meta;
-  
-  use warnings;
-+ no warnings 'redefine';
-  use strict;
-  use IkiWiki 2.00;
-  
-***************
-*** 289,294 ****
---- 290,319 ----
-        }
-  } #}}}
-  
-+ sub IkiWiki::pagetitle ($;$) { #{{{
-+       my $page=shift;
-+       my $unescaped=shift;
-+ 
-+       if ($page =~ m#/#) {
-+               $page =~ s#^/##;
-+               $page =~ s#/index$##;
-+               if ($pagestate{"$page/index"}{meta}{title}) {
-+                       $page = $pagestate{"$page/index"}{meta}{title};
-+               } else {
-+                       $page = IkiWiki::basename($page);
-+               }
-+       }
-+ 
-+       if ($unescaped) {
-+               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
-+       }
-+       else {
-+               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : "&#$2;"/eg;
-+       }
-+ 
-+       return $page;
-+ } #}}}
-+ 
-  package IkiWiki::PageSpec;
-  
-  sub match_title ($$;@) { #{{{
-
-
-
diff --git a/doc/todo/varioki_--_add_template_variables___40__with_closures_for_values__41___in_ikiwiki.setup.mdwn b/doc/todo/varioki_--_add_template_variables___40__with_closures_for_values__41___in_ikiwiki.setup.mdwn index 492a32b36..b28469993 100644 --- a/doc/todo/varioki_--_add_template_variables___40__with_closures_for_values__41___in_ikiwiki.setup.mdwn +++ b/doc/todo/varioki_--_add_template_variables___40__with_closures_for_values__41___in_ikiwiki.setup.mdwn @@ -157,9 +157,9 @@ ManojSrivastava +=cut + + -+sub import { #{{{ ++sub import { + hook(type => "pagetemplate", id => "varioki", call => \&pagetemplate); -+} # }}} ++} + + +=pod @@ -175,7 +175,7 @@ ManojSrivastava + +=cut + -+sub pagetemplate (@) { #{{{ ++sub pagetemplate (@) { + my %params=@_; + my $page=$params{page}; + my $template=$params{template}; @@ -207,7 +207,7 @@ ManojSrivastava + $template->param("$var" =>"$value"); + } + } -+} # }}} ++} + +1; + diff --git a/doc/todo/wiki-formatted_comments_with_syntax_plugin.mdwn b/doc/todo/wiki-formatted_comments_with_syntax_plugin.mdwn index 08ca61b0c..a5244c9ef 100644 --- a/doc/todo/wiki-formatted_comments_with_syntax_plugin.mdwn +++ b/doc/todo/wiki-formatted_comments_with_syntax_plugin.mdwn @@ -1 +1,4 @@ -[[Wishlist]] item: I'd love to see the ability to optionally switch back to wiki syntax within the comments of code pretty-printed with the [[plugins/contrib/syntax]] plugin. This would allow the use of links and formatting in comments. +[[Wishlist]] item: I'd love to see the ability to optionally switch back to +wiki syntax within the comments of code pretty-printed with the +[[plugins/contrib/syntax]] plugin. This would allow the use of links and +formatting in comments. diff --git a/doc/todo/wikiwyg.mdwn b/doc/todo/wikiwyg.mdwn index e3d1b3927..839986c7b 100644 --- a/doc/todo/wikiwyg.mdwn +++ b/doc/todo/wikiwyg.mdwn @@ -57,3 +57,8 @@ The plugin can be downloaded from * Personalized settings [Wikiwyg]: http://www.wikiwyg.net/ + +> As noted in [[discussion]], the url above doesn't work, and I stupidly +> lost my copy of this before merging it. I hope that this plugin will turn +> back up. In the meantime, there is a wmd plugin that accomplishes the +> same basic task of WSYWIG markdown editing. --[[Joey]] diff --git a/doc/usage.mdwn b/doc/usage.mdwn index b6af75ac8..0c618de5c 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -6,7 +6,7 @@ ikiwiki - a wiki compiler ikiwiki [options] source destination -ikiwiki --setup configfile +ikiwiki --setup setupfile # DESCRIPTION @@ -30,19 +30,19 @@ These options control the mode that ikiwiki operates in. Force a rebuild of all pages. -* --setup configfile +* --setup setupfile In setup mode, ikiwiki reads the config file, which is really a perl program that can call ikiwiki internal functions. The default action when --setup is specified is to automatically generate - wrappers for a wiki based on data in a config file, and rebuild the wiki. + wrappers for a wiki based on data in a setup file, and rebuild the wiki. If you only want to build any changed pages, you can use --refresh with --setup. -* --dumpsetup configfile +* --dumpsetup setupfile - Causes ikiwiki to write to the specified config file, dumping out + Causes ikiwiki to write to the specified setup file, dumping out its current configuration. * --wrappers @@ -103,13 +103,14 @@ These options control the mode that ikiwiki operates in. # CONFIG OPTIONS These options configure the wiki. Note that [[plugins]] can add additional -configuration options of their own. +configuration options of their own. All of these options and more besides can +also be configured using a setup file. -* --wikiname +* --wikiname name The name of the wiki, default is "wiki". -* --templatedir +* --templatedir dir Specify the directory that the page [[templates|wikitemplates]] are stored in. Default is `/usr/share/ikiwiki/templates`, or another location as configured at @@ -121,7 +122,7 @@ configuration options of their own. ikiwiki. Old versions of templates do not always work with new ikiwiki versions. -* --underlaydir +* --underlaydir dir Specify the directory that is used to underlay the source directory. Source files will be taken from here unless overridden by a file in the @@ -292,7 +293,7 @@ configuration options of their own. * --prefix-directives, --no-prefix-directives Toggle new '!'-prefixed syntax for preprocessor directives. ikiwiki currently - defaults to --no-prefix-directives. + defaults to --prefix-directives. * --w3mmode, --no-w3mmode @@ -307,19 +308,37 @@ configuration options of their own. * --getctime - Pull last changed time for each new page out of the revision control + Pull creation time for each new page out of the revision control system. This rarely used option provides a way to get the real creation times of items in weblogs, such as when building a wiki from a new - Subversion checkout. It is unoptimised and quite slow. It is best used + VCS checkout. It is unoptimised and quite slow. It is best used with --rebuild, to force ikiwiki to get the ctime for all pages. * --set var=value This allows setting an arbitrary configuration variable, the same as if it - were set via a configuration file. Since most options can be configured + were set via a setup file. Since most options can be configured using command-line switches, you will rarely need to use this, but it can be useful for the odd option that lacks a command-line switch. +# EXAMPLES + +* ikiwiki --setup my.setup + + Completly (re)build the wiki using the specified setup file. + +* ikiwiki --setup my.setup --refresh + + Refresh the wiki, using settings from my.setup, and avoid + rebuilding any pages that have not changed. This is faster. + +* ikiwiki --setup my.setup --refresh --wrappers + + Refresh the wiki, including regnerating all wrapper programs, + but do not rebuild all pages. Useful if you have changed something + in the setup file that does not need a full wiki rebuild to update + all pages, but that you want to immediatly take effect. + # ENVIRONMENT * CC diff --git a/doc/users/Edward_Betts.mdwn b/doc/users/Edward_Betts.mdwn index 0d4483fa8..b32927a1c 100644 --- a/doc/users/Edward_Betts.mdwn +++ b/doc/users/Edward_Betts.mdwn @@ -3,5 +3,7 @@ My watchlist: [[!inline archive="yes" sort="mtime" atom="yes" pages=" todo/allow_wiki_syntax_in_commit_messages* todo/shortcut_with_different_link_text* -todo/structured_page_data* "]] +todo/structured_page_data* +tips/convert_mediawiki_to_ikiwiki* +"]] diff --git a/doc/users/StevenBlack.mdwn b/doc/users/StevenBlack.mdwn new file mode 100644 index 000000000..ea7a6a97a --- /dev/null +++ b/doc/users/StevenBlack.mdwn @@ -0,0 +1,5 @@ +It feels like there are a lot of people named Steven Black. While I'm just one of many with my name, sometimes it is actually just me and I've forgotten that I had an account somewhere. + +I'm not a doctor, though I would certainly trust any doctor, dentist, or philosopher named Steven Black. (There are several.) + +I *am* a huge Ikiwiki fan. I've had my eye on it for many years for personal projects (though I never quite got around to installing it). Recently, however, I managed to convince my coworkers that it would be a good idea for an internal wiki. Boy was I right. The thing is practically designed to be the perfect developer-centered wiki. diff --git a/doc/users/ajt.mdwn b/doc/users/ajt.mdwn new file mode 100644 index 000000000..bc47040b6 --- /dev/null +++ b/doc/users/ajt.mdwn @@ -0,0 +1,20 @@ +[[!meta title="Adam Trickett"]] + +# Adam Trickett + +## "ajt" + +I'm a long time hacker of sorts, I like to program in Perl on Debian systems but work pays me to program in ABAP (COBOL) on SAP. + +I like wikis and I'm currently in love with ikiwiki, having moved my home intranet from a home made template solution to ikiwiki over a weekend. I'm using ikiwiki more like a web content management system (e.g. RedDot) rather than a traditional wiki. + +### My Links + +* [iredale dot net](http://www.iredale.net/) my web server and main blog +* [ajt](http://www.perlmonks.org/index.pl?node_id=113686) my Perkmonks home node +* [ajt](http://use.perl.org/~ajt) my use Perl home +* [ATRICKETT](http://search.cpan.org/~atrickett/) my CPAN folder +* [ajt](http://www.debian-administration.org/users/ajt) my Debian-Administration home (good site btw) +* [drajt](http://www.linkedin.com/in/drajt) my LinkedIn profile +* [drajt](http://www.slideshare.net/drajt) my "Slidespace" on SlideShare +* [AdamTrickett](http://www.hants.lug.org.uk/cgi-bin/wiki.pl?AdamTrickett) my wiki page on my LUG's site diff --git a/doc/users/alexander.mdwn b/doc/users/alexander.mdwn new file mode 100644 index 000000000..b2894a90c --- /dev/null +++ b/doc/users/alexander.mdwn @@ -0,0 +1 @@ +I use ikiwiki to organize information - projects, reading notes, outlines, todo lists, etc. diff --git a/doc/users/cfm.mdwn b/doc/users/cfm.mdwn new file mode 100644 index 000000000..4feab9601 --- /dev/null +++ b/doc/users/cfm.mdwn @@ -0,0 +1 @@ +I maintain a [home page](http://www.panix.com/~cfm/ "Cory Myers"). diff --git a/doc/users/hb/discussion.mdwn b/doc/users/hb/discussion.mdwn index 6dfa6a23b..15c065e45 100644 --- a/doc/users/hb/discussion.mdwn +++ b/doc/users/hb/discussion.mdwn @@ -1,4 +1,5 @@ I'd love to see any notes you have on using ikiwiki for GTD. Would you consider documenting them? Perhaps we could turn the result into a [[tip|tips]]. -[[JoshTriplett]] -> Well, certainly. Basically it's just inline + tag feature. I'm going to have more time in May for ikiwiki, I hope. \ No newline at end of file +> Well, certainly. Basically it's just inline + tag feature. I'm going to have more time in May for ikiwiki, I hope. +> > Any news about that ? diff --git a/doc/users/intrigeri.mdwn b/doc/users/intrigeri.mdwn index f9a216e18..8fa9965a5 100644 --- a/doc/users/intrigeri.mdwn +++ b/doc/users/intrigeri.mdwn @@ -1,4 +1,4 @@ intrigeri AT boum.org, already loving ikiwiki. * [gnupg key](http://gaffer.ptitcanardnoir.org/intrigeri/intrigeri.asc) -* Git repository ([gitweb](http://repo.or.cz/w/ikiwiki/intrigeri.git)) with various ikiwiki {feature, bugfix}-branches : `git://repo.or.cz/ikiwiki/intrigeri.git` +* Git repository with various ikiwiki {feature, bugfix}-branches : `git://gaffer.ptitcanardnoir.org/ikiwiki.git` diff --git a/doc/users/jasonblevins.mdwn b/doc/users/jasonblevins.mdwn index 52420f7c9..61c381d96 100644 --- a/doc/users/jasonblevins.mdwn +++ b/doc/users/jasonblevins.mdwn @@ -1,11 +1,109 @@ +[[!meta title="Jason Blevins"]] + I'm currently hosting a private ikiwiki for keeping research notes -which, with some patches and a (currently unreleased) plugin, will +which, with some patches and a plugin (below), will convert inline LaTeX expressions to MathML. I'm working towards a patchset and instructions for others to do the same. -There is one thing that needs to be decided first: whether or not to -include [[sanitization|todo/svg]] of MathML in htmlscrubber (and while -we're at it, why not SVG). +I've setup a test ikiwiki [here](http://xbeta.org/colab/) where I've +started keeping a few notes on my progress. There is an example of +inline SVG on the homepage (note that the logo scales along with the +font size). There are a few example mathematical expressions in the +[sandbox](http://xbeta.org/colab/sandbox/). The MathML is generated +automatically from inline LaTeX expressions using an experimental +plugin I'm working on. My (also MathML-enabled) homepage: (still using Blosxom...maybe one day I'll convert it to ikiwiki...) + +Current ikiwki issues of interest: + + * [[bugs/recentchanges_feed_links]] + * [[bugs/HTML_inlined_into_Atom_not_necessarily_well-formed]] + * [[plugins/toc/discussion]] + * [[todo/BibTeX]] + * [[todo/svg]] + * [[todo/Option_to_make_title_an_h1?]] + * [[bugs/SVG_files_not_recognized_as_images]] + +## Plugins + +These plugins are experimental. Use them at your own risk. Read the +perldoc documentation for more details. Patches and suggestions are +welcome. + + * [mdwn_itex][] - Works with the `mdwn` plugin to convert inline LaTeX + expressions to MathML using `itex2MML`. + + * [h1title][] - If present, use the leading level 1 Markdown header to + set the page title and remove it from the page body. + + * [code][] - Whole file and inline code snippet syntax highlighting + via GNU Source-highlight. The list of supported file extensions is + configurable. There is also some preliminary [documentation][code-doc]. + See the [FortranWiki](http://fortranwiki.org) for examples. + + * [metamail][] - a plugin for loading metadata from email-style + headers at top of a file (e.g., `title: Page Title` or + `date: November 2, 2008 11:14 EST`). + + * [pandoc][] - Markdown page processing via Pandoc. LaTeX and + reStructuredText are optional. + + * [path][] - Provides path-specific template conditionals such as + `IS_HOMEPAGE` and `IN_DIR_SUBDIR`. + + [mdwn_itex]: http://code.jblevins.org/ikiwiki/plugins.git/plain/mdwn_itex.pm + [h1title]: http://code.jblevins.org/ikiwiki/plugins.git/plain/h1title.pm + [code]: http://code.jblevins.org/ikiwiki/plugins.git/plain/code.pm + [code-doc]: http://code.jblevins.org/ikiwiki/plugins.git/plain/code.text + [metamail]: http://code.jblevins.org/ikiwiki/plugins.git/plain/metamail.pm + [pandoc]: http://code.jblevins.org/ikiwiki/plugins.git/plain/pandoc.pm + [path]: http://code.jblevins.org/ikiwiki/plugins.git/plain/path.pm + + +## MathML and SVG support + +So far, I've made some notes on sanitizing MathML and SVG via +htmlscrubber on the [[todo/svg]] todo item. + +I've also worked out some content-negotiation issues. First of all, +one needs to modify the default templates to use the +XHTML+MathML+SVG doctype (see e.g., this [patch][template-patch]). +For most browsers, the content type of the pages should be +`application/xhtml+xml`. The solution is easy if you want to +just send `application/xhtml+xml` to everybody: +just change the content type of `.html` files across the board. + +However, if you want to support browsers that don't accept +`application/xhtml+xml` (and those that will but say they +don't, such as IE with the MathPlayer plugin), then one +needs a `mod_rewrite` rule like the following: + + RewriteCond %{HTTP_ACCEPT} application\/xhtml\+xml [OR] + RewriteCond %{HTTP_USER_AGENT} (W3C.*Validator|MathPlayer) + RewriteRule \.html$ - [T=application/xhtml+xml] + +This solves the problem of MathML and inline SVG in static pages +but some additional work is required for dynamically generated +pages, like page previews, that are generated by `ikiwiki.cgi`. +We need to allow `ikiwiki.cgi` to set the content type dynamically +based on the `HTTP_CONTENT_TYPE` environment variable +(e.g., with the following [patch][cgi-patch]). Then, the following +rewrite rules can pass the correct content type to ikiwiki: + + RewriteCond %{HTTP_ACCEPT} application\/xhtml\+xml [OR] + RewriteCond %{HTTP_USER_AGENT} (W3C.*Validator|MathPlayer) + RewriteRule ikiwiki.cgi$ - [T=application/xhtml+xml] + +One final critical issue is that a production-ready setup needs to +implement some sort of on-the-fly error handling. If a user submits +an invalid LaTeX expression or SVG code (not malicious, just invalid) +and saves the page, then browsers like Firefox will halt processing of +the page, preventing any further viewing or editing. A less than +optimal solution is to force users to preview the page before saving. +That way if someone introduces invalid XHTML then they can't save the +page in the first place (unless they post directly to the right URL). + + [template-patch]: http://xbeta.org/gitweb/?p=xbeta/ikiwiki.git;a=blobdiff;f=templates/page.tmpl;h=380ef699fa72223744eb5c1ee655fb79aa6bce5b;hp=9084ba7e11e92a10528b2ab12c9b73cf7b0f40a7;hb=416d5d1b15b94e604442e4e209a30dee4b77b684;hpb=ececf4fb8766a4ff7eff943b3ef600be81a0df49 + [cgi-patch]: http://xbeta.org/gitweb/?p=xbeta/ikiwiki.git;a=commitdiff;h=fa538c375250ab08f396634135f7d79fce2a9d36 diff --git a/doc/users/jelmer.mdwn b/doc/users/jelmer.mdwn new file mode 100644 index 000000000..1f2f71aad --- /dev/null +++ b/doc/users/jelmer.mdwn @@ -0,0 +1 @@ +[Jelmer Vernooij](http://samba.org/~jelmer/) diff --git a/doc/users/jon.mdwn b/doc/users/jon.mdwn new file mode 100644 index 000000000..1cda23999 --- /dev/null +++ b/doc/users/jon.mdwn @@ -0,0 +1,20 @@ +[[!meta title="Jon Dowland"]] +I'm looking at ikiwiki both for my personal site but also as a +team-documentation management system for a small-sized group of UNIX +sysadmins. + +* my edits should appear either as 'Jon' (if I've used + [[tips/untrusted_git_push]]) or 'jmtd.net' (or once upon a time + 'alcopop.org/me/openid/' or 'jondowland'). +* My [homepage](http://jmtd.net/) is powered by ikiwiki + +I gave a talk at the [UK UNIX User's Group](http://www.ukuug.org/) annual +[Linux conference](http://www.ukuug.org/events/linux2008/) about organising +system administrator documentation. Roughly a third of this talk was +discussing IkiWiki in some technical detail and suggesting it as a good piece +of software for this task. + + * slides at . + +I am also working on some ikiwiki hacks: an alternative approach to +[[plugins/comments]]; a system for [[forum/managing_todo_lists]]. diff --git a/doc/users/jondowland.mdwn b/doc/users/jondowland.mdwn deleted file mode 100644 index c6302616f..000000000 --- a/doc/users/jondowland.mdwn +++ /dev/null @@ -1,5 +0,0 @@ -A new ikiwiki user, looking at ikiwiki both for his personal site but also as a team-documentation management system for a small-sized group of UNIX sysadmins. - -* My [homepage](http://jmtd.net/) is powered by ikiwiki (replacing my [older homepage](http://alcopop.org/), which was a mess of scripts) - -I am giving a talk at the [UK UNIX User's Group](http://www.ukuug.org/) annual [Linux conference](http://www.ukuug.org/events/linux2008/) about organising system administrator documentation which will feature IkiWiki. diff --git a/doc/users/joshtriplett.mdwn b/doc/users/joshtriplett.mdwn index f32d23bb7..f85c068c3 100644 --- a/doc/users/joshtriplett.mdwn +++ b/doc/users/joshtriplett.mdwn @@ -1,10 +1,15 @@ [[!meta title="Josh Triplett"]] -Josh Triplett; `josh@{freedesktop.org,kernel.org,psas.pdx.edu}`. +Email: `josh@{joshtriplett.org,freedesktop.org,kernel.org,psas.pdx.edu}`. + +[Josh Triplett's homepage](http://joshtriplett.org) Proud user of ikiwiki. -Currently working on scripts to convert MoinMoin and TWiki wikis to ikiwikis -backed by a git repository, including full history. +Currently working on scripts to convert MoinMoin and TWiki wikis to +ikiwikis backed by a git repository, including full history. +Available from the following repositories, though not well-documented: -> I've written about how I converted from Mediawiki here: Are you ever going to release your scripts? --[[sabr]] + git clone git://svcs.cs.pdx.edu/git/wiki2iki/moin2iki + git clone git://svcs.cs.pdx.edu/git/wiki2iki/html-wikiconverter + git clone git://svcs.cs.pdx.edu/git/wiki2iki/twiki diff --git a/doc/users/jrblevin.mdwn b/doc/users/jrblevin.mdwn new file mode 100644 index 000000000..4eb250bfa --- /dev/null +++ b/doc/users/jrblevin.mdwn @@ -0,0 +1 @@ +[[!meta redir=users/jasonblevins]] diff --git a/doc/users/jwalzer.mdwn b/doc/users/jwalzer.mdwn new file mode 100644 index 000000000..e66ad1a52 --- /dev/null +++ b/doc/users/jwalzer.mdwn @@ -0,0 +1,3 @@ +Jan Walzer started to look on ikiwiki just recently. + +Read [here](http://wa.lzer.net/wiki/ikiwiki/whyikiwiki/) why he uses ikiwiki. diff --git a/doc/users/neale.mdwn b/doc/users/neale.mdwn new file mode 100644 index 000000000..5245c2c99 --- /dev/null +++ b/doc/users/neale.mdwn @@ -0,0 +1,10 @@ +I used IkiWiki to supplant some custom journal software. I like that it uses +the filesystem, my intent is to make journal entries as future-proof as +possible. I'll probably start using it for generation of entire sites, soon. + +Things generated by IkiWiki with some fancypants stylesheets: + +* [woozle.org](http://woozle.org/) +* [My page](http://woozle.org/~neale/) +* [Amy's blog](http://woozle.org/~aim/blog/) +* [Heidi's blog](http://woozle.org/~heidi/blog/) diff --git a/doc/users/nolan.mdwn b/doc/users/nolan.mdwn new file mode 100644 index 000000000..64b405e60 --- /dev/null +++ b/doc/users/nolan.mdwn @@ -0,0 +1 @@ +Hi, I'm Nolan. I'll add more later. diff --git a/doc/users/seanh.mdwn b/doc/users/seanh.mdwn new file mode 100644 index 000000000..d093c2f32 --- /dev/null +++ b/doc/users/seanh.mdwn @@ -0,0 +1 @@ +seanh is an ikiwiki user. diff --git a/doc/users/simonraven.mdwn b/doc/users/simonraven.mdwn new file mode 100644 index 000000000..0706859aa --- /dev/null +++ b/doc/users/simonraven.mdwn @@ -0,0 +1,3 @@ +New ikiwiki site at my personal site under /ikiwiki/ . This might move to /wiki/ or be on wiki.k.o depending on if I can import my MediaWiki stuff to it. + +Thought I'd try it out again and it grew on me. diff --git a/doc/users/smcv.mdwn b/doc/users/smcv.mdwn index 33ae450b2..59d1affba 100644 --- a/doc/users/smcv.mdwn +++ b/doc/users/smcv.mdwn @@ -1 +1,10 @@ -I'm trying to add enough features/fix enough bugs to convert [smcv.pseudorandom.co.uk](http://smcv.pseudorandom.co.uk/) from Django + Python + misc hacks to ikiwiki. +Website: [pseudorandom.co.uk](http://www.pseudorandom.co.uk/) + +Blog: [smcv.pseudorandom.co.uk](http://smcv.pseudorandom.co.uk/) + +My repository containing ikiwiki branches: + +* gitweb: http://git.pseudorandom.co.uk/smcv/ikiwiki.git +* anongit: git://git.pseudorandom.co.uk/git/smcv/ikiwiki.git + +Currently thinking about a [[users/smcv/gallery]] plugin. diff --git a/doc/users/smcv/gallery.mdwn b/doc/users/smcv/gallery.mdwn new file mode 100644 index 000000000..b6b8de79f --- /dev/null +++ b/doc/users/smcv/gallery.mdwn @@ -0,0 +1,342 @@ +[[!template id=plugin name=smcvgallery author="[[Simon_McVittie|smcv]]"]] +[[!tag type/chrome]] + +This plugin has not yet been written; this page is an experiment in +design-by-documentation :-) + +## Requirements + +This plugin formats a collection of images into a photo gallery, +in the same way as many websites: good examples include the +PHP application [Gallery](http://gallery.menalto.com/), Flickr, +and Facebook's Photos "application". + +The web UI I'm trying to achieve consists of one +[HTML page of thumbnails](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/) +as an entry point to the gallery, where each thumbnail links to +[a "viewer" HTML page](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/img_0068/) +with a full size image, next/previous thumbnail links, and +[[plugins/comments]]. + +(The Summer of Code [[plugins/contrib/gallery]] plugin does the +next/previous UI in Javascript using Lightbox, which means that +individual photos can't be bookmarked in a meaningful way, and +the best it can do as a fallback for non-Javascript browsers +is to provide a direct link to the image.) + +Other features that would be good to have: + +* minimizing the number of separate operations needed to make a gallery - + editing one source file per gallery is acceptable, editing one + source file per photo is not + +* keeping photos outside source code control, for instance in an + underlay + +* assigning [[tags|ikiwiki/directive/tag]] to photos, providing a + superset of Facebook's "show tagged photos of this person" functionality + +* constructing galleries entirely via the web by uploading attachments + +* inserting grouping (section headings) within a gallery; as in the example + linked above, I'd like this to split up the thumbnails but not the + next/previous trail + +* rendering an `/` arrangement to display videos, and possibly + thumbnailing them in the same way as totem-video-thumbnailer + (my camera can record short videos, so some of my web photo galleries + contain them) + +My plan is to have these directives: + +* \[[!gallery]] registers the page it's on as a gallery, and displays all + photos that are part of this gallery but not part of a \[[!gallerysection]] + (below). + + All images (i.e. `*.png *.jpg *.gif`) that are attachments to the gallery page + or its subpages are considered to be part of the gallery. + + Optional arguments: + + * filter="[[ikiwiki/PageSpec]]": only consider images to be part of the + gallery if they also match this filter + + * sort="date|filename": order in which to sort the images + +* \[[!gallerysection filter="[[ikiwiki/PageSpec]]"]] displays all photos in the + gallery that match the filter + +So, +[the gallery I'm using as an example](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/) +could look something like this: + + \[[!gallery]] + + + # Gamarra + + \[[!gallerysection filter="link(sometag)"]] + + + # Smokescreen + + \[[!gallerysection filter="link(someothertag)"]] + + + + +## Implementation ideas + +The next/previous part this plugin overlaps with [[todo/wikitrails]]. + +A \[[!galleryimg]] directive to assign metadata to images might be necessary, so +the gallery page can contain something like: + + \[[!galleryimg p1010001.jpg title="..." caption="..." tags="foo"]] + \[[!galleryimg p1010002.jpg title="..." caption="..." tags="foo bar"]] + +However, allowing other pages to push in metadata like that will make +dependency tracking difficult. + +Making the viewer pages could be rather tricky. Here are some options: +"synthesize source pages for viewers" is the one I'm leaning towards at the +moment. + +### Viewers' source page is the gallery + +One possibility is to write out the viewer pages as a side-effect of +preprocessing the \[[!gallery]] directive. The proof-of-concept implementation +below does this. However, this does mean the viewer pages can't have tags or +metadata of their own and can't be matched by [[pagespecs|ikiwiki/pagespec]] or +[[wikilinks|ikiwiki/wikilink]]. + +It might be possible to implement tagging by using \[[!galleryimg]] to assign +the metadata to the *images* instead of their viewers; however, that would +require hacking up both `IkiWiki::htmllink` and `IkiWiki::urlto` to redirect +links to the image (e.g. from the \[[!map]] on a tag page) to become links to +the viewer page. + +Modifications to the comments plugin would also be required, to make it allow +comments written to `foo/bar/comment_1._comment` even though the page foo/bar +does not really exist, and display comments on the viewer pages even though +they're not real pages. (Writing comments to `foo/bar.jpg/*._comment` is not +an option!) + +### Synthesize source pages for viewers + +Another is to synthesize source pages for the viewers. This means they can have +tags and metadata, but trying to arrange for them to be scanned etc. correctly +without needing another refresh run is somewhat terrifying. +[[plugins/autoindex]] can safely create source pages because it runs in +the refresh hook, but I don't really like the idea of a refresh hook that scans +all source pages to see if they contain \[[!gallery]]... + +The photo galleries I have at the moment, like the Panic Cell example above, +are made by using an external script to parse XML gallery descriptions (lists +of image filenames, with metadata such as titles), and using this to write +IkiWiki markup into a directory which is then used as an underlay. This is a +hack, but it works. The use of XML is left over from a previous attempt at +solving the same problem using Django. + +Perhaps a better approach would be to have a setupfile option that names a +particular underlay directory (meeting the objective of not having large +photos under source code control) and generates a source page for each file +in that directory during the refresh hook. The source pages could be in the +underlay until they are edited (e.g. tagged), at which point they would be +copied into the source-code-controlled version in the usual way. + +The synthetic source pages can be very simple, using the same trick as my +[[plugins/comments]] plugin (a dedicated [[directive|ikiwiki/directives]] +encapsulating everything the plugin needs). If the plugin automatically +gathers information like file size, pixel size, date etc. from the images, then +only the human-edited information and a filename reference need to be present +in the source page; with some clever lookup rules based on the filename of +the source page, not even the photo's filename is necessarily needed. + + \[[!meta title="..."]] + \[[!meta date="..."]] + \[[!meta copyright="..."]] + \[[!tag ...]] + + \[[!galleryimageviewer p1010001.jpg]] + +However, this would mean that editing tags and other metadata would require +editing pages individually. Rather than trying to "fix" that, perhaps it would +be better to have a special CGI interface for bulk tagging/metadata editing. +This could even be combined with a bulk upload form (a reasonable number of +file upload controls - maybe 20 - with metadata alongside each). + +Uploading multiple images is necessarily awkward due to restrictions placed on +file upload controls by browsers for security reasons - sites like Facebook +allow whole directories to be uploaded at the same time, but they achieve this +by using a signed Java applet with privileged access to the user's filesystem. + +I've found that it's often useful to be able to force the creation time of +photos (my camera's battery isn't very reliable, and it frequently decides that +the date is 0000-00-00 00:00:00), so treating the \[[!meta date]] of the source +page and the creation date of the photo as synonymous would be useful. + +### Images are the viewer's source - special filename extension + +Making the image be the source page (and generate HTML itself) would be +possible, but I wouldn't want to generate a HTML viewer for every `.jpg` on a +site, so either the images would have to have a special extension (awkward for +uploads from Windows users) or the plugin would have to be able to change +whether HTML was generated in some way (not currently possible). + +### Images are the viewer's source - alter `ispage()` + +It might be possible to hack up `ispage()` so some, but not all, images are +considered to "be a page": + +* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg +* srcdir/gallery/photo.jpg → destdir/gallery/photo/index.html + +Perhaps one way to do this would be for the photos to appear in a particular +underlay directory, which would also fulfil the objective of having photos not +be version-controlled: + +* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg +* underlay/gallery/photo.jpg → destdir/gallery/photo/index.html + +## Proof-of-concept implementation of "viewers' source page is the gallery" + + #!/usr/bin/perl + package IkiWiki::Plugin::gallery; + + use warnings; + use strict; + use IkiWiki 2.00; + + sub import { + hook(type => "getsetup", id => "gallery", call => \&getsetup); + hook(type => "checkconfig", id => "gallery", call => \&checkconfig); + hook(type => "preprocess", id => "gallery", + call => \&preprocess_gallery, scan => 1); + hook(type => "preprocess", id => "gallerysection", + call => \&preprocess_gallerysection, scan => 1); + hook(type => "preprocess", id => "galleryimg", + call => \&preprocess_galleryimg, scan => 1); + } + + sub getsetup () { + return + plugin => { + safe => 1, + rebuild => undef, + }, + } + + sub checkconfig () { + } + + # page that is a gallery => array of images + my %galleries; + # page that is a gallery => array of filters + my %sections; + # page that is an image => page name of generated "viewer" + my %viewers; + + sub preprocess_gallery { + # \[[!gallery filter="!*/cover.jpg"]] + my %params=@_; + + my $subpage = qr/^\Q$params{page}\E\//; + + my @images; + + foreach my $page (keys %pagesources) { + # Reject anything not a subpage or attachment of this page + next unless $page =~ $subpage; + + # Reject non-images + # FIXME: hard-coded list of extensions + next unless $page =~ /\.(jpg|gif|png|mov)$/; + + # Reject according to the filter, if any + next if (exists $params{filter} && + !pagespec_match($page, $params{filter}, + location => $params{page})); + + # OK, we'll have that one + push @images, $page; + + my $viewername = $page; + $viewername =~ s/\.[^.]+$//; + $viewers{$page} = $viewername; + + my $filename = htmlpage($viewername); + will_render($params{page}, $filename); + } + + $galleries{$params{page}} = \@images; + + # If we're just scanning, don't bother producing output + return unless defined wantarray; + + # actually render the viewers + foreach my $img (@images) { + my $filename = htmlpage($viewers{$img}); + debug("rendering image viewer $filename for $img"); + writefile($filename, $config{destdir}, "# placeholder"); + } + + # display a list of "loose" images (those that are in no section); + # this works because we collected the sections' filters during the + # scan stage + + my @loose = @images; + + foreach my $filter (@{$sections{$params{page}}}) { + my $_; + @loose = grep { !pagespec_match($_, $filter, + location => $params{page}) } @loose; + } + + my $_; + my $ret = "
    \n"; + foreach my $img (@loose) { + $ret .= "
  • "; + $ret .= "$img
  • \n" + } + return "$ret
\n"; + } + + sub preprocess_gallerysection { + # \[[!gallerysection filter="friday/*"]] + my %params=@_; + + # remember the filter for this section so the "loose images" section + # won't include these images + push @{$sections{$params{page}}}, $params{filter}; + + # If we're just scanning, don't bother producing output + return unless defined wantarray; + + # this relies on the fact that we ran preprocess_gallery once + # already, during the scan stage + my @images = @{$galleries{$params{page}}}; + @images = grep { pagespec_match($_, $params{filter}, + location => $params{page}) } @images; + + my $_; + my $ret = "
    \n"; + foreach my $img (@images) { + $ret .= "
  • "; + $ret .= htmllink($params{page}, $params{destpage}, + $viewers{$img}); + $ret .= "
  • "; + } + return "$ret
\n"; + } + + sub preprocess_galleryimg { + # \[[!galleryimg p1010001.jpg title="" caption="" tags=""]] + my $file = $_[0]; + my %params=@_; + + return ""; + } + + 1 diff --git a/doc/users/svend.mdwn b/doc/users/svend.mdwn new file mode 100644 index 000000000..69d83584f --- /dev/null +++ b/doc/users/svend.mdwn @@ -0,0 +1,4 @@ +[[!meta title="Svend Sorensen"]] + +* [website](http://www.ciffer.net/~svend/) +* [blog](http://www.ciffer.net/~svend/blog/) diff --git a/doc/users/weakish.mdwn b/doc/users/weakish.mdwn new file mode 100644 index 000000000..ccd5665ad --- /dev/null +++ b/doc/users/weakish.mdwn @@ -0,0 +1 @@ +email: weakish@gmail.com diff --git a/doc/users/weakishjiang.mdwn b/doc/users/weakishjiang.mdwn new file mode 100644 index 000000000..0cafb4653 --- /dev/null +++ b/doc/users/weakishjiang.mdwn @@ -0,0 +1,4 @@ +[My blog](http://millenniumdark.blog.ubuntu.org.cn) + +> So, you're learning haskell. You know, I want to add support for haskell +> external plugins to ikiwiki.. :-) --[[Joey]] diff --git a/doc/users/xma.mdwn b/doc/users/xma.mdwn new file mode 100644 index 000000000..89f2ff74c --- /dev/null +++ b/doc/users/xma.mdwn @@ -0,0 +1,28 @@ +[[!meta title="Xavier Maillard"]] +# Xavier Maillard + +I just started using [[ikiwiki]] for my own webspace at http://maillard.mobi/~xma/wiki + +I am learning how to effectively use it. + +Anyway, [[ikiwiki]] is really *awesome* ! + +## More about me + +I am CLI user living in the linux console. More precisely, I live in an [[GNU_Emacs]] frame all day long. My main computer is an EeePC 901 running Slackware GNU/Linux 12.1. I do not have X installed (too lazy) but when in X, I am running an instance of [[CLFSWM]]. + +## Contacting me + +Various channels to contact me: + +- mail: xma@gnu.org +- jabber: xma01@jabber.fr +- mobile: +33 621-964-362 (I only anwser to people I know though) + +Voila. + +## Plans + +I am planning to make a presentation of [[ikiwiki]]to my [local LUG](http://lolica.org) for our next montly meeting. Any help would be greatly appreciated. + +We are discussing to replace our old unmaintained (and unmaintainable) [SPIP](http://spip.net) website with a wiki. This is why I would like using ikiwiki ;) diff --git a/doc/users/xma/discussion.mdwn b/doc/users/xma/discussion.mdwn new file mode 100644 index 000000000..34adbf821 --- /dev/null +++ b/doc/users/xma/discussion.mdwn @@ -0,0 +1,18 @@ +How do you edit this wiki (I mean [ikiwiki]) without the web browser ? Is there a way to git clone/pull/push and thus to use our favorite [text editor](http://www.gnu.org/software/emacs) ? --[[xma]] + +> You can clone ikiwiki's [[git]] repo. I have not implemented a way to +> allow users to push doc wiki only changesets anonymously, but you can +> mails changesets to me. --[[Joey]] +> > How can I send you the changesets ? (git command) --[[xma]] +> > > `git-format-patch` --[[Joey]] + +> > > > Glad to hear I can mail changesets to you, since I wrote the [[todo/applydiff_plugin]] wishlist entry. --[[intrigeri]] + +> It would be nice to have a git recieve hook that +> checked that a commit contained only changes to .mdwn or other allowed +> extensions.. if someone writes up a good one, I'd be willing to deploy it +> for ikiwiki. --[[Joey]] + +> > I'll think about it. It may solve some of my offline-being issues. --[[intrigeri]] + +>>>> Now developed! --[[Joey]] diff --git a/doc/wikiicons/openidlogin-bg.gif b/doc/wikiicons/openidlogin-bg.gif index c8f43d08e..a3bfe1098 100644 Binary files a/doc/wikiicons/openidlogin-bg.gif and b/doc/wikiicons/openidlogin-bg.gif differ diff --git a/doc/wikitemplates.mdwn b/doc/wikitemplates.mdwn index babd70211..fc5893677 100644 --- a/doc/wikitemplates.mdwn +++ b/doc/wikitemplates.mdwn @@ -29,6 +29,12 @@ located in /usr/share/ikiwiki/templates by default. form to wiki pages. * `searchquery.tmpl` - This is an omega template, used by the [[plugins/search]] plugin. +* `comment.tmpl` - This template is used to display a comment + by the [[plugins/comments]] plugin. +* `editcomment.tmpl` - This template is the comment post form for the + [[plugins/comments]] plugin. +* `commentmoderation.tmpl` - This template is used to produce the comment + moderation form. The [[plugins/pagetemplate]] plugin can allow individual pages to use a different template than `page.tmpl`. diff --git a/docwiki.setup b/docwiki.setup index 6d732fd6b..ffb4a7c16 100644 --- a/docwiki.setup +++ b/docwiki.setup @@ -15,5 +15,7 @@ use IkiWiki::Setup::Standard { userdir => "users", usedirs => 0, prefix_directives => 1, + cgiurl => "http://me", + url => "http://me", add_plugins => [qw{goodstuff version haiku polygen fortune}], } diff --git a/gitremotes b/gitremotes new file mode 100755 index 000000000..7b9484dd1 --- /dev/null +++ b/gitremotes @@ -0,0 +1,29 @@ +#!/usr/bin/perl +# Parses list of remotes in doc/git.mdwn, configures git to use them +# all, and fetches updates from them. + +my $error=0; + +open (IN, "doc/git.mdwn") || die "doc/git.mdwn: $!"; +while () { + if (/^\*\s+\[?\[?(\w+)\]?\]?\s+`([^>]+)`/) { + # note that the remote name has to be a simple word (\w) + # for security/sanity reasons + my $remote=$1; + my $url=$2; + + # check configured url to deal with it changing + my $info=`git remote show -n $remote`; + my ($oldurl)=$info=~/URL: (.*)/m; + if ($oldurl ne $url) { + system("git remote rm $remote 2>/dev/null"); + $error |= system("git", "remote", "add", "-f", $remote, $url); + } + else { + $error |= system("git", "fetch", $remote); + } + } +} +close IN; + +exit $error; diff --git a/ikiwiki-makerepo b/ikiwiki-makerepo index 78eea8f53..1c9f256bd 100755 --- a/ikiwiki-makerepo +++ b/ikiwiki-makerepo @@ -75,7 +75,7 @@ mercurial) hg init "$srcdir" cd "$srcdir" echo .ikiwiki > .hgignore - hg add * .hgignore + hg add hg commit -m "initial import" echo "Directory $srcdir is now set up as a mercurial repository" ;; @@ -83,7 +83,7 @@ bzr) bzr init "$srcdir" cd "$srcdir" echo .ikiwiki > .bzrignore - bzr add * .bzrignore + bzr add bzr commit -m "initial import" echo "Directory $srcdir is now set up as a bzr repository" ;; diff --git a/ikiwiki-transition b/ikiwiki-transition index e42a5137c..599261a09 100755 --- a/ikiwiki-transition +++ b/ikiwiki-transition @@ -1,4 +1,4 @@ -#!/usr/bin/perl -i +#!/usr/bin/perl use warnings; use strict; use IkiWiki; @@ -42,11 +42,33 @@ sub handle_directive { } sub prefix_directives { - $/=undef; # process whole files at once - - while (<>) { - s{$regex}{handle_directive($1, $2, $3, $4)}eg; - print; + my $setup=shift; + if (! defined $setup) { + usage(); + } + + require IkiWiki::Setup; + require IkiWiki::Plugin::aggregate; + + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::loadplugins(); + IkiWiki::checkconfig(); + IkiWiki::loadindex(); + + if (! %pagesources) { + error "ikiwiki has not built this wiki yet, cannot transition"; + } + + foreach my $page (values %pagesources) { + next unless defined pagetype($page) && + -f $config{srcdir}."/".$page; + my $content=readfile($config{srcdir}."/".$page); + my $oldcontent=$content; + $content=~s{$regex}{handle_directive($1, $2, $3, $4)}eg; + if ($oldcontent ne $content) { + writefile($page, $config{srcdir}, $content); + } } } @@ -109,12 +131,10 @@ sub aggregateinternal { require IkiWiki::Plugin::aggregate; %config = IkiWiki::defaultconfig(); - IkiWiki::Setup::load(); + IkiWiki::Setup::load($setup); IkiWiki::checkconfig(); IkiWiki::Plugin::aggregate::migrate_to_internal(); - - print "... now add aggregateinternal => 1 to your .setup file\n"; } sub setupformat { @@ -161,14 +181,54 @@ sub setupformat { IkiWiki::Setup::dump($setup); } +sub moveprefs { + my $setup=shift; + if (! defined $setup) { + usage(); + } + + require IkiWiki::Setup; + + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::checkconfig(); + + eval q{use IkiWiki::UserInfo}; + error $@ if $@; + + foreach my $field (qw{allowed_attachments locked_pages}) { + my $orig=$config{$field}; + foreach my $admin (@{$config{adminuser}}) { + my $a=IkiWiki::userinfo_get($admin, $field); + if (defined $a && length $a && + # might already have been moved + (! defined $orig || $a ne $orig)) { + if (defined $config{$field} && + length $config{$field}) { + $config{$field}=IkiWiki::pagespec_merge($config{$field}, $a); + } + else { + $config{$field}=$a; + } + } + } + } + + my %banned=map { $_ => 1 } @{$config{banned_users}}, IkiWiki::get_banned_users(); + $config{banned_users}=[sort keys %banned]; + + IkiWiki::Setup::dump($setup); +} + sub usage { print STDERR "Usage: ikiwiki-transition type ...\n"; print STDERR "Currently supported transition subcommands:\n"; - print STDERR "\tprefix_directives file\n"; - print STDERR "\tindexdb srcdir\n"; - print STDERR "\thashpassword srcdir\n"; + print STDERR "\tprefix_directives setupfile ...\n"; print STDERR "\taggregateinternal setupfile\n"; print STDERR "\tsetupformat setupfile\n"; + print STDERR "\tmoveprefs setupfile\n"; + print STDERR "\thashpassword srcdir\n"; + print STDERR "\tindexdb srcdir\n"; exit 1; } @@ -190,6 +250,9 @@ elsif ($mode eq 'aggregateinternal') { elsif ($mode eq 'setupformat') { setupformat(@ARGV); } +elsif ($mode eq 'moveprefs') { + moveprefs(@ARGV); +} else { usage(); } @@ -247,3 +310,15 @@ sub oldloadindex { return close($in); } + +# Used to be in IkiWiki/UserInfo, but only used here now. +sub get_banned_users () { + my @ret; + my $userinfo=userinfo_retrieve(); + foreach my $user (keys %{$userinfo}) { + push @ret, $user if $userinfo->{$user}->{banned}; + } + return @ret; +} + +1 diff --git a/ikiwiki.in b/ikiwiki.in index 4f24cfc2e..c79a2bfef 100755 --- a/ikiwiki.in +++ b/ikiwiki.in @@ -9,12 +9,12 @@ use strict; use lib '.'; # For use in nonstandard directory, munged by Makefile. use IkiWiki; -sub usage () { #{{{ +sub usage () { die gettext("usage: ikiwiki [options] source dest"), "\n", gettext(" ikiwiki --setup configfile"), "\n"; -} #}}} +} -sub getconfig () { #{{{ +sub getconfig () { if (! exists $ENV{WRAPPED_OPTIONS}) { %config=defaultconfig(); eval q{use Getopt::Long}; @@ -40,6 +40,7 @@ sub getconfig () { #{{{ "post-commit" => \$config{post_commit}, "render=s" => \$config{render}, "wrappers!" => \$config{genwrappers}, + "wrappergroup=s" => \$config{wrappergroup}, "usedirs!" => \$config{usedirs}, "prefix-directives!" => \$config{prefix_directives}, "getctime" => \$config{getctime}, @@ -98,7 +99,7 @@ sub getconfig () { #{{{ "help|h" => sub { $SIG{__WARN__}=sub {}; die }, ) || usage(); - if (! $config{setup} && ! $config{render}) { + if (! $config{setup}) { loadplugins(); if (@ARGV == 2) { $config{srcdir} = possibly_foolish_untaint(shift @ARGV); @@ -118,12 +119,13 @@ sub getconfig () { #{{{ error("WRAPPED_OPTIONS: $@"); } delete $ENV{WRAPPED_OPTIONS}; + loadplugins(); checkconfig(); } -} #}}} +} -sub main () { #{{{ +sub main () { getconfig(); if ($config{setup}) { @@ -133,7 +135,8 @@ sub main () { #{{{ if (@{$config{wrappers}} && ! $config{render} && ! $config{dumpsetup} && - (! $config{refresh} || $config{genwrappers})) { + ((! $config{refresh} && ! $config{post_commit}) + || $config{genwrappers})) { debug(gettext("generating wrappers..")); require IkiWiki::Wrapper; my %origconfig=(%config); @@ -145,7 +148,8 @@ sub main () { #{{{ if exists $config{setupsyslog}; delete @config{qw(setupsyslog setupverbose wrappers genwrappers rebuild)}; checkconfig(); - if (! $config{cgi} && ! $config{post_commit}) { + if (! $config{cgi} && ! $config{post_commit} && + ! $config{test_receive}) { $config{post_commit}=1; } gen_wrapper(); @@ -154,13 +158,16 @@ sub main () { #{{{ } # setup implies a wiki rebuild by default - if (! $config{refresh}) { + if (! $config{refresh} && ! $config{render} && + ! $config{post_commit}) { $config{rebuild}=1; } } if ($config{dumpsetup}) { - $config{srdir}=$config{destdir}=""; + $config{srcdir}="" if ! defined $config{srcdir}; + $config{destdir}="" if ! defined $config{destdir}; + $config{syslog}=1 if $config{setupsyslog}; require IkiWiki::Setup; IkiWiki::Setup::dump($config{dumpsetup}); } @@ -183,6 +190,10 @@ sub main () { #{{{ elsif ($config{post_commit} && ! commit_hook_enabled()) { # do nothing } + elsif ($config{test_receive}) { + require IkiWiki::Receive; + IkiWiki::Receive::test(); + } else { if ($config{rebuild}) { debug(gettext("rebuilding wiki..")); @@ -198,6 +209,6 @@ sub main () { #{{{ saveindex(); debug(gettext("done")); } -} #}}} +} main; diff --git a/plugins/externaldemo b/plugins/externaldemo index fa93e672d..be7aba8b9 100755 --- a/plugins/externaldemo +++ b/plugins/externaldemo @@ -101,16 +101,15 @@ sub import { # stage of ikiwiki. rpc_call("hook", type => "preprocess", id => "externaldemo", call => "preprocess"); - # Here's an example of how to inject an arbitrary function into - # ikiwiki. Ikiwiki will be able to call bob() just like any other - # function. Note use of automatic memoization. - rpc_call("inject", name => "IkiWiki::bob", call => "bob", - memoize => 1); - # Here's an exmaple of how to access values in %IkiWiki::config. print STDERR "url is set to: ". rpc_call("getvar", "config", "url")."\n"; + # Here's an example of how to inject an arbitrary function into + # ikiwiki. Note use of automatic memoization. + rpc_call("inject", name => "IkiWiki::bob", + call => "formattime", memoize => 1); + print STDERR "externaldemo plugin successfully imported\n"; } diff --git a/pm_filter b/pm_filter index 5ee5a1b98..4984f32d9 100755 --- a/pm_filter +++ b/pm_filter @@ -7,14 +7,14 @@ BEGIN { } if (/INSTALLDIR_AUTOREPLACE/) { - $_=qq{my \$installdir="$prefix";}; + $_=qq{our \$installdir="$prefix";}; } elsif (/VERSION_AUTOREPLACE/) { $_=qq{our \$version="$ver";}; } elsif (/^use lib/) { # The idea here is to figure out if the libdir the Makefile.PL - # was configure to use is in perl's normal search path. + # was configured to use is in perl's normal search path. # If not, hard code it into ikiwiki. if ((grep { $_ eq $libdir } @INC) && (! exists $ENV{PERL5LIB} || ! length $ENV{PERL5LIB} || diff --git a/po/bg.po b/po/bg.po index a8f386ccf..ce963f994 100644 --- a/po/bg.po +++ b/po/bg.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki-bg\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-01-12 01:19+0200\n" "Last-Translator: Damyan Ivanov \n" "Language-Team: Bulgarian \n" @@ -20,109 +20,115 @@ msgstr "" msgid "You need to log in first." msgstr "Първо трябва да влезете." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 #, fuzzy msgid "Preferences" msgstr "Предпочитанията са запазени." -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Предпочитанията са запазени." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Достъпът ви е забранен." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Грешка" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, fuzzy, perl-format msgid "missing %s parameter" msgstr "липсващ параметър „id” на шаблона" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "нов източник" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "съобщения" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "ново" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "премахване на „%s” (на %s дни)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "премахване на „%s”" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "е обработен нормално от %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "проверка на източника „%s”" -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "не е намерен източник на адрес „%s”" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 #, fuzzy msgid "feed not found" msgstr "шаблонът „%s” не е намерен" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "данните от източника предизвикаха грешка в модула XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "създаване на нова страницa „%s”" @@ -131,7 +137,7 @@ msgstr "създаване на нова страницa „%s”" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "готово" @@ -154,29 +160,35 @@ msgstr "Грешка при изпращане на поща" msgid "Failed to delete file from S3: " msgstr "грешка при запис на файла „%s”: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -191,6 +203,71 @@ msgstr "" msgid "There are no broken links!" msgstr "Няма „счупени” връзки!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "създаване на %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -212,19 +289,19 @@ msgstr "" msgid "removing old preview %s" msgstr "премахване на старата страница „%s”" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "създаване на %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "промяна на %s" @@ -249,14 +326,47 @@ msgstr "" msgid "failed to process" msgstr "грешка при обработване на шаблона" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "грешшка в приставката „fortune”" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "При използване на приеставката „search” е необходимо е да се укаже %s" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 #, fuzzy -msgid "failed to find url in html" -msgstr "приставката „googlecalendar” не намери URL в HTML-кода" +msgid "missing page" +msgstr "липсващ параметър „id” на шаблона" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 #, fuzzy @@ -293,41 +403,45 @@ msgstr "грешка при запис на файла „%s”: %s" msgid "failed to determine size of image %s" msgstr "грешка при запис на файла „%s”: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Когато се използва „--rss” или „--atom” трябва да се укаже и " "местоположението на уикито посредством параметъра „--url”" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "шаблонът „%s” не е намерен" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "липсващ параметър „id” на шаблона" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "непознат вид сортиране „%s”" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Дискусия" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "модулът „RPC::XML::Client” не е намерен; източникът не е проверен" @@ -336,7 +450,7 @@ msgstr "модулът „RPC::XML::Client” не е намерен; източ msgid "failed to run dot" msgstr "приставката „linkmap”: грешка при изпълнение на „dot”" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "" @@ -353,17 +467,17 @@ msgstr "" "грешка при зареждането на perl-модула „Markdown.pm” (%s) или „/usr/bin/" "markdown” (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 #, fuzzy msgid "stylesheet not found" msgstr "шаблонът „%s” не е намерен" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "шаблонът „%s” не е намерен" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "шаблонът „%s” не е намерен" @@ -549,17 +663,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "липсващ параметър „id” на шаблона" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -579,16 +683,16 @@ msgstr "" msgid "%s is not a file" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -626,20 +730,20 @@ msgstr "обновяване на страницата „%s”" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "обновяване на страниците от уики „%s”: %s от потребител „%s”" @@ -658,11 +762,12 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 #, fuzzy msgid "missing name or url parameter" msgstr "препратката няма указани параметрите „name” или „url”" @@ -670,7 +775,7 @@ msgstr "препратката няма указани параметрите #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, fuzzy, perl-format msgid "shortcut %s points to %s" msgstr "препратката „%s” сочи към „%s”" @@ -721,34 +826,34 @@ msgstr "приставката „linkmap”: грешка при изпълне msgid "cannot find file" msgstr "" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, fuzzy, perl-format msgid "parse fail at line %d: %s" msgstr "грешка при запис на файла „%s”: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 #, fuzzy msgid "missing id parameter" msgstr "липсващ параметър „id” на шаблона" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "шаблонът „%s” не е намерен" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 #, fuzzy msgid "failed to process:" msgstr "грешка при обработване на шаблона" @@ -775,10 +880,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -807,6 +908,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "пропускане на невалидното име на файл „%s”" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -871,16 +982,16 @@ msgstr "ikiwiki: неуспех при обновяване на страниц msgid "cannot read %s: %s" msgstr "грешка при четене на „%s”: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -897,21 +1008,14 @@ msgstr "не може да бъде създадена обвивка, коят msgid "wrapper filename not specified" msgstr "не е указан файл на обвивката" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "грешка при запис на файла „%s”: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "крешка при компилиране на файла %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "успешно генериране на %s" @@ -924,43 +1028,43 @@ msgstr "формат: ikiwiki [опции] източник местоназна msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "генериране на обвивки..." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "обновяване на уики..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "осъвременяване на уики..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" "При използване на пареметъра „--cgi” е необходимо да се укаже и " "местоположението на уикито чрез параметъра „--url”" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "открита е циклична завидимост при %s на „%s” на дълбочина %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -977,13 +1081,23 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "грешка при запис на файла „%s”: %s" + +#, fuzzy +#~ msgid "failed to find url in html" +#~ msgstr "приставката „googlecalendar” не намери URL в HTML-кода" + +#~ msgid "processed ok at %s" +#~ msgstr "е обработен нормално от %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "Паролата ви е изпратена по пощата." diff --git a/po/cs.po b/po/cs.po index 757fae5fb..c66004dcb 100644 --- a/po/cs.po +++ b/po/cs.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-05-09 21:21+0200\n" "Last-Translator: Miroslav Kure \n" "Language-Team: Czech \n" @@ -19,107 +19,113 @@ msgstr "" msgid "You need to log in first." msgstr "Nejprve se musíte přihlásit." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "přihlášení selhalo; možná si musíte povolit cookies?" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "Přihlášení" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "Předvolby" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "Správce" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Nastavení uloženo." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Jste vyhoštěni." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Chyba" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "chybí parametr %s" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "nový zdroj" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "příspěvky" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "nový" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "expiruji %s (stará %s dnů)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "expiruji %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "zpracováno ok %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "kontroluji zdroj %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "nemohu najít zdroj na %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "zdroj nebyl nalezen" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "(neplatné UTF-8 bylo ze zdroje odstraněno)" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "zdroj shodil XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "vytvářím novou stránku %s" @@ -128,7 +134,7 @@ msgstr "vytvářím novou stránku %s" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "hotovo" @@ -151,29 +157,35 @@ msgstr "Nepodařilo se odeslat email." msgid "Failed to delete file from S3: " msgstr "nelze změnit velikost: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -188,6 +200,71 @@ msgstr "" msgid "There are no broken links!" msgstr "Žádné porušené odkazy!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "vytvářím %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -209,19 +286,19 @@ msgstr "" msgid "removing old preview %s" msgstr "odstraňuji starou stránku %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "%s není editovatelná stránka" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "vytvářím %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "upravuji %s" @@ -246,13 +323,47 @@ msgstr "" msgid "failed to process" msgstr "nepodařilo se zpracovat:" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "fortune selhal" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" -msgstr "v html se nepodařilo nalézt url" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Při používání vyhledávacího modulu musíte zadat %s" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 +#, fuzzy +msgid "missing page" +msgstr "chybí hodnoty" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" @@ -288,39 +399,43 @@ msgstr "nelze změnit velikost: %s" msgid "failed to determine size of image %s" msgstr "nelze změnit velikost: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "Při používání --rss nebo --atom musíte pomocí --url zadat url k wiki" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "zdroj nebyl nalezen" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "chybí parametr %s" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "neznámý typ řazení %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Přidat nový příspěvek nazvaný:" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "neexistující šablona %s" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Diskuse" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "RPC::XML::Client nebyl nalezen, nepinkám" @@ -328,7 +443,7 @@ msgstr "RPC::XML::Client nebyl nalezen, nepinkám" msgid "failed to run dot" msgstr "nepodařilo se spustit dot" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "Stránka %s je zamknutá uživatelem %s a nelze ji měnit" @@ -343,16 +458,16 @@ msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)" msgstr "" "selhalo nahrání perlového modulu Markdown.pm (%s) nebo /usr/bin/markdown (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "styl nebyl nalezen" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "zdroj nebyl nalezen" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "zdroj nebyl nalezen" @@ -538,17 +653,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "chybí hodnoty" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -567,16 +672,16 @@ msgstr "Stránka %s je zamknutá uživatelem %s a nelze ji měnit" msgid "%s is not a file" msgstr "%s není editovatelná stránka" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -614,20 +719,20 @@ msgstr "zpracovávám %s" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "aktualizace %s (%s) uživatelem %s" @@ -646,18 +751,19 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "chybí parametr jméno nebo url" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "zkratka %s odkazuje na %s" @@ -702,33 +808,33 @@ msgstr "nepodařilo se spustit php" msgid "cannot find file" msgstr "nemohu najít soubor" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "neznámý formát dat" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "prázdná data" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Stáhnout zdrojová data" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "zpracovávání selhalo na řádku %d: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "chybí parametr id" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "šablona %s nebyla nalezena" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "nepodařilo se zpracovat:" @@ -755,10 +861,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -788,6 +890,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "přeskakuji chybné jméno souboru %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -852,16 +964,16 @@ msgstr "ikiwiki: nelze zpracovat %s" msgid "cannot read %s: %s" msgstr "nemohu číst %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -878,21 +990,14 @@ msgstr "nemohu vytvořit obal, který využívá soubor setup" msgid "wrapper filename not specified" msgstr "jméno souboru s obalem nebylo zadáno" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "nelze zapsat %s: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "nelze zkompilovat %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "%s byl úspěšně vytvořen" @@ -905,41 +1010,41 @@ msgstr "použití: ikiwiki [volby] zdroj cíl" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "generuji obaly..." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "znovu vytvářím wiki..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "obnovuji wiki..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "Při použití --cgi musíte pomocí --url zadat url k wiki" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "Byla rozpoznána smyčka direktivy %s na %s v hloubce %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -956,13 +1061,22 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "nelze zapsat %s: %s" + +#~ msgid "failed to find url in html" +#~ msgstr "v html se nepodařilo nalézt url" + +#~ msgid "processed ok at %s" +#~ msgstr "zpracováno ok %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "Vaše heslo vám bylo zasláno." diff --git a/po/da.po b/po/da.po index 9378a4fb9..5f582312d 100644 --- a/po/da.po +++ b/po/da.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" -"PO-Revision-Date: 2008-08-11 01:04+0200\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" +"PO-Revision-Date: 2008-10-22 19:13+0100\n" "Last-Translator: Jonas Smedegaard \n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Danish\n" "X-Poedit-Country: DENMARK\n" "X-Poedit-SourceCharset: utf-8\n" @@ -23,107 +23,113 @@ msgstr "" msgid "You need to log in first." msgstr "Du skal først logge på." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "Pålogning mislykkedes, måske skal du tillade infokager (cookies)?" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "Din kørsel (login session) er udløbet" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "Pålogning" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "Indstillinger" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "Admin" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Indstillinger gemt" -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Du er banlyst." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Fejl" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "Indsamling udløst via web." -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "Intet at gøre lige nu, alle fødninger er tidssvarende!" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "mangler parametren %s" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "ny fødning" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "indlæg" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "nyt" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "udløber %s (%s dage gammel)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "udløber %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "korrekt dannet ved %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "undersøger fødning %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "kunne ikke finde fødning ved %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "fødning ikke fundet" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "(defekt UTF-8 fjernet fra fødning)" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "(fødningselementer omgået (escaped))" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "fødning fik XML::Feed til at bryde sammen!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "opretter ny side %s" @@ -132,7 +138,7 @@ msgstr "opretter ny side %s" msgid "deleting bucket.." msgstr "sletter bundt.." -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "færdig" @@ -153,29 +159,35 @@ msgstr "Arkivering af fil i S3 mislykkedes: " msgid "Failed to delete file from S3: " msgstr "Sletning af fil fra S3 mislykkedes: " -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "der er allerede en side ved navn %s" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "forhindret af allowed_attachments" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "dårligt vedhæftningsfilnavn" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "vedhæftningsoplægning" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "automatisk indeks-dannelse" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -190,6 +202,72 @@ msgstr "%s fra %s" msgid "There are no broken links!" msgstr "Ingen henvisninger der ikker fungerer!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, fuzzy, perl-format +msgid "unsupported page format %s" +msgstr "revisionskontrolsystem %s ikke understøttet" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +#, fuzzy +msgid "bad page name" +msgstr "dårligt vedhæftningsfilnavn" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "opretter %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "du er ikke logget på som en administrator" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -207,23 +285,23 @@ msgid "no text was copied in this page with id %s" msgstr "ingen tekst blev kopieret i denne side med id %s" #: ../IkiWiki/Plugin/editpage.pm:40 -#, fuzzy, perl-format +#, perl-format msgid "removing old preview %s" -msgstr "fjerner gammel side %s" +msgstr "fjerner gammelt smugkig %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "%s er ikke en redigérbar side" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "opretter %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "redigerer %s" @@ -245,13 +323,47 @@ msgstr "redigeringsskabelon %s registreret for %s" msgid "failed to process" msgstr "dannelsen mislykkedes" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "spådom (fortune) fejlede" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" -msgstr "lokalisering af url i html mislykkedes" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, fuzzy, perl-format +msgid "you are not allowed to change %s" +msgstr "du er ikke logget på som en administrator" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +#, fuzzy +msgid "you are not allowed to change file modes" +msgstr "du er ikke logget på som en administrator" + +#: ../IkiWiki/Plugin/google.pm:27 +#, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Skal angive %s når google søgeudvidelsen bruges" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "Tolkning af URL mislykkedes, kan ikke afgøre domænenavn" + +#: ../IkiWiki/Plugin/goto.pm:49 +msgid "missing page" +msgstr "manglende side" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "Siden %s eksisterer ikke." #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" @@ -286,38 +398,41 @@ msgstr "Ændring af størrelse mislykkedes: %s" msgid "failed to determine size of image %s" msgstr "Vurdering af størrelse på billede mislykkedes: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "Skal angive url til wiki med --url når --rss eller --atom anvendes" -#: ../IkiWiki/Plugin/inline.pm:139 -#, fuzzy +#: ../IkiWiki/Plugin/inline.pm:138 msgid "page editing not allowed" -msgstr "ring af henvisninger er ikke tilladt" +msgstr "sideredigering er ikke tilladt" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 msgid "missing pages parameter" msgstr "mangler pages-parametren" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "ukendt sorteringsform %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Tilføj nyt indlæg med følgende titel:" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "ikke-eksisterende skabelon: %s" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Diskussion" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "RPC::XML::Client ikke fundet, pinger ikke" @@ -325,10 +440,10 @@ msgstr "RPC::XML::Client ikke fundet, pinger ikke" msgid "failed to run dot" msgstr "dot-kørsel mislykkedes" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 -#, fuzzy, perl-format +#: ../IkiWiki/Plugin/lockedit.pm:47 +#, perl-format msgid "%s is locked and cannot be edited" -msgstr "%s er låst af %s og kan ikke redigeres" +msgstr "%s er låst og kan ikke redigeres" #: ../IkiWiki/Plugin/mdwn.pm:44 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed" @@ -342,15 +457,15 @@ msgstr "" "Indlæsning af perl-modulet Markdown.pm (%s) eller /usr/bin/markdown (%s) " "mislykkedes" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "stilsnit (stylesheet) ikke fundet" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 msgid "redir page not found" msgstr "henvisningsside ikke fundet" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 msgid "redir cycle is not allowed" msgstr "ring af henvisninger er ikke tilladt" @@ -526,24 +641,15 @@ msgid "at noon on %A" msgstr "midt på dagen %A" #: ../IkiWiki/Plugin/progress.pm:34 -#, fuzzy, perl-format +#, perl-format msgid "illegal percent value %s" -msgstr "ugyldigt navn" +msgstr "ugyldigt procentværdi %s" #: ../IkiWiki/Plugin/progress.pm:59 msgid "need either `percent` or `totalpages` and `donepages` parameters" -msgstr "" +msgstr "Kræver enten parametre `percent` eller `totalpages og `donepages`" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -msgid "missing page" -msgstr "manglende side" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "Siden %s eksisterer ikke." - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "(Diff trunkeret)" @@ -562,16 +668,16 @@ msgstr "%s er ikke i srcdir, så kan ikke blive slettet" msgid "%s is not a file" msgstr "%s er ikke en fil" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "bekræft at %s bliver fjernet" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "Vælg vedhæftning der skal slettes." -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "fjernet" @@ -606,22 +712,22 @@ msgstr "omdøb %s" #: ../IkiWiki/Plugin/rename.pm:138 msgid "Also rename SubPages and attachments" -msgstr "" +msgstr "Omdøb også UnderSider og vedhæftninger" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "Kun en vedhæftning kan blive omdøbt ad gangen." -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "Vælg vedhæftningen som skal omdøbes." -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "omdøb %s til %s" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, perl-format msgid "update for rename of %s to %s" msgstr "opdatering til omdøbning af %s til %s" @@ -640,18 +746,19 @@ msgstr "behøver Digest::SHA1 til indeks %s" msgid "search" msgstr "søg" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, fuzzy, perl-format +msgid "shortcut plugin will not work without %s" msgstr "genvejsudvidelsen vil ikke fungere uden en shortcuts.mdwn" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "manglende navn eller url parameter" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "genvej %s viser til %s" @@ -696,33 +803,33 @@ msgstr "php-kørsel mislykkedes" msgid "cannot find file" msgstr "kan ikke finde fil" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "ukendt dataformat" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "blanke data" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Direkte datanedlastning" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "afkodningsfejl på linje %d: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "manglende id-parameter" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "skabelon %s ikke fundet" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "dannelsen mislykkedes:" @@ -740,52 +847,63 @@ msgstr "billedopbygning fra kode mislykkedes" #: ../IkiWiki/Plugin/websetup.pm:89 msgid "plugin" -msgstr "" +msgstr "udvidelse" #: ../IkiWiki/Plugin/websetup.pm:108 -#, fuzzy, perl-format +#, perl-format msgid "enable %s?" -msgstr "omdøb %s" - -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" +msgstr "aktivér %s?" #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" -msgstr "" +msgstr "opsætningsfilen for denne wiki er ukendt" #: ../IkiWiki/Plugin/websetup.pm:256 -#, fuzzy msgid "main" -msgstr "Admin" +msgstr "primær" #: ../IkiWiki/Plugin/websetup.pm:257 msgid "plugins" -msgstr "" +msgstr "udvidelser" #: ../IkiWiki/Plugin/websetup.pm:395 msgid "" "The configuration changes shown below require a wiki rebuild to take effect." msgstr "" +"Opsætningsændringerne vist nedenfor kræver wiki-genopbygning for at træde i " +"kraft." #: ../IkiWiki/Plugin/websetup.pm:399 msgid "" "For the configuration changes shown below to fully take effect, you may need " "to rebuild the wiki." msgstr "" +"For at opsætningsændringerne vist nedenfor træder fuldt ud i kraft, skal du " +"muligvis genopbygge wikien." #: ../IkiWiki/Plugin/websetup.pm:433 #, perl-format msgid "

Error: %s exited nonzero (%s)" +msgstr "

Fejl: %s sluttede med fejl (%s)" + +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" msgstr "" +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "udelader forkert filnavn %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to " "allow this" msgstr "" +"symbolsk lænke fundet i srcdir-sti (%s) -- sæt allow_symlinks_before_srcdir " +"for at tillade dette" #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302 #, perl-format @@ -795,7 +913,7 @@ msgstr "udelader forkert filnavn %s" #: ../IkiWiki/Render.pm:284 #, perl-format msgid "%s has multiple possible source pages" -msgstr "" +msgstr "%s har flere mulige kildesider" #: ../IkiWiki/Render.pm:360 #, perl-format @@ -844,18 +962,18 @@ msgstr "ikiwiki: kan ikke danne %s" msgid "cannot read %s: %s" msgstr "kan ikke læse %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" -msgstr "" +msgstr "du skal angive et wikinavn (som indeholder alfanumeriske tegn)" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" -msgstr "" +msgstr "revisionskontrolsystem %s ikke understøttet" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" -msgstr "" +msgstr "opsætning af depotet med ikiwiki-makerepo mislykkedes" #: ../IkiWiki/Wrapper.pm:16 #, perl-format @@ -870,21 +988,14 @@ msgstr "kan ikke oprette en wrapper som bruger en opsætningsfil" msgid "wrapper filename not specified" msgstr "wrapper-navn ikke angivet" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "skrivning ad %s mislykkedes: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "kompilering af %s mislykkedes" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "Korrekt bygget %s" @@ -895,62 +1006,73 @@ msgstr "brug: ikiwiki [valg] kilde mål" #: ../ikiwiki.in:14 msgid " ikiwiki --setup configfile" -msgstr "" +msgstr " ikiwiki --setup opsætningsfil" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "brug: --set var=værdi" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "bygger wrappers.." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "genopbygger wiki..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "genopfrisker wiki..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "Skal angive url til wiki med --url når der bruges --cgi" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" -msgstr "" +msgstr "kan ikke bruge flere samtidige RCS-udvidelser" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" +"indlæsning af ekstern udvidelse krævet af udvidelsen %s mislykkedes: %s" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "forudberegningssløkke fundet på %s ved dybde %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "ja" #: ../auto.setup:16 msgid "What will the wiki be named?" -msgstr "" +msgstr "Hvad skal wikien hedde?" #: ../auto.setup:16 msgid "wiki" -msgstr "" +msgstr "wiki" #: ../auto.setup:18 msgid "What revision control system to use?" -msgstr "" +msgstr "Hvilket revisionskontrolsystem skal bruges?" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" -msgstr "" +#, fuzzy +msgid "What wiki user (or openid) will be admin?" +msgstr "Hvilken wiki bruger (eller openid) skal være administrator?" #: ../auto.setup:23 msgid "What is the domain name of the web server?" -msgstr "" +msgstr "Hvad er domænenavnet på webserveren?" + +#~ msgid "failed to write %s: %s" +#~ msgstr "skrivning ad %s mislykkedes: %s" + +#~ msgid "failed to find url in html" +#~ msgstr "lokalisering af url i html mislykkedes" + +#~ msgid "processed ok at %s" +#~ msgstr "korrekt dannet ved %s" diff --git a/po/de.po b/po/de.po index d33a6aca7..748265924 100644 --- a/po/de.po +++ b/po/de.po @@ -1,13 +1,13 @@ # German translation of the ikiwiki language file resulting in de.po -# Copyright © 2008 Kai Wasserbäch +# Copyright © 2008-2009 Kai Wasserbäch # This file is distributed under the same license as the ikiwiki package. # msgid "" msgstr "" -"Project-Id-Version: ikiwiki 2.40\n" +"Project-Id-Version: ikiwiki 3.06\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" -"PO-Revision-Date: 2008-03-03 21:22+0100\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" +"PO-Revision-Date: 2009-03-02 15:39+0100\n" "Last-Translator: Kai Wasserbäch \n" "Language-Team: German \n" "MIME-Version: 1.0\n" @@ -18,162 +18,176 @@ msgstr "" msgid "You need to log in first." msgstr "Sie müssen sich zuerst anmelden." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" +"mögliche Fehlkonfiguration: »sslcookie« ist gesetzt, aber Sie versuchen sich " +"mittels HTTP und nicht HTTPS anzumelden" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" "Anmeldung fehlgeschlagen, möglicherweise müssen Sie zuvor Cookies aktivieren?" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." -msgstr "" +msgstr "Ihre Anmeldung für die aktuelle Sitzung ist abgelaufen." -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "Anmelden" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "Einstellungen" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "Administrator" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Einstellungen gespeichert." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Sie sind ausgeschlossen worden." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Fehler" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." -msgstr "" +msgstr "Feed-Erstellung wurde über das Web ausgelöst." -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" -msgstr "" +msgstr "Derzeit nichts zu tun, alle Feeds sind auf dem neusten Stand!" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "Parameter %s fehlt" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "neuer Feed" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "Beiträge" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "neu" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "%s läuft aus (%s Tage alt)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "%s läuft aus" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "normal verarbeitet um %s" +msgid "last checked %s" +msgstr "zuletzt überprüft am %s" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "überprüfe Feed %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "konnte Feed unter %s nicht finden" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "Feed nicht gefunden" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" -msgstr "(ungültiges UTF-8 wurde aus dem Feed entfernt)" +msgstr "(ungültiges UTF-8-Zeichen wurde aus dem Feed entfernt)" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" -msgstr "(Feedentitäten maskiert)" +msgstr "(Feed-Entitäten maskiert)" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "Feed führte zum Absturz von XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "erstelle neue Seite %s" #: ../IkiWiki/Plugin/amazon_s3.pm:31 msgid "deleting bucket.." -msgstr "" +msgstr "Lösche Bucket..." -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "fertig" #: ../IkiWiki/Plugin/amazon_s3.pm:97 #, perl-format msgid "Must specify %s" -msgstr "" +msgstr "%s muss angegeben werden" #: ../IkiWiki/Plugin/amazon_s3.pm:136 msgid "Failed to create bucket in S3: " -msgstr "" +msgstr "Konnte keinen Bucket in S3 erstellen: " #: ../IkiWiki/Plugin/amazon_s3.pm:221 -#, fuzzy msgid "Failed to save file to S3: " -msgstr "Es konnte keine E-Mail versandt werden" +msgstr "Konnte Datei nicht bei S3 speichern: " #: ../IkiWiki/Plugin/amazon_s3.pm:243 -#, fuzzy msgid "Failed to delete file from S3: " -msgstr "konnte kein Bild aus dem Code erzeugen" +msgstr "Konnte Datei nicht bei S3 löschen: " -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" -msgstr "" +msgstr "eine Seite mit dem Namen %s existiert bereits" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" -msgstr "" +msgstr "durch allowed_attachements verboten" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" -msgstr "" +msgstr "fehlerhafter Dateiname für Anhang" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" -msgstr "" +msgstr "Anhang hochladen" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" -msgstr "" +msgstr "automatische Index-Erstellung" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" +"Entschuldigung, aber blogspam stuft das " +"als Spam ein: " + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -188,6 +202,74 @@ msgstr "%s von %s" msgid "There are no broken links!" msgstr "Es gibt keine ungültigen Links!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "nicht unterstütztes Seitenformat %s" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "Kommentare dürfen nicht leer sein." + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "Anonymer Benutzer" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "fehlerhafter Seitenname" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, perl-format +msgid "commenting on %s" +msgstr "kommentiere %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" +"Die Seite »%s« existiert nicht, deshalb können Sie sie nicht kommentieren." + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" +"Es können keine weiteren Kommentare für die Seite »%s« abgegeben werden." + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "Kommentar wurde gespeichert und erwartet Freischaltung." + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" +"Ihr Kommentar wird freigegeben, nachdem ein Moderator ihn überprüft hat." + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "Kommentar hinzugefügt." + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "Kommentar hinzugefügt: %s" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "Sie sind nicht als Administrator angemeldet" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "Kommentarmoderation" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "Kommentarmoderation" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "Kommentare" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -197,31 +279,31 @@ msgstr "der Parameter %s wird benötigt" #: ../IkiWiki/Plugin/cutpaste.pm:66 msgid "no text was copied in this page" -msgstr "" +msgstr "es wurde kein Text in diese Seite kopiert" #: ../IkiWiki/Plugin/cutpaste.pm:69 #, perl-format msgid "no text was copied in this page with id %s" -msgstr "" +msgstr "es wurde kein Text in die Seite mit der ID %s kopiert" #: ../IkiWiki/Plugin/editpage.pm:40 -#, fuzzy, perl-format +#, perl-format msgid "removing old preview %s" -msgstr "entferne alte Seite %s" +msgstr "entferne alte Vorschau %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" -msgstr "%s ist keine bearbeitbare Seite" +msgstr "Die Seite %s kann nicht bearbeitet werden" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "erstelle %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "bearbeite %s" @@ -237,37 +319,71 @@ msgstr "Übereinstimmung nicht angegeben" #: ../IkiWiki/Plugin/edittemplate.pm:62 #, perl-format msgid "edittemplate %s registered for %s" -msgstr "»edittemplate« %s registriert für %s" +msgstr "»edittemplate« %s für %s registriert." #: ../IkiWiki/Plugin/edittemplate.pm:133 msgid "failed to process" -msgstr "Bearbeitung fehlgeschlagen" +msgstr "Verarbeitung fehlgeschlagen" + +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "Format und Text müssen spezifiziert werden" #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "»fortune« fehlgeschlagen" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" -msgstr "URL in HTML nicht gefunden" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "es ist Ihnen nicht erlaubt, %s zu ändern" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "Sie können Dateien mit den Zugriffsrechten %s nicht verändern" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "Es ist Ihnen nicht erlaubt, Dateizugriffsrechte zu ändern" + +#: ../IkiWiki/Plugin/google.pm:27 +#, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "" +"%s muss angegeben werden, wenn die Google-Sucherweiterung verwandt wird" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" +"Verarbeiten der URL fehlgeschlagen, konnte Domainnamen nicht feststellen" + +#: ../IkiWiki/Plugin/goto.pm:49 +msgid "missing page" +msgstr "fehlende Seite" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "Die Seite %s existiert nicht." #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" -msgstr "konnte graphviz nicht ausführen" +msgstr "graphviz konnte nicht ausgeführt werden" #: ../IkiWiki/Plugin/graphviz.pm:94 msgid "prog not a valid graphviz program" msgstr "prog ist kein gültiges graphviz-Programm" #: ../IkiWiki/Plugin/img.pm:62 -#, fuzzy msgid "Image::Magick is not installed" -msgstr "polygen ist nicht installiert" +msgstr "Image::Magick ist nicht installiert" #: ../IkiWiki/Plugin/img.pm:69 #, perl-format msgid "bad size \"%s\"" -msgstr "falsche Größe \"%s\"" +msgstr "falsche Größe »%s«" #: ../IkiWiki/Plugin/img.pm:80 ../IkiWiki/Plugin/img.pm:84 #: ../IkiWiki/Plugin/img.pm:101 @@ -285,73 +401,76 @@ msgstr "Größenänderung fehlgeschlagen: %s" msgid "failed to determine size of image %s" msgstr "Größe des Bildes %s konnte nicht festgestellt werden." -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Die URL zum Wiki muss mit --url angegeben werden, wenn --rss oder --atom " "genutzt wird" -#: ../IkiWiki/Plugin/inline.pm:139 -#, fuzzy +#: ../IkiWiki/Plugin/inline.pm:138 msgid "page editing not allowed" -msgstr "Zyklische Umleitungen sind nicht erlaubt" +msgstr "Seitenbearbeitungen sind nicht erlaubt" -#: ../IkiWiki/Plugin/inline.pm:156 -#, fuzzy +#: ../IkiWiki/Plugin/inline.pm:155 msgid "missing pages parameter" -msgstr "Parameter %s fehlt" +msgstr "Fehlender Seitenparameter" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "Unbekannter Sortierungstyp %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Füge einen neuen Beitrag hinzu. Titel:" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "nicht-vorhandene Vorlage %s" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Diskussion" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" -msgstr "RPC::XML::Client nicht gefunden, pinge nicht" +msgstr "RPC::XML::Client nicht gefunden, führe Ping nicht aus" #: ../IkiWiki/Plugin/linkmap.pm:106 msgid "failed to run dot" msgstr "dot konnte nicht ausgeführt werden" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 -#, fuzzy, perl-format +#: ../IkiWiki/Plugin/lockedit.pm:47 +#, perl-format msgid "%s is locked and cannot be edited" -msgstr "%s wurde von %s gesperrt und kann nicht bearbeitet werden" +msgstr "%s wurde gesperrt und kann nicht bearbeitet werden" #: ../IkiWiki/Plugin/mdwn.pm:44 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed" msgstr "" +"»multimarkdown« ist aktiviert, aber Text::MultiMarkdown ist nicht installiert" #: ../IkiWiki/Plugin/mdwn.pm:67 #, perl-format msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)" msgstr "" -"Laden des des Perl-Moduls »Markdown.pm« (%s) oder von »/usr/bin/markdown« (%s) " +"Laden des Perl-Moduls »Markdown.pm« (%s) oder »/usr/bin/markdown« (%s) " "fehlgeschlagen" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "Stylesheet nicht gefunden" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 msgid "redir page not found" msgstr "Umleitungsseite nicht gefunden" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 msgid "redir cycle is not allowed" msgstr "Zyklische Umleitungen sind nicht erlaubt" @@ -398,6 +517,8 @@ msgstr "Konto konnte nicht erstellt werden." #: ../IkiWiki/Plugin/passwordauth.pm:257 msgid "No email address, so cannot email password reset instructions." msgstr "" +"Keine E-Mail-Adresse angegeben; deshalb können keine Anweisungen zum " +"Zurücksetzen des Passworts via E-Mail versandt werden." #: ../IkiWiki/Plugin/passwordauth.pm:291 msgid "Failed to send mail" @@ -405,38 +526,37 @@ msgstr "Es konnte keine E-Mail versandt werden" #: ../IkiWiki/Plugin/passwordauth.pm:293 msgid "You have been mailed password reset instructions." -msgstr "" +msgstr "Ihnen wurden Anweisungen zum Zurücksetzen des Passworts zugesandt." #: ../IkiWiki/Plugin/passwordauth.pm:328 msgid "incorrect password reset url" -msgstr "" +msgstr "Fehlerhafte URL zum Zurücksetzen des Passworts" #: ../IkiWiki/Plugin/passwordauth.pm:331 msgid "password reset denied" -msgstr "" +msgstr "Zurücksetzen des Passworts abgelehnt" #: ../IkiWiki/Plugin/pingee.pm:30 msgid "Ping received." -msgstr "" +msgstr "Ping empfangen." #: ../IkiWiki/Plugin/pinger.pm:53 msgid "requires 'from' and 'to' parameters" -msgstr "" +msgstr "erfordert die Parameter »from« und »to«" #: ../IkiWiki/Plugin/pinger.pm:58 -#, fuzzy, perl-format +#, perl-format msgid "Will ping %s" -msgstr "bearbeite %s" +msgstr "Werde Ping an %s senden" #: ../IkiWiki/Plugin/pinger.pm:61 #, perl-format msgid "Ignoring ping directive for wiki %s (this wiki is %s)" -msgstr "" +msgstr "Ignoriere Ping-Direktiven für Wiki %s (dies ist Wiki %s)" #: ../IkiWiki/Plugin/pinger.pm:77 -#, fuzzy msgid "LWP not found, not pinging" -msgstr "RPC::XML::Client nicht gefunden, pinge nicht" +msgstr "LWP nicht gefunden, führe Ping nicht aus" #: ../IkiWiki/Plugin/poll.pm:69 msgid "vote" @@ -451,9 +571,8 @@ msgid "polygen not installed" msgstr "polygen ist nicht installiert" #: ../IkiWiki/Plugin/polygen.pm:60 -#, fuzzy msgid "command failed" -msgstr "»fortune« fehlgeschlagen" +msgstr "Befehl fehlgeschlagen" #: ../IkiWiki/Plugin/postsparkline.pm:41 msgid "missing formula" @@ -469,11 +588,11 @@ msgstr "unbekannte Formel" #. translators: %A- is the name of the previous day. #: ../IkiWiki/Plugin/prettydate.pm:15 msgid "late %A- night" -msgstr "spät am %A- in der Nacht" +msgstr "%A- spät in der Nacht" #: ../IkiWiki/Plugin/prettydate.pm:17 msgid "in the wee hours of %A- night" -msgstr "in den frühen Morgenstunden %A-" +msgstr "%A- in den frühen Morgenstunden" #: ../IkiWiki/Plugin/prettydate.pm:20 msgid "terribly early %A morning" @@ -525,109 +644,103 @@ msgstr "um Mitternacht" #: ../IkiWiki/Plugin/prettydate.pm:108 msgid "at noon on %A" -msgstr "am Nachmittag des %A" +msgstr "%A am Nachmittag" #: ../IkiWiki/Plugin/progress.pm:34 #, perl-format msgid "illegal percent value %s" -msgstr "" +msgstr "Unzulässiger Prozentwert (%s)" #: ../IkiWiki/Plugin/progress.pm:59 msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" +"Es werden entweder »percent«- oder »totalpages«- und »donepages«-Parameter " +"benötigt" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -msgid "missing page" -msgstr "fehlende Seite" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "Die Seite %s exisitiert nicht." - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" -msgstr "" +msgstr "(Diff verkürzt)" #: ../IkiWiki/Plugin/remove.pm:31 ../IkiWiki/Plugin/rename.pm:36 -#, fuzzy, perl-format +#, perl-format msgid "%s does not exist" -msgstr "Die Seite %s exisitiert nicht." +msgstr "%s existiert nicht" #: ../IkiWiki/Plugin/remove.pm:38 -#, fuzzy, perl-format +#, perl-format msgid "%s is not in the srcdir, so it cannot be deleted" -msgstr "%s wurde von %s gesperrt und kann nicht bearbeitet werden" +msgstr "" +"%s ist nicht im Quellverzeichnis und kann deshalb nicht gelöscht werden" #: ../IkiWiki/Plugin/remove.pm:41 ../IkiWiki/Plugin/rename.pm:45 -#, fuzzy, perl-format +#, perl-format msgid "%s is not a file" -msgstr "%s ist keine bearbeitbare Seite" +msgstr "%s ist keine Datei" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" -msgstr "" +msgstr "Bestätigen Sie die Entfernung von %s" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." -msgstr "" +msgstr "Bitte wählen Sie die zu entfernenden Anhänge aus." -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" -msgstr "" +msgstr "entfernt" #: ../IkiWiki/Plugin/rename.pm:42 #, perl-format msgid "%s is not in the srcdir, so it cannot be renamed" msgstr "" +"%s ist nicht im Quellverzeichnis und kann deshalb nicht umbenannt werden" #: ../IkiWiki/Plugin/rename.pm:62 -#, fuzzy msgid "no change to the file name was specified" -msgstr "Dateiname des Wrappers nicht angegeben" +msgstr "Es wurde keine Änderung des Dateinames angegeben" #: ../IkiWiki/Plugin/rename.pm:68 #, perl-format msgid "illegal name" -msgstr "" +msgstr "unzulässiger Name" #: ../IkiWiki/Plugin/rename.pm:73 #, perl-format msgid "%s already exists" -msgstr "" +msgstr "%s existiert bereits" #: ../IkiWiki/Plugin/rename.pm:79 #, perl-format msgid "%s already exists on disk" -msgstr "" +msgstr "%s existiert bereits auf der Festplatte" #: ../IkiWiki/Plugin/rename.pm:101 -#, fuzzy, perl-format +#, perl-format msgid "rename %s" -msgstr "erzeuge %s" +msgstr "benenne %s um" #: ../IkiWiki/Plugin/rename.pm:138 msgid "Also rename SubPages and attachments" -msgstr "" +msgstr "Auch Unterseiten und Anhänge umbenennen" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." -msgstr "" +msgstr "Es kann immer nur ein Anhang gleichzeitig umbenannt werden." -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." -msgstr "" +msgstr "Bitte wählen Sie den umzubenennenden Anhang aus." -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" -msgstr "" +msgstr "Benenne %s in %s um" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, perl-format msgid "update for rename of %s to %s" -msgstr "" +msgstr "Aktualisierung für Umbenennung von %s in %s" #: ../IkiWiki/Plugin/search.pm:36 #, perl-format @@ -637,35 +750,36 @@ msgstr "%s muss angegeben werden, wenn die Sucherweiterung verwandt wird" #: ../IkiWiki/Plugin/search.pm:182 #, perl-format msgid "need Digest::SHA1 to index %s" -msgstr "" +msgstr "Benötige Digest::SHA1, um %s zu indexieren" #: ../IkiWiki/Plugin/search.pm:217 msgid "search" -msgstr "" +msgstr "suchen" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" -msgstr "das »shortcut«-Plugin funktioniert nicht ohne eine »shortcuts.mdwn«" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" +msgstr "die »shortcut«-Erweiterung funktioniert nicht ohne %s" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "fehlender Name oder URL-Parameter" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" -msgstr "Shortcut %s zeigt auf %s" +msgstr "Tastenkürzel %s verweist auf %s" #: ../IkiWiki/Plugin/smiley.pm:43 msgid "failed to parse any smileys" -msgstr "Smileys konnten nicht geparst werden" +msgstr "Smileys konnten nicht verarbeitet werden" #: ../IkiWiki/Plugin/sparkline.pm:72 msgid "parse error" -msgstr "Parse-Fehler" +msgstr "Verarbeitungsfehler" #: ../IkiWiki/Plugin/sparkline.pm:78 msgid "bad featurepoint diameter" @@ -693,39 +807,39 @@ msgstr "fehlerhafte Breitenangabe" #: ../IkiWiki/Plugin/sparkline.pm:153 msgid "failed to run php" -msgstr "konnte PHP nicht ausführen" +msgstr "PHP konnte nicht ausgeführt werden" #: ../IkiWiki/Plugin/table.pm:31 msgid "cannot find file" -msgstr "konnte Datei nicht finden" +msgstr "Datei konnte nicht gefunden werden" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "unbekanntes Datenformat" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "keine Daten" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Direkter Daten-Download" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" -msgstr "Parse-Fehler in Zeile %d: %s" +msgstr "Verarbeitungsfehler in Zeile %d: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "fehlender »id«-Parameter" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "Vorlage %s nicht gefunden" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "Verarbeitung fehlgeschlagen von:" @@ -743,45 +857,55 @@ msgstr "konnte kein Bild aus dem Code erzeugen" #: ../IkiWiki/Plugin/websetup.pm:89 msgid "plugin" -msgstr "" +msgstr "Erweiterung" #: ../IkiWiki/Plugin/websetup.pm:108 #, perl-format msgid "enable %s?" -msgstr "" - -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" +msgstr "%s aktivieren?" #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" -msgstr "" +msgstr "Die Einrichtungsdatei für dieses Wiki ist unbekannt" #: ../IkiWiki/Plugin/websetup.pm:256 -#, fuzzy msgid "main" -msgstr "Administrator" +msgstr "Hauptseite" #: ../IkiWiki/Plugin/websetup.pm:257 msgid "plugins" -msgstr "" +msgstr "Erweiterungen" #: ../IkiWiki/Plugin/websetup.pm:395 msgid "" "The configuration changes shown below require a wiki rebuild to take effect." msgstr "" +"Die unten aufgeführten Konfigurationsänderungen erfordern eine erneute " +"Erzeugung des Wikis, um aktiviert zu werden." #: ../IkiWiki/Plugin/websetup.pm:399 msgid "" "For the configuration changes shown below to fully take effect, you may need " "to rebuild the wiki." msgstr "" +"Damit die unten aufgeführten Konfigurationsänderungen aktiviert werden, kann " +"es erforderlich sein, das Wiki neu zu erzeugen." #: ../IkiWiki/Plugin/websetup.pm:433 #, perl-format msgid "

Error: %s exited nonzero (%s)" msgstr "" +"

Fehler: %s beendete sich mit einem Wert ungleich Null (%s)" + +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "Kann ID des nicht vertrauenswürdigen Bearbeiters %s nicht feststellen" + +#: ../IkiWiki/Receive.pm:85 +#, perl-format +msgid "bad file name %s" +msgstr "fehlerhafter Dateiname %s" #: ../IkiWiki/Render.pm:253 #, perl-format @@ -789,6 +913,8 @@ msgid "" "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to " "allow this" msgstr "" +"Symbolischer Verweis im Quellverzeichnis (%s) gefunden -- setzen Sie " +"allow_symlinks_before_srcdir, um dies zu erlauben" #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302 #, perl-format @@ -798,7 +924,7 @@ msgstr "überspringe fehlerhaften Dateinamen %s" #: ../IkiWiki/Render.pm:284 #, perl-format msgid "%s has multiple possible source pages" -msgstr "" +msgstr "%s hat mehrere mögliche Quellseiten" #: ../IkiWiki/Render.pm:360 #, perl-format @@ -818,12 +944,12 @@ msgstr "erzeuge %s" #: ../IkiWiki/Render.pm:426 #, perl-format msgid "rendering %s, which links to %s" -msgstr "erzeuge %s, was auf %s verweist" +msgstr "erzeuge %s, die auf %s verlinkt" #: ../IkiWiki/Render.pm:447 #, perl-format msgid "rendering %s, which depends on %s" -msgstr "erzeuge %s, das von %s abhängt" +msgstr "erzeuge %s, die von %s abhängt" #: ../IkiWiki/Render.pm:486 #, perl-format @@ -847,18 +973,19 @@ msgstr "ikiwiki: kann %s nicht erzeugen" msgid "cannot read %s: %s" msgstr "kann %s nicht lesen: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" +"Sie müssen einen Wiki-Namen eingeben (der alphanumerische Zeichen enthält)" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" -msgstr "" +msgstr "Nicht unterstütztes Versionskontrollsystem %s" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" -msgstr "" +msgstr "Erstellen des Depots mit ikiwiki-makerepo ist fehlgeschlagen" #: ../IkiWiki/Wrapper.pm:16 #, perl-format @@ -873,104 +1000,85 @@ msgstr "Kann keinen Wrapper erzeugen, der eine Einrichtungsdatei verwendet" msgid "wrapper filename not specified" msgstr "Dateiname des Wrappers nicht angegeben" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "schreiben von %s fehlgeschlagen: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" -msgstr "erzeugen von %s fehlgeschlagen" +msgstr "Erzeugen von %s fehlgeschlagen" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "%s wurde erfolgreich erstellt" #: ../ikiwiki.in:13 msgid "usage: ikiwiki [options] source dest" -msgstr "Benutzung: ikiwiki [Optionen] Quelle Ziel" +msgstr "Aufruf: ikiwiki [Optionen] Quelle Ziel" #: ../ikiwiki.in:14 msgid " ikiwiki --setup configfile" -msgstr "" +msgstr " ikiwiki --setup Konfigurationsdatei " -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" -msgstr "Benutzung: --set Variable=Wert" +msgstr "Aufruf: --set Variable=Wert" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." -msgstr "erzeuge Wrapper.." +msgstr "erzeuge Wrapper..." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." -msgstr "erzeuge Wiki neu.." +msgstr "erzeuge Wiki neu..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." -msgstr "aktualisiere Wiki.." +msgstr "aktualisiere Wiki..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" "Es muss eine URL zum Wiki mit --url angegeben werden, wenn --cgi verwandt " "wird" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" +"Es können nicht mehrere Versionskontrollsystem-Erweiterungen verwandt werden" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" -msgstr "" +msgstr "Laden der für %s benötigten externen Erweiterung fehlgeschlagen: %s" -#: ../IkiWiki.pm:1136 -#, fuzzy, perl-format +#: ../IkiWiki.pm:1194 +#, perl-format msgid "preprocessing loop detected on %s at depth %i" -msgstr "Präprozessorschleife %s auf Seite %s in Tiefe %i erkannt" +msgstr "Präprozessorschleife auf %s in Tiefe %i erkannt" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" -msgstr "" +msgstr "ja" #: ../auto.setup:16 msgid "What will the wiki be named?" -msgstr "" +msgstr "Wie soll das Wiki heißen?" #: ../auto.setup:16 msgid "wiki" -msgstr "" +msgstr "Wiki" #: ../auto.setup:18 msgid "What revision control system to use?" -msgstr "" +msgstr "Welches Versionskontrollsystem soll verwandt werden?" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" +"Welcher Wiki-Benutzer (oder welche OpenID) soll der Administrator des Wikis " +"sein?" #: ../auto.setup:23 msgid "What is the domain name of the web server?" -msgstr "" - -#~ msgid "Your password has been emailed to you." -#~ msgstr "Ihr Passwort wurde Ihnen via E-Mail zugesandt." - -#~ msgid "polygen failed" -#~ msgstr "polygen fehlgeschlagen" - -#~ msgid "cleaning hyperestraier search index" -#~ msgstr "bereinige hyperestraier-Suchindex" - -#~ msgid "updating hyperestraier search index" -#~ msgstr "aktualisiere hyperestraier-Suchindex" - -#~ msgid "(not toggleable in preview mode)" -#~ msgstr "(nicht aus-/einklappbar im Vorschaumodus)" +msgstr "Wie lautet der Domainname des Webservers?" diff --git a/po/es.po b/po/es.po index ff02ea86a..f7887ad7c 100644 --- a/po/es.po +++ b/po/es.po @@ -1,127 +1,140 @@ +# translation of es.po to spanish +# translation of es.po to # ikiwiki spanish translation -# Copyright (C) 2007 The Free Software Foundation, Inc +# Copyright (C) 2007, 2009 The Free Software Foundation, Inc # This file is distributed under the same license as the ikiwiki package. # -# Víctor Moral , 2007. +# Víctor Moral , 2007, 2009. +# Victor Moral , 2009. msgid "" msgstr "" "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-08 17:34-0400\n" -"PO-Revision-Date: 2008-10-07 12:44+0200\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" +"PO-Revision-Date: 2009-03-03 10:48+0100\n" "Last-Translator: Víctor Moral \n" -"Language-Team: Spanish \n" +"Language-Team: spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" #: ../IkiWiki/CGI.pm:113 msgid "You need to log in first." msgstr "Antes es necesario identificarse." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" +"probablemente algo está mal configurado: la característica 'sslcookie' está " +"activa, pero está intentando registrarse en el sistema vía el protocolo " +"'http' y no 'https'" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" "registro fallido, ¿ tal vez necesita activar las cookies en el navegador ?" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "Su registro en el sistema ha expirado." -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "Identificación" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "Preferencias" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "Administración" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Las preferencias se han guardado." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Ha sido expulsado." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Error" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "Contenido añadido activado vía web." -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" "¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "falta el parámetro %s" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "nueva entrada" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "entradas" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "nuevo" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "%s caducada (%s días de antigüedad)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "%s caducada" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "proceso completado con éxito a %s" +msgid "last checked %s" +msgstr "última comprobación el %s" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "comprobando fuente de datos %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "no puedo encontrar la fuente de datos en %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "fuente de datos no encontrada" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "(una secuencia UTF-8 inválida ha sido eliminada de la fuente de datos)" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "(los caracteres especiales de la fuente de datos están exceptuados)" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "¡ la fuente de datos ha provocado un error fatal en XML::Feed !" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "creando nueva página %s" @@ -130,7 +143,7 @@ msgstr "creando nueva página %s" msgid "deleting bucket.." msgstr "borrando el directorio.." -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "completado" @@ -151,20 +164,20 @@ msgstr "No puedo guardar el archivo en S3: " msgid "Failed to delete file from S3: " msgstr "No puedo borrar archivo en S3: " -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "ya existe una página de nombre %s" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "prohibido por la claúsula allowed_attachments" -#: ../IkiWiki/Plugin/attachment.pm:189 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "nombre de archivo adjunto erróneo" -#: ../IkiWiki/Plugin/attachment.pm:231 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "enviado el adjunto" @@ -172,8 +185,16 @@ msgstr "enviado el adjunto" msgid "automatic index generation" msgstr "creación de índice automática" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" +"Lo siento, pero el analizador blogspam " +"dice que el texto puede ser spam." + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -188,6 +209,71 @@ msgstr "%s desde la página %s" msgid "There are no broken links!" msgstr "¡ No hay enlaces rotos !" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "formato de página %s no soportado" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "Un comentario debe tener algún contenido" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "Anónimo" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "nombre de página erróneo" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, perl-format +msgid "commenting on %s" +msgstr "creando comentarios en la página %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "la página '%s' no existe, así que no se puede comentar sobre ella" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "los comentarios para la página '%s' están cerrados" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "comentario guardado a la espera de aprobación" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "Su comentario será publicado después de que el moderador lo revise" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "Añadir un comentario" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "Comentario añadido: %s" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "No está registrado como un administrador" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "Aprobación de comentarios" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "aprobación de comentarios" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "Comentarios" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -209,19 +295,19 @@ msgstr "no se ha copiado ningún texto con el identificador %s en esta pagina" msgid "removing old preview %s" msgstr "eliminando la antigua previsualización %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "la página %s no es modificable" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "creando página %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "modificando página %s" @@ -243,14 +329,49 @@ msgstr "plantilla de edición %s registrada para %s" msgid "failed to process" msgstr "fallo en el proceso" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "se deben especificar tanto el formato como el texto" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "el programa fortune ha fallado" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "No puede cambiar %s" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "no puede actuar sobre un archivo con permisos %s" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "No puede cambiar los permisos de acceso de un archivo" + +#: ../IkiWiki/Plugin/google.pm:27 +#, perl-format +msgid "Must specify %s when using the google search plugin" msgstr "" -"El complemento googlecalendar no ha encontrado un URL en el código html " +"Es obligatorio indicar %s cuando se utiliza el complemento de búsqueda de " +"google" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" +"Error en el análisis del URL, no puedo determinar el nombre del dominio" + +#: ../IkiWiki/Plugin/goto.pm:49 +msgid "missing page" +msgstr "página no encontrada" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "No existe la página %s." #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" @@ -278,46 +399,50 @@ msgstr "no puedo leer de %s: %s " #: ../IkiWiki/Plugin/img.pm:87 #, perl-format msgid "failed to resize: %s" -msgstr "redimensionado fallido: %s" +msgstr "dimensionamiento fallido: %s" #: ../IkiWiki/Plugin/img.pm:118 #, perl-format msgid "failed to determine size of image %s" msgstr "no he podido determinar el tamaño de la imagen %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Es obligatorio indicar un url al wiki cuando se usan los parámetros --rss ó " "--atom" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 msgid "page editing not allowed" msgstr "no está permitida la modificación de páginas" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 msgid "missing pages parameter" msgstr "falta el parámetro pages" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "no conozco este tipo de ordenación %s" -#: ../IkiWiki/Plugin/inline.pm:285 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Añadir una entrada nueva titulada:" -#: ../IkiWiki/Plugin/inline.pm:301 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "la plantilla %s no existe " -#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Comentarios" -#: ../IkiWiki/Plugin/inline.pm:571 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna" @@ -325,7 +450,7 @@ msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna msgid "failed to run dot" msgstr "no he podido ejecutar el programa dot" -#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, perl-format msgid "%s is locked and cannot be edited" msgstr "La página %s está bloqueada y no puede modificarse" @@ -342,15 +467,15 @@ msgstr "" "no he podido cargar el módulo Perl Markdown.pm (%s) ó no he podido ejecutar " "el programa /usr/bin/markdown (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "hoja de estilo no encontrada " -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 msgid "redir page not found" msgstr "falta la página a donde redirigir" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 msgid "redir cycle is not allowed" msgstr "ciclo de redirección no permitido" @@ -407,7 +532,7 @@ msgstr "No he podido enviar el mensaje de correo electrónico" #: ../IkiWiki/Plugin/passwordauth.pm:293 msgid "You have been mailed password reset instructions." msgstr "" -"Las instrucciones para reinicar la contraseña se le han enviado por correo " +"Las instrucciones para reiniciar la contraseña se le han enviado por correo " "electrónico" #: ../IkiWiki/Plugin/passwordauth.pm:328 @@ -537,16 +662,7 @@ msgstr "%s es un valor erróneo para un porcentaje" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "son necesarios los parámetros 'donepages' y 'percent' ó 'totalpages'" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -msgid "missing page" -msgstr "página no encontrada" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "No existe la página %s." - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "(Lista de diferencias truncada)" @@ -624,7 +740,7 @@ msgstr "Por favor, seleccione el adjunto al que cambiar el nombre." msgid "rename %s to %s" msgstr "%s cambia de nombre a %s" -#: ../IkiWiki/Plugin/rename.pm:490 +#: ../IkiWiki/Plugin/rename.pm:493 #, perl-format msgid "update for rename of %s to %s" msgstr "actualizado el cambio de nombre de %s a %s" @@ -643,18 +759,19 @@ msgstr "se necesita la instalación de Digest::SHA1 para indexar %s" msgid "search" msgstr "buscar" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" -msgstr "el complemento shortcut no funciona sin una página shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" +msgstr "el complemento shortcut no funcionará si no existe la página %s" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "shortcut necesita el parámetro 'name' ó el parámetro 'url'" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "El atajo %s apunta a %s" @@ -699,33 +816,33 @@ msgstr "error fatal invocando el programa php" msgid "cannot find file" msgstr "no puedo encontrar el archivo" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "formato de datos desconocido" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "sin datos" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Enlace directo para descarga" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "error de análisis en la línea %d: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "falta el parámetro \"id\"" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "no he encontrado la plantilla %s" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "se ha producido un error fatal mientras procesaba la plantilla:" @@ -750,10 +867,6 @@ msgstr "complemento" msgid "enable %s?" msgstr "¿ activar %s ?" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "No está registrado como un administrador" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "El archivo de configuración para este wiki es desconocido" @@ -786,6 +899,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "

Error: %s finaliza con código distinto de cero (%s)" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "no puedo determinar el identificador de un usuario no fiable como %s" + +#: ../IkiWiki/Receive.pm:85 +#, perl-format +msgid "bad file name %s" +msgstr "el nombre de archivo %s es erróneo" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -845,7 +968,7 @@ msgstr "eliminando la página %s puesto que ya no se deriva de %s" #: ../IkiWiki/Render.pm:522 #, perl-format msgid "ikiwiki: cannot render %s" -msgstr "ikwiki: no puedo convertir la página %s" +msgstr "ikiwiki: no puedo convertir la página %s" #. translators: The first parameter is a filename, and the second #. translators: is a (probably not translated) error message. @@ -854,16 +977,16 @@ msgstr "ikwiki: no puedo convertir la página %s" msgid "cannot read %s: %s" msgstr "no puedo leer el archivo %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "debe escribir un nombre wiki (que contiene caracteres alfanuméricos)" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "el sistema de control de versiones %s no está soportado" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "no he podido crear un repositorio con el programa ikiwiki-makerepo" @@ -881,21 +1004,14 @@ msgstr "" msgid "wrapper filename not specified" msgstr "el programa envoltorio no ha sido especificado" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "no puedo escribir en %s: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "ha fallado la compilación del programa %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "creado con éxito el programa envoltorio %s" @@ -908,45 +1024,45 @@ msgstr "uso: ikiwiki [opciones] origen destino" msgid " ikiwiki --setup configfile" msgstr " ikiwiki --setup archivo_de_configuración" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "uso: --set variable=valor" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "generando programas auxiliares.." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "reconstruyendo el wiki.." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "actualizando el wiki.." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" "Es obligatorio especificar un url al wiki con el parámetro --url si se " "utiliza el parámetro --cgi" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "no puedo emplear varios complementos rcs" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "no he podido cargar el complemento externo %s necesario para %s" -#: ../IkiWiki.pm:1149 +#: ../IkiWiki.pm:1194 #, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "" "se ha detectado en la página %s un bucle de preprocesado en la iteración " "número %i" -#: ../IkiWiki.pm:1658 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "si" @@ -963,58 +1079,11 @@ msgid "What revision control system to use?" msgstr "¿ Qué sistema de control de versiones empleará ?" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" -"¿ Qué usuario del wiki (ó identificador openid) será el administrador del " -"wiki ? " +"¿ Qué usuario del wiki (ó qué identificador openid) será el empleado como " +"administrador ? " #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "¿ Cuál es el dominio para el servidor web ?" - -#~ msgid "Your password has been emailed to you." -#~ msgstr "Se le ha enviado su contraseña por correo electrónico." - -#~ msgid "polygen failed" -#~ msgstr "El programa polygen ha fallado" - -#~ msgid "cleaning hyperestraier search index" -#~ msgstr "limpiando el índice de búsquedas de hyperestraier" - -#~ msgid "updating hyperestraier search index" -#~ msgstr "actualizando el índice de búsquedas de hyperstraier" - -#~ msgid "(not toggleable in preview mode)" -#~ msgstr "(no se puede cambiar en el modo de previsualización)" - -#~ msgid "" -#~ "REV is not set, not running from mtn post-commit hook, cannot send " -#~ "notifications" -#~ msgstr "" -#~ "La variable de entorno REV no está definida, por lo que no puede " -#~ "funcionar svn post-commit desde monotone; no puedo enviar ninguna " -#~ "notificación" - -#~ msgid "REV is not a valid revision identifier, cannot send notifications" -#~ msgstr "" -#~ "REV no es un identificador de revisión válido, por lo que no puedo enviar " -#~ "ninguna notificación" - -#~ msgid "" -#~ "REV is not set, not running from svn post-commit hook, cannot send " -#~ "notifications" -#~ msgstr "" -#~ "La variable de entorno REV no está definida, por lo que no puede " -#~ "funcionar svn post-commit; no puedo enviar ninguna notificación" - -#~ msgid "link is no longer supported" -#~ msgstr "el metadato link ya no puede usarse" - -#~ msgid "%s not found" -#~ msgstr "no he encontrado la plantilla %s " - -#~ msgid "What's this?" -#~ msgstr "¿ Qué es esto ?" - -#~ msgid "(use FirstnameLastName)" -#~ msgstr "(utilice la forma NombreApellidos)" diff --git a/po/fr.po b/po/fr.po index 0c8406381..78b3bbe0f 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,132 +7,138 @@ # Cyril Brulebois , 2007. msgid "" msgstr "" -"Project-Id-Version: \n" +"Project-Id-Version: ikiwiki 3.04\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-05 19:11-0400\n" -"PO-Revision-Date: 2008-09-23 10:00+0100\n" -"Last-Translator: Julien Patriarca \n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" +"PO-Revision-Date: 2009-03-15 16:10+0100\n" +"Last-Translator: Philippe Batailler \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" #: ../IkiWiki/CGI.pm:113 msgid "You need to log in first." msgstr "Vous devez d'abord vous identifier." -#: ../IkiWiki/CGI.pm:145 -msgid "login failed, perhaps you need to turn on cookies?" +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" msgstr "" -"Échec de l'identification, vous devriez peut-être autoriser les cookies." +"Erreur de configuration probable : sslcookie est positionné mais vous tentez " +"de vous connecter avec http et non https" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:149 +msgid "login failed, perhaps you need to turn on cookies?" +msgstr "Échec de l'identification, vous devez autoriser les cookies." + +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "Session d'authentification expirée." -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "S’identifier" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "Préférences" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "Administrateur" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Les préférences ont été enregistrées." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Vous avez été banni." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Erreur" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." -msgstr "Agrégation déclenchée via Internet" +msgstr "Agrégation déclenchée par le web" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" -msgstr "Rien à faire pour le moment, tous les flux sont à jour!" +msgstr "Rien à faire pour le moment, tous les flux sont à jour !" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "Paramètre %s manquant" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "Nouveau flux" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "Articles" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "Nouveau" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "Fin de validité de %s (date de %s jours)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "Fin de validité de %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "A été correctement traité à %s" +msgid "last checked %s" +msgstr "dernière vérification : %s" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "Vérification du flux %s..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "Impossible de trouver de flux à %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "Flux introuvable " -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "(chaîne UTF-8 non valable supprimée du flux)" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "(échappement des entités de flux)" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "Plantage du flux XML::Feed !" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "Création de la nouvelle page %s" #: ../IkiWiki/Plugin/amazon_s3.pm:31 msgid "deleting bucket.." -msgstr "vidage du panier..." +msgstr "Suppression du compartiment S3 (« bucket »)..." -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "Terminé" @@ -143,39 +149,47 @@ msgstr "Vous devez spécifier %s" #: ../IkiWiki/Plugin/amazon_s3.pm:136 msgid "Failed to create bucket in S3: " -msgstr "Echec lors de la création du panier en S3:" +msgstr "Impossible de créer un compartiment S3 :" #: ../IkiWiki/Plugin/amazon_s3.pm:221 msgid "Failed to save file to S3: " -msgstr "Echec lors de la création du fichier en S3:" +msgstr "Impossible de sauvegarder le fichier dans le compartiment S3 :" #: ../IkiWiki/Plugin/amazon_s3.pm:243 msgid "Failed to delete file from S3: " -msgstr "Echec lors de la suppression du fichier de S3:" +msgstr "Échec lors de la suppression du fichier sur S3 :" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" -msgstr "il existe déjà une page nommée %s" +msgstr "Il existe déjà une page nommée %s" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" -msgstr "action interdite par pièces jointes autorisées" +msgstr "Action interdite par allowed_attachments" -#: ../IkiWiki/Plugin/attachment.pm:189 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" -msgstr "Mauvais nom de la pièce jointe" +msgstr "Nom de la pièce jointe incorrect" -#: ../IkiWiki/Plugin/attachment.pm:231 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" -msgstr "envoi de la pièce jointe" +msgstr "Envoi de la pièce jointe" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" -msgstr "génération de l'index automatique" +msgstr "Génération de l'index automatique" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" +"Désolé, mais ceci ressemble à un spam à destination de blogspam: " + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -188,18 +202,83 @@ msgstr "%s sur %s" #: ../IkiWiki/Plugin/brokenlinks.pm:56 msgid "There are no broken links!" -msgstr "Il n'existe pas de lien cassé !" +msgstr "Aucun lien cassé !" + +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "Format de page non reconnu %s" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "Un commentaire doit avoir un contenu." + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "Anonyme" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "Nom de page incorrect" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, perl-format +msgid "commenting on %s" +msgstr "Faire un commentaire sur %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "La page '%s' n'existe pas, commentaire impossible." + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "Le commentaire pour la page '%s' est terminé." + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "Le commentaire a été enregistré en attente de modération" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "Votre commentaire sera publié après que le modérateur l'ait vérifié" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "Commentaire ajouté" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "Commentaire ajouté : %s" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "Vous n'êtes pas authentifié comme administrateur" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "Modération du commentaire" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "modération du commentaire" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "Commentaires" #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 #, perl-format msgid "%s parameter is required" -msgstr "le paramètre %s est obligatoire" +msgstr "Le paramètre %s est obligatoire" #: ../IkiWiki/Plugin/cutpaste.pm:66 msgid "no text was copied in this page" -msgstr "aucun texte n'a été copié dans cette page" +msgstr "Aucun texte n'a été copié dans cette page" #: ../IkiWiki/Plugin/cutpaste.pm:69 #, perl-format @@ -207,23 +286,23 @@ msgid "no text was copied in this page with id %s" msgstr "Aucun texte n'a été copié dans cette page avec l'identifiant %s" #: ../IkiWiki/Plugin/editpage.pm:40 -#, fuzzy, perl-format +#, perl-format msgid "removing old preview %s" -msgstr "Suppression de l'ancienne page %s" +msgstr "Suppression de l'ancienne prévisualisation %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "%s n'est pas une page éditable" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "Création de %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "Édition de %s" @@ -245,13 +324,46 @@ msgstr "edittemplate %s enregistré pour %s" msgid "failed to process" msgstr "Échec du traitement" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "le format et le texte doivent être indiqués" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "Échec du lancement de « fortune »" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" -msgstr "Échec dans la recherche d'une URL dans le Code HTML" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "Vous n'êtes pas autorisé à modifier %s" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "Vous ne pouvez utiliser le mode %s pour les fichiers" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "Vous n'êtes pas autorisé à modifier le mode des fichiers" + +#: ../IkiWiki/Plugin/google.pm:27 +#, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Vous devez indiquer %s lors de l'utilisation du greffon « google »." + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "Impossible d'analyser l'url, pas de nom de domaine" + +#: ../IkiWiki/Plugin/goto.pm:49 +msgid "missing page" +msgstr "Page manquante" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "La page %s n'existe pas." #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" @@ -286,40 +398,43 @@ msgstr "Échec du redimensionnement : %s" msgid "failed to determine size of image %s" msgstr "Échec de la détermination de la taille de l'image : %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Vous devez indiquer l'URL du wiki par --url lors de l'utilisation de --rss " "ou --atom" -#: ../IkiWiki/Plugin/inline.pm:139 -#, fuzzy +#: ../IkiWiki/Plugin/inline.pm:138 msgid "page editing not allowed" -msgstr "Redirection cyclique non autorisée" +msgstr "Modification de page interdite" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 msgid "missing pages parameter" -msgstr "paramètres de la page manquants" +msgstr "Paramètre « pages » manquant" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "Type de tri %s inconnu" -#: ../IkiWiki/Plugin/inline.pm:285 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Ajouter un nouvel article dont le titre est :" -#: ../IkiWiki/Plugin/inline.pm:301 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" -msgstr "Le modèle (« template ») %s n'existe pas" +msgstr "Le modèle de page %s n'existe pas" -#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Discussion" -#: ../IkiWiki/Plugin/inline.pm:571 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "RPC::XML::Client introuvable, pas de réponse au ping" @@ -327,10 +442,10 @@ msgstr "RPC::XML::Client introuvable, pas de réponse au ping" msgid "failed to run dot" msgstr "Échec du lancement de dot" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, perl-format msgid "%s is locked and cannot be edited" -msgstr "%s est verouillé et ne peut être édité" +msgstr "%s est verrouillé et ne peut être modifié" #: ../IkiWiki/Plugin/mdwn.pm:44 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed" @@ -343,15 +458,15 @@ msgstr "" "Échec du chargement du module Perl Markdown.pm (%s) ou de /usr/bin/markdown " "(%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "Feuille de style introuvable " -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 msgid "redir page not found" -msgstr "Page de redirection introuvable " +msgstr "Page de redirection introuvable" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 msgid "redir cycle is not allowed" msgstr "Redirection cyclique non autorisée" @@ -385,7 +500,7 @@ msgstr "Toutes les pages sont liées à d'autres pages." #: ../IkiWiki/Plugin/pagetemplate.pm:30 msgid "bad or missing template" -msgstr "Modèle incorrect ou manquant" +msgstr "Modèle de page incorrect ou manquant" #: ../IkiWiki/Plugin/passwordauth.pm:247 msgid "Account creation successful. Now you can Login." @@ -398,26 +513,26 @@ msgstr "Erreur lors de la création du compte." #: ../IkiWiki/Plugin/passwordauth.pm:257 msgid "No email address, so cannot email password reset instructions." msgstr "" -"Pas d'adresse email spécifiée. Impossible d'envoyer les instructions de " -"remise à zéro du mot de passe" +"Pas d'adresse spécifiée. Impossible d'envoyer les instructions pour " +"réinitialiser le mot de passe." #: ../IkiWiki/Plugin/passwordauth.pm:291 msgid "Failed to send mail" -msgstr "Échec de l'envoi du courriel" +msgstr "Impossible d'envoyer un courriel" #: ../IkiWiki/Plugin/passwordauth.pm:293 msgid "You have been mailed password reset instructions." msgstr "" -"Vous avez reçu un message contenant les instructions de remise à zéro du mot " -"de passe" +"Vous avez reçu un message contenant les instructions pour réinitialiser le " +"mot de passe" #: ../IkiWiki/Plugin/passwordauth.pm:328 msgid "incorrect password reset url" -msgstr "Adresse de remise à zéro du mot de passe incorrecte" +msgstr "Adresse pour la réinitialisation du mot de passe incorrecte" #: ../IkiWiki/Plugin/passwordauth.pm:331 msgid "password reset denied" -msgstr "remise à zéro du mot de passe refusée" +msgstr "réinitialisation du mot de passe refusée" #: ../IkiWiki/Plugin/pingee.pm:30 msgid "Ping received." @@ -435,7 +550,7 @@ msgstr "va envoyer un ping à %s" #: ../IkiWiki/Plugin/pinger.pm:61 #, perl-format msgid "Ignoring ping directive for wiki %s (this wiki is %s)" -msgstr "les instructions du wiki %s sont ignorées (ce wiki est %s)" +msgstr "Les instructions du wiki %s sont ignorées (ce wiki est %s)" #: ../IkiWiki/Plugin/pinger.pm:77 msgid "LWP not found, not pinging" @@ -455,7 +570,7 @@ msgstr "polygen n'est pas installé" #: ../IkiWiki/Plugin/polygen.pm:60 msgid "command failed" -msgstr "Echec lors du lancement de la commande" +msgstr "Échec de la commande" #: ../IkiWiki/Plugin/postsparkline.pm:41 msgid "missing formula" @@ -503,15 +618,15 @@ msgstr "%A après-midi" #: ../IkiWiki/Plugin/prettydate.pm:32 msgid "late %A afternoon" -msgstr "tard l'après-midi de %A" +msgstr "tard dans l'après-midi de %A" #: ../IkiWiki/Plugin/prettydate.pm:33 msgid "%A evening" -msgstr "%A soir" +msgstr "%A en soirée" #: ../IkiWiki/Plugin/prettydate.pm:35 msgid "late %A evening" -msgstr "tard %A soir" +msgstr "tard %A en soirée" #: ../IkiWiki/Plugin/prettydate.pm:37 msgid "%A night" @@ -530,24 +645,16 @@ msgid "at noon on %A" msgstr "%A, à midi" #: ../IkiWiki/Plugin/progress.pm:34 -#, fuzzy, perl-format +#, perl-format msgid "illegal percent value %s" -msgstr "appellation non autorisé" +msgstr "pourcentage %s illégal" #: ../IkiWiki/Plugin/progress.pm:59 msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" +"L'un des paramètres « percent », « totalpages » ou « donepages » est nécessaire." -#: ../IkiWiki/Plugin/recentchanges.pm:100 -msgid "missing page" -msgstr "Page manquante" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "La page %s n'existe pas." - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "(fichier de différences tronqué)" @@ -566,16 +673,16 @@ msgstr "%s n'est pas dans srcdir et ne peut donc pas être supprimé" msgid "%s is not a file" msgstr "%s n'est pas un fichier" -#: ../IkiWiki/Plugin/remove.pm:113 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "Suppression de %s confirmée" -#: ../IkiWiki/Plugin/remove.pm:150 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "Veuillez choisir la pièce jointe à supprimer" -#: ../IkiWiki/Plugin/remove.pm:190 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "supprimé" @@ -591,7 +698,7 @@ msgstr "Aucun changement dans le nom du fichier n'a été spécifié" #: ../IkiWiki/Plugin/rename.pm:68 #, perl-format msgid "illegal name" -msgstr "appellation non autorisé" +msgstr "Appellation non autorisée" #: ../IkiWiki/Plugin/rename.pm:73 #, perl-format @@ -606,15 +713,15 @@ msgstr "%s existe déjà sur le disque" #: ../IkiWiki/Plugin/rename.pm:101 #, perl-format msgid "rename %s" -msgstr "%s renommé" +msgstr "%s renommé" #: ../IkiWiki/Plugin/rename.pm:138 msgid "Also rename SubPages and attachments" -msgstr "" +msgstr "« SubPages » et attachements renommés." #: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." -msgstr "Seule une pièce jointe peut être renommée à la fois" +msgstr "Une seule pièce jointe peut être renommée à la fois" #: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." @@ -623,17 +730,17 @@ msgstr "Veuillez sélectionner la pièce jointe à renommer" #: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" -msgstr "renomme %s en %s" +msgstr "Renomme %s en %s" -#: ../IkiWiki/Plugin/rename.pm:490 +#: ../IkiWiki/Plugin/rename.pm:493 #, perl-format msgid "update for rename of %s to %s" -msgstr "du nouveau nom de %s en %s" +msgstr "mise à jour, suite au changement de %s en %s" #: ../IkiWiki/Plugin/search.pm:36 #, perl-format msgid "Must specify %s when using the search plugin" -msgstr "Vous devez indiquer %s lors de l'utilisation du greffon de recherche" +msgstr "Vous devez indiquer %s lors de l'utilisation du greffon « search »." #: ../IkiWiki/Plugin/search.pm:182 #, perl-format @@ -644,19 +751,19 @@ msgstr "Digest::SHA1 est nécessaire pour indexer %s" msgid "search" msgstr "recherche" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" -msgstr "" -"Le greffon de raccourci (« shortcut ») ne fonctionnera pas sans shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" +msgstr "Le greffon « shortcut » ne fonctionnera pas sans %s" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "Il manque le paramètre nom ou URL." #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "Le raccourci %s pointe vers %s" @@ -687,7 +794,7 @@ msgstr "Hauteur incorrecte" #: ../IkiWiki/Plugin/sparkline.pm:111 msgid "missing width parameter" -msgstr "Le paramètre de largeur manque dans le modèle (« template »)" +msgstr "Le paramètre largeur manque" #: ../IkiWiki/Plugin/sparkline.pm:115 msgid "bad width value" @@ -701,33 +808,33 @@ msgstr "Échec du lancement de php" msgid "cannot find file" msgstr "Fichier introuvable" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "Format de données inconnu" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" -msgstr "Données vides" +msgstr "Pas de données" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Téléchargement direct des données" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "Erreur d'analyse à la ligne %d : %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "Paramètre d'identification manquant" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" -msgstr "Modèle (« template ») %s introuvable " +msgstr "Modèle de page %s introuvable" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "Échec du traitement :" @@ -745,34 +852,30 @@ msgstr "Échec de la création de l'image à partir du code" #: ../IkiWiki/Plugin/websetup.pm:89 msgid "plugin" -msgstr "module complémentaire" +msgstr "greffon" #: ../IkiWiki/Plugin/websetup.pm:108 #, perl-format msgid "enable %s?" -msgstr "activer %s?" - -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "vous n'êtes pas authentifié comme administrateur" +msgstr "activer %s ?" #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" -msgstr "le fichier de configuration de ce wiki n'est pas connu" +msgstr "Le fichier de configuration de ce wiki n'est pas connu" #: ../IkiWiki/Plugin/websetup.pm:256 msgid "main" -msgstr "principal" +msgstr "Partie principale" #: ../IkiWiki/Plugin/websetup.pm:257 msgid "plugins" -msgstr "modules complémentaires" +msgstr "Greffons" #: ../IkiWiki/Plugin/websetup.pm:395 msgid "" "The configuration changes shown below require a wiki rebuild to take effect." msgstr "" -"les changements de configuration ci dessous nécessitent une recompilation du " +"Les changements de configuration ci-dessous nécessitent une recompilation du " "wiki pour prendre effet" #: ../IkiWiki/Plugin/websetup.pm:399 @@ -780,13 +883,25 @@ msgid "" "For the configuration changes shown below to fully take effect, you may need " "to rebuild the wiki." msgstr "" -"Pour que les changements de configuration ci dessous prennent effet vous " +"Pour que les changements de configuration ci-dessous prennent effet vous " "devez recompiler le wiki" #: ../IkiWiki/Plugin/websetup.pm:433 #, perl-format msgid "

Error: %s exited nonzero (%s)" -msgstr "

Erreur: %s a quitté nonzero (%s)" +msgstr "" +"

Erreur : %s s'est terminé, valeur de sortie nonzero (%s)" + +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" +"Impossible de déterminer l'identifiant de %s, (enregistrement non fiable)" + +#: ../IkiWiki/Receive.pm:85 +#, perl-format +msgid "bad file name %s" +msgstr "Nom de fichier incorrect %s" #: ../IkiWiki/Render.pm:253 #, perl-format @@ -794,6 +909,8 @@ msgid "" "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to " "allow this" msgstr "" +"Lien symbolique trouvé dans l'adresse de srcdir (%s) -- pour l'autoriser, " +"activez le paramètre « allow_symlinks_before_srcdir »." #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302 #, perl-format @@ -803,7 +920,7 @@ msgstr "Omission du fichier au nom incorrect %s" #: ../IkiWiki/Render.pm:284 #, perl-format msgid "%s has multiple possible source pages" -msgstr "" +msgstr "%s peut être associé à plusieurs pages source." #: ../IkiWiki/Render.pm:360 #, perl-format @@ -813,37 +930,37 @@ msgstr "Suppression de l'ancienne page %s" #: ../IkiWiki/Render.pm:400 #, perl-format msgid "scanning %s" -msgstr "Parcours de %s" +msgstr "Examen de %s" #: ../IkiWiki/Render.pm:405 #, perl-format msgid "rendering %s" -msgstr "Affichage de %s" +msgstr "Reconstruction de %s" #: ../IkiWiki/Render.pm:426 #, perl-format msgid "rendering %s, which links to %s" -msgstr "Affichage de %s, qui est lié à %s" +msgstr "Reconstruction de %s, qui est lié à %s" #: ../IkiWiki/Render.pm:447 #, perl-format msgid "rendering %s, which depends on %s" -msgstr "Affichage de %s, qui dépend de %s" +msgstr "Reconstruction de %s, qui dépend de %s" #: ../IkiWiki/Render.pm:486 #, perl-format msgid "rendering %s, to update its backlinks" -msgstr "Affichage de %s, afin de mettre à jour ses rétroliens" +msgstr "Reconstruction de %s, afin de mettre à jour ses rétroliens" #: ../IkiWiki/Render.pm:498 #, perl-format msgid "removing %s, no longer rendered by %s" -msgstr "Suppression de %s, qui n'est plus affiché par %s" +msgstr "Suppression de %s, qui n'est plus rendu par %s" #: ../IkiWiki/Render.pm:522 #, perl-format msgid "ikiwiki: cannot render %s" -msgstr "ikiwiki : impossible d'afficher %s" +msgstr "ikiwiki : impossible de reconstruire %s" #. translators: The first parameter is a filename, and the second #. translators: is a (probably not translated) error message. @@ -852,20 +969,20 @@ msgstr "ikiwiki : impossible d'afficher %s" msgid "cannot read %s: %s" msgstr "Lecture impossible de %s : %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" "Vous devez spécifier un nom de wiki (contenant des caractères " "alphanumériques)" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" -msgstr "Système de contôles des version non supporté" +msgstr "Système de contrôle de version non reconnu : %s" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" -msgstr "Echec lors de la création du dépôt avec ikiwiki-makerepo" +msgstr "Échec lors de la création du dépôt avec ikiwiki-makerepo" #: ../IkiWiki/Wrapper.pm:16 #, perl-format @@ -879,23 +996,16 @@ msgstr "" #: ../IkiWiki/Wrapper.pm:24 msgid "wrapper filename not specified" -msgstr "Le nom de fichier de l'enrobage n'a pas été indiqué" - -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "Échec de l'écriture de %s : %s" +msgstr "Le nom du fichier CGI n'a pas été indiqué" #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "Échec de la compilation de %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "%s a été créé avec succès" @@ -906,53 +1016,50 @@ msgstr "Syntaxe : ikiwiki [options] source destination" #: ../ikiwiki.in:14 msgid " ikiwiki --setup configfile" -msgstr "" +msgstr " ikiwiki --setup fichier de configuration" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "Syntaxe : -- set var=valeur" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "Création des fichiers CGI..." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "Reconstruction du wiki..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "Rafraîchissement du wiki..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" -"Vous devez indiquer une URL vers le wiki par --url lors de l'utilisation de " -"--cgi" +"Vous devez indiquer l'URL du wiki par --url lors de l'utilisation de --cgi" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" -msgstr "" -"impossible d'utiliser plusieurs modules complémentaires dans le système de " -"contrôle des versions" +msgstr "Impossible d'utiliser plusieurs systèmes de contrôle des versions" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" -msgstr "" +msgstr "Impossible de charger le greffon externe nécessaire au greffon %s : %s" -#: ../IkiWiki.pm:1149 +#: ../IkiWiki.pm:1194 #, perl-format msgid "preprocessing loop detected on %s at depth %i" -msgstr "une boucle de pré traitement a été detectée sur %s à hauteur de %i" +msgstr "Une boucle de pré traitement a été détectée sur %s à hauteur de %i" -#: ../IkiWiki.pm:1658 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "oui" #: ../auto.setup:16 msgid "What will the wiki be named?" -msgstr "Nom du wiki" +msgstr "Nom du wiki :" #: ../auto.setup:16 msgid "wiki" @@ -960,27 +1067,12 @@ msgstr "wiki" #: ../auto.setup:18 msgid "What revision control system to use?" -msgstr "Système de contrôle de version utilisé?" +msgstr "Système de contrôle de version utilisé :" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" -msgstr "Identifiant de l'administrateur?" +msgid "What wiki user (or openid) will be admin?" +msgstr "Identifiant de l'administrateur (utilisateur du wiki ou openid) :" #: ../auto.setup:23 msgid "What is the domain name of the web server?" -msgstr "Nom de domaine du serveur HTTP?" - -#~ msgid "Your password has been emailed to you." -#~ msgstr "Votre mot de passe vous a été envoyé par courriel." - -#~ msgid "polygen failed" -#~ msgstr "Échec du lancement de polygen" - -#~ msgid "cleaning hyperestraier search index" -#~ msgstr "Nettoyage de l'index de recherche de hyperestraier" - -#~ msgid "updating hyperestraier search index" -#~ msgstr "Mise à jour de l'index de recherche de hyperestraier" - -#~ msgid "(not toggleable in preview mode)" -#~ msgstr "(non permutable en mode prévisualisation)" +msgstr "Nom de domaine du serveur HTTP :" diff --git a/po/gu.po b/po/gu.po index afde93b9e..dd9c7c5a1 100644 --- a/po/gu.po +++ b/po/gu.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki-gu\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-01-11 16:05+0530\n" "Last-Translator: Kartik Mistry \n" "Language-Team: Gujarati \n" @@ -19,108 +19,114 @@ msgstr "" msgid "You need to log in first." msgstr "તમારે પ્રથમ લોગ ઇન થવું પડશે." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "પ્રવેશ નિષ્ફળ, કદાચ તમારી કુકીઓ સક્રિય બનાવવી પડશે?" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 #, fuzzy msgid "Preferences" msgstr "પ્રાથમિકતાઓ સંગ્રહાઇ." -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "પ્રાથમિકતાઓ સંગ્રહાઇ." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "તમારા પર પ્રતિબંધ છે." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "ક્ષતિ" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "ખોવાયેલ %s વિકલ્પ" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "નવું ફીડ" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "પોસ્ટ" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "નવું" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "જુનું કરે છે %s (%s દિવસો જુનું)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "જુનું કરે છે %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "આના પર બરાબર છે %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "ફીડ %s ચકાસે છે ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "%s પર ફીડ મળી શક્યું નહી" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "ફીડ મળ્યું નહી" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, fuzzy, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "ફીડમાંથી અયોગ્ય રીતે UTF-8 નીકાળેલ છે" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "ફીડ ભાંગી ગયું XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "નવું પાનું %s બનાવે છે" @@ -129,7 +135,7 @@ msgstr "નવું પાનું %s બનાવે છે" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "સંપૂર્ણ" @@ -152,29 +158,35 @@ msgstr "મેઇલ મોકલવામાં નિષ્ફળ" msgid "Failed to delete file from S3: " msgstr "માપ બદલવામાં નિષ્ફળ: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -189,6 +201,71 @@ msgstr "" msgid "There are no broken links!" msgstr "અહીં કોઇ તૂટેલ કડી નથી!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "%s બનાવે છે" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -210,19 +287,19 @@ msgstr "" msgid "removing old preview %s" msgstr "જુનાં પાનાં દૂર કરે છે %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "%s એ સુધારી શકાય તેવું પાનું નથી" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "%s બનાવે છે" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "%s સુધારે છે" @@ -247,13 +324,47 @@ msgstr "" msgid "failed to process" msgstr "ક્રિયા કરવામાં નિષ્ફળ:" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "ભવિષ્ય નિષ્ફળ" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" -msgstr "htmlમાં યુઆરએલ શોધવામાં નિષ્ફળ" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "જ્યારે શોધ પ્લગઇન ઉપયોગ કરતા હોવ ત્યારે %s સ્પષ્ટ કરવું જ પડશે" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 +#, fuzzy +msgid "missing page" +msgstr "ખોવાયેલ કિંમતો" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 msgid "failed to run graphviz" @@ -289,39 +400,43 @@ msgstr "માપ બદલવામાં નિષ્ફળ: %s" msgid "failed to determine size of image %s" msgstr "માપ બદલવામાં નિષ્ફળ: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "--rss અથવા --atom ઉપયોગ કરતી વખતે વીકીમાં --url ઉપયોગ કરવું જ પડશે" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "ફીડ મળ્યું નહી" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "ખોવાયેલ %s વિકલ્પ" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "અજાણ્યો ગોઠવણી પ્રકાર %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "આ શિર્ષકથી નવું પોસ્ટ ઉમેરો:" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "અસ્તિત્વમાં ન હોય તેવું ટેમ્પલેટ %s" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "ચર્ચા" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "RPC::XML::Client મળ્યું નહી, પિંગ કરવામાં આવતું નથી" @@ -329,7 +444,7 @@ msgstr "RPC::XML::Client મળ્યું નહી, પિંગ કરવા msgid "failed to run dot" msgstr "ડોટ ચલાવવામાં નિષ્ફળ" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "%s એ %s દ્વારા તાળું મરાયેલ છે અને તેમાં સુધારો કરી શકાશે નહી" @@ -343,16 +458,16 @@ msgstr "" msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)" msgstr "Markdown.pm પર્લ મોડ્યુલ (%s) અથવા /usr/bin/markdown (%s) લાવવામાં નિષ્ફળ" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "સ્ટાઇલશીટ મળ્યું નહી" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "ફીડ મળ્યું નહી" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "ફીડ મળ્યું નહી" @@ -539,17 +654,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "ખોવાયેલ કિંમતો" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -568,16 +673,16 @@ msgstr "%s એ %s દ્વારા તાળું મરાયેલ છે msgid "%s is not a file" msgstr "%s એ સુધારી શકાય તેવું પાનું નથી" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -615,20 +720,20 @@ msgstr "રેન્ડર કરે છે %s" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "%s નો સુધારો %s નાં %s વડે" @@ -647,18 +752,19 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "ખોવાયેલ નામ અથવા યુઆરએલ વિકલ્પ" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "ટુંકોરસ્તો %s એ %s નો નિર્દેશ કરે છે" @@ -703,33 +809,33 @@ msgstr "php ચલાવવામાં નિષ્ફળ" msgid "cannot find file" msgstr "ફાઇલ મળી શકી નહી" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "અજાણ્યો માહિતી પ્રકાર" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "ખાલી માહિતી" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "સીધી માહિતી ડાઉનલોડ" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "ઉકેલવાનું લીટી %d પર નિષ્ફળ: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "ખોવાયેલ આઇડી વિકલ્પ" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "ટેમ્પલેટ %s મળ્યું નહી" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "ક્રિયા કરવામાં નિષ્ફળ:" @@ -756,10 +862,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -788,6 +890,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "ખરાબ ફાઇલ નામ છોડી દે છે %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -852,16 +964,16 @@ msgstr "ikiwiki: %s રેન્ડર કરી શકાતું નથી" msgid "cannot read %s: %s" msgstr "વાંચી શકાતી નથી %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -878,21 +990,14 @@ msgstr "ગોઠવણ ફાઇલનો ઉપયોગ કરે છે ત msgid "wrapper filename not specified" msgstr "આવરણ ફાઇલનામ સ્પષ્ટ કરેલ નથી" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "%s લખવામાં નિષ્ફળ: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "%s કમ્પાઇલ કરવામાં નિષ્ફળ" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "સફળતાપૂર્વક પેદા કરેલ છે %s" @@ -905,41 +1010,41 @@ msgstr "ઉપયોગ: ikiwiki [વિકલ્પો] source dest" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "આવરણ બનાવે છે.." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "વીકી ફરીથી બનાવે છે.." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "વીકીને તાજી કરે છે.." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "જ્યારે --cgi ઉપયોગ કરતાં હોય ત્યારે વીકીનું યુઆરએલ સ્પષ્ટ કરવું જ પડશે" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "%s પર શોધાયેલ લુપ %s પર ચલાવે છે %i ઉંડાણ પર" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -956,13 +1061,22 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "%s લખવામાં નિષ્ફળ: %s" + +#~ msgid "failed to find url in html" +#~ msgstr "htmlમાં યુઆરએલ શોધવામાં નિષ્ફળ" + +#~ msgid "processed ok at %s" +#~ msgstr "આના પર બરાબર છે %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "તમારો પાસવર્ડ તમને ઇમેઇલ કરવામાં આવ્યો છે." diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot index f07f2bf62..b8592bd48 100644 --- a/po/ikiwiki.pot +++ b/po/ikiwiki.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-08 17:34-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -20,107 +20,113 @@ msgstr "" msgid "You need to log in first." msgstr "" -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 msgid "Preferences" msgstr "" -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "" -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "" -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, perl-format msgid "missing %s parameter" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" +msgid "last checked %s" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 msgid "feed not found" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "" @@ -129,7 +135,7 @@ msgstr "" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "" @@ -150,20 +156,20 @@ msgstr "" msgid "Failed to delete file from S3: " msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:189 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:231 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" @@ -171,8 +177,14 @@ msgstr "" msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -187,6 +199,71 @@ msgstr "" msgid "There are no broken links!" msgstr "" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, perl-format +msgid "commenting on %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -208,19 +285,19 @@ msgstr "" msgid "removing old preview %s" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "" @@ -242,12 +319,45 @@ msgstr "" msgid "failed to process" msgstr "" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 -msgid "failed to find url in html" +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 +msgid "missing page" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 @@ -283,37 +393,41 @@ msgstr "" msgid "failed to determine size of image %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 msgid "page editing not allowed" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 msgid "missing pages parameter" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:285 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:301 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:571 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "" @@ -321,7 +435,7 @@ msgstr "" msgid "failed to run dot" msgstr "" -#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, perl-format msgid "%s is locked and cannot be edited" msgstr "" @@ -335,15 +449,15 @@ msgstr "" msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)" msgstr "" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 msgid "stylesheet not found" msgstr "" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 msgid "redir page not found" msgstr "" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 msgid "redir cycle is not allowed" msgstr "" @@ -526,16 +640,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -msgid "missing page" -msgstr "" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -613,7 +718,7 @@ msgstr "" msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:490 +#: ../IkiWiki/Plugin/rename.pm:493 #, perl-format msgid "update for rename of %s to %s" msgstr "" @@ -632,18 +737,19 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 msgid "missing name or url parameter" msgstr "" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, perl-format msgid "shortcut %s points to %s" msgstr "" @@ -688,33 +794,33 @@ msgstr "" msgid "cannot find file" msgstr "" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, perl-format msgid "parse fail at line %d: %s" msgstr "" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 msgid "missing id parameter" msgstr "" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 msgid "failed to process:" msgstr "" @@ -739,10 +845,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -771,6 +873,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, perl-format +msgid "bad file name %s" +msgstr "" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -835,16 +947,16 @@ msgstr "" msgid "cannot read %s: %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -861,21 +973,14 @@ msgstr "" msgid "wrapper filename not specified" msgstr "" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "" @@ -888,41 +993,41 @@ msgstr "" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "" -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "" -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "" -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1149 +#: ../IkiWiki.pm:1194 #, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "" -#: ../IkiWiki.pm:1658 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -939,7 +1044,7 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 diff --git a/po/pl.po b/po/pl.po index 3cf7377a1..305d8bfc6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki 1.51\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-04-27 22:05+0200\n" "Last-Translator: Pawel Tecza \n" "Language-Team: Debian L10n Polish \n" @@ -20,111 +20,117 @@ msgstr "" msgid "You need to log in first." msgstr "Proszę najpierw zalogować się." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" "Nieudane logowanie. Proszę sprawdzić czy w przeglądarce włączone są " "ciasteczka (ang. cookies)" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 #, fuzzy msgid "Preferences" msgstr "Preferencje zapisane." -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Preferencje zapisane." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Twój dostęp został zabroniony przez administratora." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Błąd" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, fuzzy, perl-format msgid "missing %s parameter" msgstr "brakujący parametr %s" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "nowy kanał RSS" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "wpisy" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "nowy wpis" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "wygasający wpis %s (ma już %s dni)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "wygasający wpis %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "kanał RSS przetworzony w dniu %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "sprawdzanie kanału RSS %s..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "nie znaleziono kanału RSS pod adresem %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 #, fuzzy msgid "feed not found" msgstr "nieznaleziony kanał RSS" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, fuzzy, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "Nieprawidłowe kodowanie UTF-8 usunięte z kanału RSS" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "awaria kanału RSS w module XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "tworzenie nowej strony %s" @@ -133,7 +139,7 @@ msgstr "tworzenie nowej strony %s" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "gotowe" @@ -156,29 +162,35 @@ msgstr "Awaria w trakcie wysyłania wiadomości" msgid "Failed to delete file from S3: " msgstr "awaria w trakcie zmiany rozmiaru: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -193,6 +205,71 @@ msgstr "" msgid "There are no broken links!" msgstr "Wszystkie odnośniki są aktualne!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "tworzenie %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -214,19 +291,19 @@ msgstr "" msgid "removing old preview %s" msgstr "usuwanie starej strony %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "Strona %s nie może być edytowana" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "tworzenie %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "edycja %s" @@ -251,14 +328,47 @@ msgstr "" msgid "failed to process" msgstr "awaria w trakcie przetwarzania:" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "awaria fortunki" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Wtyczka do wyszukiwarka wymaga podania %s" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 #, fuzzy -msgid "failed to find url in html" -msgstr "awaria w trakcie wyszukiwania adresu URL na stronie HTML" +msgid "missing page" +msgstr "brakujące wartości" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 #, fuzzy @@ -295,41 +405,45 @@ msgstr "awaria w trakcie zmiany rozmiaru: %s" msgid "failed to determine size of image %s" msgstr "awaria w trakcie zmiany rozmiaru: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Użycie parametru --rss lub --atom wymaga podania adresu URL do wiki za " "pomocą parametru --url" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "nieznaleziony kanał RSS" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "brakujący parametr %s" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "nieznany sposób sortowania %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "Tytuł nowego wpisu" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "brakujący szablon %s" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Dyskusja" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "Nieznaleziony moduł RPC::XML::Client, brak możliwości pingowania" @@ -338,7 +452,7 @@ msgstr "Nieznaleziony moduł RPC::XML::Client, brak możliwości pingowania" msgid "failed to run dot" msgstr "awaria w trakcie uruchamiania dot" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "" @@ -356,17 +470,17 @@ msgstr "" "Awaria w trakcie ładowania perlowego modułu Markdown.pm (%s) lub " "uruchamiania programu /usr/bin/markdown (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 #, fuzzy msgid "stylesheet not found" msgstr "nieznaleziony szablon ze stylami CSS" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "nieznaleziony kanał RSS" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "nieznaleziony kanał RSS" @@ -553,17 +667,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "brakujące wartości" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -584,16 +688,16 @@ msgstr "" msgid "%s is not a file" msgstr "Strona %s nie może być edytowana" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -631,20 +735,20 @@ msgstr "renderowanie %s" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "aktualizacja stron wiki %s: %s przez użytkownika %s" @@ -663,11 +767,12 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 #, fuzzy msgid "missing name or url parameter" msgstr "brakujący parametr name lub url" @@ -675,7 +780,7 @@ msgstr "brakujący parametr name lub url" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, fuzzy, perl-format msgid "shortcut %s points to %s" msgstr "skrót %s wskazuje na adres %s" @@ -726,34 +831,34 @@ msgstr "awaria w trakcie uruchamiania php" msgid "cannot find file" msgstr "nie można znaleźć pliku" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "nieznany format danych" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "brak danych" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "Bezpośrednie pobieranie danych" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, fuzzy, perl-format msgid "parse fail at line %d: %s" msgstr "awaria w trakcie przetwarzania linii %d: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 #, fuzzy msgid "missing id parameter" msgstr "brakujący parametr id" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "nieznaleziony szablon %s" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 #, fuzzy msgid "failed to process:" msgstr "awaria w trakcie przetwarzania:" @@ -781,10 +886,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -813,6 +914,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "pomijanie nieprawidłowej nazwy pliku %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -877,16 +988,16 @@ msgstr "ikiwiki: awaria w trakcie tworzenia %s" msgid "cannot read %s: %s" msgstr "awaria w trakcie odczytu %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -903,21 +1014,14 @@ msgstr "awaria w trakcie tworzenia osłony używającej pliku konfiguracyjnego" msgid "wrapper filename not specified" msgstr "nieokreślona nazwa pliku osłony" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "awaria w trakcie zapisu %s: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "awaria w trakcie kompilowania %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "pomyślnie utworzono %s" @@ -930,43 +1034,43 @@ msgstr "użycie: ikiwiki [parametry] źródło cel" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "tworzenie osłon..." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "przebudowywanie wiki..." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "odświeżanie wiki..." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "" "Użycie parametru --cgi wymaga podania adresu URL do wiki za pomocą parametru " "--url" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "polecenie preprocesora %s wykryte w %s na głębokości %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -983,13 +1087,23 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "awaria w trakcie zapisu %s: %s" + +#, fuzzy +#~ msgid "failed to find url in html" +#~ msgstr "awaria w trakcie wyszukiwania adresu URL na stronie HTML" + +#~ msgid "processed ok at %s" +#~ msgstr "kanał RSS przetworzony w dniu %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "Wiadomość z hasłem została wysłana." diff --git a/po/sv.po b/po/sv.po index cf5341af0..eeeac88f8 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-01-10 23:47+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -19,109 +19,115 @@ msgstr "" msgid "You need to log in first." msgstr "Du måste logga in först." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 #, fuzzy msgid "Preferences" msgstr "Inställningar sparades." -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Inställningar sparades." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Du är bannlyst." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Fel" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, fuzzy, perl-format msgid "missing %s parameter" msgstr "mall saknar id-parameter" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "ny kanal" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "inlägg" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "ny" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "låter %s gå ut (%s dagar gammal)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "låter %s gå ut" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "behandlad ok på %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "kontrollerar kanalen %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "kunde inte hitta kanalen på %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 #, fuzzy msgid "feed not found" msgstr "mallen %s hittades inte" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "kanalen kraschade XML::Feed!" -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "skapar nya sidan %s" @@ -130,7 +136,7 @@ msgstr "skapar nya sidan %s" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "klar" @@ -153,29 +159,35 @@ msgstr "Misslyckades med att skicka e-post" msgid "Failed to delete file from S3: " msgstr "misslyckades med att skriva %s: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -190,6 +202,71 @@ msgstr "" msgid "There are no broken links!" msgstr "Det finns inga trasiga länkar!" +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "skapar %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -211,19 +288,19 @@ msgstr "" msgid "removing old preview %s" msgstr "tar bort gammal sida %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "skapar %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "redigerar %s" @@ -248,14 +325,47 @@ msgstr "" msgid "failed to process" msgstr "misslyckades med att behandla mall:" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "fortune misslyckades" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Måste ange %s när sökinsticket används" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 #, fuzzy -msgid "failed to find url in html" -msgstr "googlecalendar misslyckades med att hitta url i html" +msgid "missing page" +msgstr "mall saknar id-parameter" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 #, fuzzy @@ -292,39 +402,43 @@ msgstr "misslyckades med att skriva %s: %s" msgid "failed to determine size of image %s" msgstr "misslyckades med att skriva %s: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "Måste ange url till wiki med --url när --rss eller --atom används" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "mallen %s hittades inte" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "mall saknar id-parameter" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "okänd sorteringstyp %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Diskussion" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "RPC::XML::Client hittades inte, pingar inte" @@ -333,7 +447,7 @@ msgstr "RPC::XML::Client hittades inte, pingar inte" msgid "failed to run dot" msgstr "linkmap misslyckades att köra dot" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "%s är låst av %s och kan inte redigeras" @@ -349,17 +463,17 @@ msgstr "" "misslyckades med att läsa in Perl-modulen Markdown.pm (%s) eller /usr/bin/" "markdown (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 #, fuzzy msgid "stylesheet not found" msgstr "mallen %s hittades inte" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "mallen %s hittades inte" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "mallen %s hittades inte" @@ -545,17 +659,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "mall saknar id-parameter" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -574,16 +678,16 @@ msgstr "%s är låst av %s och kan inte redigeras" msgid "%s is not a file" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -621,20 +725,20 @@ msgstr "ritar upp %s" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "uppdatering av %s, %s av %s" @@ -653,11 +757,12 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 #, fuzzy msgid "missing name or url parameter" msgstr "genväg saknar parameter för namn eller url" @@ -665,7 +770,7 @@ msgstr "genväg saknar parameter för namn eller url" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, fuzzy, perl-format msgid "shortcut %s points to %s" msgstr "genvägen %s pekar på %s" @@ -716,34 +821,34 @@ msgstr "linkmap misslyckades att köra dot" msgid "cannot find file" msgstr "" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, fuzzy, perl-format msgid "parse fail at line %d: %s" msgstr "misslyckades med att skriva %s: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 #, fuzzy msgid "missing id parameter" msgstr "mall saknar id-parameter" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "mallen %s hittades inte" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 #, fuzzy msgid "failed to process:" msgstr "misslyckades med att behandla mall:" @@ -770,10 +875,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -802,6 +903,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "hoppar över felaktigt filnamn %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -866,16 +977,16 @@ msgstr "ikiwiki: kan inte rita upp %s" msgid "cannot read %s: %s" msgstr "kan inte läsa %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -892,21 +1003,14 @@ msgstr "kan inte skapa en wrapper som använder en konfigurationsfil" msgid "wrapper filename not specified" msgstr "filnamn för wrapper har inte angivits" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "misslyckades med att skriva %s: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "misslyckades med att kompilera %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "generering av %s lyckades" @@ -919,41 +1023,41 @@ msgstr "användning: ikiwiki [flaggor] källa mål" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "genererar wrappers.." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "bygger om wiki.." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "uppdaterar wiki.." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "Måste ange url till wiki med --url när --cgi används" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "%s förbehandlingsslinga detekterades på %s, djup %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -970,13 +1074,23 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "misslyckades med att skriva %s: %s" + +#, fuzzy +#~ msgid "failed to find url in html" +#~ msgstr "googlecalendar misslyckades med att hitta url i html" + +#~ msgid "processed ok at %s" +#~ msgstr "behandlad ok på %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "Ditt lösenord har skickats till dig via e-post." diff --git a/po/vi.po b/po/vi.po index c988f38d9..719e99889 100644 --- a/po/vi.po +++ b/po/vi.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: ikiwiki\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2009-04-04 14:59-0400\n" "PO-Revision-Date: 2007-01-13 15:31+1030\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" @@ -20,109 +20,115 @@ msgstr "" msgid "You need to log in first." msgstr "Trước tiên bạn cần phải đăng nhập." -#: ../IkiWiki/CGI.pm:145 +#: ../IkiWiki/CGI.pm:146 +msgid "" +"probable misconfiguration: sslcookie is set, but you are attepting to login " +"via http, not https" +msgstr "" + +#: ../IkiWiki/CGI.pm:149 msgid "login failed, perhaps you need to turn on cookies?" msgstr "" -#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350 +#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299 msgid "Your login session has expired." msgstr "" -#: ../IkiWiki/CGI.pm:184 +#: ../IkiWiki/CGI.pm:189 msgid "Login" msgstr "" -#: ../IkiWiki/CGI.pm:185 +#: ../IkiWiki/CGI.pm:190 #, fuzzy msgid "Preferences" msgstr "Tùy thích đã được lưu." -#: ../IkiWiki/CGI.pm:186 +#: ../IkiWiki/CGI.pm:191 msgid "Admin" msgstr "" -#: ../IkiWiki/CGI.pm:253 +#: ../IkiWiki/CGI.pm:231 msgid "Preferences saved." msgstr "Tùy thích đã được lưu." -#: ../IkiWiki/CGI.pm:271 +#: ../IkiWiki/CGI.pm:262 msgid "You are banned." msgstr "Bạn bị cấm ra." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211 msgid "Error" msgstr "Lỗi" -#: ../IkiWiki/Plugin/aggregate.pm:80 +#: ../IkiWiki/Plugin/aggregate.pm:84 msgid "Aggregation triggered via web." msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:89 +#: ../IkiWiki/Plugin/aggregate.pm:93 msgid "Nothing to do right now, all feeds are up-to-date!" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:216 +#: ../IkiWiki/Plugin/aggregate.pm:220 #, fuzzy, perl-format msgid "missing %s parameter" msgstr "mẫu thiếu tham số id" -#: ../IkiWiki/Plugin/aggregate.pm:250 +#: ../IkiWiki/Plugin/aggregate.pm:255 msgid "new feed" msgstr "nguồn tin mới" -#: ../IkiWiki/Plugin/aggregate.pm:264 +#: ../IkiWiki/Plugin/aggregate.pm:269 msgid "posts" msgstr "bài" -#: ../IkiWiki/Plugin/aggregate.pm:266 +#: ../IkiWiki/Plugin/aggregate.pm:271 msgid "new" msgstr "mới" -#: ../IkiWiki/Plugin/aggregate.pm:429 +#: ../IkiWiki/Plugin/aggregate.pm:435 #, perl-format msgid "expiring %s (%s days old)" msgstr "đang mãn hạn %s (cũ %s ngày)" -#: ../IkiWiki/Plugin/aggregate.pm:436 +#: ../IkiWiki/Plugin/aggregate.pm:442 #, perl-format msgid "expiring %s" msgstr "đang mãn hạn %s" -#: ../IkiWiki/Plugin/aggregate.pm:463 +#: ../IkiWiki/Plugin/aggregate.pm:469 #, perl-format -msgid "processed ok at %s" -msgstr "đã xử lý được ở %s" +msgid "last checked %s" +msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:467 +#: ../IkiWiki/Plugin/aggregate.pm:473 #, perl-format msgid "checking feed %s ..." msgstr "đang kiểm tra nguồn tin %s ..." -#: ../IkiWiki/Plugin/aggregate.pm:472 +#: ../IkiWiki/Plugin/aggregate.pm:478 #, perl-format msgid "could not find feed at %s" msgstr "không tìm thấy nguồn tin ở %s" -#: ../IkiWiki/Plugin/aggregate.pm:487 +#: ../IkiWiki/Plugin/aggregate.pm:497 #, fuzzy msgid "feed not found" msgstr "không tìm thấy mẫu %s" -#: ../IkiWiki/Plugin/aggregate.pm:498 +#: ../IkiWiki/Plugin/aggregate.pm:508 #, perl-format msgid "(invalid UTF-8 stripped from feed)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:504 +#: ../IkiWiki/Plugin/aggregate.pm:516 #, perl-format msgid "(feed entities escaped)" msgstr "" -#: ../IkiWiki/Plugin/aggregate.pm:510 +#: ../IkiWiki/Plugin/aggregate.pm:524 msgid "feed crashed XML::Feed!" msgstr "nguồn tin đã gây ra XML::Feed sụp đổ." -#: ../IkiWiki/Plugin/aggregate.pm:590 +#: ../IkiWiki/Plugin/aggregate.pm:610 #, perl-format msgid "creating new page %s" msgstr "đang tạo trang mới %s" @@ -131,7 +137,7 @@ msgstr "đang tạo trang mới %s" msgid "deleting bucket.." msgstr "" -#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199 +#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210 msgid "done" msgstr "xong" @@ -154,29 +160,35 @@ msgstr "Lỗi gửi thư" msgid "Failed to delete file from S3: " msgstr "lỗi ghi %s: %s" -#: ../IkiWiki/Plugin/attachment.pm:48 +#: ../IkiWiki/Plugin/attachment.pm:49 #, perl-format msgid "there is already a page named %s" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:81 +#: ../IkiWiki/Plugin/attachment.pm:65 msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:140 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:182 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/blogspam.pm:105 +msgid "" +"Sorry, but that looks like spam to blogspam: " +msgstr "" + +#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233 +#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -191,6 +203,71 @@ msgstr "" msgid "There are no broken links!" msgstr "Không có liên kết bị ngắt nào." +#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23 +#, perl-format +msgid "unsupported page format %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:127 +msgid "comment must have content" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:183 +msgid "Anonymous" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97 +msgid "bad page name" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:331 +#, fuzzy, perl-format +msgid "commenting on %s" +msgstr "đang tạo %s" + +#: ../IkiWiki/Plugin/comments.pm:349 +#, perl-format +msgid "page '%s' doesn't exist, so you can't comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:356 +#, perl-format +msgid "comments on page '%s' are closed" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:450 +msgid "comment stored for moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:452 +msgid "Your comment will be posted after moderator review" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:465 +msgid "Added a comment" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:469 +#, perl-format +msgid "Added a comment: %s" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236 +msgid "you are not logged in as an admin" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:562 +msgid "Comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:601 +msgid "comment moderation" +msgstr "" + +#: ../IkiWiki/Plugin/comments.pm:752 +msgid "Comments" +msgstr "" + #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61 #: ../IkiWiki/Plugin/testpagespec.pm:26 @@ -212,19 +289,19 @@ msgstr "" msgid "removing old preview %s" msgstr "đang gỡ bỏ trang cũ %s" -#: ../IkiWiki/Plugin/editpage.pm:141 +#: ../IkiWiki/Plugin/editpage.pm:113 #, perl-format msgid "%s is not an editable page" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:317 +#: ../IkiWiki/Plugin/editpage.pm:289 #, perl-format msgid "creating %s" msgstr "đang tạo %s" -#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363 -#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408 -#: ../IkiWiki/Plugin/editpage.pm:453 +#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326 +#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380 +#: ../IkiWiki/Plugin/editpage.pm:419 #, perl-format msgid "editing %s" msgstr "đang sửa %s" @@ -249,14 +326,47 @@ msgstr "" msgid "failed to process" msgstr "mẫu không xử lý được:" +#: ../IkiWiki/Plugin/format.pm:20 +msgid "must specify format and text" +msgstr "" + #: ../IkiWiki/Plugin/fortune.pm:27 msgid "fortune failed" msgstr "fortune bị lỗi" -#: ../IkiWiki/Plugin/googlecalendar.pm:32 +#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644 +#: ../IkiWiki/Receive.pm:129 +#, perl-format +msgid "you are not allowed to change %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:666 +#, perl-format +msgid "you cannot act on a file with mode %s" +msgstr "" + +#: ../IkiWiki/Plugin/git.pm:670 +msgid "you are not allowed to change file modes" +msgstr "" + +#: ../IkiWiki/Plugin/google.pm:27 +#, fuzzy, perl-format +msgid "Must specify %s when using the google search plugin" +msgstr "Cần phải xác định %s khi dùng bổ sung tìm kiếm" + +#: ../IkiWiki/Plugin/google.pm:31 +msgid "Failed to parse url, cannot determine domain name" +msgstr "" + +#: ../IkiWiki/Plugin/goto.pm:49 #, fuzzy -msgid "failed to find url in html" -msgstr "googlecalendar không tìm thấy địa chỉ URL trong mã HTML" +msgid "missing page" +msgstr "mẫu thiếu tham số id" + +#: ../IkiWiki/Plugin/goto.pm:51 +#, perl-format +msgid "The page %s does not exist." +msgstr "" #: ../IkiWiki/Plugin/graphviz.pm:67 #, fuzzy @@ -293,41 +403,45 @@ msgstr "lỗi ghi %s: %s" msgid "failed to determine size of image %s" msgstr "lỗi ghi %s: %s" -#: ../IkiWiki/Plugin/inline.pm:93 +#: ../IkiWiki/Plugin/inline.pm:92 msgid "Must specify url to wiki with --url when using --rss or --atom" msgstr "" "Cần phải xác định địa chỉ URL tới wiki với « --url » khi dùng « --rss » hay « --" "atom »" -#: ../IkiWiki/Plugin/inline.pm:139 +#: ../IkiWiki/Plugin/inline.pm:138 #, fuzzy msgid "page editing not allowed" msgstr "không tìm thấy mẫu %s" -#: ../IkiWiki/Plugin/inline.pm:156 +#: ../IkiWiki/Plugin/inline.pm:155 #, fuzzy msgid "missing pages parameter" msgstr "mẫu thiếu tham số id" -#: ../IkiWiki/Plugin/inline.pm:204 +#: ../IkiWiki/Plugin/inline.pm:200 +msgid "Sort::Naturally needed for title_natural sort" +msgstr "" + +#: ../IkiWiki/Plugin/inline.pm:211 #, perl-format msgid "unknown sort type %s" msgstr "kiểu sắp xếp không rõ %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:314 msgid "Add a new post titled:" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:334 #, perl-format msgid "nonexistant template %s" msgstr "" -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Thảo luận" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:600 msgid "RPC::XML::Client not found, not pinging" msgstr "Không tìm thấy RPC::XML::Client nên không gửi gói tin ping" @@ -336,7 +450,7 @@ msgstr "Không tìm thấy RPC::XML::Client nên không gửi gói tin ping" msgid "failed to run dot" msgstr "linkmap không chạy dot được" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:47 #, fuzzy, perl-format msgid "%s is locked and cannot be edited" msgstr "%s bị %s khoá nên không thể sửa được" @@ -350,17 +464,17 @@ msgstr "" msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)" msgstr "lỗi nạp mô-đun perl Markdown.pm (%s) hay « /usr/bin/markdown » (%s)" -#: ../IkiWiki/Plugin/meta.pm:150 +#: ../IkiWiki/Plugin/meta.pm:158 #, fuzzy msgid "stylesheet not found" msgstr "không tìm thấy mẫu %s" -#: ../IkiWiki/Plugin/meta.pm:184 +#: ../IkiWiki/Plugin/meta.pm:192 #, fuzzy msgid "redir page not found" msgstr "không tìm thấy mẫu %s" -#: ../IkiWiki/Plugin/meta.pm:197 +#: ../IkiWiki/Plugin/meta.pm:205 #, fuzzy msgid "redir cycle is not allowed" msgstr "không tìm thấy mẫu %s" @@ -546,17 +660,7 @@ msgstr "" msgid "need either `percent` or `totalpages` and `donepages` parameters" msgstr "" -#: ../IkiWiki/Plugin/recentchanges.pm:100 -#, fuzzy -msgid "missing page" -msgstr "mẫu thiếu tham số id" - -#: ../IkiWiki/Plugin/recentchanges.pm:102 -#, perl-format -msgid "The page %s does not exist." -msgstr "" - -#: ../IkiWiki/Plugin/recentchangesdiff.pm:36 +#: ../IkiWiki/Plugin/recentchangesdiff.pm:37 msgid "(Diff truncated)" msgstr "" @@ -575,16 +679,16 @@ msgstr "%s bị %s khoá nên không thể sửa được" msgid "%s is not a file" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "" @@ -622,20 +726,20 @@ msgstr "đang vẽ %s" msgid "Also rename SubPages and attachments" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "" -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:493 #, fuzzy, perl-format msgid "update for rename of %s to %s" msgstr "cập nhật %2$s của %1$s bởi %3$s" @@ -654,11 +758,12 @@ msgstr "" msgid "search" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:27 -msgid "shortcut plugin will not work without a shortcuts.mdwn" +#: ../IkiWiki/Plugin/shortcut.pm:31 +#, perl-format +msgid "shortcut plugin will not work without %s" msgstr "" -#: ../IkiWiki/Plugin/shortcut.pm:36 +#: ../IkiWiki/Plugin/shortcut.pm:44 #, fuzzy msgid "missing name or url parameter" msgstr "lối tắt thiếu tên hay tham số url" @@ -666,7 +771,7 @@ msgstr "lối tắt thiếu tên hay tham số url" #. translators: This is used to display what shortcuts are defined. #. translators: First parameter is the name of the shortcut, the second #. translators: is an URL. -#: ../IkiWiki/Plugin/shortcut.pm:45 +#: ../IkiWiki/Plugin/shortcut.pm:54 #, fuzzy, perl-format msgid "shortcut %s points to %s" msgstr "lối tắt %s chỉ tới %s" @@ -717,34 +822,34 @@ msgstr "linkmap không chạy dot được" msgid "cannot find file" msgstr "" -#: ../IkiWiki/Plugin/table.pm:73 +#: ../IkiWiki/Plugin/table.pm:87 msgid "unknown data format" msgstr "" -#: ../IkiWiki/Plugin/table.pm:81 +#: ../IkiWiki/Plugin/table.pm:95 msgid "empty data" msgstr "" -#: ../IkiWiki/Plugin/table.pm:100 +#: ../IkiWiki/Plugin/table.pm:114 msgid "Direct data download" msgstr "" -#: ../IkiWiki/Plugin/table.pm:134 +#: ../IkiWiki/Plugin/table.pm:148 #, fuzzy, perl-format msgid "parse fail at line %d: %s" msgstr "lỗi ghi %s: %s" -#: ../IkiWiki/Plugin/template.pm:28 +#: ../IkiWiki/Plugin/template.pm:29 #, fuzzy msgid "missing id parameter" msgstr "mẫu thiếu tham số id" -#: ../IkiWiki/Plugin/template.pm:35 +#: ../IkiWiki/Plugin/template.pm:36 #, perl-format msgid "template %s not found" msgstr "không tìm thấy mẫu %s" -#: ../IkiWiki/Plugin/template.pm:54 +#: ../IkiWiki/Plugin/template.pm:55 #, fuzzy msgid "failed to process:" msgstr "mẫu không xử lý được:" @@ -771,10 +876,6 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:236 -msgid "you are not logged in as an admin" -msgstr "" - #: ../IkiWiki/Plugin/websetup.pm:240 msgid "setup file for this wiki is not known" msgstr "" @@ -803,6 +904,16 @@ msgstr "" msgid "

Error: %s exited nonzero (%s)" msgstr "" +#: ../IkiWiki/Receive.pm:35 +#, perl-format +msgid "cannot determine id of untrusted committer %s" +msgstr "" + +#: ../IkiWiki/Receive.pm:85 +#, fuzzy, perl-format +msgid "bad file name %s" +msgstr "đang bỏ qua tên tập tin sai %s" + #: ../IkiWiki/Render.pm:253 #, perl-format msgid "" @@ -867,16 +978,16 @@ msgstr "ikiwiki: không thể vẽ %s" msgid "cannot read %s: %s" msgstr "không thể đọc %s: %s" -#: ../IkiWiki/Setup/Automator.pm:33 +#: ../IkiWiki/Setup/Automator.pm:34 msgid "you must enter a wikiname (that contains alphanumerics)" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:67 +#: ../IkiWiki/Setup/Automator.pm:68 #, perl-format msgid "unsupported revision control system %s" msgstr "" -#: ../IkiWiki/Setup/Automator.pm:83 +#: ../IkiWiki/Setup/Automator.pm:94 msgid "failed to set up the repository with ikiwiki-makerepo" msgstr "" @@ -893,21 +1004,14 @@ msgstr "không thể tạo bộ bao bọc sử dụng tập tin thiết lập" msgid "wrapper filename not specified" msgstr "chưa xác định tên tập tin bộ bao bọc" -#. translators: The first parameter is a filename, and the second is -#. translators: a (probably not translated) error message. -#: ../IkiWiki/Wrapper.pm:48 -#, perl-format -msgid "failed to write %s: %s" -msgstr "lỗi ghi %s: %s" - #. translators: The parameter is a C filename. -#: ../IkiWiki/Wrapper.pm:99 +#: ../IkiWiki/Wrapper.pm:152 #, perl-format msgid "failed to compile %s" msgstr "lỗi biên dịch %s" #. translators: The parameter is a filename. -#: ../IkiWiki/Wrapper.pm:119 +#: ../IkiWiki/Wrapper.pm:172 #, perl-format msgid "successfully generated %s" msgstr "%s đã được tạo ra" @@ -920,41 +1024,41 @@ msgstr "cách sử dụng: ikiwiki [tùy chọn] nguồn đích" msgid " ikiwiki --setup configfile" msgstr "" -#: ../ikiwiki.in:90 +#: ../ikiwiki.in:91 msgid "usage: --set var=value" msgstr "" -#: ../ikiwiki.in:137 +#: ../ikiwiki.in:140 msgid "generating wrappers.." msgstr "đang tạo ra các bộ bao bọc.." -#: ../ikiwiki.in:188 +#: ../ikiwiki.in:199 msgid "rebuilding wiki.." msgstr "đang xây dựng lại wiki.." -#: ../ikiwiki.in:191 +#: ../ikiwiki.in:202 msgid "refreshing wiki.." msgstr "đang làm tươi wiki.." -#: ../IkiWiki.pm:458 +#: ../IkiWiki.pm:480 msgid "Must specify url to wiki with --url when using --cgi" msgstr "Cần phải xác định địa chỉ URL tới wiki với « --url » khi dùng « --cgi »" -#: ../IkiWiki.pm:504 +#: ../IkiWiki.pm:526 msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:533 +#: ../IkiWiki.pm:555 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1194 #, fuzzy, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "vòng lặp tiền xử lý %s được phát hiện trên %s ở độ sâu %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1732 msgid "yes" msgstr "" @@ -971,13 +1075,23 @@ msgid "What revision control system to use?" msgstr "" #: ../auto.setup:20 -msgid "What wiki user (or openid) will be wiki admin?" +msgid "What wiki user (or openid) will be admin?" msgstr "" #: ../auto.setup:23 msgid "What is the domain name of the web server?" msgstr "" +#~ msgid "failed to write %s: %s" +#~ msgstr "lỗi ghi %s: %s" + +#, fuzzy +#~ msgid "failed to find url in html" +#~ msgstr "googlecalendar không tìm thấy địa chỉ URL trong mã HTML" + +#~ msgid "processed ok at %s" +#~ msgstr "đã xử lý được ở %s" + #~ msgid "Your password has been emailed to you." #~ msgstr "Mật khẩu đã được gửi đính kèm thư cho bạn." diff --git a/t/404.t b/t/404.t new file mode 100755 index 000000000..0bb3c6063 --- /dev/null +++ b/t/404.t @@ -0,0 +1,44 @@ +#!/usr/bin/perl +use warnings; +use strict; +use Test::More tests => 17; + +BEGIN { use_ok("IkiWiki::Plugin::404"); } + +sub cgi_page_from_404 { + return IkiWiki::Plugin::404::cgi_page_from_404(shift, shift, shift); +} + +$IkiWiki::config{htmlext} = 'html'; + +is(cgi_page_from_404('/', 'http://example.com', 1), 'index'); +is(cgi_page_from_404('/index.html', 'http://example.com', 0), 'index'); +is(cgi_page_from_404('/', 'http://example.com/', 1), 'index'); +is(cgi_page_from_404('/index.html', 'http://example.com/', 0), 'index'); + +is(cgi_page_from_404('/~user/foo/bar', 'http://example.com/~user', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar/index.html', 'http://example.com/~user', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar/', 'http://example.com/~user', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar.html', 'http://example.com/~user', 0), + 'foo/bar'); + +is(cgi_page_from_404('/~user/foo/bar', 'http://example.com/~user/', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar/index.html', 'http://example.com/~user/', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar/', 'http://example.com/~user/', 1), + 'foo/bar'); +is(cgi_page_from_404('/~user/foo/bar.html', 'http://example.com/~user/', 0), + 'foo/bar'); + +is(cgi_page_from_404('/~user/foo', 'https://example.com/~user', 1), + 'foo'); +is(cgi_page_from_404('/~user/foo/index.html', 'https://example.com/~user', 1), + 'foo'); +is(cgi_page_from_404('/~user/foo/', 'https://example.com/~user', 1), + 'foo'); +is(cgi_page_from_404('/~user/foo.html', 'https://example.com/~user', 0), + 'foo'); diff --git a/t/basewiki_brokenlinks/index.mdwn b/t/basewiki_brokenlinks/index.mdwn index 0a6b2c39e..41768f782 100644 --- a/t/basewiki_brokenlinks/index.mdwn +++ b/t/basewiki_brokenlinks/index.mdwn @@ -1 +1 @@ -[[brokenlinks ]] +[[!brokenlinks ]] diff --git a/t/beautify_urlpath.t b/t/beautify_urlpath.t new file mode 100755 index 000000000..94b923d3b --- /dev/null +++ b/t/beautify_urlpath.t @@ -0,0 +1,17 @@ +#!/usr/bin/perl +use warnings; +use strict; +use Test::More tests => 8; + +BEGIN { use_ok("IkiWiki"); } + +$IkiWiki::config{usedirs} = 1; +$IkiWiki::config{htmlext} = "HTML"; +is(IkiWiki::beautify_urlpath("foo/bar"), "./foo/bar"); +is(IkiWiki::beautify_urlpath("../badger"), "../badger"); +is(IkiWiki::beautify_urlpath("./bleh"), "./bleh"); +is(IkiWiki::beautify_urlpath("foo/index.HTML"), "./foo/"); +is(IkiWiki::beautify_urlpath("index.HTML"), "./"); +is(IkiWiki::beautify_urlpath("../index.HTML"), "../"); +$IkiWiki::config{usedirs} = 0; +is(IkiWiki::beautify_urlpath("foo/index.HTML"), "./foo/index.HTML"); diff --git a/t/git.t b/t/git.t index b3aa6a80b..f1c24b359 100755 --- a/t/git.t +++ b/t/git.t @@ -3,19 +3,17 @@ use warnings; use strict; my $dir; -my $gitrepo; BEGIN { $dir="/tmp/ikiwiki-test-git.$$"; - $gitrepo="$dir/repo"; my $git=`which git`; chomp $git; - if (! -x $git || ! mkdir($dir) || ! mkdir($gitrepo)) { + if (! -x $git || ! mkdir($dir)) { eval q{ - use Test::More skip_all => "git not available or could not make test dirs" + use Test::More skip_all => "git not available or could not make test dir" } } } -use Test::More tests => 16; +use Test::More tests => 18; BEGIN { use_ok("IkiWiki"); } @@ -25,17 +23,16 @@ $config{srcdir} = "$dir/src"; IkiWiki::loadplugins(); IkiWiki::checkconfig(); -system "cd $gitrepo && git init >/dev/null 2>&1"; -system "cd $gitrepo && echo dummy > dummy; git add . >/dev/null 2>&1"; -system "cd $gitrepo && git commit -m Initial >/dev/null 2>&1"; -system "git clone -l -s $gitrepo $config{srcdir} >/dev/null 2>&1"; +ok (mkdir($config{srcdir})); +is (system("./ikiwiki-makerepo git $config{srcdir} $dir/repo"), 0); my @changes; @changes = IkiWiki::rcs_recentchanges(3); is($#changes, 0); # counts for dummy commit during repo creation -is($changes[0]{message}[0]{"line"}, "Initial"); -is($changes[0]{pages}[0]{"page"}, "dummy"); +# ikiwiki-makerepo's first commit is setting up the .gitignore +is($changes[0]{message}[0]{"line"}, "initial commit"); +is($changes[0]{pages}[0]{"page"}, ".gitignore"); # Web commit my $test1 = readfile("t/test1.mdwn"); diff --git a/t/htmlbalance.t b/t/htmlbalance.t new file mode 100755 index 000000000..e5a5db0ee --- /dev/null +++ b/t/htmlbalance.t @@ -0,0 +1,23 @@ +#!/usr/bin/perl +use warnings; +use strict; + +BEGIN { + eval q{ + use HTML::TreeBuilder; + }; + if ($@) { + eval q{use Test::More skip_all => "HTML::TreeBuilder not available"}; + } + else { + eval q{use Test::More tests => 7}; + } + use_ok("IkiWiki::Plugin::htmlbalance"); +} + +is(IkiWiki::Plugin::htmlbalance::sanitize(content => "

"), "
"); +is(IkiWiki::Plugin::htmlbalance::sanitize(content => "

hello world

"), "

hello world

"); +is(IkiWiki::Plugin::htmlbalance::sanitize(content => ""), ""); +is(IkiWiki::Plugin::htmlbalance::sanitize(content => "foo "), "foo "); +is(IkiWiki::Plugin::htmlbalance::sanitize(content => " foo "), " foo "); +is(IkiWiki::Plugin::htmlbalance::sanitize(content => "a>"), "a>"); diff --git a/t/openiduser.t b/t/openiduser.t new file mode 100755 index 000000000..52d879484 --- /dev/null +++ b/t/openiduser.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl +use warnings; +use strict; + +BEGIN { + eval q{ + use Net::OpenID::VerifiedIdentity; + }; + if ($@) { + eval q{use Test::More skip_all => "Net::OpenID::VerifiedIdentity not available"}; + } + else { + eval q{use Test::More tests => 9}; + } + use_ok("IkiWiki::Plugin::openid"); +} + +# Some typical examples: + +# This test, when run by Test::Harness using perl -w, exposes a warning in +# Net::OpenID::VerifiedIdentity. Normally that warning is not displayed, as +# that module does not use warnings. To avoid cluttering the test output, +# disable the -w switch temporarily. +$^W=0; +is(IkiWiki::openiduser('http://josephturian.blogspot.com'), 'josephturian [blogspot.com]'); +$^W=1; + +is(IkiWiki::openiduser('http://yam655.livejournal.com/'), 'yam655 [livejournal.com]'); +is(IkiWiki::openiduser('http://id.mayfirst.org/jamie/'), 'jamie [id.mayfirst.org]'); + +# and some less typical ones taken from the ikiwiki commit history + +is(IkiWiki::openiduser('http://thm.id.fedoraproject.org/'), 'thm [id.fedoraproject.org]'); +is(IkiWiki::openiduser('http://dtrt.org/'), 'dtrt.org'); +is(IkiWiki::openiduser('http://alcopop.org/me/openid/'), 'openid [alcopop.org/me]'); +is(IkiWiki::openiduser('http://id.launchpad.net/882/bielawski1'), 'bielawski1 [id.launchpad.net/882]'); +is(IkiWiki::openiduser('http://technorati.com/people/technorati/drajt'), 'drajt [technorati.com/people/technorati]'); diff --git a/t/pagename.t b/t/pagename.t index c7f1ce180..540d10f4c 100755 --- a/t/pagename.t +++ b/t/pagename.t @@ -1,14 +1,35 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 5; +use Test::More tests => 19; BEGIN { use_ok("IkiWiki"); } -# Used internally. -$IkiWiki::hooks{htmlize}{mdwn}{call}=sub {}; - +# define mdwn as an extension +$IkiWiki::hooks{htmlize}{mdwn}={}; +is(pagetype("foo.mdwn"), "mdwn"); is(pagename("foo.mdwn"), "foo"); +is(pagetype("foo/bar.mdwn"), "mdwn"); is(pagename("foo/bar.mdwn"), "foo/bar"); + +# bare files get the full filename as page name, undef type +is(pagetype("foo.png"), undef); is(pagename("foo.png"), "foo.png"); +is(pagetype("foo/bar.png"), undef); +is(pagename("foo/bar.png"), "foo/bar.png"); +is(pagetype("foo"), undef); is(pagename("foo"), "foo"); + +# keepextension preserves the extension in the page name +$IkiWiki::hooks{htmlize}{txt}={keepextension => 1}; +is(pagename("foo.txt"), "foo.txt"); +is(pagetype("foo.txt"), "txt"); +is(pagename("foo/bar.txt"), "foo/bar.txt"); +is(pagetype("foo/bar.txt"), "txt"); + +# noextension makes extensionless files be treated as first-class pages +$IkiWiki::hooks{htmlize}{Makefile}={noextension =>1}; +is(pagetype("Makefile"), "Makefile"); +is(pagename("Makefile"), "Makefile"); +is(pagetype("foo/Makefile"), "Makefile"); +is(pagename("foo/Makefile"), "foo/Makefile"); diff --git a/t/pagespec_match.t b/t/pagespec_match.t index c61d16122..69cf361de 100755 --- a/t/pagespec_match.t +++ b/t/pagespec_match.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 56; +use Test::More tests => 51; BEGIN { use_ok("IkiWiki"); } @@ -40,6 +40,7 @@ $links{"bugs/bar"}=[qw{done}]; $links{"done"}=[]; $links{"examples/softwaresite/bugs/fails_to_frobnicate"}=[qw{done}]; $links{"examples/softwaresite/bugs/done"}=[]; +$links{"ook"}=[qw{/blog/tags/foo}]; ok(pagespec_match("foo", "link(bar)"), "link"); ok(pagespec_match("foo", "link(ba?)"), "glob link"); @@ -55,6 +56,8 @@ ok(pagespec_match("bar", "backlink(foo)"), "backlink"); ok(! pagespec_match("quux", "backlink(foo)"), "failed backlink"); ok(! pagespec_match("bar", ""), "empty pagespec should match nothing"); ok(! pagespec_match("bar", " "), "blank pagespec should match nothing"); +ok(pagespec_match("ook", "link(blog/tags/foo)"), "link internal absolute success"); +ok(pagespec_match("ook", "link(/blog/tags/foo)"), "link explicit absolute success"); $IkiWiki::pagectime{foo}=1154532692; # Wed Aug 2 11:26 EDT 2006 $IkiWiki::pagectime{bar}=1154532695; # after @@ -74,12 +77,3 @@ ok(! pagespec_match("foo", "no_such_function(foo)"), "foo"); my $ret=pagespec_match("foo", "(invalid"); ok(! $ret, "syntax error"); ok($ret =~ /syntax error/, "error message"); - -# old style globlists -ok(pagespec_match("foo", "foo bar"), "simple list"); -ok(pagespec_match("bar", "foo bar"), "simple list 2"); -ok(pagespec_match("foo", "f?? !foz")); -ok(! pagespec_match("foo", "f?? !foo")); -ok(! pagespec_match("foo", "* !foo")); -ok(! pagespec_match("foo", "foo !foo")); -ok(! pagespec_match("foo.png", "* !*.*")); diff --git a/t/pagespec_merge.t b/t/pagespec_merge.t index cbb06219c..9e38d5761 100755 --- a/t/pagespec_merge.t +++ b/t/pagespec_merge.t @@ -28,17 +28,17 @@ ok(same("!foo", "!bar", "foo"), "double inversion failed match"); ok(same("!foo", "!bar", "bar"), "double inversion failed match 2"); ok(same("*", "!bar", "foo"), "glob+inversion match"); ok(same("*", "!bar", "bar"), "matching glob and matching inversion"); -ok(same("* !foo", "!bar", "bar"), "matching glob and matching inversion"); -ok(same("* !foo", "!bar", "foo"), "matching glob with matching inversion and non-matching inversion"); -ok(same("* !foo", "!foo", "foo"), "matching glob with matching inversion and matching inversion"); +ok(same("* and !foo", "!bar", "bar"), "matching glob and matching inversion"); +ok(same("* and !foo", "!bar", "foo"), "matching glob with matching inversion and non-matching inversion"); +ok(same("* and !foo", "!foo", "foo"), "matching glob with matching inversion and matching inversion"); ok(same("b??", "!b??", "bar"), "matching glob and matching inverted glob"); ok(same("f?? !f??", "!bar", "bar"), "matching glob and matching inverted glob"); ok(same("b??", "!b?z", "bar"), "matching glob and non-matching inverted glob"); ok(same("f?? !f?z", "!bar", "bar"), "matching glob and non-matching inverted glob"); ok(same("!foo bar baz", "!bar", "bar"), "matching list and matching inversion"); ok(pagespec_match("foo/Discussion", - IkiWiki::pagespec_merge("* !*/Discussion", "*/Discussion")), "should match"); -ok(same("* !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1"); -ok(same("*/Discussion", "* !*/Discussion", "foo/Discussion"), "Discussion merge 2"); + IkiWiki::pagespec_merge("* and !*/Discussion", "*/Discussion")), "should match"); +ok(same("* and !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1"); +ok(same("*/Discussion", "* and !*/Discussion", "foo/Discussion"), "Discussion merge 2"); ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/Discussion"), "bidirectional merge 1"); ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/bar"), "bidirectional merge 2"); diff --git a/t/pagetype.mdwn b/t/pagetype.mdwn deleted file mode 100755 index 76cacd8f7..000000000 --- a/t/pagetype.mdwn +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl -use warnings; -use strict; -use Test::More tests => 5; - -BEGIN { use_ok("IkiWiki"); } - -# Used internally. -$IkiWiki::hooks{htmlize}{mdwn}=1; - -is(pagetype("foo.mdwn"), "mdwn"); -is(pagetype("foo/bar.mdwn"), "mdwn"); -is(pagename("foo.png"), undef); -is(pagename("foo"), undef); diff --git a/t/tinyblog/index.mdwn b/t/tinyblog/index.mdwn index 010c85de1..72ba7846a 100644 --- a/t/tinyblog/index.mdwn +++ b/t/tinyblog/index.mdwn @@ -1 +1 @@ -[[inline pages="post" rss=yes]] +[[!inline pages="post" rss=yes]] diff --git a/t/yesno.t b/t/yesno.t new file mode 100755 index 000000000..60a8c071d --- /dev/null +++ b/t/yesno.t @@ -0,0 +1,21 @@ +#!/usr/bin/perl +use warnings; +use strict; +use Test::More tests => 10; + +BEGIN { use_ok("IkiWiki"); } + +# note: yesno always accepts English even if localized. +# So no need to bother setting locale to C. + +ok(IkiWiki::yesno("yes") == 1); +ok(IkiWiki::yesno("Yes") == 1); +ok(IkiWiki::yesno("YES") == 1); + +ok(IkiWiki::yesno("no") == 0); +ok(IkiWiki::yesno("No") == 0); +ok(IkiWiki::yesno("NO") == 0); + +ok(IkiWiki::yesno("1") == 1); +ok(IkiWiki::yesno("0") == 0); +ok(IkiWiki::yesno("mooooooooooo") == 0); diff --git a/templates/atomitem.tmpl b/templates/atomitem.tmpl index 1ff7f4f4e..768695a2c 100644 --- a/templates/atomitem.tmpl +++ b/templates/atomitem.tmpl @@ -39,4 +39,10 @@ + + " type="text/html" /> + + + " type="application/atom+xml" /> + diff --git a/templates/change.tmpl b/templates/change.tmpl index 4a99cf5ff..0e61a80f4 100644 --- a/templates/change.tmpl +++ b/templates/change.tmpl @@ -3,7 +3,10 @@ [[!meta authorurl=""""""]] [[!meta title="""change to on """]] - +
diff --git a/templates/googleform.tmpl b/templates/googleform.tmpl index 523cff001..e2d4a1f43 100644 --- a/templates/googleform.tmpl +++ b/templates/googleform.tmpl @@ -1,6 +1,6 @@
- - + +
diff --git a/templates/inlinepage.tmpl b/templates/inlinepage.tmpl index ffcb897a8..3c0b93315 100644 --- a/templates/inlinepage.tmpl +++ b/templates/inlinepage.tmpl @@ -5,9 +5,9 @@ - + - + @@ -35,7 +35,7 @@ Posted Tags: - +
@@ -58,9 +58,13 @@ License:
  • Edit
  • + +
  • +
  • +
    diff --git a/templates/misc.tmpl b/templates/misc.tmpl index 7f65217d1..0de56edeb 100644 --- a/templates/misc.tmpl +++ b/templates/misc.tmpl @@ -17,11 +17,13 @@ +
    diff --git a/templates/page.tmpl b/templates/page.tmpl index f2f9c34cc..29ba688c7 100644 --- a/templates/page.tmpl +++ b/templates/page.tmpl @@ -13,6 +13,7 @@ + @@ -22,7 +23,7 @@ -/ +/ @@ -49,9 +50,13 @@
  • Preferences
  • + +

  • +

  • +
    @@ -67,6 +72,19 @@ + +
    + + + + +
    Comments on this page are closed.
    +
    +
    +
    +