# Optimisation.
use Memoize;
memoize("abs2rel");
+memoize("cmpspec_translate");
memoize("pagespec_translate");
memoize("template_file");
},
setuptype => {
type => "internal",
- default => "IkiWiki::Setup::Standard",
+ default => "Standard",
description => "perl class to use to dump setup file",
safe => 0,
rebuild => 0,
unless grep { $_ eq $link } @{$links{$page}};
}
+sub cmpspec_translate ($) {
+ my $spec = shift;
+
+ my $code = "";
+ my @data;
+ while ($spec =~ m{
+ \s*
+ (-?) # group 1: perhaps negated
+ \s*
+ ( # group 2: a word
+ \w+\([^\)]*\) # command(params)
+ |
+ [^\s]+ # or anything else
+ )
+ \s*
+ }gx) {
+ my $negated = $1;
+ my $word = $2;
+ my $params = undef;
+
+ if ($word =~ m/^(\w+)\((.*)\)$/) {
+ # command with parameters
+ $params = $2;
+ $word = $1;
+ }
+ elsif ($word !~ m/^\w+$/) {
+ error(sprintf(gettext("invalid sort type %s"), $word));
+ }
+
+ if (length $code) {
+ $code .= " || ";
+ }
+
+ if ($negated) {
+ $code .= "-";
+ }
+
+ if (exists $IkiWiki::PageSpec::{"cmp_$word"}) {
+ if (exists $IkiWiki::PageSpec::{"check_cmp_$word"}) {
+ $IkiWiki::PageSpec::{"check_cmp_$word"}->($params);
+ }
+
+ if (defined $params) {
+ push @data, $params;
+ $code .= "IkiWiki::PageSpec::cmp_$word(\@_, \$data[$#data])";
+ }
+ else {
+ $code .= "IkiWiki::PageSpec::cmp_$word(\@_, undef)";
+ }
+ }
+ else {
+ error(sprintf(gettext("unknown sort type %s"), $word));
+ }
+ }
+
+ if (! length $code) {
+ # undefined sorting method... sort arbitrarily
+ return sub { 0 };
+ }
+
+ no warnings;
+ return eval 'sub { '.$code.' }';
+}
+
sub pagespec_translate ($) {
my $spec=shift;
}
if (defined $params{sort}) {
- my $f;
- if ($params{sort} eq 'title') {
- $f=sub { pagetitle(basename($a)) cmp pagetitle(basename($b)) };
- }
- elsif ($params{sort} eq 'title_natural') {
- eval q{use Sort::Naturally};
- if ($@) {
- error(gettext("Sort::Naturally needed for title_natural sort"));
- }
- $f=sub { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) };
- }
- elsif ($params{sort} eq 'mtime') {
- $f=sub { $pagemtime{$b} <=> $pagemtime{$a} };
- }
- elsif ($params{sort} eq 'age') {
- $f=sub { $pagectime{$b} <=> $pagectime{$a} };
- }
- else {
- error sprintf(gettext("unknown sort type %s"), $params{sort});
- }
- @candidates = sort { &$f } @candidates;
+ my $f = cmpspec_translate($params{sort});
+
+ @candidates = sort { $f->($a, $b) } @candidates;
}
@candidates=reverse(@candidates) if $params{reverse};
}
}
+sub cmp_title {
+ IkiWiki::pagetitle(IkiWiki::basename($_[0]))
+ cmp
+ IkiWiki::pagetitle(IkiWiki::basename($_[1]))
+}
+
+sub cmp_mtime { $IkiWiki::pagemtime{$_[1]} <=> $IkiWiki::pagemtime{$_[0]} }
+sub cmp_age { $IkiWiki::pagectime{$_[1]} <=> $IkiWiki::pagectime{$_[0]} }
+
+sub check_cmp_title_natural {
+ eval q{use Sort::Naturally};
+ if ($@) {
+ error(gettext("Sort::Naturally needed for title_natural sort"));
+ }
+}
+sub cmp_title_natural {
+ Sort::Naturally::ncmp(IkiWiki::pagetitle(IkiWiki::basename($_[0])),
+ IkiWiki::pagetitle(IkiWiki::basename($_[1])))
+}
+
1