/[pub]/suikawiki/script/misc/plugins/SuikaWiki09.wp2
Suika

Contents of /suikawiki/script/misc/plugins/SuikaWiki09.wp2

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations) (download)
Sat Dec 13 04:53:59 2003 UTC (20 years, 10 months ago) by wakaba
Branch: MAIN
Changes since 1.1: +282 -17 lines
SuikaWiki/0.9 text -> xml -> text/html fragment implemented

1 wakaba 1.1 #?SuikaWikiConfig/2.0
2    
3     Plugin:
4     @Name: SuikaWiki09
5     @Description:
6     @@@: SuikaWiki/0.9 document format
7     @@lang:en
8     @License: %%GPL%%
9     @Author:
10     @@Name:
11     @@@@: Wakaba
12     @@@lang:ja
13     @@@script:Latn
14     @@Mail[list]: w@suika.fam.cx
15     @Date.RCS: $Date: 2003/10/30 07:45:10 $
16     @RequiredPlugin[list]:
17 wakaba 1.2 WikiLinking
18 wakaba 1.1 @Use:
19     use Message::Markup::XML::QName qw/NS_xml_URI/;
20     my $Reg_Form_Content_M = qr{
21     \ \#form
22     \ (?:
23     \ \( (\w+) \) ## id
24     \ )?
25     \ : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' ## input
26     \ (?: : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' ## template
27     \ (?: : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' )? )? ## option
28     }x;
29     my $Reg_Embed_Content_M = qr{
30     \ \#([a-z-]+)
31     \ (?>
32     \ \( (\w+) \) ## id
33     \ )?
34     \ (?>
35     \ : ( \w+ (?> : \w+ )* ) ## parameter
36     \ )?
37     }x;
38     my $Reg_URI_Opaque = qr{
39     \ (?>[^<>"]*)
40     \ (?>
41     \ (?>
42     \ [^<>"]+
43     \ | "(?>[^"\\]*)(?>(?>[^"\\]+|\\.)*)"
44     \ )*
45     \ )
46     }x;
47    
48 wakaba 1.2 PluginConst:
49     @NS_SW09:
50     urn:x-suika-fam-cx:markup:suikawiki:0:9:
51     @NS_HTML3:
52     urn:x-suika-fam-cx:markup:ietf:html:3:draft:00:
53     @NS_XHTML1:
54     http://www.w3.org/1999/xhtml
55     @NS_XHTML2:
56     http://www.w3.org/2002/06/xhtml2
57    
58 wakaba 1.1 Format:
59     @ModuleName:
60     SuikaWiki::V0
61     @Description:
62     @@@: Dummy base format for SuikaWiki/0.*
63     @@lang:en
64     @Inherit[list]:
65     Text::Plain
66    
67     Format:
68     @Name: SuikaWiki
69     @Version: 0.9
70     @Type:
71     @@@: text/x-suikawiki
72     @@version: 0.9
73     @ModuleName:
74     SuikaWiki::V0_9
75     @Inherit[list]:
76     SuikaWiki::V0
77     @Description:
78     @@@: SuikaWiki/0.9 document format (Standard document format for SuikaWiki 2)
79     @@lang:en
80 wakaba 1.2
81     @Use:
82     use Message::Markup::XML::QName qw/NS_xml_URI/;
83 wakaba 1.1
84     @Converter:
85     @@Type: text/html
86     @@IsFragment: 1
87     @@Description:
88     @@@@: Converting SuikaWiki/0.9 to Hypertext Markup Language fragment
89     @@@lang:en
90     @@Main:
91 wakaba 1.2 # __FUNCPACK__->to_html ($source, %$opt);
92     ## Text format -> XML format
93     my $xml = new Message::Markup::XML::Node type => '#fragment';
94     __FUNCPACK__->text_to_xml ($source, {%$opt, -parent => $xml});
95    
96     my ($apply_template, $apply_template_children);
97     $apply_template_children = sub {
98     my ($parent, $result) = @_;
99     for (@{$parent->child_nodes}) {
100     $apply_template->($_ => $result) unless $_->node_type eq '#attribute';
101     }
102     };
103     $apply_template = sub {
104     my ($source, $result) = @_;
105     my $ln = $source->local_name;
106     if ($source->node_type eq '#text') {
107     $result->append_text ($source->inner_text);
108     } elsif ({qw/code 1 samp 1 var 1 dfn 1 kbd 1 sub 1 sup 1/}->{$ln}) {
109     my $node = $result->append_new_node
110     (type => '#element',
111     namespace_uri => $NS_XHTML1,
112     local_name => $ln);
113     my $class = $source->get_attribute_value ('class', default => '');
114     $node->set_attribute (class => $class) if $class;
115     $apply_template_children->($source => $node);
116     } elsif ({qw/ins 1 del 1/}->{$ln}) {
117     my $node = $result->append_new_node
118     (type => '#element',
119     namespace_uri => $NS_XHTML1,
120     local_name => $ln);
121     my $class = $source->get_attribute_value ('class', default => '');
122     $node->set_attribute (class => $class) if $class;
123     ## TODO: cite
124     $apply_template_children->($source => $node);
125     } elsif ({qw/table 1 tbody 1 tr 1 td 1 blockquote 1 ul 1 ol 1
126     li 1 pre 1 dl 1 dt 1 dd 1 em 1 strong 1/}->{$ln}) {
127     my $node = $result->append_new_node
128     (type => '#element',
129     namespace_uri => $NS_XHTML1,
130     local_name => $ln);
131     if ($ln eq 'td') {
132     my $colspan = $source->get_attribute_value ('colspan', default => 0);
133     $node->set_attribute (colspan => $colspan) if $colspan;
134     } elsif ($ln eq 'pre') {
135     $node->set_attribute (space => 'preserve',
136     namespace_uri => NS_xml_URI);
137     }
138     $apply_template_children->($source => $node);
139     } elsif ($ln eq 'anchor') {
140     local $opt->{o}->{var}->{sw09__anchor_content} = sub {
141     $apply_template_children->($source => shift);
142     };
143     SuikaWiki::Plugin->module_package ('WikiLinking')
144     ->to_wikipage_in_html ({
145     label => SuikaWiki::Plugin->resource
146     ('Link:SuikaWiki/0.9:toWikiPage:SourceLabel'),
147     } => {
148     ## TODO:
149     page_name_relative => [split m#//#, $source->inner_text],
150     page_anchor_no => $source->get_attribute_value ('anchor'),
151     }, {
152     o => $opt->{o},
153     parent => $result,
154     });
155     } elsif ($ln eq 'p') {
156     $apply_template_children->($source => $result->append_new_node
157     (type => '#element',
158     namespace_uri => $NS_XHTML1,
159     local_name => 'p'));
160     } elsif ($ln eq 'h') {
161     my $node;
162     if ($opt->{o}->{var}->{ws__section_depth} > 6) {
163     $node = $result->append_new_node
164     (type => '#element',
165     namespace_uri => $NS_XHTML1,
166     local_name => 'div');
167     $node->set_attribute (class => 'heading h'.$opt->{o}->{var}
168     ->{ws__section_depth});
169     } else {
170     $node = $result->append_new_node
171     (type => '#element',
172     namespace_uri => $NS_XHTML1,
173     local_name => 'h'.$opt->{o}->{var}
174     ->{ws__section_depth});
175     }
176     $apply_template_children->($source => $node);
177     } elsif ($ln eq 'ruby' or $ln eq 'rubyb') {
178     my @child;
179     for (@{$source->child_nodes}) {
180     if ({qw/rb 1 rt 1/}->{$_->local_name}) {
181     push @child, $_;
182     }
183     }
184     for ($result->append_new_node (type => '#element',
185     namespace_uri => $NS_XHTML1,
186     local_name => 'ruby')) {
187     if ($ln eq 'rubyb') {
188     my $class = join ' ',
189     'descriptive',
190     split /\s+/, $source->get_attribute_value
191     ('class', default => '');
192     $_->set_attribute (class => $class) if $class;
193     } else {
194     my $class = $source->get_attribute_value ('class', default => '');
195     $_->set_attribute (class => $class) if $class;
196     }
197     $apply_template_children->($child[0]
198     => $_->append_new_node (type => '#element',
199     namespace_uri => $NS_XHTML1,
200     local_name => 'rb'));
201     $_->append_new_node (type => '#element',
202     namespace_uri => $NS_XHTML1,
203     local_name => 'rp')
204     ->append_text ('(');
205     if ($child[1]) {
206     $apply_template_children->($child[1]
207     => $_->append_new_node (type => '#element',
208     namespace_uri => $NS_XHTML1,
209     local_name => 'rt'));
210     } else {
211     $_->append_new_node (type => '#element',
212     namespace_uri => $NS_XHTML1,
213     local_name => 'rt');
214     }
215     if ($child[2]) {
216     $_->append_new_node (type => '#element',
217     namespace_uri => $NS_XHTML1,
218     local_name => 'rp')
219     ->append_text ('/');
220     $apply_template_children->($child[2]
221     => $_->append_new_node (type => '#element',
222     namespace_uri => $NS_XHTML1,
223     local_name => 'rt'));
224     }
225     $_->append_new_node (type => '#element',
226     namespace_uri => $NS_XHTML1,
227     local_name => 'rp')
228     ->append_text (')');
229     }
230     } elsif ($ln eq 'abbr') {
231     my (@b);
232     for (@{$source->child_nodes}) {
233     push @b, $_ if {qw/rb 1 rt 1/}->{$_->local_name};
234     }
235     my $node = $result->append_new_node
236     (type => '#element',
237     namespace_uri => $NS_XHTML1,
238     local_name => 'abbr');
239     $node->set_attribute (title => $b[1]->inner_text) if $b[1];
240     $apply_template_children->($b[0] => $node);
241     } elsif ($ln eq 'q') {
242     my $node = $result->append_new_node
243     (type => '#element',
244     namespace_uri => $NS_XHTML1,
245     local_name => 'q');
246     ## TODO: cite
247     $apply_template_children->($source => $node);
248     } elsif ($ln eq 'weak') {
249     my $node = $result->append_new_node
250     (type => '#element',
251     namespace_uri => $NS_XHTML1,
252     local_name => 'span');
253     $node->set_attribute (class => 'weak');
254     $apply_template_children->($source => $node);
255     } elsif ({qw/section 1 bodytext 1/}->{$ln}) {
256     my $node = $result->append_new_node
257     (type => '#element',
258     namespace_uri => $NS_XHTML1,
259     local_name => 'div');
260     $node->set_attribute (class => $ln);
261     local $opt->{o}->{var}->{ws__section_depth}
262     = $opt->{o}->{var}->{ws__section_depth} + 1;
263     $apply_template_children->($source => $node);
264     } elsif ($ln eq 'anchor-end') {
265     my $node = $result->append_new_node
266     (type => '#element',
267     namespace_uri => $NS_XHTML1,
268     local_name => 'a');
269     $node->set_attribute (id => 'anchor-'.$source->get_attribute_value
270     ('anchor', default => '0'));
271     $node->append_text ($source->inner_text);
272     } elsif ($ln eq 'anchor-internal') {
273     my $node = $result->append_new_node
274     (type => '#element',
275     namespace_uri => $NS_XHTML1,
276     local_name => 'a');
277     $node->set_attribute (href => '#anchor-'.$source->get_attribute_value
278     ('anchor', default => '0'));
279     $node->set_attribute (class => 'wiki-anchor');
280     $node->append_text ($source->inner_text);
281     } elsif ($ln eq 'dr') {
282     $apply_template_children->($source => $result);
283     } elsif ($ln eq 'document') {
284     my $body;
285     for (@{$source->child_nodes}) {
286     $body = $_ and last if $_->local_name eq 'body';
287     }
288     my $body_block = $result->append_new_node
289     (type => '#element',
290     namespace_uri => $NS_XHTML1,
291     local_name => 'div');
292     $body_block->set_attribute (class => 'block SuikaWiki-0-9');
293     local $opt->{o}->{var}->{ws__section_depth}
294     = $opt->{o}->{var}->{ws__section_depth} + 1;
295     $apply_template_children->($body => $body_block);
296     } else {
297     my $node = $result->append_new_node
298     (type => '#element',
299     namespace_uri => $NS_XHTML1,
300     local_name => 'span');
301     $node->set_attribute (class => 'warn');
302     for ($node->append_new_node
303     (type => '#element',
304     namespace_uri => $NS_XHTML1,
305     local_name => 'ins')
306     ->append_new_node
307     (type => '#element',
308     namespace_uri => $NS_XHTML1,
309     local_name => 'code')) {
310     $_->set_attribute (class => 'XML element');
311     $_->append_text ("<".$source->namespace_uri.">:$ln");
312     }
313     $apply_template_children->($source => $node);
314     }
315     };
316    
317     $apply_template_children->($xml => $opt->{-parent});
318    
319 wakaba 1.1
320     @Converter:
321     @@Type:
322     @@@@: application/x-suikawiki+xml
323     @@@version: 0.9
324     @@Description:
325     @@@@: Converting SuikaWiki/0.9 text format to XML format
326     @@@lang: en
327     @@Main:
328     __FUNCPACK__->text_to_xml ($source, $opt);
329    
330     Function:
331     @Name: text_to_xml
332     @Description:
333     @@@:
334     Converting SuikaWiki/0.9 text format to XML representation
335     @@lang: en
336     @Main:
337     my (undef, $source, $opt) = @_;
338     $source =~ s/\x0D\x0A/\x0A/g;
339     $source =~ tr/\x0D/\x0A/;
340     $source .= "\x0A";
341     my $root = $opt->{-parent}
342     ->append_new_node (type => '#element',
343     namespace_uri => $NS_SW09,
344     local_name => 'document');
345     my $head = $root->append_new_node (type => '#element',
346     namespace_uri => $NS_XHTML2,
347     local_name => 'head');
348     if ($source =~ s#^\#\?SuikaWiki/0\.9\b((?>.*))\s*##) {
349     my $param = $1;
350     while ($param =~ /\G\s+([a-z-]+)="((?>[^"\\]*)(?>(?>[^"\\]+|\\.)*))"/g) {
351     my ($name, $value) = ($1, $2);
352     $value =~ s/\\(.)/$1/g;
353     for ($head->append_new_node (type => '#element',
354     namespace_uri => $NS_SW09,
355     local_name => 'parmeter')) {
356     $_->set_attribute (name => $name);
357     for my $value (split /,/, $value) {
358     $_->append_new_node (type => '#element',
359     namespace_uri => $NS_SW09,
360     local_name => 'value')
361     ->append_text ($value);
362     }
363     }
364     $head->append_text ("\x0A");
365     }
366     } else {
367     ## TODO: warn
368     }
369     $root->append_text ("\x0A");
370    
371     my $body = $root->append_new_node (type => '#element',
372     namespace_uri => $NS_XHTML2,
373     local_name => 'body');
374     __FUNCPACK__->block_text_to_xml (\$source => $body);
375    
376     Function:
377     @Name:block_text_to_xml
378     @Description:
379     @@@:
380     SuikaWiki/0.9 text format to XML representation convertion - block
381     level elements
382     @@lang:en
383     @Main:
384     my (undef, $source, $current, %opt) = @_;
385     my %depth;
386     my $back_to_section = sub {
387     my $cur_type = $current->local_name;
388     while (not (
389     $cur_type eq 'section'
390     or $cur_type eq 'body'
391     or $cur_type eq 'bodytext'
392     or $cur_type eq 'ins'
393     or $cur_type eq 'del'
394     )
395     ) {
396     $current = $current->parent_node;
397     $cur_type = $current->local_name;
398     }
399     delete $depth{list};
400     };
401     my $back_to_real_section = sub {
402     my $cur_type = $current->local_name;
403     while (not (
404     $cur_type eq 'section'
405     or $cur_type eq 'body'
406     or $cur_type eq 'ins'
407     or $cur_type eq 'del'
408     )
409     ) {
410     $current = $current->parent_node;
411     $cur_type = $current->local_name;
412     }
413     delete $depth{bq};
414     delete $depth{list};
415     };
416     while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
417     my $line = $1;
418     if ($line eq '') {
419     $back_to_real_section->();
420     } elsif ($line =~ s/^([-=]+)\s*//) {
421     my $list_type = substr ($1, -1) eq '-' ? 'ul' : 'ol';
422     my $depth = length $1;
423     my $parent_type = $current->parent_node->local_name;
424     ## Parent node is list element
425     if ($parent_type eq 'ul' or $parent_type eq 'ol') {
426     if ($depth{list} == $depth) {
427     if ($parent_type eq $list_type) {
428     $current = $current->parent_node;
429     } else {
430     $current = $current->parent_node
431     ->parent_node
432     ->append_new_node
433     (type => '#element',
434     namespace_uri => $NS_XHTML2,
435     local_name => $list_type);
436     }
437     } elsif ($depth < $depth{list}) {
438     for ($depth+1..$depth{list}) {
439     $current = $current->parent_node->parent_node;
440     }
441     $current = $current->parent_node;
442     if ($current->local_name ne $list_type) {
443     $current = $current->parent_node
444     ->append_new_node
445     (type => '#element',
446     namespace_uri => $NS_XHTML2,
447     local_name => $list_type);
448     }
449     $depth{list} = $depth;
450     } else { # $depth{list} < $depth
451     $current = $current->append_new_node
452     (type => '#element',
453     namespace_uri => $NS_XHTML2,
454     local_name => $list_type);
455     $depth{list}++;
456     }
457     ## Parent node is non-list element
458     } else {
459     $current = $current->append_new_node (type => '#element',
460     namespace_uri => $NS_XHTML2,
461     local_name => $list_type);
462     $depth{list} = 1;
463     }
464     $current->append_text ("\x0A".(" " x $depth{list}));
465     $current = $current->append_new_node (type => '#element',
466     namespace_uri => $NS_XHTML2,
467     local_name => 'li');
468     __FUNCPACK__->inline_text_to_xml (\$line => $current);
469     } elsif ($line =~ s/^(\*+)\s*//) {
470     my $depth = length $1;
471     $back_to_real_section->();
472     if ($depth <= $depth{section}) {
473     for ($depth..$depth{section}) {
474     $back_to_real_section->();
475     $current = $current->parent_node;
476     }
477     $depth{section} = $depth;
478     } else { # $depth{section} < $depth
479     for ($depth{section}+2..$depth) {
480     $current = $current->append_new_node
481     (type => '#element',
482     namespace_uri => $NS_XHTML2,
483     local_name => 'section');
484     }
485     $depth{section} = $depth;
486     }
487     $current = $current->append_new_node
488     (type => '#element',
489     namespace_uri => $NS_XHTML2,
490     local_name => 'section');
491     __FUNCPACK__->inline_text_to_xml (\$line =>
492     $current->append_new_node (type => '#element',
493     namespace_uri => $NS_XHTML2,
494     local_name => 'h')
495     );
496     } elsif ($line =~ s/^(?!>>[0-9])(>+)\s*//) {
497     my $depth = length $1;
498     if ($depth <= $depth{bq}) {
499     for ($depth+1..$depth{bq}) {
500     $back_to_section->();
501     $current = $current->parent_node->parent_node;
502     }
503     $back_to_section->();
504     $current->append_text ("\x0A");
505     $depth{bq} = $depth;
506     } else { # $depth{bq} < $depth
507     $back_to_section->();
508     for ($depth{bq}+1..$depth) {
509     $current = $current->append_new_node
510     (type => '#element',
511     namespace_uri => $NS_XHTML2,
512     local_name => 'blockquote')
513     ->append_new_node
514     (type => '#element',
515     namespace_uri => $NS_HTML3,
516     local_name => 'bodytext');
517     $current->append_text ("\x0A");
518     }
519     $depth{bq} = $depth;
520     }
521     if (length $line) {
522     $current = $current->append_new_node
523     (type => '#element',
524     namespace_uri => $NS_XHTML2,
525     local_name => 'p');
526     __FUNCPACK__->inline_text_to_xml (\$line => $current);
527     }
528     } elsif ($line =~ s/^(?>:\s*)([^:]+?)\s*:\s*//) {
529     my $parent_type = $current->local_name;
530     if ($parent_type eq 'dd') {
531     $current = $current->parent_node->parent_node;
532     $current->append_text ("\x0A");
533     } else { #if ($parent_type ne 'dl') {
534     $current = $current->append_new_node (type => '#element',
535     namespace_uri => $NS_XHTML2,
536     local_name => 'dl');
537     }
538     $current = $current->append_new_node
539     (type => '#element',
540     namespace_uri => $NS_SW09,
541     local_name => 'dr');
542     __FUNCPACK__->inline_text_to_xml (\"$1" =>
543     $current->append_new_node (type => '#element',
544     namespace_uri => $NS_XHTML2,
545     local_name => 'dt')
546     );
547     $current->append_text ("\x0A");
548     $current = $current->append_new_node (type => '#element',
549     namespace_uri => $NS_XHTML2,
550     local_name => 'dd');
551     __FUNCPACK__->inline_text_to_xml (\$line => $current);
552     } elsif ($line =~ /^\[(INS|DEL)(\([^()\\]*\))?\[\s*$/) {
553     $current->append_text ("\x0A");
554     my $mod = $current->append_new_node (type => '#element',
555     namespace_uri => $NS_XHTML1,
556     local_name => lc $1);
557     $mod->set_attribute (class => $2) if $2;
558     __FUNCPACK__->block_text_to_xml ($source => $mod,
559     'return_by_'.$1 => 1);
560     } elsif ($line =~ /^\](INS|DEL)\]\s*$/) {
561     if ($opt{'return_by_'.$1}) {
562     return;
563     } else {
564     ## TODO: warn
565     }
566     } elsif ($line =~ /^\[PRE(\([^()\\]*\))?\[\s*$/) {
567     $current->append_text ("\x0A");
568     my $pre = $current->append_new_node (type => '#element',
569     namespace_uri => $NS_XHTML1,
570     local_name => 'pre');
571     $pre->set_attribute (class => $1) if $1;
572     $pre->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI);
573     my $f = 1;
574     while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
575     my $line = $1;
576     if ($line =~ /^\]PRE\]\s*$/) {
577     undef $pre;
578     last;
579     } else {
580     $f ? undef $f : $pre->append_text ("\x0A");
581     __FUNCPACK__->inline_text_to_xml (\$line => $pre);
582     }
583     }
584     if (ref $pre) {
585     # warn unmatched start-tag
586     }
587     } elsif ($line =~ /^\s/) {
588     $current->append_text ("\x0A");
589     my $pre = $current->append_new_node (type => '#element',
590     namespace_uri => $NS_XHTML1,
591     local_name => 'pre');
592     $pre->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI);
593     __FUNCPACK__->inline_text_to_xml (\$line => $pre);
594     while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
595     my $line = $1;
596     if (length $line == 0) {
597     pos ($$source) -= 1;
598     last;
599     } else {
600     $pre->append_text ("\x0A");
601     __FUNCPACK__->inline_text_to_xml (\$line => $pre);
602     }
603     }
604     } elsif ($line =~ /^,/) {
605     $current->append_text ("\x0A");
606     my $tbody = $current->append_new_node (type => '#element',
607     namespace_uri => $NS_XHTML2,
608     local_name => 'table')
609     ->append_new_node (type => '#element',
610     namespace_uri => $NS_XHTML2,
611     local_name => 'tbody');
612     __FUNCPACK__->tablerow_text_to_xml (\$line => $tbody);
613     while ($$source =~ /\G(,[^\x0A]*)\x0A/gc) {
614     __FUNCPACK__->tablerow_text_to_xml (\"$1" => $tbody);
615     }
616     } else {
617     my $current_type = $current->local_name;
618     if ($current_type eq 'section'
619     or $current_type eq 'body'
620     or $current_type eq 'bodytext'
621     or $current_type eq 'ins'
622     or $current_type eq 'del') {
623     $current->append_text ("\x0A");
624     if ($line =~ s/^__&&([^&]+)&&__//) {
625     $current->append_new_node (type => '#element',
626     namespace_uri => $NS_SW09,
627     local_name => 'replace')
628     ->set_attribute (by => $1);
629     } elsif ($line =~ s/^\[\[$Reg_Form_Content_M\]\]//o) {
630     for ($current->append_new_node (type => '#element',
631     namespace_uri => $NS_SW09,
632     local_name => 'form')) {
633     $_->set_attribute (id => $1) if $1;
634     my ($i, $t, $o) = ($2, $3 || '', $4 || '');
635     s/\\(.)/$1/g for $i, $t, $o;
636     $_->set_attribute (input => $i);
637     $_->set_attribute (template => $t);
638     $_->set_attribute (option => $o);
639     }
640     } elsif ($line =~ s/^\[\[$Reg_Embed_Content_M\]\]//o) {
641     for ($current->append_new_node (type => '#element',
642     namespace_uri => $NS_SW09,
643     local_name => 'form')) {
644     $_->set_attribute (ref => $1);
645     $_->set_attribute (id => $2) if $2;
646     $_->set_attribute (parameter => $3) if defined $3;
647     }
648     }
649     $current = $current->append_new_node
650     (type => '#element',
651     namespace_uri => $NS_XHTML2,
652     local_name => 'p');
653     __FUNCPACK__->inline_text_to_xml (\$line => $current);
654     } else {
655     $current->append_text (" "); # replacement of prev.line's \n
656     __FUNCPACK__->inline_text_to_xml (\$line => $current);
657     }
658     }
659     }
660    
661     if ($opt{return_by_INS} or $opt{return_by_DEL}) {
662     # warn
663     }
664    
665     Function:
666     @Name: tablerow_text_to_xml
667     @Description:
668     @@@:
669     SuikaWiki/0.9 text format to XML representation - table row
670     @@lang:en
671     @Main:
672     my (undef, $source => $current, %opt) = @_;
673     $current->append_text ("\x0A");
674     $current = $current->append_new_node (type => '#element',
675     namespace_uri => $NS_XHTML2,
676     local_name => 'tr');
677     my $prev_cell;
678     while ($$source =~ /\G,\s*/gc) {
679     $$source =~ /\G([^,"]+|"(?>[^"\\]*)(?>(?>[^"\\]+|\\.)*)"\s*)/gc;
680     my $cell = $1;
681     if ($cell =~ s/^"//) {
682     $cell =~ s/"\s*$//g;
683     $cell =~ s/\\(.)/$1/g;
684     } else {
685     $cell =~ s/\s+$//g;
686     if ($cell eq '==') {
687     if (ref $prev_cell) {
688     $prev_cell->set_attribute (colspan =>
689     $prev_cell->get_attribute_value ('colspan', default => 1)
690     + 1);
691     next;
692     } else {
693     # TODO: warn
694     }
695     }
696     }
697     $prev_cell = $current->append_new_node
698     (type => '#element',
699     namespace_uri => $NS_XHTML2,
700     local_name => 'td');
701     __FUNCPACK__->inline_text_to_xml (\$cell => $prev_cell);
702     }
703     # TODO: warn
704    
705     Function:
706     @Name: inline_text_to_xml
707     @Description:
708     @@@:
709     SuikaWiki/0.9 text format to XML representation - inline level elements
710     @@lang:en
711     @Main:
712     my $ElementDef = {
713     ABBR => {ln => 'abbr', ns_uri => $NS_SW09},
714     CODE => {ln => 'code', ns_uri => $NS_XHTML2},
715     DEL => {ln => 'del', ns_uri => $NS_XHTML1},
716     DFN => {ln => 'dfn', ns_uri => $NS_XHTML2},
717     INS => {ln => 'ins', ns_uri => $NS_XHTML1},
718     KBD => {ln => 'kbd', ns_uri => $NS_XHTML2},
719     Q => {ln => 'q', ns_uri => $NS_XHTML1},
720     RUBY => {ln => 'ruby', ns_uri => $NS_XHTML2},
721     RUBYB => {ln => 'rubyb', ns_uri => $NS_SW09},
722     SAMP => {ln => 'samp', ns_uri => $NS_XHTML2},
723     SUB => {ln => 'sub', ns_uri => $NS_XHTML2},
724     SUP => {ln => 'sup', ns_uri => $NS_XHTML2},
725     VAR => {ln => 'var', ns_uri => $NS_XHTML2},
726     WEAK => {ln => 'weak', ns_uri => $NS_SW09},
727     anchor => {ln => 'anchor', ns_uri => $NS_SW09, has_fragment_no => 1},
728     del => {has_cite => 1},
729     ins => {has_cite => 1},
730     q => {has_cite => 1},
731     rb => {ln => 'rb', ns_uri => $NS_XHTML2, is_nested => 1},
732     rt => {ln => 'rt', ns_uri => $NS_XHTML2, is_nested => 1},
733     };
734    
735     my (undef, $source => $current, %opt) = @_;
736     if ($$source =~ /\G\[([0-9]+)\]/gc) {
737     for ($current->append_new_node (type => '#element',
738     namespace_uri => $NS_SW09,
739     local_name => 'anchor-end')) {
740 wakaba 1.2 $_->set_attribute (anchor => 0+$1);
741 wakaba 1.1 $_->append_text ('['.$1.']');
742     }
743     }
744     my $depth = 0;
745     while (pos $$source < length $$source) {
746     if ($$source =~ /\G\[\[(?=\#)/gc) {
747     my $form = $current->append_new_node (type => '#element',
748     namespace_uri => $NS_SW09,
749     local_name => 'form');
750     if ($$source =~ /\G$Reg_Form_Content_M\]\]/ogc) {
751     $form->set_attribute (id => $1) if $1;
752     $form->set_attribute (input => $2);
753     $form->set_attribute (template => $3);
754     $form->set_attribute (option => $4);
755     } elsif ($$source =~ /\G$Reg_Embed_Content_M\]\]/ogc) {
756     $form->set_attribute (ref => $1);
757     $form->set_attribute (id => $2) if $2;
758     $form->set_attribute (parameter => $3) if defined $3;
759     } else {
760     ## TODO: error
761     CORE::die $$source;
762     }
763     } elsif ($$source =~ /\G\[(?>([A-Z]+)(?>\(([^)]*)\))?)?\[/gc) {
764     my $type = $1 || 'anchor';
765     my $param = $2;
766     my $def = $ElementDef->{ $type };
767     unless ($def) {
768     ## TODO: error
769     }
770     $current = $current->append_new_node (type => '#element',
771     namespace_uri => $def->{ns_uri},
772     local_name => $def->{ln});
773     $current->set_attribute (class => $param) if $param;
774     if ($type eq 'RUBY' or $type eq 'RUBYB'
775     or $type eq 'ABBR') {
776     $current = $current->append_new_node
777     (type => '#element',
778     namespace_uri => $ElementDef->{rb}->{ns_uri},
779     local_name => $ElementDef->{rb}->{ln});
780     }
781     $depth++;
782     } elsif ($$source =~ /\G\](?> <([0-9A-Za-z_+.%-]+):($Reg_URI_Opaque)>
783     \ | >>([0-9]+) )?
784     \ \]/gcox) {
785     my ($scheme, $opaque, $anchor) = ($1, $2, $3);
786     unless ($depth) {
787     $current->append_text (substr ($$source, $-[0], $+[0]-$-[0]));
788     next;
789     }
790     my $def = $ElementDef->{$current->local_name} || {};
791     if (defined $anchor) {
792     if ($def->{has_fragment_no}) {
793     $current->set_attribute (anchor => $anchor + 0);
794     } else {
795     $current->set_attribute (anchor => $anchor + 0,
796     namespace_uri => $NS_SW09);
797     }
798     } elsif (defined $scheme) {
799     if ($def->{has_cite}) {
800     $current->set_attribute (cite => "$scheme:$opaque");
801     } else {
802     $current->set_attribute (cite => "$scheme:$opaque",
803     namespace_uri => $NS_SW09);
804     }
805     }
806     $current = $current->parent_node;
807     $current = $current->parent_node if $def->{is_nested};
808     $depth--;
809     } elsif ($$source =~ /\G\]\s+\[/gc) {
810     if ($current->local_name eq 'rb' or $current->local_name eq 'rt') {
811     $current = $current->parent_node
812     ->append_new_node
813     (type => '#element',
814     namespace_uri => $ElementDef->{rt}->{ns_uri},
815     local_name => $ElementDef->{rt}->{ln});
816     } else {
817     $current->append_text ($$source, $-[0], $+[0]-$-[0]);
818     }
819     } elsif ($$source =~ /\G'''?/gc) {
820     my $type = $+[0] - $-[0] == 3 ? 'strong' : 'em';
821     if ($current->local_name eq $type) {
822     $current = $current->parent_node;
823     } else {
824     $current = $current->append_new_node
825     (type => '#element',
826     namespace_uri => $NS_XHTML2,
827     local_name => $type);
828     }
829     } elsif ($$source =~ /\G<([0-9A-Za-z_+.%-]+):($Reg_URI_Opaque)>/gc) {
830     my ($scheme, $data) = ($1, $2);
831     my $link = $current->append_new_node
832     (type => '#element',
833     namespace_uri => $NS_SW09,
834 wakaba 1.2 local_name => 'anchor-external');
835 wakaba 1.1 if (substr ($scheme, 0, 1) =~ /[A-Z]/) {
836     $link->set_attribute (scheme => $scheme);
837     $link->set_attribute (data => $data);
838     } else { # URI Reference
839     $link->set_attribute (href => $scheme.':'.$data);
840     }
841     } elsif ($$source =~ /\G__&&/gc) {
842     if ($$source =~ /\G([^&]+)&&__/gc) {
843     $current->append_new_node
844     (type => '#element',
845     namespace_uri => $NS_SW09,
846 wakaba 1.2 local_name => 'replace')
847 wakaba 1.1 ->set_attribute (by => $1);
848     } else {
849 wakaba 1.2 $current->append_text ('__&&');
850 wakaba 1.1 }
851     } elsif ($$source =~ /\G((?>
852     [^'\[\]<>]+
853     | ' (?!')
854     | \[ (?![A-Z\[])
855     | \] (?! \]
856     | >>[0-9]+\]
857     | <[0-9A-Za-z_+.%-]+:$Reg_URI_Opaque>\]
858     | \s*\[ )
859     | < (?![0-9A-Za-z_+.%-]+:$Reg_URI_Opaque>)
860     | > (?!>[0-9])
861     | _ (?!_&&)
862     )+)/oxgc) {
863     $current->append_text ($1);
864     } elsif ($$source =~ /\G>>([0-9]+)/gc) {
865     for ($current->append_new_node (type => '#element',
866     namespace_uri => $NS_SW09,
867 wakaba 1.2 local_name => 'anchor-internal')) {
868     $_->set_attribute (anchor => 0+$1);
869 wakaba 1.1 $_->append_text ('>>'.$1);
870     }
871     } else {
872     die "Implementation buggy: ", substr ($$source, pos $$source);
873     }
874     }
875    
876     Function:
877     @Name: to_html
878     @Description:
879     @@@:Converting SuikaWiki/0.9 to Hypertext Markup Language
880     @@lang:en
881     @Main:
882     my (undef, $txt, %option) = @_;
883    
884     ## Load constants
885     # my %const;
886     # if ($option{magic} =~ /import="([^"]+)"/) {
887     # for (split /\s*,\s*/, $1) {
888     # my $wp = $main::database{$_};
889     # if ($wp =~ m!^\#\?SuikaWikiConst/(?:0.9|1.0)!) {
890     # wiki::suikawikiconst::to_hash ($wp => \%const);
891     # }
892     # }
893     # }
894    
895     # $txt =~ s{__&&([^&]+)&&__}{defined $const{$1}?$const{$1}:qq(__&&$1&&__)}ge;
896    
897     my (@txt) = split(/\n/, $txt);
898     my (@saved, @result);
899     my $p = $option{-parent}
900     || Message::Markup::XML::Node->new (type => '#fragment');
901     my $current = $p;
902     my %depth;
903     my $exit_p = sub {
904     my $current = shift;
905     if ($current->local_name eq 'p') {
906     $current = $current->parent_node;
907     }
908     $current;
909     };
910     my $cut_anchor = sub {
911     my ($current, $content) = @_;
912     if ($content =~ s/^\s*\[([0-9]+)\]\s+//) {
913     my $num = 0 + $1;
914     for my $A ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'a')) {
915     $A->set_attribute (id => 'anchor-' . $num);
916     $A->set_attribute (name => 'anchor-' . $num);
917     $A->set_attribute (class => 'anchor');
918     $A->append_text ('[' . $num . ']');
919     }
920     $current->append_text (' ');
921     }
922     $content;
923     };
924     my $back_to_section = sub {
925     my $current = shift;
926     while ($current->node_type ne '#fragment') {
927     if ({ins=>1,del=>1,blockquote=>1}->{$current->local_name}) {
928     return $current;
929     }
930     $current = $current->parent_node;
931     }
932     return $current;
933     };
934    
935     foreach (@txt) {
936     chomp;
937     if ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\*\*\*\*\*([^\x0D\x0A]*)/) {
938     $current = &$back_to_section ($current);
939     for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h6')) {
940     $H->append_node (_inline_xml ($1, %option));
941     }
942     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\*\*\*\*([^\x0D\x0A]*)/) {
943     $current = &$back_to_section ($current);
944     for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h5')) {
945     $H->append_node (_inline_xml ($1, %option));
946     }
947     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\*\*\*([^\x0D\x0A]*)/) {
948     $current = &$back_to_section ($current);
949     for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h4')) {
950     $H->append_node (_inline_xml ($1, %option));
951     }
952     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\*\*([^\x0D\x0A]*)/) {
953     $current = &$back_to_section ($current);
954     for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h3')) {
955     $H->append_node (_inline_xml ($1, %option));
956     }
957     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\*([^\x0D\x0A]*)/) {
958     $current = &$back_to_section ($current);
959     for my $H ($current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'h2')) {
960     $H->append_node (_inline_xml ($1, %option));
961     }
962     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^([-=]{1,6})(.*)/) {
963     my ($depth, $content, $type) = (length ($1), $2, (substr ($1, -1) eq '-' ? 'ul' : 'ol'));
964     $current = &$exit_p ($current);
965     if ($current->local_name eq 'li') {
966     if ($depth{list} == $depth && $depth{list_type} eq $type) {
967     $current = $current->parent_node;
968     } elsif ($depth <= $depth{list}) {
969     for (1..($depth{list} - $depth)*2) {
970     ($depth{list} = 1, last) unless ref $current->parent_node;
971     ($depth{list} = 1, last) unless {li=>1,ul=>1,ol=>1}->{$current->local_name};
972     $current = $current->parent_node;
973     $depth{list} -= 0.5;
974     }
975     $current = $current->parent_node;
976     if ($type ne $current->local_name) {
977     $current = $current->parent_node->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
978     $current->parent_node->append_text ("\n");
979     }
980     } else { # $depth{list} < $depth
981     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
982     $current->parent_node->append_text ("\n");
983     $depth{list}++;
984     }
985     } else {
986     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => $type);
987     $current->parent_node->append_text ("\n\n");
988     $depth{list} = 1;
989     }
990     $depth{list_type} = $type;
991     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'li');
992     $current->parent_node->append_text ("\n");
993     $content = &$cut_anchor ($current, $content);
994     $current->append_node (_inline_xml ($content, %option));
995     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^:([^:]+):(.*)/) {
996     $current = &$exit_p ($current);
997     if ($current->local_name eq 'dd') {
998     $current = $current->parent_node;
999     } else {
1000     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'dl');
1001     }
1002     $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'dt')
1003     ->append_node (_inline_xml ($1, %option));
1004     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'dd');
1005     $current->append_node (_inline_xml ($2, %option));
1006     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^(?!>>[0-9])(>{1,5})(.*)/) {
1007     my ($depth, $content) = (length $1, $2);
1008     $current = &$exit_p ($current);
1009     if ($depth == $depth{bq}) {
1010     #
1011     } elsif ($depth{bq} < $depth) {
1012     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'blockquote');
1013     $depth{bq}++;
1014     } else { # $depth < $depth{bq}
1015     for (1..($depth{bq}-$depth)) {
1016     last if $current->node_type eq '#fragment';
1017     $current = &$back_to_section ($current->parent_node);
1018     }
1019     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'blockquote')
1020     unless $current->local_name eq 'blockquote';
1021     $depth{bq} = $depth;
1022     }
1023     if (length $content) {
1024     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'p');
1025     $current->append_node (_inline_xml ($content, %option));
1026     }
1027     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\s*$/) {
1028     $current = &$back_to_section ($current);
1029     while ($current->local_name eq 'blockquote') {
1030     $depth{bq}--;
1031     $current = &$back_to_section ($current->parent_node);
1032     }
1033     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^(\s+.*)$/) {
1034     if ($current->local_name ne 'pre') {
1035     $current = &$exit_p ($current)->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'pre');
1036     #$depth{block_name}->{++$depth{block}} = 'pre';
1037     }
1038     $current->append_node (_inline_xml ($1, %option));
1039     } elsif ($depth{block_name}->{$depth{block}} ne 'PRE' && /^\,(.*?)[\x0D\x0A]*$/) {
1040     $current = &$exit_p ($current);
1041     if ($current->local_name eq 'td') {
1042     $current = $current
1043     ->parent_node # tr
1044     ->parent_node # tbody
1045     ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tr');
1046     } else {
1047     $current = $current
1048     ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'table')
1049     ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tbody')
1050     ->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'tr');
1051     }
1052     $current->parent_node->append_text ("\n"); # </tr>\n
1053     my $tmp = "$1,";
1054     my @value = map {/^"(.*)"$/ ? scalar($_ = $1, s/""/"/g, $_) : $_} ($tmp =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
1055     my @colspan = map {($_ eq '==') ? 0 : 1} @value;
1056     my ($tr, $td) = ($current, $current);
1057     for (my $i = 0; $i < @value; $i++) {
1058     if ($colspan[$i]) {
1059     while ($i + $colspan[$i] < @value and $value[$i + $colspan[$i]] eq '==') {
1060     $colspan[$i]++;
1061     }
1062     $td = $tr->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'td');
1063     $td->set_attribute (colspan => $colspan[$i]) if $colspan[$i] > 1;
1064     $td->append_node (_inline_xml ($value[$i], %option));
1065     }
1066     }
1067     if ($td->local_name eq 'tr') { # No <td/> in the <tr/> (error!)
1068     $td = $tr->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'td');
1069     }
1070     $current = $td;
1071     } elsif (/^\[(INS|DEL|PRE)\[\s*$/) {
1072     if ($depth{block_name}->{$depth{block}} ne 'PRE') {
1073     $current = &$exit_p ($current)->append_new_node (namespace_uri => $NS_XHTML1, local_name => lc $1);
1074     $depth{block}++;
1075     $depth{block_name}->{$depth{block}} = $1;
1076     } else {
1077     $current->append_text ($_);
1078     }
1079     } elsif ($depth{block} && /^\]($depth{block_name}->{$depth{block}})\]\s*$/) {
1080     while ($current->node_type ne '#fragment') {
1081     if ($current->local_name eq lc $depth{block_name}->{$depth{block}}) {
1082     $current = $current->parent_node;
1083     $depth{block}--;
1084     last;
1085     }
1086     $current = $current->parent_node;
1087     }
1088     } else {
1089     if ($current->node_type eq '#fragment' || {ins=>1,del=>1}->{$current->local_name}) {
1090     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'p');
1091     $current->parent_node->append_text ("\n\n"); # <P> is two <BR>s:-)
1092     }
1093     $current->append_node (_inline_xml (&$cut_anchor ($current, $_), %option));
1094     }
1095     }
1096     $p;
1097    
1098     Function:
1099     @Name: _id_and_name_xml
1100     @Main:
1101     my ($e, $name) = @_;
1102     $e->set_attribute (id => $name);
1103     if (SuikaWiki::Plugin->user_agent_names =~ m#Mozilla/[12]\.|Microsoft Internet Explorer#) {
1104     $e->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'a')
1105     ->set_attribute (name => $name);
1106     }
1107    
1108     Function:
1109     @Name: _inline_xml
1110     @Main:
1111     my ($line, %option) = @_;
1112     my $l = Message::Markup::XML::Node->new (type => '#fragment');
1113     my $current = $l;
1114     $line =~ s{(?:\[([A-Z]+)(?:\(([^)]*)\))?\[|(\[\[#form(?:\([A-Za-z0-9-]+\))?(?::'(?:[^'\\]|\\.)*')+\]\]|\[\[[^]]+\](?:>>[0-9]+)?\])|(\]\])|(\] \[)|(>>[0-9]+|<[A-Za-z0-9%]+:[^>]+>|'''?)|([\[\]'<>]|[^\[\]'<>]+))}{
1115     my ($el_name, $attr, $lnk, $etag, $nxt, $misc, $s) = ($1, $2, $3, $4, $5, $6, $7);
1116     if ($el_name) {
1117     my $edef = {
1118     ABBR => {html_el => 'abbr', use_class_attr => 1},
1119     CODE => {html_el => 'code', use_class_attr => 1},
1120     DEL => {html_el => 'del', use_class_attr => 1},
1121     DFN => {html_el => 'dfn', use_class_attr => 1},
1122     INS => {html_el => 'ins', use_class_attr => 1},
1123     KBD => {html_el => 'kbd', use_class_attr => 1},
1124     RUBY => {html_el => 'ruby'},
1125     RUBYB => {html_el => 'ruby', html_class => 'descriptive'},
1126     SAMP => {html_el => 'samp', use_class_attr => 1},
1127     SUB => {html_el => 'sub'},
1128     SUP => {html_el => 'sup'},
1129     VAR => {html_el => 'var', use_class_attr => 1},
1130     WEAK => {html_el => 'span', html_class => 'weak'},
1131     }->{ $el_name };
1132     if ($edef) {
1133     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => $edef->{html_el});
1134     $current->set_attribute (class => $edef->{html_class}) if $edef->{html_class};
1135     $current->get_attribute ('class', make_new_node => 1)
1136     ->append_text ($attr) if $attr && $edef->{use_class_attr};
1137     if ($edef->{html_el} eq 'ruby') {
1138     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rb');
1139     }
1140     } else {
1141     $current->append_text ($&);
1142     }
1143     } elsif ($etag) {
1144     if (ref $current->parent_node) {
1145     if ($current->node_type eq '#attribute') {
1146     $current = $current->parent_node;
1147     }
1148     $current = $current->parent_node;
1149     if ($current->local_name eq 'ruby') {
1150     $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rp', value => ')');
1151     $current = $current->parent_node;
1152     }
1153     } else {
1154     $current->append_text (']]');
1155     }
1156     } elsif ($nxt) {
1157     my $c_l_n = $current->local_name;
1158     if ($c_l_n eq 'rb') {
1159     for ($current->parent_node) {
1160     $_->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rp', value => '(');
1161     $current = $_->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rt');
1162     }
1163     } elsif ($c_l_n eq 'rt') {
1164     for ($current->parent_node) {
1165     $_->append_text (' ');
1166     $current = $_->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'rt');
1167     }
1168     } elsif ($c_l_n eq 'abbr') {
1169     $current = $current->get_attribute ('title', make_new_node => 1);
1170     } else {
1171     $current->append_text ('] [');
1172     }
1173     } elsif ($lnk) {
1174     if ($lnk =~ /\[\[\#form(?:\(([A-Za-z0-9-]+)\))?:'((?:[^'\\]|\\.)*)':'((?:[^'\\]|\\.)*)'(?::'((?:[^'\\]|\\.)*)')?\]\]/) {
1175     $current->append_new_node (type => '#xml', value => scalar SuikaWiki::Plugin::WikiFormCore->_make_custom_form ($1, $2, $3, $4, \%option));
1176     } elsif ($lnk =~ /\[\[([^]]+)\](?:>>([0-9]+))?\]/) {
1177     my ($page, $anchor) = ($1, $2);
1178     if (substr ($page, 0, 1) eq '#') {
1179     $current->append_new_node (type => '#xml', value => scalar embedded_to_html ($lnk, $option{page}));
1180     } else {
1181     $current->append_node (SuikaWiki::Plugin->module_package ('WikiLinking')->to_wikipage_in_html ({
1182     label => SuikaWiki::Plugin->resource ('Link:toWikiPage:SourceLabel'),
1183     } => {
1184     #TODO: base => [$option{page}],
1185     page_name_relative => [split m#//#, $page],
1186     page_anchor_no => 0+$anchor,
1187     }, {o=>$option{o}}));
1188     #$current->append_new_node (type => '#xml', value => scalar main::make_wikilink ($page, anchor => 0+$anchor, base => $option{page}));
1189     }
1190     }
1191     } elsif ($misc) {
1192     if ($misc =~ />>([0-9]+)/) {
1193     for my $A ($current->append_new_node (local_name => 'a', namespace_uri => $NS_XHTML1)) {
1194     $A->set_attribute (href => '#anchor-' . $1);
1195     $A->set_attribute (class => 'wiki-anchor');
1196     $A->append_text ('>>' . $1);
1197     }
1198     } elsif ($misc =~ /<([A-Za-z0-9%]+:[^>]+)>/) { # BUG: <IW:foo:"<foo>"> doesn't match
1199     $current->append_new_node (type => '#xml', value => scalar main::make_urilink ($1));
1200     } elsif ($misc eq q('')) {
1201     if ($current->local_name eq 'em') {
1202     $current = $current->parent_node;
1203     } else {
1204     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'em');
1205     }
1206     } else { # '''
1207     if ($current->local_name eq 'strong') {
1208     $current = $current->parent_node;
1209     } else {
1210     $current = $current->append_new_node (namespace_uri => $NS_XHTML1, local_name => 'strong');
1211     }
1212     }
1213     } else {
1214     $current->append_text ($s);
1215     }
1216     '';
1217     }ge;
1218     return $l;
1219    
1220     Function:
1221     @Name: embedded_to_html
1222     @Main:
1223     my ($embedded, $bPage) = @_;
1224     my $CommentIndex = SuikaWiki::Plugin->new_index ('sw09--comment');
1225     if ($embedded eq '[[#comment]]' or $embedded eq '[[#rcomment]]') {
1226     unless ($main::_EMBEDED) {
1227     my $lastmodified = SuikaWiki::Plugin->get_data (lastmodified => [split m!//!, $bPage]);
1228     return <<"EOD";
1229     <form action="@{[SuikaWiki::Plugin->uri ('wiki')]}" method="post" id="x-comment-@{[$CommentIndex]}" class="comment"><p>
1230     <input type="hidden" name="mycmd" value="comment" />
1231     <input type="hidden" name="mypage" value="@{[SuikaWiki::Plugin->escape($bPage)]}" />
1232     <input type="hidden" name="myLastModified" value="$lastmodified" />
1233     <input type="hidden" name="mytouch" value="on" />
1234     <input type="hidden" name="comment_index" value="$CommentIndex" />
1235     \ @{[SuikaWiki::Plugin->resource('WikiForm:WikiComment:Name=',escape=>1)]}
1236     <input type="text" name="myname" value="" size="10" class="comment-name" />
1237     <input type="text" name="mymsg" value="" size="30" class="comment-msg" />
1238     <input type="submit" value="@{[SuikaWiki::Plugin->resource('WikiForm:Add',escape=>1)]}" title="@{[SuikaWiki::Plugin->resource('WikiForm:AddLong',escape=>1)]}" class="comment-submit" />
1239     </p></form>
1240     EOD
1241     } else {
1242     return <<"EOD";
1243     <del><form action="@{[SuikaWiki::Plugin->uri ('wiki')]}" method="get">
1244     <input type="hidden" name="mycmd" value="default" />
1245     <input type="hidden" name="mypage" value="@{[SuikaWiki::Plugin->escape($bPage)]}" />
1246     \ @{[SuikaWiki::Plugin->resource('WikiForm:WikiComment:Name=',escape=>1)]}
1247     <input type="text" name="myname" value="" size="10" disabled="disabled" />
1248     <input type="text" name="mymsg" value="" size="60" disabled="disabled" />
1249     </form></del>
1250     EOD
1251     }
1252     } elsif ($embedded =~ /^\[\[\#embed:(.+)\]\]$/) {
1253     my ($name, $r) = ($1, '');
1254     if ($name =~ s/^IMG://) {
1255     my ($magic, $content) = SuikaWiki::Plugin->magic_and_content ($main::database{$name});
1256     $r = &main::convert_format ($content, $magic => 'HTML_fragment', page => $name, magic => $magic, -error_no_return => 1);
1257     if (defined $r) {
1258     return $r;
1259     } else {
1260     return '<span class="error-embed-image">'.SuikaWiki::Plugin->resource ('Embed:ImageNotSupported', escape=>1).'</span>';
1261     }
1262     } else {
1263     if ($main::_EMBEDED != 1) {
1264     my ($cf, $content) = SuikaWiki::Plugin->magic_and_content ($main::database{$name});
1265     $cf ||= '#?SuikaWiki/0.9';
1266     if ($cf =~ m!^#\?SuikaWiki/0.9(?:$|\s)!) {
1267     $main::_EMBEDED = 1;
1268     $r = &text_to_html ($content, magic => $cf, page => $name);
1269     $main::_EMBEDED = 0;
1270     } elsif (length $content) {
1271     $r = "<pre>@{[SuikWiki::Plugin->escape ($content)]}</pre>";
1272     } else {
1273     $r = &text_to_html ("[INS[\n[[$name]]: @{[SuikaWiki::Plugin->resource('Embed:PageNotFound')]}\n]INS]\n", magic => '#?SuikaWiki/0.9');
1274     }
1275     } else { ## nested #EMBED
1276     $r = &text_to_html ("[INS[\n[[$name]]: @{[SuikaWiki::Plugin->resource('Embed:Nested',escape=>1)]}\n]INS]\n", magic => '#?SuikaWiki/0.9');
1277     }
1278     return qq(<blockquote title="@{[SuikaWiki::Plugin->escape($name)]}" class="wiki-embed">$r<div class="cite-note">¡Ø<cite><a href="@{[SuikaWiki::Plugin->uri ('wiki') . SuikaWiki::Plugin->encode($name)]}" class="wiki">@{[SuikaWiki::Plugin->escape($name)]}</a></cite>¡Ù</div></blockquote>);
1279     }
1280     } else {
1281     return $embedded;
1282     }
1283 wakaba 1.2
1284     FormattingRule:
1285     @Category[list]: page-link
1286     @Name: sw09--link-anchor-content
1287     @Description:
1288     @@@:
1289     Output content of the anchor element
1290     @@lang:en
1291     @Formatting:
1292     if ($o->{var}->{sw09__anchor_content}) {
1293     $o->{var}->{sw09__anchor_content}->($p->{-parent});
1294     } else {
1295     $p->{-parent}->append_node (SuikaWiki::Plugin->resource
1296     ('Link:SuikaWiki/0.9:link-anchor-content:InvalidContext'),
1297     node_or_text => 1);
1298     }
1299    
1300     Resource:
1301     @Link:SuikaWiki/0.9:link-anchor-content:InvalidContext:
1302     @@@: %sw09--link-anchor-content; cannot be used in this context.
1303     @@lang:en
1304     @Link:SuikaWiki/0.9:toWikiPage:SourceLabel:
1305     @@@:
1306     %link-to-it(
1307     label=>{%sw09--link-anchor-content;%if-linked-wikipage-exist(
1308     true=>{%if-link-has-dest-anchor-no(true=>{>>%link-dest-anchor-no;});},
1309     false=>{%res(name=>{Link:toWikiPage:NotExist:Mark});}
1310     );}p,
1311     description=>{%page-name(absolute);; %if-linked-wikipage-exist(
1312     true=>{%page-headline;},
1313     false=>{(%res(name=>{Link:toWikiPage:NotExist:Description});)},
1314     );}p,
1315     class=>{%if-linked-wikipage-exist(false=>{not-exist});}p,
1316     );

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24