>>>>> [[ikiwiki/pagespec]], and decided that yes, sorting is
>>>>> a bit like a pagespec :-) Which name would you prefer? --s
->>>> I would be inclined to drop the `check_` stuff. --J
+>>>>>> `SortSpec` --[[Joey]]
+
+>>>>>>> Done. --s
+
+>>>> I would be inclined to drop the `check_` stuff. --[[Joey]]
>>>>> It basically exists to support `title_natural`, to avoid
>>>>> firing up the whole import mechanism on every `cmp`
>>>>> [[field|plugins/contrib/field/discussion]], fail early
>>>>> (again, not so valuable).
>>>>>
+>>>>>> AFAIK, `use foo` has very low overhead when the module is already
+>>>>>> loaded. There could be some evalation overhead in `eval q{use foo}`,
+>>>>>> if so it would be worth addressing across the whole codebase.
+>>>>>> --[[Joey]]
+>>>>>>
+>>>>>>> check_cmp_foo now dropped. --s
+>>>>>
>>>>> The former function could be achieved at a small
>>>>> compatibility cost by putting `title_natural` in a new
>>>>> `sortnatural` plugin (that fails to load if you don't
>>>>> have happened if `title_natural` was written after this
>>>>> code had been merged, I suspect. Would you prefer this? --s
+>>>>>> Yes! (Assuming it does not make sense to support
+>>>>>> natural order sort of other keys than the title, at least..)
+>>>>>> --[[Joey]]
+
+>>>>>>> Done. I added some NEWS.Debian for it, too. --s
+
>>>> Wouldn't it make sense to have `meta(title)` instead
->>>> of `meta_title`? --J
+>>>> of `meta_title`? --[[Joey]]
>>>>> Yes, you're right. I added parameters to support `field`,
>>>>> and didn't think about making `meta` use them too.
>>>>> same place as the meta-title, but occasionally not), while
>>>>> displaying meta-titles, does look quite odd. --s
+>>>>>> Agreed. --[[Joey]]
+
+>>>>>>> I've implemented meta(title). meta(author) also has the
+>>>>>>> `sortas` special case; meta(updated) and meta(date)
+>>>>>>> should also work how you'd expect them to (but they're
+>>>>>>> earliest-first, unlike age). --s
+
>>>> As I read the regexp in `cmpspec_translate`, the "command"
>>>> is required to have params. They should be optional,
>>>> to match the documentation and because most sort methods
->>>> do not need parameters. --J
+>>>> do not need parameters. --[[Joey]]
>>>>> No, `$2` is either `\w+\([^\)]*\)` or `[^\s]+` (with the
>>>>> latter causing an error later if it doesn't also match `\w+`).
>>>>> result. Again, I think this is getting too complex, and could just
>>>>> be solved with smarter cmp functions.
>>>>>
+>>>>>> I agree. (Also, I think returning keys may make it harder to write
+>>>>>> smarter cmp functions.) --[[Joey]]
+>>>>>
>>>>> Unfortunately, `sort="ascending mtime"` actually sorts by *descending*
>>>>> timestamp (but`sort=age` is fine, because `age` could be defined as
>>>>> now minus `ctime`). `sort=freshness` isn't right either, because
>>>>> directions - it seems clearer to have `ascending` always be a no-op,
>>>>> and `descending` always negate.
>>>>>
+>>>>>> I think you've convinced me that ascending/descending impose too
+>>>>>> much semantics on it, so "-" is better. --[[Joey]]
+
+>>>>>>> I've kept the semantics from `report` as-is, then:
+>>>>>>> e.g. `sort="age -title"`. --s
+
>>>>> Perhaps we could borrow from `meta updated` and use `update_age`?
>>>>> `updateage` would perhaps be a more normal IkiWiki style - but that
>>>>> makes me think that updateage is a quantity analagous to tonnage or
>>>>> I'm sure there's a much better word, but I can't see it. Do you have
>>>>> a better idea? --s
+[Regarding the `meta title=foo sort=bar` special case]
+
+> I feel it sould be clearer to call that "sortas", since "sort=" is used
+> to specify a sort method in other directives. --[[Joey]]
+>> Done. --[[smcv]]
+
+## speed
+
+I notice the implementation does not use the magic `$a` and `$b` globals.
+That nasty perl optimisation is still worthwhile:
+
+ perl -e 'use warnings; use strict; use Benchmark; sub a { $a <=> $b } sub b ($$) { $_[0] <=> $_[1] }; my @list=reverse(1..9999); timethese(10000, {a => sub {my @f=sort a @list}, b => sub {my @f=sort b @list}, c => => sub {my @f=sort { b($a,$b) } @list}})'
+ Benchmark: timing 10000 iterations of a, b, c...
+ a: 80 wallclock secs (76.74 usr + 0.05 sys = 76.79 CPU) @ 130.23/s (n=10000)
+ b: 112 wallclock secs (106.14 usr + 0.20 sys = 106.34 CPU) @ 94.04/s (n=10000)
+ c: 330 wallclock secs (320.25 usr + 0.17 sys = 320.42 CPU) @ 31.21/s (n=10000)
+
+Unfortunatly, I think that c is closest to the new implementation.
+--[[Joey]]
+
+> Unfortunately, `$a` isn't always `$main::a` - it's `$Package::a` where
+> `Package` is the call site of the sort call. This was a showstopper when
+> `sort` was a hook implemented in many packages, but now that it's a
+> `SortSpec`, I may be able to fix this by putting a `sort` wrapper in the
+> `SortSpec` namespace, so it's like this:
+>
+> sub sort ($@)
+> {
+> my $cmp = shift;
+> return sort $cmp @_;
+> }
+>
+> which would mean that the comparison used `$IkiWiki::SortSpec::a`.
+>
+> I do notice that `pagespec_match_list` performs the sort before the
+> filter by pagespec. Is this a deliberate design choice, or
+> coincidence? I can see that when `limit` is used, this could be
+> used to only run the pagespec match function until `limit` pages
+> have been selected, but the cost is that every page in the wiki
+> is sorted. Or, it might be useful to do the filtering first, then
+> sort the sub-list thus produced, then finally apply the limit? --s
+
+>> Yes, it was deliberate, pagespec matching can be expensive enough that
+>> needing to sort a lot of pages seems likely to be less work. (I don't
+>> remember what benchmarking was done though.) --[[Joey]]
+
## Documentation from sort-package branch
-### meta_title sort order (conditionally added to [[ikiwiki/pagespec/sorting]])
+### advanced sort orders (conditionally added to [[ikiwiki/pagespec/sorting]])
-* `meta_title` - Order according to the `\[[!meta title="foo" sort="bar"]]`
+* `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")
+* `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.
-
- > I feel it sould be clearer to call that "sortas", since "sort=" is used
- > to specify a sort method in other directives. --[[Joey]]
-
- >> Fair enough, that's easy to do. --[[smcv]]
+ full title was set. `meta(author)`, `meta(date)`, `meta(updated)`, etc.
+ also work.
### Multiple sort orders (added to [[ikiwiki/pagespec/sorting]])
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).
-### meta title sort parameter (added to [[ikiwiki/directive/meta]])
+### meta sortas parameter (added to [[ikiwiki/directive/meta]])
+
+[in title]
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"]]
\[[!meta title="David Bowie" sort="Bowie, David"]]
+[in author]
+
+ An optional `sortas` parameter will be used preferentially when
+ [[ikiwiki/pagespec/sorting]] by `meta(author)`:
+
+ \[[!meta author="Joey Hess" sortas="Hess, Joey"]]
+
### Sorting plugins (added to [[plugins/write]])
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
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.