/[pub]/suikawiki/script/misc/plugins/SuikaWiki09XML.wps
Suika

Contents of /suikawiki/script/misc/plugins/SuikaWiki09XML.wps

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations) (download)
Sun Feb 1 12:12:45 2004 UTC (21 years, 2 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
FILE REMOVED
Use try..catch for WikiDB

1 Name:
2 SuikaWiki09XML
3 FullName:
4 SuikaWiki/0.9 documentation format support with XML syntax
5 URI:
6 IW:SuikaWiki:SuikaWiki
7
8 Initialize:
9 my $NS_XHTML1 = 'http://www.w3.org/1999/xhtml';
10 my $NS_SW09 = 'urn:x-suika-fam-cx:markup:suikawiki:0:9:';
11
12 {
13 Name:
14 wikiformat/SuikaWiki/0.9-to-SuikaWiki/0.9/XML
15 FullName:
16 SuikaWiki/0.9 wiki syntax -> XML syntax
17 URI:
18 IW:SuikaWiki:SuikaWiki
19 Format:
20 $r = wiki2xml ($o->{content}, %$o);
21 }
22
23 MODULE:
24 sub wiki2xml {
25 my ($txt, %option) = @_;
26 ## TODO: const and paramters
27 ## Load constants
28 my %const;
29 #if ($option{magic} =~ /import="([^"]+)"/) {
30 # for (split /\s*,\s*/, $1) {
31 # my $wp = $main::database{$_};
32 # if ($wp =~ m!^\#\?SuikaWikiConst/(?:0.9|1.0)!) {
33 # wiki::suikawikiconst::to_hash ($wp => \%const);
34 # }
35 # }
36 #}
37
38 #$txt =~ s{__&&([^&]+)&&__}{defined $const{$1}?$const{$1}:qq(__&&$1&&__)}ge;
39 my (@txt) = split(/\n/, $txt);
40 my (@saved, @result);
41 my $p = SuikaWiki::Markup::XML->new (type => '#fragment');
42 my $current = $p;
43 my %depth;
44 my $exit_p = sub {
45 my $current = shift;
46 if ($current->local_name eq 'p') {
47 $current = $current->parent_node;
48 }
49 $current;
50 };
51 my $cut_anchor = sub {
52 my ($current, $content) = @_;
53 if ($content =~ s/^\s*\[([0-9]+)\]\s+//) {
54 $current->append_new_node (type => '#element',
55 namespace_uri => $NS_SW09,
56 local_name => 'anchor-end')
57 ->append_text (0+$1);
58 }
59 $content;
60 };
61 my $back_to_section = sub {
62 my $current = shift;
63 while ($current->node_type ne '#fragment') {
64 if ({ins=>1,del=>1,blockquote=>1}->{$current->local_name}) {
65 return $current;
66 }
67 $current = $current->parent_node;
68 }
69 return $current;
70 };
71
72 foreach (@txt) {
73 chomp;
74 if ($depth{block_name}->{$depth{block}} ne 'PRE'
75 && /^(\*{1,5})([^\x0D\x0A]*)/) {
76 $current = &$back_to_section ($current);
77 for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h'.length ($1))) {
78 $H->append_node (_inline_xml ($2, %option,
79 const => \%const));
80 }
81 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^([-=]{1,6})(.*)/) {
82 my ($depth, $content, $type) = (length ($1), $2, (substr ($1, -1) eq '-' ? 'ul' : 'ol'));
83 $current = &$exit_p ($current);
84 if ($current->local_name eq 'li') {
85 if ($depth{list} == $depth && $depth{list_type} eq $type) {
86 $current = $current->parent_node;
87 } elsif ($depth <= $depth{list}) {
88 for (1..($depth{list} - $depth)*2) {
89 ($depth{list} = 1, last) unless ref $current->parent_node;
90 ($depth{list} = 1, last) unless {li=>1,ul=>1,ol=>1}->{$current->local_name};
91 $current = $current->parent_node;
92 $depth{list} -= 0.5;
93 }
94 $current = $current->parent_node;
95 if ($type ne $current->local_name) {
96 $current = $current->parent_node->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
97 $current->parent_node->append_text ("\n");
98 }
99 } else { # $depth{list} < $depth
100 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
101 $current->parent_node->append_text ("\n");
102 $depth{list}++;
103 }
104 } else {
105 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
106 $current->parent_node->append_text ("\n\n");
107 $depth{list} = 1;
108 }
109 $depth{list_type} = $type;
110 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'li');
111 $current->parent_node->append_text ("\n");
112 $content = &$cut_anchor ($current, $content);
113 $current->append_node (_inline_xml ($content, %option, const => \%const));
114 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^:([^:]+):(.*)/) {
115 $current = &$exit_p ($current);
116 if ($current->local_name eq 'dd') {
117 $current = $current->parent_node->parent_node;
118 } else {
119 $current = $current->append_new_node (type => '#element',
120 namespace_uri => $NS_XHTML1,
121 local_name => 'dl');
122 }
123 $current = $current->append_new_node (type => '#element',
124 namespace_uri => $NS_SW09,
125 local_name => 'dr');
126 $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'dt')
127 ->append_node (_inline_xml ($1, %option, const => \%const));
128 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'dd');
129 $current->append_node (_inline_xml ($2, %option, const => \%const));
130 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^(?!>>[0-9])(>{1,5})(.*)/) {
131 my ($depth, $content) = (length $1, $2);
132 $current = &$exit_p ($current);
133 if ($depth == $depth{bq}) {
134 #
135 } elsif ($depth{bq} < $depth) {
136 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'blockquote');
137 $depth{bq}++;
138 } else { # $depth < $depth{bq}
139 for (1..($depth{bq}-$depth)) {
140 last if $current->node_type eq '#fragment';
141 $current = &$back_to_section ($current->parent_node);
142 }
143 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'blockquote')
144 unless $current->local_name eq 'blockquote';
145 $depth{bq} = $depth;
146 }
147 if (length $content) {
148 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'p');
149 $current->append_node (_inline_xml ($content, %option, const => \%const));
150 }
151 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\s*$/) {
152 $current = &$back_to_section ($current);
153 while ($current->local_name eq 'blockquote') {
154 $depth{bq}--;
155 $current = &$back_to_section ($current->parent_node);
156 }
157 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^(\s+.*)$/) {
158 if ($current->local_name ne 'pre') {
159 $current = &$exit_p ($current)->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'pre');
160 #$depth{block_name}->{++$depth{block}} = 'pre';
161 }
162 $current->append_node (_inline_xml ($1, %option, const => \%const));
163 } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\,(.*?)[\x0D\x0A]*$/) {
164 $current = &$exit_p ($current);
165 if ($current->local_name eq 'td') {
166 $current = $current
167 ->parent_node # tr
168 ->parent_node # tbody
169 ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tr');
170 } else {
171 $current = $current
172 ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'table')
173 ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tbody')
174 ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tr');
175 }
176 $current->parent_node->append_text ("\n"); # </tr>\n
177 my $tmp = "$1,";
178 my @value = map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_} ($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
179 my @colspan = map {($_ eq '==') ? 0 : 1} @value;
180 my ($tr, $td) = ($current, $current);
181 for (my $i = 0; $i < @value; $i++) {
182 if ($colspan[$i]) {
183 while ($i + $colspan[$i] < @value and $value[$i + $colspan[$i]] eq '==') {
184 $colspan[$i]++;
185 }
186 $td = $tr->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'td');
187 $td->set_attribute (colspan => $colspan[$i]) if $colspan[$i] > 1;
188 $td->append_node (_inline_xml ($value[$i], %option, const => \%const));
189 }
190 }
191 if ($td->local_name eq 'tr') { # No <td/> in the <tr/> (error!)
192 $td = $tr->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'td');
193 }
194 $current = $td;
195 } elsif (/^\[(INS|DEL|PRE)\[\s*$/) {
196 if ($depth{block_name}->{$depth{block}} ne 'PRE') {
197 $current = &$exit_p ($current)->append_new_node (namespace_uri => $NS_XHTML1, local_name => lc $1);
198 $depth{block}++;
199 $depth{block_name}->{$depth{block}} = $1;
200 } else {
201 $current->append_text ($_);
202 }
203 } elsif ($depth{block} && /^\]($depth{block_name}->{$depth{block}})\]\s*$/) {
204 while ($current->node_type ne '#fragment') {
205 if ($current->local_name eq lc $depth{block_name}->{$depth{block}}) {
206 $current = $current->parent_node;
207 $depth{block}--;
208 last;
209 }
210 $current = $current->parent_node;
211 }
212 } else {
213 if ($current->node_type eq '#fragment' || {ins=>1,del=>1}->{$current->local_name}) {
214 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'p');
215 $current->parent_node->append_text ("\n\n"); # <P> is two <BR>s:-)
216 }
217 $current->append_node (_inline_xml (&$cut_anchor ($current, $_), %option, const => \%const));
218 }
219 }
220 my $root = SuikaWiki::Markup::XML->new (type => '#document')
221 ->append_new_node (type => '#element',
222 namespace_uri => $NS_SW09,
223 local_name => 'body');
224 $root->append_node ($p);
225 $root->define_new_namespace ('' => $NS_XHTML1);
226 $root->define_new_namespace (sw => $NS_SW09);
227 $root->parent_node;
228 }
229
230 sub _inline_xml ($;%) {
231 my ($line, %option) = @_;
232 my $l = SuikaWiki::Markup::XML->new (type => '#fragment');
233 my $current = $l;
234 $line =~ s{(?:\[([A-Z]+)(?:\(([^)]*)\))?\[|(\[\[#form(?:\([A-Za-z0-9-]+\))?(?::'(?:[^'\\]|\\.)*')+\]\]|\[\[[^]]+\](?:>>[0-9]+)?\])|(\]\])|(\] \[)|(>>[0-9]+|<[A-Za-z0-9%]+:[^>]+>|'''?)|([\[\]'<>]|[^\[\]'<>]+))}{
235 ## BUG: <IW:foo:"<foo>">
236 my ($el_name, $attr, $lnk, $etag, $nxt, $misc, $s) = ($1, $2, $3, $4, $5, $6, $7);
237 if ($el_name) {
238 my $edef = {
239 ABBR => {html_el => 'abbr', use_class_attr => 1},
240 CODE => {html_el => 'code', use_class_attr => 1},
241 DEL => {html_el => 'del', use_class_attr => 1},
242 DFN => {html_el => 'dfn', use_class_attr => 1},
243 INS => {html_el => 'ins', use_class_attr => 1},
244 KBD => {html_el => 'kbd', use_class_attr => 1},
245 RUBY => {html_el => 'ruby'},
246 RUBYB => {html_el => 'rubyb', ns_uri => $NS_SW09},
247 SAMP => {html_el => 'samp', use_class_attr => 1},
248 SUB => {html_el => 'sub'},
249 SUP => {html_el => 'sup'},
250 VAR => {html_el => 'var', use_class_attr => 1},
251 WEAK => {html_el => 'weak', ns_uri => $NS_SW09},
252 }->{ $el_name };
253 if ($edef) {
254 $current = $current->append_new_node (namespace_uri => ($edef->{ns_uri} || $NS_XHTML1), local_name => $edef->{html_el});
255 $current->set_attribute (class => $edef->{html_class}) if $edef->{html_class};
256 $current->get_attribute ('class', make_new_node => 1)
257 ->append_text ($attr) if $attr && $edef->{use_class_attr};
258 if ($edef->{html_el} eq 'ruby' || $edef->{html_el} eq 'abbr') {
259 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rb');
260 }
261 } else {
262 $current->append_text ($&);
263 }
264 } elsif ($etag) {
265 if (ref $current->parent_node) {
266 if ($current->node_type eq '#attribute') {
267 $current = $current->parent_node;
268 }
269 $current = $current->parent_node;
270 if ($current->local_name eq 'ruby') {
271 $current = $current->parent_node;
272 }
273 } else {
274 $current->append_text (']]');
275 }
276 } elsif ($nxt) {
277 my $c_l_n = $current->local_name;
278 if ($c_l_n eq 'rb') {
279 for ($current->parent_node) {
280 $current = $_->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rt');
281 }
282 } elsif ($c_l_n eq 'rt') {
283 for ($current->parent_node) {
284 $_->append_text (' ');
285 $current = $_->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rt');
286 }
287 } elsif ($c_l_n eq 'abbr') {
288 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rt');
289 } else {
290 $current->append_text ('] [');
291 }
292 } elsif ($lnk) {
293 if ($lnk =~ /\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/) {
294 my $form = $current->append_new_node (type => '#element',
295 namespace_uri => $NS_SW09,
296 local_name => 'form');
297 $form->set_attribute (id => $1) if $1;
298 $form->append_new_node (type => '#element',
299 namespace_uri => $NS_SW09,
300 local_name => 'input')
301 # ->append_new_node (type => '#section',
302 # namespace_uri => $NS_SGML.'cdata')
303 ->append_text ($2);
304 $form->append_new_node (type => '#element',
305 namespace_uri => $NS_SW09,
306 local_name => 'output')
307 ->append_text ($3);
308 $form->append_new_node (type => '#element',
309 namespace_uri => $NS_SW09,
310 local_name => 'option')
311 ->append_text ($4);
312 } elsif ($lnk =~ /\[\[([^]]+)\](?:>>([0-9]+))?\]/) {
313 my ($page, $anchor_no) = ($1, $2);
314 if ($page eq '#comment') {
315 $current->append_new_node (type => '#element',
316 namespace_uri => $NS_SW09,
317 local_name => 'comment')
318 ->option (use_EmptyElemTag => 1);
319 } elsif ($page eq '#rcomment') {
320 $current->append_new_node (type => '#element',
321 namespace_uri => $NS_SW09,
322 local_name => 'rcomment')
323 ->option (use_EmptyElemTag => 1);
324 } elsif ($page =~ /^\#embed:(IMG:)?(.+)$/) {
325 my $e = $current->append_new_node (type => '#element',
326 namespace_uri => $NS_SW09,
327 local_name => 'embed')
328 ->option (use_EmptyElemTag => 1);
329 $e->set_attribute (type => 'IMG') if $1;
330 $e->set_attribute (page => $2);
331 } else {
332 my $anchor = $current->append_new_node (type => '#element',
333 namespace_uri => $NS_SW09,
334 local_name => 'anchor');
335 $anchor->append_new_node (type => '#element',
336 namespace_uri => $NS_SW09,
337 local_name => 'page')
338 ->append_text ($page);
339 $anchor->append_new_node (type => '#element',
340 namespace_uri => $NS_SW09,
341 local_name => 'fragment')
342 ->append_text (0+$anchor_no) if defined $anchor_no;
343 }
344 }
345 } elsif ($misc) {
346 if ($misc =~ />>([0-9]+)/) {
347 $current->append_new_node (type => '#element',
348 namespace_uri => $NS_SW09, local_name => 'anchor')
349 ->append_new_node (type => '#element',
350 namespace_uri => $NS_SW09, local_name => 'fragment')
351 ->append_text (0+$1);
352 } elsif ($misc =~ /<([A-Z]+):((?:[^>"]|"(?:[^"\\]|\\.)*")+)>/) {
353 $current->append_new_node (type => '#element',
354 namespace_uri => $NS_SW09, local_name => 'anchor')
355 ->append_new_node (type => '#element',
356 namespace_uri => $NS_SW09, local_name => $1)
357 ->append_text ($2);
358 } elsif ($misc =~ /<([A-Za-z0-9%]+:[^>]+)>/) {
359 $current->append_new_node (type => '#element',
360 namespace_uri => $NS_SW09, local_name => 'anchor')
361 ->append_new_node (type => '#element',
362 namespace_uri => $NS_SW09, local_name => 'uri')
363 ->append_text ($1);
364 } elsif ($misc eq q('')) {
365 if ($current->local_name eq 'em') {
366 $current = $current->parent_node;
367 } else {
368 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'em');
369 }
370 } else { # '''
371 if ($current->local_name eq 'strong') {
372 $current = $current->parent_node;
373 } else {
374 $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'strong');
375 }
376 }
377 } else {
378 $current->append_text ($s);
379 }
380 '';
381 }ge;
382 return $l;
383 }
384
385 SuikaWiki::View->definition (sw09x__xml => {
386 media => {type => 'text/plain', expires => 240*3600,
387 charset => 1},
388 check => sub { ($_->[0]->{magic}||'SuikaWiki/0.9') =~ m!SuikaWiki/0\.9! ? 1 : 0 },
389 template => '%read(to=>SuikaWiki/0.9/XML);'});
390
391
392 POD:LICENSE:
393 Copyright 2002-2003 Wakaba <w@suika.fam.cx>
394
395 %%GNUGPL2%%

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24