]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - doc/bugs/color_plugin_produces_artifacts_in_table-of-contents.mdwn
color: Use markup for the preserved CSS, not character data
[git.ikiwiki.info.git] / doc / bugs / color_plugin_produces_artifacts_in_table-of-contents.mdwn
1 # Bug Description 
3 If color and toc plugins are enabled and you use colored headers, those headers are never colored but sometimes are prefixed with text artifacts like "color: red".
5 Example: The header 
7     # [[!color  foreground=red text="Testing"]]
9 would sometimes be seen in the toc as
11     color: redTesting
13 Reason for this behaviour is: 
15 1. the color plugin uses a special syntax to preserve the color through sanitize and that syntax has a plain text component. 
16 1. the toc plugin removes everything except plain text from headers in the toc
17 1. if the toc plugin is executed before the color plugin in the format hook it sees the special syntax and clobbers the toc, otherwise it just removes the color markup
19 > The bug here is that the color plugin's special syntax does not
20 > gracefully degrade to "render nothing", which I have now [[fixed|done]]
21 > by putting the color bits through a value attribute instead of
22 > character data. --[[smcv]]
24 # Solutions
26 There are a few possible solutions to this depending on how it should work:
28 1. The easiest thing would be to just add a "last" parameter to the toc plugin format hook (or "first" to the color plugin). Result: No color in tocs at all
29 1. Adding seven lines to toc.pm would make it preserve ALL markup in headers, color as well as html markup or markdown (*emphasize* for example). Execution order of the plugins would not matter at all
30 1. A bit more code would be necessary to just specifically preserve the color, but nothing else
32 I would propose implementing the second option because visual markers in headers are useful to convey additional information very fast and this information should be preserved in the toc. Example: Bug or task/project tracker with color conveying status of the bug or task.
34 > This is really a separate feature request: copy non-`<a>` markup
35 > in headings into the TOC. I don't think this necessarily makes
36 > sense in general. In particular, any `id` attributes on child
37 > elements must not be passed through because that would make
38 > the ID non-unique. --[[smcv]]
40 It seems you can stuff anything into ordered lists (according to w3.orgs doku), so apart from stylistic reasons and suboptimal display of links in headers (see below) I don't see any problems with markup in the toc. 
42 # Patch
44 This is the proposed patch to the second solution. Tested with the latest version. It works with all markup and markdown I could think of. The only case not handled optimal is if the header is just a link and nothing else, then there is no text left for the local link, the toc links directly to a different page. Is that acceptable or not?
48     diff --git a/IkiWiki/Plugin/toc.pm b/IkiWiki/Plugin/toc.pm
49     index ac07b9a..5c2b056 100644
50     --- a/IkiWiki/Plugin/toc.pm
51     +++ b/IkiWiki/Plugin/toc.pm
52     @@ -57,6 +57,7 @@ sub format (@) {
53             my $startlevel=($params{startlevel} ? $params{startlevel} : 0);
54             my $curlevel=$startlevel-1;
55             my $liststarted=0;
56     +   my $headercollect=0;
57             my $indent=sub { "\t" x $curlevel };
58             $p->handler(start => sub {
59                     my $tagname=shift;
60     @@ -107,6 +108,7 @@ sub format (@) {
61                             $index.=&$indent."<li class=\"L$curlevel\">".
62                                     "<a href=\"#$anchor\">";
64     +                   $headercollect=1;
65                             $p->handler(text => sub {
66                                     $page.=join("", @_);
67                                     $index.=join("", @_);
68     @@ -117,12 +119,17 @@ sub format (@) {
69                                             $p->handler(text => undef);
70                                             $p->handler(end => undef);
71                                             $index.="</a>\n";
72     +                                   $headercollect=0;
73     +                           }
74     +                           else {
75     +                               $index.=join("",@_);
76                                     }
77                                     $page.=join("", @_);
78                             }, "tagname, text");
79                     }
80                     else {
81                             $page.=$text;
82     +                   $index.=$text if ($headercollect);
83                     }
84             }, "tagname, text");
85             $p->handler(default => sub { $page.=join("", @_) }, "text");
89 [[!tag  patch]]