aboutsummaryrefslogtreecommitdiff
path: root/doc/todo/inline:_numerical_ordering_by_title.mdwn
blob: 3d7424b3f606a21b3318b8e19dc11544815392b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
Could you please add numerical ordering by title to [[inline|plugins/inline]]
plugin? Now I can do only alphabetical order by title, but sometime it's not enough.

> Implemented, see [[natural_sorting]] [[!tag done]] --[[Joey]] 

BTW, it seems that ordering by title is rather ordering by filename of page.
For me "title" means title of page I can set using `title` parameter
of [[meta|plugins/meta]] plugin :)

Why do I need that feature? I've just been migrating an info site of our university
[mail system](http://poczta.uw.edu.pl/) to Ikiwiki from very static, console handling
Makefile+[WML](http://thewml.org/)+XML+XSL=HTML solution. I have many news files
(`1.mdwn`, `2.mdwn`, etc.) and unfortunately I did very stupid thing. I've commited
all of them in the same revision of our Subversion repo...

Now I have a problem with sorting these files using inline plugin. I can't do
sorting by age, because both old and young news files have the same age. I can't
sort by title too. For example, when I sort them by title, then `9.mdwn` page is
between `90.mdwn` and `89.mdwn` pages... It sucks, of course. Sorting by mtime
also is not a solution for me, because it means that I can't touch/fix old news
anymore.

Do you have any idea how to workaround that issue? --[[Paweł|ptecza]]

> Delete all files. Add files back one at a time, committing after adding
> each file. Sort by date. --[[Joey]]

>> The simplest solutions are the best :D Thanks for the hint! I didn't
>> want to do it before, because I was affaid that my Subversion keeps
>> old date of creation of file. --[[Paweł|ptecza]]

> Maybe you can rename `9.mdwn` to `09.mdwn`? See `rename(1)`, it renames multiple files
> in one go. --[[buo]]

>> Thanks for your suggestion! But what about if number of my news files grows to 100+?

>>     $ ls
>>     09.mdwn  100.mdwn  101.mdwn  102.mdwn  89.mdwn  90.mdwn

>> I don't want to rename all previous files to add `0` prefix. --[[Paweł|ptecza]]

>>> Rather than adding 0's or or a 'sorttype' parameter, I'd just fix the sort order.
>>> Both MacOS and Windows use a smarter sort order than just lexical in their
>>> file browsers (e.g. <http://support.microsoft.com/default.aspx?kbid=319827>,
>>> <http://docs.info.apple.com/article.html?artnum=300989>).
>>>
>>> The [Unicode Collation algorithm](http://en.wikipedia.org/wiki/Unicode_collation_algorithm)
>>> would seem to be a reasonable sort order.  (See also <http://www.unicode.org/unicode/reports/tr10/>.)
>>> Unfortunately the standard perl implementation, [Unicode::Collate](http://perldoc.perl.org/Unicode/Collate.html)
>>> doesn't handle the optional [numbers](http://www.unicode.org/unicode/reports/tr10/#Customization)
>>> extension which is what you want.  --[[Will]]

---

Below is my simple patch. Feel free to use it or comment!

I have also 2 considerations for inline sorting:

1. Maybe changing name of `sort` parameter to `sortby` or `sortkey` will
   be good idea?

   > No, that would break existing wikis. --[[Joey]]
   >> It's no problem. You just have `ikiwiki-transition` utility :D --[[Paweł|ptecza]]

1. Maybe you should use `title` sort key for title from meta plugin and `name`, 
   `filename`, `page` or `pagename` for page names? In the future you can also
   sort by meta author, license or another key.

   > There are many places in ikiwiki that do not use meta title info and
   > could. I'd prefer to deal with that issue as a whole, not here,
   > --[[Joey]]

--[[Paweł|ptecza]]

    --- inline.pm-orig  2008-09-02 09:53:20.000000000 +0200
    +++ inline.pm       2008-09-02 10:09:02.000000000 +0200
    @@ -186,7 +186,15 @@
        }

        if (exists $params{sort} && $params{sort} eq 'title') {
    -           @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
    +           if (! $params{sorttype} || $params{sorttype} eq 'lexical') {
    +                   @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
    +           }
    +           elsif ($params{sorttype} eq 'numeric') {
    +                   @list=sort { pagetitle(basename($a)) <=> pagetitle(basename($b)) } @list;
    +           }
    +           else {
    +                   return sprintf(gettext("unknown sort type %s"), $params{sorttype});
    +           }
        }
        elsif (exists $params{sort} && $params{sort} eq 'mtime') {
                @list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
    @@ -195,7 +203,7 @@
                @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
        }
        else {
    -           return sprintf(gettext("unknown sort type %s"), $params{sort});
    +           return sprintf(gettext("unknown sort key %s"), $params{sort});
        }

        if (yesno($params{reverse})) {

> To users, "sort" already determines the type of sort. It can be by title,
> or by date, etc. Adding a separate "sorttype" value is thus fairly
> confusing. --[[Joey]]

>> OK. I will be more careful when I play with inline plugin :) --[[Paweł|ptecza]]

---

Joey, have you forgotten about that request? ;) --[[Paweł|ptecza]]

> Okie.  Here is a different [[patch]] based on my comment above.  It doesn't introduce
> a new key, but rather changes the title sorting order. Two caveats:

 * I've only tested this in `inline`, not the other places I changed the sort order.
 * I'm unsure if the regexp used in the split should be `/(-?\d+)/` instead of `/(\d+)/`.
    As written, '-' is interpreted as a hyphen rather than a minus sign.

> --[[Will]]

>> I"m not comfortable with tossing out perl's default collator and trying
>> to maintain some other one going forward. Especially not for such an
>> edge case. --[[Joey]]

>> Hi Will! Your idea looks interesting for me, but I'm affraid that it's too big
>> change in Ikiwiki... Maybe I'm wrong? ;) What do you think, Joey? --[[Paweł|ptecza]]

>>> It isn't that big a change.  It is just supplying a sort order to the sort.  The
>>> patch is a little larger because I then went through and made that sort
>>> order available in other places where it makes sense.  (Looking at the
>>> patch again briefly, I should have also used it in the `map` plugin.)
>>>
>>> If you wanted a simple patch, you could just move the `titlecmp` function
>>> into the inline plugin and only use it there.  The problem with that is that
>>> it only fixes the inline plugin. -- [[Will]]

>>>> Will, I agree with you that it's improved way of sort order. But on the other
>>>> hand I prefer to be careful when I change something in a several places,
>>>> because I don't want to break any working things when I fix one thing.
>>>> I hope that Joey agree with us too and all Ikiwiki users will be happy
>>>> after applying your patch ;) --[[Paweł|ptecza]]

----

    diff --git a/IkiWiki.pm b/IkiWiki.pm
    index c0f5dea..d001f8d 100644
    --- a/IkiWiki.pm
    +++ b/IkiWiki.pm
    @@ -20,7 +20,7 @@ use Exporter q{import};
     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
    +		 add_underlay titlecmp
                      %config %links %pagestate %renderedfiles
                      %pagesources %destsources);
     our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
    @@ -835,6 +835,42 @@ sub titlepage ($) {
     	return $title;
     }
     
    +sub titlecmp ($$) {
    +	my $titleA=shift;
    +	my $titleB=shift;
    +	
    +	my @listA=split(/(\d+)/,$titleA);
    +	my @listB=split(/(\d+)/,$titleB);
    +	
    +	while (@listA && @listB) {
    +		# compare bits of text
    +		my $a = shift @listA;
    +		my $b = shift @listB;
    +		my $c = ($a cmp $b);
    +		return $c if ($c);
    +
    +		if (@listA && @listB) {
    +			# compare numbers
    +			$a = shift @listA;
    +			$b = shift @listB;
    +			$c = $a <=> $b;
    +			return $c if ($c);
    +			
    +			# 01 is different to 1
    +			$c = (length($a) <=> length($b));
    +			return $c if ($c);
    +
    +			$c = ($a cmp $b);
    +			return $c if ($c);
    +		}
    +	}
    +	
    +	return 1 if (@listA);
    +	return -1 if (@listB);
    +	
    +	return 0;
    +}
    +
     sub linkpage ($) {
     	my $link=shift;
     	my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_";
    diff --git a/IkiWiki/Plugin/brokenlinks.pm b/IkiWiki/Plugin/brokenlinks.pm
    index 37752dd..ccaa399 100644
    --- a/IkiWiki/Plugin/brokenlinks.pm
    +++ b/IkiWiki/Plugin/brokenlinks.pm
    @@ -59,7 +59,7 @@ sub preprocess (@) {
     			map {
     				"<li>$_</li>"
     			}
    -			sort @broken)
    +			sort titlecmp @broken)
     		."</ul>\n";
     }
     
    diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
    index 8efef3f..263e7a6 100644
    --- a/IkiWiki/Plugin/inline.pm
    +++ b/IkiWiki/Plugin/inline.pm
    @@ -192,7 +192,7 @@ sub preprocess_inline (@) {
     	}
     
     	if (exists $params{sort} && $params{sort} eq 'title') {
    -		@list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
    +		@list=sort { titlecmp(pagetitle(basename($a)),pagetitle(basename($b))) } @list;
     	}
     	elsif (exists $params{sort} && $params{sort} eq 'mtime') {
     		@list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
    diff --git a/IkiWiki/Plugin/orphans.pm b/IkiWiki/Plugin/orphans.pm
    index b910758..10a1d87 100644
    --- a/IkiWiki/Plugin/orphans.pm
    +++ b/IkiWiki/Plugin/orphans.pm
    @@ -56,7 +56,7 @@ sub preprocess (@) {
     				htmllink($params{page}, $params{destpage}, $_,
     					 noimageinline => 1).
     				"</li>"
    -			} sort @orphans).
    +			} sort titlecmp @orphans).
     		"</ul>\n";
     }
     
    diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
    index ceb7c84..00798e1 100644
    --- a/IkiWiki/Render.pm
    +++ b/IkiWiki/Render.pm
    @@ -89,7 +89,7 @@ sub genpage ($$) {
     		$template->param(have_actions => 1);
     	}
     
    -	my @backlinks=sort { $a->{page} cmp $b->{page} } backlinks($page);
    +	my @backlinks=sort { titlecmp($a->{page}, $b->{page}) } backlinks($page);
     	my ($backlinks, $more_backlinks);
     	if (@backlinks <= $config{numbacklinks} || ! $config{numbacklinks}) {
     		$backlinks=\@backlinks;