From e67a9382f67e745af3be7d367fe7a0d36c1777e6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 24 Mar 2010 00:29:10 +0000 Subject: Allow hooks to add sorting functions to pagespec_match_list --- doc/ikiwiki/pagespec/sorting.mdwn | 2 ++ doc/plugins/write.mdwn | 15 +++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'doc') diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index 697818a2a..9007c23bf 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -10,4 +10,6 @@ orders can be specified. installed. Orders by title, but numbers in the title are treated as such, ("1 2 9 10 20" instead of "1 10 2 20 9") +Plugins can add additional sort orders. + [[!meta robots="noindex, follow"]] diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 96a2aa16d..bfa6617bd 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -588,6 +588,21 @@ describes the plugin as a whole. For example: This hook is used to inject C code (which it returns) into the `main` function of the ikiwiki wrapper when it is being generated. +### sort + + hook(type => "sort", id => "foo", call => \&sort_by_foo); + +This hook adds an additional [[ikiwiki/pagespec/sorting]] order or overrides +an existing one. The callback is given two page names as arguments, and +returns negative, zero or positive if the first page should come before, +close to (i.e. undefined order), or after the second page. + +For instance, the built-in `title` sort order could be reimplemented as + + sub sort_by_title { + pagetitle(basename($_[0])) cmp pagetitle(basename($_[1])); + } + ## Exported variables Several variables are exported to your plugin when you `use IkiWiki;` -- cgit v1.2.3 From 0618f099dab8bd4f7f47e2695db01eabe49e3316 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 24 Mar 2010 00:59:01 +0000 Subject: Have the meta plugin add a meta_title sort order --- IkiWiki/Plugin/meta.pm | 15 +++++++++++++++ doc/ikiwiki/pagespec/sorting.mdwn | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index 5f046cb2a..bf8159814 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -13,6 +13,7 @@ sub import { hook(type => "needsbuild", id => "meta", call => \&needsbuild); hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1); hook(type => "pagetemplate", id => "meta", call => \&pagetemplate); + hook(type => "sort", id => "meta_title", call => \&sort_meta_title); } sub getsetup () { @@ -282,6 +283,20 @@ sub pagetemplate (@) { } } +sub title { + my $title = $pagestate{$_[0]}{meta}{title}; + + if (defined $title) { + return $title; + } + + return pagetitle(IkiWiki::basename($_[0])); +} + +sub sort_meta_title { + return title($_[0]) cmp title($_[1]); +} + sub match { my $field=shift; my $page=shift; diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index 9007c23bf..3a9fef9b6 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -9,7 +9,12 @@ orders can be specified. * `title_natural` - Only available if [[!cpan Sort::Naturally]] is installed. Orders by title, but numbers in the title are treated as such, ("1 2 9 10 20" instead of "1 10 2 20 9") +[[!if test="enabled(meta)" then=""" +* `meta_title` - Order by the full title set by the `\[[!meta title="foo"]]` + [[ikiwiki/directive]]. +"""]] -Plugins can add additional sort orders. +Plugins can add additional sort orders, so more might be available on this +wiki. [[!meta robots="noindex, follow"]] -- cgit v1.2.3 From b0ae19872d443860aeaab7069255e3a68a520887 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 24 Mar 2010 03:18:24 +0000 Subject: Add an optional "sort" argument to meta titles, defaulting to the title This allows correct sorting of titles, names, etc., with: [[!meta title="David Bowie" sort="Bowie, David"]] [[!meta title="The Beatles" sort="Beatles, The"]] --- IkiWiki/Plugin/meta.pm | 16 +++++++++++----- doc/ikiwiki/directive/meta.mdwn | 7 +++++++ doc/ikiwiki/pagespec/sorting.mdwn | 7 ++++--- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index bf8159814..a470041c9 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -90,6 +90,12 @@ sub preprocess (@) { # Metadata collection that needs to happen during the scan pass. if ($key eq 'title') { $pagestate{$page}{meta}{title}=HTML::Entities::encode_numeric($value); + if (exists $params{sort}) { + $pagestate{$page}{meta}{titlesort}=$params{sort}; + } + else { + $pagestate{$page}{meta}{titlesort}=$value; + } return ""; } elsif ($key eq 'description') { @@ -283,18 +289,18 @@ sub pagetemplate (@) { } } -sub title { - my $title = $pagestate{$_[0]}{meta}{title}; +sub titlesort { + my $key = $pagestate{$_[0]}{meta}{titlesort}; - if (defined $title) { - return $title; + if (defined $key) { + return $key; } return pagetitle(IkiWiki::basename($_[0])); } sub sort_meta_title { - return title($_[0]) cmp title($_[1]); + return titlesort($_[0]) cmp titlesort($_[1]); } sub match { diff --git a/doc/ikiwiki/directive/meta.mdwn b/doc/ikiwiki/directive/meta.mdwn index 557441c0b..8d2a5b1ad 100644 --- a/doc/ikiwiki/directive/meta.mdwn +++ b/doc/ikiwiki/directive/meta.mdwn @@ -23,6 +23,13 @@ Supported fields: be set to a true value in the template; this can be used to format things differently in this case. + An optional `sort` parameter will be used preferentially when + [[ikiwiki/pagespec/sorting]] by `meta_title`: + + \[[!meta title="The Beatles" sort="Beatles, The"]] + + \[[!meta title="David Bowie" sort="Bowie, David"]] + * license Specifies a license for the page, for example, "GPL". Can contain diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index 3a9fef9b6..61516bec5 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -5,13 +5,14 @@ orders can be specified. * `age` - List pages from the most recently created to the oldest. * `mtime` - List pages with the most recently modified first. -* `title` - Order by title. +* `title` - Order by title (page name). * `title_natural` - Only available if [[!cpan Sort::Naturally]] is installed. Orders by title, but numbers in the title are treated as such, ("1 2 9 10 20" instead of "1 10 2 20 9") [[!if test="enabled(meta)" then=""" -* `meta_title` - Order by the full title set by the `\[[!meta title="foo"]]` - [[ikiwiki/directive]]. +* `meta_title` - Order according to the `\[[!meta title="foo" sort="bar"]]` + or `\[[!meta title="foo"]]` [[ikiwiki/directive]], or the page name if no + full title was set. """]] Plugins can add additional sort orders, so more might be available on this -- cgit v1.2.3 From 60edd2dc3157f756f4f7a213ee15836fe7bbb769 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 24 Mar 2010 23:51:48 +0000 Subject: Allow sorting to be combined and/or reversed --- IkiWiki.pm | 84 ++++++++++++++++++++++++++++----------- doc/ikiwiki/pagespec/sorting.mdwn | 4 ++ doc/plugins/write.mdwn | 17 +++++++- t/pagespec_match_list.t | 12 +++++- 4 files changed, 91 insertions(+), 26 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index 1a4dc47dd..ce8fdd454 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2005,6 +2005,64 @@ sub pagespec_match ($$;@) { return $sub->($page, @params); } +sub get_sort_function { + my $method = $_[0]; + + if ($method =~ m/\s/) { + my @methods = map { get_sort_function($_) } split(' ', $method); + + return sub { + foreach my $method (@methods) { + my $answer = $method->($_[0], $_[1]); + return $answer if $answer; + } + + return 0; + }; + } + + my $sense = 1; + + if ($method =~ s/^-//) { + $sense = -1; + } + + my $token = $method; + my $parameter = undef; + + if ($method =~ m/^(\w+)\((.*)\)$/) { + $token = $1; + $parameter = $2; + } + + if (exists $hooks{sort}{$token}{call}) { + my $callback = $hooks{sort}{$token}{call}; + return sub { $sense * $callback->($_[0], $_[1], $parameter) }; + } + + if ($method eq 'title') { + return sub { $sense * (pagetitle(basename($_[0])) cmp pagetitle(basename($_[1]))) }; + } + + if ($method eq 'title_natural') { + eval q{use Sort::Naturally}; + if ($@) { + error(gettext("Sort::Naturally needed for title_natural sort")); + } + return sub { $sense * Sort::Naturally::ncmp(pagetitle(basename($_[0])), pagetitle(basename($_[1]))) }; + } + + if ($method eq 'mtime') { + return sub { $sense * ($pagemtime{$_[1]} <=> $pagemtime{$_[0]}) }; + } + + if ($method eq 'age') { + return sub { $sense * ($pagectime{$_[1]} <=> $pagectime{$_[0]}) }; + } + + error sprintf(gettext("unknown sort type %s"), $method); +} + sub pagespec_match_list ($$;@) { my $page=shift; my $pagespec=shift; @@ -2034,31 +2092,9 @@ sub pagespec_match_list ($$;@) { } if (defined $params{sort}) { - my $f; + my $f = get_sort_function($params{sort}); - if (exists $hooks{sort}{$params{sort}}{call}) { - $f = sub { $hooks{sort}{$params{sort}}{call}($a, $b) }; - } - elsif ($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; + @candidates = sort { $f->($a, $b) } @candidates; } @candidates=reverse(@candidates) if $params{reverse}; diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index 61516bec5..f27972d4e 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -15,6 +15,10 @@ orders can be specified. full title was set. """]] +In addition, you can combine several sort orders and/or reverse the order of +sorting, with a string like `age -title` (which would sort by age, then by +title in reverse order if two pages have the same age). + Plugins can add additional sort orders, so more might be available on this wiki. diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index bfa6617bd..1010e76e4 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -593,7 +593,9 @@ function of the ikiwiki wrapper when it is being generated. hook(type => "sort", id => "foo", call => \&sort_by_foo); This hook adds an additional [[ikiwiki/pagespec/sorting]] order or overrides -an existing one. The callback is given two page names as arguments, and +an existing one. + +The callback is given two page names followed by the parameter as arguments, and returns negative, zero or positive if the first page should come before, close to (i.e. undefined order), or after the second page. @@ -603,6 +605,19 @@ For instance, the built-in `title` sort order could be reimplemented as pagetitle(basename($_[0])) cmp pagetitle(basename($_[1])); } +and to sort by an arbitrary `meta` value, you could use: + + # usage: sort="meta(description)" + sub sort_by_meta { + my $param = $_[2]; + error "sort=meta requires a parameter" unless defined $param; + my $left = $pagestate{$_[0]}{meta}{$param}; + $left = "" unless defined $left; + my $right = $pagestate{$_[1]}{meta}{$param}; + $right = "" unless defined $right; + return $left cmp $right; + } + ## Exported variables Several variables are exported to your plugin when you `use IkiWiki;` diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t index b34ee769f..309961f1c 100755 --- a/t/pagespec_match_list.t +++ b/t/pagespec_match_list.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 89; +use Test::More tests => 90; BEGIN { use_ok("IkiWiki"); } @@ -20,6 +20,13 @@ hook(type => "sort", id => "path", call => sub { $_[0] cmp $_[1] }); "post/2" => "post/2.mdwn", "post/3" => "post/3.mdwn", ); +$IkiWiki::pagectime{foo} = 2; +$IkiWiki::pagectime{foo2} = 2; +$IkiWiki::pagectime{foo3} = 1; +$IkiWiki::pagectime{bar} = 3; +$IkiWiki::pagectime{"post/1"} = 6; +$IkiWiki::pagectime{"post/2"} = 6; +$IkiWiki::pagectime{"post/3"} = 6; $links{foo}=[qw{post/1 post/2}]; $links{foo2}=[qw{bar}]; $links{foo3}=[qw{bar}]; @@ -38,6 +45,9 @@ is_deeply([pagespec_match_list("foo", "post/*", sort => "title", ["post/1", "post/2"]); is_deeply([pagespec_match_list("foo", "*", sort => "path", num => 2)], ["bar", "foo"]); +is_deeply([pagespec_match_list("foo", "foo* or bar*", + sort => "-age title")], # oldest first, break ties by title + ["foo3", "foo", "foo2", "bar"]); my $r=eval { pagespec_match_list("foo", "beep") }; ok(eval { pagespec_match_list("foo", "beep") } == 0); ok(! $@, "does not fail with error when unable to match anything"); -- cgit v1.2.3 From b86276ffed7ee001b35cd610e5d56e5afb4088cf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 25 Mar 2010 23:31:53 +0000 Subject: Reimplement extensible sorting mechanisms, in the same way as pagespecs --- IkiWiki.pm | 145 ++++++++++++++++++++++++++++-------------------- IkiWiki/Plugin/meta.pm | 11 ++-- doc/plugins/write.mdwn | 53 ++++++++---------- t/pagespec_match_list.t | 6 +- 4 files changed, 120 insertions(+), 95 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index ce8fdd454..a89c14058 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -37,6 +37,7 @@ our $DEPEND_LINKS=4; # Optimisation. use Memoize; memoize("abs2rel"); +memoize("cmpspec_translate"); memoize("pagespec_translate"); memoize("template_file"); @@ -1934,6 +1935,70 @@ sub add_link ($$) { 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; @@ -2005,64 +2070,6 @@ sub pagespec_match ($$;@) { return $sub->($page, @params); } -sub get_sort_function { - my $method = $_[0]; - - if ($method =~ m/\s/) { - my @methods = map { get_sort_function($_) } split(' ', $method); - - return sub { - foreach my $method (@methods) { - my $answer = $method->($_[0], $_[1]); - return $answer if $answer; - } - - return 0; - }; - } - - my $sense = 1; - - if ($method =~ s/^-//) { - $sense = -1; - } - - my $token = $method; - my $parameter = undef; - - if ($method =~ m/^(\w+)\((.*)\)$/) { - $token = $1; - $parameter = $2; - } - - if (exists $hooks{sort}{$token}{call}) { - my $callback = $hooks{sort}{$token}{call}; - return sub { $sense * $callback->($_[0], $_[1], $parameter) }; - } - - if ($method eq 'title') { - return sub { $sense * (pagetitle(basename($_[0])) cmp pagetitle(basename($_[1]))) }; - } - - if ($method eq 'title_natural') { - eval q{use Sort::Naturally}; - if ($@) { - error(gettext("Sort::Naturally needed for title_natural sort")); - } - return sub { $sense * Sort::Naturally::ncmp(pagetitle(basename($_[0])), pagetitle(basename($_[1]))) }; - } - - if ($method eq 'mtime') { - return sub { $sense * ($pagemtime{$_[1]} <=> $pagemtime{$_[0]}) }; - } - - if ($method eq 'age') { - return sub { $sense * ($pagectime{$_[1]} <=> $pagectime{$_[0]}) }; - } - - error sprintf(gettext("unknown sort type %s"), $method); -} - sub pagespec_match_list ($$;@) { my $page=shift; my $pagespec=shift; @@ -2092,7 +2099,7 @@ sub pagespec_match_list ($$;@) { } if (defined $params{sort}) { - my $f = get_sort_function($params{sort}); + my $f = cmpspec_translate($params{sort}); @candidates = sort { $f->($a, $b) } @candidates; } @@ -2407,4 +2414,24 @@ sub match_ip ($$;@) { } } +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 diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index a470041c9..e8cc1e392 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -13,7 +13,6 @@ sub import { hook(type => "needsbuild", id => "meta", call => \&needsbuild); hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1); hook(type => "pagetemplate", id => "meta", call => \&pagetemplate); - hook(type => "sort", id => "meta_title", call => \&sort_meta_title); } sub getsetup () { @@ -299,10 +298,6 @@ sub titlesort { return pagetitle(IkiWiki::basename($_[0])); } -sub sort_meta_title { - return titlesort($_[0]) cmp titlesort($_[1]); -} - sub match { my $field=shift; my $page=shift; @@ -353,4 +348,10 @@ sub match_copyright ($$;@) { IkiWiki::Plugin::meta::match("copyright", @_); } +sub cmp_meta_title { + IkiWiki::Plugin::meta::titlesort($_[0]) + cmp + IkiWiki::Plugin::meta::titlesort($_[1]) +} + 1 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 1010e76e4..de2b47015 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -588,36 +588,6 @@ describes the plugin as a whole. For example: This hook is used to inject C code (which it returns) into the `main` function of the ikiwiki wrapper when it is being generated. -### sort - - hook(type => "sort", id => "foo", call => \&sort_by_foo); - -This hook adds an additional [[ikiwiki/pagespec/sorting]] order or overrides -an existing one. - -The callback is given two page names followed by the parameter as arguments, and -returns negative, zero or positive if the first page should come before, -close to (i.e. undefined order), or after the second page. - -For instance, the built-in `title` sort order could be reimplemented as - - sub sort_by_title { - pagetitle(basename($_[0])) cmp pagetitle(basename($_[1])); - } - -and to sort by an arbitrary `meta` value, you could use: - - # usage: sort="meta(description)" - sub sort_by_meta { - my $param = $_[2]; - error "sort=meta requires a parameter" unless defined $param; - my $left = $pagestate{$_[0]}{meta}{$param}; - $left = "" unless defined $left; - my $right = $pagestate{$_[1]}{meta}{$param}; - $right = "" unless defined $right; - return $left cmp $right; - } - ## Exported variables Several variables are exported to your plugin when you `use IkiWiki;` @@ -1140,6 +1110,29 @@ For example, "backlink(foo)" is influenced by the contents of page foo; they match; "created_before(foo)" is influenced by the metadata of foo; while "glob(*)" is not influenced by the contents of any page. +### Sorting plugins + +Similarly, it's possible to write plugins that add new functions as +[[ikiwiki/pagespec/sorting]] methods. To achieve this, add a function to +the IkiWiki::PageSpec package named `cmp_foo`, which will be used when sorting +by `foo` or `foo(...)` is requested. + +The function will be passed three or more parameters. The first two are +page names, and the third is `undef` if invoked as `foo`, or the parameter +`"bar"` if invoked as `foo(bar)`. It may also be passed additional, named +parameters. + +It should return the same thing as Perl's `cmp` and `<=>` operators: negative +if the first argument is less than the second, positive if the first argument +is greater, or zero if they are considered equal. It may also raise an +error using `error`, for instance if it needs a parameter but one isn't +provided. + +You can also define a function called `check_cmp_foo` in the same package. +If you do, it will be called while preparing to sort by `foo` or `foo(bar)`, +with argument `undef` or `"bar"` respectively; it may raise an error using +`error`, if sorting like that isn't going to work. + ### Setup plugins The ikiwiki setup file is loaded using a pluggable mechanism. If you look diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t index 309961f1c..743ae4637 100755 --- a/t/pagespec_match_list.t +++ b/t/pagespec_match_list.t @@ -9,7 +9,11 @@ BEGIN { use_ok("IkiWiki"); } $config{srcdir}=$config{destdir}="/dev/null"; IkiWiki::checkconfig(); -hook(type => "sort", id => "path", call => sub { $_[0] cmp $_[1] }); +{ + package IkiWiki::PageSpec; + + sub cmp_path { $_[0] cmp $_[1] } +} %pagesources=( foo => "foo.mdwn", -- cgit v1.2.3 From a875ee8be702bd4575e009dc652015c1157c7c2e Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 3 Apr 2010 13:48:30 +0100 Subject: Split out sortnaturally into a plugin --- IkiWiki.pm | 11 ----------- IkiWiki/Plugin/sortnaturally.pm | 32 ++++++++++++++++++++++++++++++++ debian/NEWS | 8 ++++++++ doc/ikiwiki/pagespec/sorting.mdwn | 5 +++-- doc/plugins/sortnaturally.mdwn | 5 +++++ 5 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 IkiWiki/Plugin/sortnaturally.pm create mode 100644 doc/plugins/sortnaturally.mdwn (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index a89c14058..8f36f5818 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2423,15 +2423,4 @@ sub cmp_title { 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 diff --git a/IkiWiki/Plugin/sortnaturally.pm b/IkiWiki/Plugin/sortnaturally.pm new file mode 100644 index 000000000..0023f31f9 --- /dev/null +++ b/IkiWiki/Plugin/sortnaturally.pm @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# Sort::Naturally-powered title_natural sort order for IkiWiki +package IkiWiki::Plugin::sortnaturally; + +use IkiWiki 3.00; +no warnings; + +sub import { + hook(type => "getsetup", id => "sortnaturally", call => \&getsetup); +} + +sub getsetup { + return + plugin => { + safe => 1, + rebuild => 1, + }, +} + +sub checkconfig () { + eval q{use Sort::Naturally}; + error $@ if $@; +} + +package IkiWiki::PageSpec; + +sub cmp_title_natural { + Sort::Naturally::ncmp(IkiWiki::pagetitle(IkiWiki::basename($_[0])), + IkiWiki::pagetitle(IkiWiki::basename($_[1]))) +} + +1; diff --git a/debian/NEWS b/debian/NEWS index 50332670f..614eb11f8 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,3 +1,11 @@ +ikiwiki (3.20100320) UNRELEASED; urgency=low + + The sort="title_natural" option on [[!inline]] etc. now requires the + new sortnaturally plugin. This is not enabled by default, because it requires + the Sort::Naturally module. + + -- Simon McVittie Sat, 03 Apr 2010 13:46:08 +0100 + ikiwiki (3.20091017) unstable; urgency=low To take advantage of significant performance improvements, all diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index f27972d4e..ba995a521 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -6,9 +6,10 @@ orders can be specified. * `age` - List pages from the most recently created to the oldest. * `mtime` - List pages with the most recently modified first. * `title` - Order by title (page name). -* `title_natural` - Only available if [[!cpan Sort::Naturally]] is - installed. Orders by title, but numbers in the title are treated +[[!if test="enabled(sortnaturally)" then=""" +* `title_natural` - Orders by title, but numbers in the title are treated as such, ("1 2 9 10 20" instead of "1 10 2 20 9") +"""]] [[!if test="enabled(meta)" then=""" * `meta_title` - Order according to the `\[[!meta title="foo" sort="bar"]]` or `\[[!meta title="foo"]]` [[ikiwiki/directive]], or the page name if no diff --git a/doc/plugins/sortnaturally.mdwn b/doc/plugins/sortnaturally.mdwn new file mode 100644 index 000000000..91f373f6b --- /dev/null +++ b/doc/plugins/sortnaturally.mdwn @@ -0,0 +1,5 @@ +[[!template id=plugin name=sortnaturally core=1 author="[[chrysn]], [[smcv]]"]] +[[!tag type/meta]] + +This plugin provides the `title_natural` [[ikiwiki/pagespec/sorting]] order, +which uses Sort::Naturally to sort numbered pages in a more natural order. -- cgit v1.2.3 From 75fd08046548940c443c46bcdf9a5b0b6968b175 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 3 Apr 2010 13:49:20 +0100 Subject: Remove support for check_cmp_foo (pre-sort checks) --- IkiWiki.pm | 4 ---- doc/plugins/write.mdwn | 5 ----- 2 files changed, 9 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index 8f36f5818..7547f1751 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1973,10 +1973,6 @@ sub cmpspec_translate ($) { } 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])"; diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index de2b47015..06c8f8e44 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1128,11 +1128,6 @@ is greater, or zero if they are considered equal. It may also raise an error using `error`, for instance if it needs a parameter but one isn't provided. -You can also define a function called `check_cmp_foo` in the same package. -If you do, it will be called while preparing to sort by `foo` or `foo(bar)`, -with argument `undef` or `"bar"` respectively; it may raise an error using -`error`, if sorting like that isn't going to work. - ### Setup plugins The ikiwiki setup file is loaded using a pluggable mechanism. If you look -- cgit v1.2.3 From 04a59b3c65e8e60805b6ed6d11d448b1d5babe64 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 3 Apr 2010 13:57:38 +0100 Subject: Move sort hooks to the IkiWiki::SortSpec namespace Also rename cmpspec_translate (internal function) to sortspec_translate for consistency. --- IkiWiki.pm | 14 ++++++++------ IkiWiki/Plugin/meta.pm | 2 ++ IkiWiki/Plugin/sortnaturally.pm | 2 +- doc/plugins/write.mdwn | 2 +- t/pagespec_match_list.t | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index 7547f1751..d716e8b39 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -37,7 +37,7 @@ our $DEPEND_LINKS=4; # Optimisation. use Memoize; memoize("abs2rel"); -memoize("cmpspec_translate"); +memoize("sortspec_translate"); memoize("pagespec_translate"); memoize("template_file"); @@ -1935,7 +1935,7 @@ sub add_link ($$) { unless grep { $_ eq $link } @{$links{$page}}; } -sub cmpspec_translate ($) { +sub sortspec_translate ($) { my $spec = shift; my $code = ""; @@ -1972,13 +1972,13 @@ sub cmpspec_translate ($) { $code .= "-"; } - if (exists $IkiWiki::PageSpec::{"cmp_$word"}) { + if (exists $IkiWiki::SortSpec::{"cmp_$word"}) { if (defined $params) { push @data, $params; - $code .= "IkiWiki::PageSpec::cmp_$word(\@_, \$data[$#data])"; + $code .= "IkiWiki::SortSpec::cmp_$word(\@_, \$data[$#data])"; } else { - $code .= "IkiWiki::PageSpec::cmp_$word(\@_, undef)"; + $code .= "IkiWiki::SortSpec::cmp_$word(\@_, undef)"; } } else { @@ -2095,7 +2095,7 @@ sub pagespec_match_list ($$;@) { } if (defined $params{sort}) { - my $f = cmpspec_translate($params{sort}); + my $f = sortspec_translate($params{sort}); @candidates = sort { $f->($a, $b) } @candidates; } @@ -2410,6 +2410,8 @@ sub match_ip ($$;@) { } } +package IkiWiki::SortSpec; + sub cmp_title { IkiWiki::pagetitle(IkiWiki::basename($_[0])) cmp diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index e8cc1e392..cd7d0d127 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -348,6 +348,8 @@ sub match_copyright ($$;@) { IkiWiki::Plugin::meta::match("copyright", @_); } +package IkiWiki::SortSpec; + sub cmp_meta_title { IkiWiki::Plugin::meta::titlesort($_[0]) cmp diff --git a/IkiWiki/Plugin/sortnaturally.pm b/IkiWiki/Plugin/sortnaturally.pm index 0023f31f9..f498820a5 100644 --- a/IkiWiki/Plugin/sortnaturally.pm +++ b/IkiWiki/Plugin/sortnaturally.pm @@ -22,7 +22,7 @@ sub checkconfig () { error $@ if $@; } -package IkiWiki::PageSpec; +package IkiWiki::SortSpec; sub cmp_title_natural { Sort::Naturally::ncmp(IkiWiki::pagetitle(IkiWiki::basename($_[0])), diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 06c8f8e44..b67142230 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1114,7 +1114,7 @@ while "glob(*)" is not influenced by the contents of any page. Similarly, it's possible to write plugins that add new functions as [[ikiwiki/pagespec/sorting]] methods. To achieve this, add a function to -the IkiWiki::PageSpec package named `cmp_foo`, which will be used when sorting +the IkiWiki::SortSpec package named `cmp_foo`, which will be used when sorting by `foo` or `foo(...)` is requested. The function will be passed three or more parameters. The first two are diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t index 743ae4637..68112f5c0 100755 --- a/t/pagespec_match_list.t +++ b/t/pagespec_match_list.t @@ -10,7 +10,7 @@ $config{srcdir}=$config{destdir}="/dev/null"; IkiWiki::checkconfig(); { - package IkiWiki::PageSpec; + package IkiWiki::SortSpec; sub cmp_path { $_[0] cmp $_[1] } } -- cgit v1.2.3 From 618bbaee3815daffe329fc1e2d77f04fcd8392b8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 3 Apr 2010 14:17:48 +0100 Subject: meta: generalize meta_title into meta(title); support author, updated, date I've left meta_title in, undocumented, as a possible replacement for sort=title in IkiWiki 4.0 or something. --- IkiWiki/Plugin/meta.pm | 58 +++++++++++++++++++++++++++++++++------ doc/ikiwiki/directive/meta.mdwn | 7 ++++- doc/ikiwiki/pagespec/sorting.mdwn | 5 ++-- 3 files changed, 58 insertions(+), 12 deletions(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index cd7d0d127..c9fdbc934 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -122,6 +122,12 @@ sub preprocess (@) { } elsif ($key eq 'author') { $pagestate{$page}{meta}{author}=$value; + if (exists $params{sort}) { + $pagestate{$page}{meta}{authorsort}=$params{sort}; + } + else { + $pagestate{$page}{meta}{authorsort}=$value; + } # fallthorough } elsif ($key eq 'authorurl') { @@ -288,14 +294,31 @@ sub pagetemplate (@) { } } -sub titlesort { - my $key = $pagestate{$_[0]}{meta}{titlesort}; +sub get_sort_key { + my $page = $_[0]; + my $meta = $_[1]; - if (defined $key) { - return $key; - } + # e.g. titlesort (also makes sense for author) + my $key = $pagestate{$page}{meta}{$meta . "sort"}; + return $key if defined $key; + + # e.g. title + $key = $pagestate{$page}{meta}{$meta}; + return $key if defined $key; - return pagetitle(IkiWiki::basename($_[0])); + # fall back to closer-to-core things + if ($meta eq 'title') { + return pagetitle(IkiWiki::basename($page)); + } + elsif ($meta eq 'date') { + return $IkiWiki::pagectime{$page}; + } + elsif ($meta eq 'updated') { + return $IkiWiki::pagemtime{$page}; + } + else { + return ''; + } } sub match { @@ -350,10 +373,27 @@ sub match_copyright ($$;@) { package IkiWiki::SortSpec; +sub cmp_meta { + my $left = $_[0]; + my $right = $_[1]; + my $meta = $_[2]; + error(gettext("sort=meta requires a parameter")) unless defined $meta; + + if ($meta eq 'updated' || $meta eq 'date') { + return IkiWiki::Plugin::meta::get_sort_key($left, $meta) + <=> + IkiWiki::Plugin::meta::get_sort_key($right, $meta); + } + + return IkiWiki::Plugin::meta::get_sort_key($left, $meta) + cmp + IkiWiki::Plugin::meta::get_sort_key($right, $meta); +} + +# A prototype of how sort=title could behave in 4.0 or something sub cmp_meta_title { - IkiWiki::Plugin::meta::titlesort($_[0]) - cmp - IkiWiki::Plugin::meta::titlesort($_[1]) + $_[2] = 'title'; + return cmp_meta(@_); } 1 diff --git a/doc/ikiwiki/directive/meta.mdwn b/doc/ikiwiki/directive/meta.mdwn index 8d2a5b1ad..c5f74fac5 100644 --- a/doc/ikiwiki/directive/meta.mdwn +++ b/doc/ikiwiki/directive/meta.mdwn @@ -24,7 +24,7 @@ Supported fields: differently in this case. An optional `sort` parameter will be used preferentially when - [[ikiwiki/pagespec/sorting]] by `meta_title`: + [[ikiwiki/pagespec/sorting]] by `meta(title)`: \[[!meta title="The Beatles" sort="Beatles, The"]] @@ -44,6 +44,11 @@ Supported fields: Specifies the author of a page. + An optional `sort` parameter will be used preferentially when + [[ikiwiki/pagespec/sorting]] by `meta(author)`: + + \[[!meta author="Joey Hess" sort="Hess, Joey"]] + * authorurl Specifies an url for the author of a page. diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index ba995a521..fbf598340 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -11,9 +11,10 @@ orders can be specified. as such, ("1 2 9 10 20" instead of "1 10 2 20 9") """]] [[!if test="enabled(meta)" then=""" -* `meta_title` - Order according to the `\[[!meta title="foo" sort="bar"]]` +* `meta(title)` - Order according to the `\[[!meta title="foo" sort="bar"]]` or `\[[!meta title="foo"]]` [[ikiwiki/directive]], or the page name if no - full title was set. + full title was set. `meta(author)`, `meta(date)`, `meta(updated)`, etc. + also work. """]] In addition, you can combine several sort orders and/or reverse the order of -- cgit v1.2.3 From 490f95616a8a49f2120655d07c282eefd067e640 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 3 Apr 2010 14:19:18 +0100 Subject: Rename sort parameter to meta title/author to sortas=bar Joey pointed out that sort=x usually takes a sort order. --- IkiWiki/Plugin/meta.pm | 8 ++++---- doc/ikiwiki/directive/meta.mdwn | 10 +++++----- doc/ikiwiki/pagespec/sorting.mdwn | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index c9fdbc934..4992617d0 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -89,8 +89,8 @@ sub preprocess (@) { # Metadata collection that needs to happen during the scan pass. if ($key eq 'title') { $pagestate{$page}{meta}{title}=HTML::Entities::encode_numeric($value); - if (exists $params{sort}) { - $pagestate{$page}{meta}{titlesort}=$params{sort}; + if (exists $params{sortas}) { + $pagestate{$page}{meta}{titlesort}=$params{sortas}; } else { $pagestate{$page}{meta}{titlesort}=$value; @@ -122,8 +122,8 @@ sub preprocess (@) { } elsif ($key eq 'author') { $pagestate{$page}{meta}{author}=$value; - if (exists $params{sort}) { - $pagestate{$page}{meta}{authorsort}=$params{sort}; + if (exists $params{sortas}) { + $pagestate{$page}{meta}{authorsort}=$params{sortas}; } else { $pagestate{$page}{meta}{authorsort}=$value; diff --git a/doc/ikiwiki/directive/meta.mdwn b/doc/ikiwiki/directive/meta.mdwn index c5f74fac5..5a3919dea 100644 --- a/doc/ikiwiki/directive/meta.mdwn +++ b/doc/ikiwiki/directive/meta.mdwn @@ -23,12 +23,12 @@ Supported fields: be set to a true value in the template; this can be used to format things differently in this case. - An optional `sort` parameter will be used preferentially when + An optional `sortas` parameter will be used preferentially when [[ikiwiki/pagespec/sorting]] by `meta(title)`: - \[[!meta title="The Beatles" sort="Beatles, The"]] + \[[!meta title="The Beatles" sortas="Beatles, The"]] - \[[!meta title="David Bowie" sort="Bowie, David"]] + \[[!meta title="David Bowie" sortas="Bowie, David"]] * license @@ -44,10 +44,10 @@ Supported fields: Specifies the author of a page. - An optional `sort` parameter will be used preferentially when + An optional `sortas` parameter will be used preferentially when [[ikiwiki/pagespec/sorting]] by `meta(author)`: - \[[!meta author="Joey Hess" sort="Hess, Joey"]] + \[[!meta author="Joey Hess" sortas="Hess, Joey"]] * authorurl diff --git a/doc/ikiwiki/pagespec/sorting.mdwn b/doc/ikiwiki/pagespec/sorting.mdwn index fbf598340..5c6cfcc2b 100644 --- a/doc/ikiwiki/pagespec/sorting.mdwn +++ b/doc/ikiwiki/pagespec/sorting.mdwn @@ -11,7 +11,7 @@ orders can be specified. as such, ("1 2 9 10 20" instead of "1 10 2 20 9") """]] [[!if test="enabled(meta)" then=""" -* `meta(title)` - Order according to the `\[[!meta title="foo" sort="bar"]]` +* `meta(title)` - Order according to the `\[[!meta title="foo" sortas="bar"]]` or `\[[!meta title="foo"]]` [[ikiwiki/directive]], or the page name if no full title was set. `meta(author)`, `meta(date)`, `meta(updated)`, etc. also work. -- cgit v1.2.3 From cb8b2f80b2f8c91eba3f3a6a5b9913ab80326df8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 5 Apr 2010 22:50:51 +0100 Subject: Use $a and $b for SortSpec cmp callbacks --- IkiWiki.pm | 27 ++++++++++++++++++--------- IkiWiki/Plugin/meta.pm | 14 ++++++-------- IkiWiki/Plugin/sortnaturally.pm | 4 ++-- doc/plugins/write.mdwn | 20 ++++++++++---------- t/pagespec_match_list.t | 2 +- 5 files changed, 37 insertions(+), 30 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index d716e8b39..da36494fb 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1975,10 +1975,10 @@ sub sortspec_translate ($) { if (exists $IkiWiki::SortSpec::{"cmp_$word"}) { if (defined $params) { push @data, $params; - $code .= "IkiWiki::SortSpec::cmp_$word(\@_, \$data[$#data])"; + $code .= "IkiWiki::SortSpec::cmp_$word(\$data[$#data])"; } else { - $code .= "IkiWiki::SortSpec::cmp_$word(\@_, undef)"; + $code .= "IkiWiki::SortSpec::cmp_$word(undef)"; } } else { @@ -2095,9 +2095,8 @@ sub pagespec_match_list ($$;@) { } if (defined $params{sort}) { - my $f = sortspec_translate($params{sort}); - - @candidates = sort { $f->($a, $b) } @candidates; + @candidates = IkiWiki::SortSpec::sort_pages($params{sort}, + @candidates); } @candidates=reverse(@candidates) if $params{reverse}; @@ -2412,13 +2411,23 @@ sub match_ip ($$;@) { package IkiWiki::SortSpec; +# This is in the SortSpec namespace so that the $a and $b that sort() uses +# $IkiWiki::SortSpec::a and $IkiWiki::SortSpec::b, so that plugins' cmp +# functions can access them easily. +sub sort_pages +{ + my $f = IkiWiki::sortspec_translate(shift); + + return sort $f @_; +} + sub cmp_title { - IkiWiki::pagetitle(IkiWiki::basename($_[0])) + IkiWiki::pagetitle(IkiWiki::basename($a)) cmp - IkiWiki::pagetitle(IkiWiki::basename($_[1])) + IkiWiki::pagetitle(IkiWiki::basename($b)) } -sub cmp_mtime { $IkiWiki::pagemtime{$_[1]} <=> $IkiWiki::pagemtime{$_[0]} } -sub cmp_age { $IkiWiki::pagectime{$_[1]} <=> $IkiWiki::pagectime{$_[0]} } +sub cmp_mtime { $IkiWiki::pagemtime{$b} <=> $IkiWiki::pagemtime{$a} } +sub cmp_age { $IkiWiki::pagectime{$b} <=> $IkiWiki::pagectime{$a} } 1 diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index 4992617d0..553f93455 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -374,25 +374,23 @@ sub match_copyright ($$;@) { package IkiWiki::SortSpec; sub cmp_meta { - my $left = $_[0]; - my $right = $_[1]; - my $meta = $_[2]; + my $meta = $_[0]; error(gettext("sort=meta requires a parameter")) unless defined $meta; if ($meta eq 'updated' || $meta eq 'date') { - return IkiWiki::Plugin::meta::get_sort_key($left, $meta) + return IkiWiki::Plugin::meta::get_sort_key($a, $meta) <=> - IkiWiki::Plugin::meta::get_sort_key($right, $meta); + IkiWiki::Plugin::meta::get_sort_key($b, $meta); } - return IkiWiki::Plugin::meta::get_sort_key($left, $meta) + return IkiWiki::Plugin::meta::get_sort_key($a, $meta) cmp - IkiWiki::Plugin::meta::get_sort_key($right, $meta); + IkiWiki::Plugin::meta::get_sort_key($b, $meta); } # A prototype of how sort=title could behave in 4.0 or something sub cmp_meta_title { - $_[2] = 'title'; + $_[0] = 'title'; return cmp_meta(@_); } diff --git a/IkiWiki/Plugin/sortnaturally.pm b/IkiWiki/Plugin/sortnaturally.pm index f498820a5..92453749d 100644 --- a/IkiWiki/Plugin/sortnaturally.pm +++ b/IkiWiki/Plugin/sortnaturally.pm @@ -25,8 +25,8 @@ sub checkconfig () { package IkiWiki::SortSpec; sub cmp_title_natural { - Sort::Naturally::ncmp(IkiWiki::pagetitle(IkiWiki::basename($_[0])), - IkiWiki::pagetitle(IkiWiki::basename($_[1]))) + Sort::Naturally::ncmp(IkiWiki::pagetitle(IkiWiki::basename($a)), + IkiWiki::pagetitle(IkiWiki::basename($b))) } 1; diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index b67142230..f42cc86ae 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1117,16 +1117,16 @@ Similarly, it's possible to write plugins that add new functions as the IkiWiki::SortSpec package named `cmp_foo`, which will be used when sorting by `foo` or `foo(...)` is requested. -The function will be passed three or more parameters. The first two are -page names, and the third is `undef` if invoked as `foo`, or the parameter -`"bar"` if invoked as `foo(bar)`. It may also be passed additional, named -parameters. - -It should return the same thing as Perl's `cmp` and `<=>` operators: negative -if the first argument is less than the second, positive if the first argument -is greater, or zero if they are considered equal. It may also raise an -error using `error`, for instance if it needs a parameter but one isn't -provided. +The names of pages to be compared are in the global variables `$a` and `$b` +in the IkiWiki::SortSpec package. The function should return the same thing +as Perl's `cmp` and `<=>` operators: negative if `$a` is less than `$b`, +positive if `$a` is greater, or zero if they are considered equal. It may +also raise an error using `error`, for instance if it needs a parameter but +one isn't provided. + +The function will also be passed one or more parameters. The first is +`undef` if invoked as `foo`, or the parameter `"bar"` if invoked as `foo(bar)`; +it may also be passed additional, named parameters. ### Setup plugins diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t index 68112f5c0..2ad7a9105 100755 --- a/t/pagespec_match_list.t +++ b/t/pagespec_match_list.t @@ -12,7 +12,7 @@ IkiWiki::checkconfig(); { package IkiWiki::SortSpec; - sub cmp_path { $_[0] cmp $_[1] } + sub cmp_path { $a cmp $b } } %pagesources=( -- cgit v1.2.3