1 # |
1 # |
2 # VimOutliner (OTL) XHTML pretty printer for mod_perl2/apache2. |
2 # VimOutliner (OTL) XHTML pretty printer for mod_perl2/apache2. |
3 # |
3 # |
4 # Copyright (c) 2006, Mahlon E. Smith <mahlon@martini.nu> |
4 # Copyright (c) 2006-2009, Mahlon E. Smith <mahlon@martini.nu> |
5 # All rights reserved. |
5 # All rights reserved. |
6 # Redistribution and use in source and binary forms, with or without |
6 # Redistribution and use in source and binary forms, with or without |
7 # modification, are permitted provided that the following conditions are met: |
7 # modification, are permitted provided that the following conditions are met: |
8 # |
8 # |
9 # * Redistributions of source code must retain the above copyright |
9 # * Redistributions of source code must retain the above copyright |
68 my %re = ( |
68 my %re = ( |
69 title => qr/(?:.+)?\/(.+).otl$/i, |
69 title => qr/(?:.+)?\/(.+).otl$/i, |
70 percent => qr/(\[.\]) (\d+)%/, |
70 percent => qr/(\[.\]) (\d+)%/, |
71 todo => qr/(\[_\]) /, |
71 todo => qr/(\[_\]) /, |
72 done => qr/(\[X\]) /, |
72 done => qr/(\[X\]) /, |
73 comment => qr/^(?:\t+)?:(.+)/, |
73 user => qr/^(?:\t+)?\<(.+)/, |
|
74 user_wrap => qr/^(?:\t+)?\>(.+)/, |
|
75 body_wrap => qr/^(?:\t+)?:(.+)/, |
|
76 body => qr/^(?:\t+)?;(.+)/, |
74 time => qr/(\d{2}:\d{2}:\d{2})/, |
77 time => qr/(\d{2}:\d{2}:\d{2})/, |
75 date => qr/(\d{2,4}-\d{2}-\d{2})/, |
78 date => qr/(\d{2,4}-\d{2}-\d{2})/, |
76 subitem => qr/^\t(?!\t)/, |
79 subitem => qr/^\t(?!\t)/, |
77 remove_tabs => qr/^(?:\t+)?(.+)/, |
80 remove_tabs => qr/^(?:\t+)?(.+)/, |
78 linetext => qr/^(?:\[.\] (?:\d+%)?)? (.+)/, |
81 linetext => qr/^(?:\[.\] (?:\d+%)?)? (.+)/, |
102 @blocks = grep { $_ !~ /^\#/ } split /\n\n+/, $data; |
105 @blocks = grep { $_ !~ /^\#/ } split /\n\n+/, $data; |
103 |
106 |
104 # get optional settings and otl title |
107 # get optional settings and otl title |
105 { |
108 { |
106 my $settings = shift @blocks; |
109 my $settings = shift @blocks; |
107 if ($settings =~ $re{comment}) { |
110 if ($settings =~ $re{user}) { |
108 %opt = map { split /=/ } split /\s?:/, $settings; |
111 %opt = map { split /=/ } split /\s?:/, $1; |
109 } |
112 } |
110 |
113 |
111 # if the first group wasn't a comment, |
114 # if the first group wasn't a comment, |
112 # we probably just aren't using a settings |
115 # we probably just aren't using a settings |
113 # line. push the group back into place. |
116 # line. push the group back into place. |
114 else { |
117 else { |
115 unshift @blocks, $settings; |
118 unshift @blocks, $settings; |
116 } |
119 } |
117 } |
120 } |
|
121 |
|
122 # Now that we have tried to detect settings, |
|
123 # remove any level 0 blocks that are user data. |
|
124 @blocks = grep { $_ !~ /^[\<\>]/ } @blocks; |
118 |
125 |
119 # GET args override settings |
126 # GET args override settings |
120 $opt{$_} = $get->{$_} foreach keys %$get; |
127 $opt{$_} = $get->{$_} foreach keys %$get; |
121 |
128 |
122 # set title (fallback to file uri) |
129 # set title (fallback to file uri) |
131 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> |
138 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> |
132 <html> |
139 <html> |
133 <!-- |
140 <!-- |
134 generated by otl_handler $VERSION |
141 generated by otl_handler $VERSION |
135 Mahlon E. Smith <mahlon\@martini.nu> |
142 Mahlon E. Smith <mahlon\@martini.nu> |
136 http://www.martini.nu/ |
143 http://projects.martini.nu/apache-otl/ |
137 |
144 |
138 Get VimOutliner at: http://www.vimoutliner.org/ |
145 Get VimOutliner at: http://www.vimoutliner.org/ |
139 --> |
146 --> |
140 <head> |
147 <head> |
141 <title>$title</title> |
148 <title>$title</title> |
193 $r->print("</div>\n"); |
200 $r->print("</div>\n"); |
194 } |
201 } |
195 |
202 |
196 foreach my $block ( sort { sorter(\%opt, \%re) } @blocks ) { |
203 foreach my $block ( sort { sorter(\%opt, \%re) } @blocks ) { |
197 # separate outline items |
204 # separate outline items |
198 my @lines = grep { $_ !~ /$re{'hideline'}/ } split /\n/, $block; |
205 my @lines; |
|
206 foreach my $line ( split /\n/, $block ) { |
|
207 push @lines, $line unless $line =~ $re{hideline} || |
|
208 $line =~ $re{user} || $line =~ $re{user_wrap}; |
|
209 } |
|
210 |
199 my $data = []; |
211 my $data = []; |
200 |
212 |
201 # build structure and get item counts |
213 # build structure and get item counts |
202 my ( $subs, $comments, $subsubs ) = ( 0, 0, 0 ); |
214 my ( $subs, $comments, $subsubs ) = ( 0, 0, 0 ); |
203 foreach ( @lines ) { |
215 foreach ( @lines ) { |
204 if (/$re{comment}/) { |
216 if (/$re{body_wrap}/) { |
205 $comments++; |
217 $comments++; |
206 } |
218 } |
207 elsif (/$re{subitem}/) { |
219 elsif (/$re{subitem}/) { |
208 $subs++; |
220 $subs++; |
209 } |
221 } |
243 my $sitmstr = $subsubs == 1 ? 'subitem' : 'subitems'; |
255 my $sitmstr = $subsubs == 1 ? 'subitem' : 'subitems'; |
244 $line .= " <span class=\"counts\">$subs $itmstr, $subsubs $sitmstr</span>"; |
256 $line .= " <span class=\"counts\">$subs $itmstr, $subsubs $sitmstr</span>"; |
245 } |
257 } |
246 |
258 |
247 my $li_class = '>'; |
259 my $li_class = '>'; |
248 $li_class = ' class="todo">' if $line =~ s#$re{todo}##; |
260 $li_class = ' class="todo">' if $line =~ s#$re{todo}##; |
249 $li_class = ' class="done">' if $line =~ s#$re{done}##; |
261 $li_class = ' class="done">' if $line =~ s#$re{done}##; |
250 $li_class = ' class="comment">' if $line =~ s#$re{comment}#$1#; |
262 $li_class = ' class="comment_pre">' if $line =~ s#$re{body}#$1#; |
|
263 $li_class = ' class="comment">' if $line =~ s#$re{body_wrap}#$1#; |
251 |
264 |
252 if ( $next_level == $level || $next_level == 0 ) { |
265 if ( $next_level == $level || $next_level == 0 ) { |
253 $r->print( "$in<li" . $li_class . "$line</li>\n" ); |
266 $r->print( "$in<li" . $li_class . "$line</li>\n" ); |
254 } |
267 } |
255 |
268 |