/[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.5 - (hide annotations) (download)
Sun Feb 1 12:11:28 2004 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.4: +180 -37 lines
#comment support, @HeadSummary 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]: [email protected]
15 wakaba 1.5 @Date.RCS: $Date: 2004/01/16 07:58:28 $
16 wakaba 1.1 @RequiredPlugin[list]:
17 wakaba 1.4 Edit
18     WikiFormCore
19 wakaba 1.2 WikiLinking
20 wakaba 1.4 WikiStruct
21 wakaba 1.1 @Use:
22     use Message::Markup::XML::QName qw/NS_xml_URI/;
23     my $Reg_Form_Content_M = qr{
24     \ \#form
25     \ (?:
26     \ \( (\w+) \) ## id
27     \ )?
28     \ : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' ## input
29     \ (?: : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' ## template
30     \ (?: : ' ((?>[^\\']*)(?>(?>[^\\']+|\\.)*)) ' )? )? ## option
31     }x;
32     my $Reg_Embed_Content_M = qr{
33     \ \#([a-z-]+)
34     \ (?>
35     \ \( (\w+) \) ## id
36     \ )?
37     \ (?>
38     \ : ( \w+ (?> : \w+ )* ) ## parameter
39     \ )?
40     }x;
41     my $Reg_URI_Opaque = qr{
42     \ (?>[^<>"]*)
43     \ (?>
44     \ (?>
45     \ [^<>"]+
46     \ | "(?>[^"\\]*)(?>(?>[^"\\]+|\\.)*)"
47     \ )*
48     \ )
49     }x;
50 wakaba 1.5 my $WIKIRESOURCE;
51 wakaba 1.1
52 wakaba 1.2 PluginConst:
53     @NS_SW09:
54     urn:x-suika-fam-cx:markup:suikawiki:0:9:
55     @NS_HTML3:
56     urn:x-suika-fam-cx:markup:ietf:html:3:draft:00:
57     @NS_XHTML1:
58     http://www.w3.org/1999/xhtml
59     @NS_XHTML2:
60     http://www.w3.org/2002/06/xhtml2
61 wakaba 1.5 @WIKIRESOURCE:
62     {($WIKIRESOURCE ||= SuikaWiki::Plugin->module_package ('WikiResource'))}
63 wakaba 1.2
64 wakaba 1.1 Format:
65     @ModuleName:
66     SuikaWiki::V0
67     @Description:
68     @@@: Dummy base format for SuikaWiki/0.*
69     @@lang:en
70     @Inherit[list]:
71     Text::Plain
72    
73     Format:
74     @Name: SuikaWiki
75     @Version: 0.9
76     @Type:
77     @@@: text/x-suikawiki
78     @@version: 0.9
79     @ModuleName:
80     SuikaWiki::V0_9
81     @Inherit[list]:
82     SuikaWiki::V0
83     @Description:
84     @@@: SuikaWiki/0.9 document format (Standard document format for SuikaWiki 2)
85     @@lang:en
86 wakaba 1.2
87     @Use:
88     use Message::Markup::XML::QName qw/NS_xml_URI/;
89 wakaba 1.4 use Message::Util::Error;
90 wakaba 1.1
91     @Converter:
92     @@Type: text/html
93     @@IsFragment: 1
94     @@Description:
95     @@@@: Converting SuikaWiki/0.9 to Hypertext Markup Language fragment
96     @@@lang:en
97     @@Main:
98 wakaba 1.4 $opt->{o}->{wiki} ||= $self->{wiki};
99    
100 wakaba 1.2 ## Text format -> XML format
101 wakaba 1.4 my $xml = __FUNCPACK__->get_xml_tree (text => $source, opt => $opt,
102     wiki => $self->{wiki});
103    
104     ## SuikaWiki/0.9 -> XHTML 1
105 wakaba 1.2 my ($apply_template, $apply_template_children);
106     $apply_template_children = sub {
107     my ($parent, $result) = @_;
108     for (@{$parent->child_nodes}) {
109     $apply_template->($_ => $result) unless $_->node_type eq '#attribute';
110     }
111     };
112     $apply_template = sub {
113     my ($source, $result) = @_;
114     my $ln = $source->local_name;
115     if ($source->node_type eq '#text') {
116     $result->append_text ($source->inner_text);
117     } elsif ({qw/code 1 samp 1 var 1 dfn 1 kbd 1 sub 1 sup 1/}->{$ln}) {
118     my $node = $result->append_new_node
119     (type => '#element',
120     namespace_uri => $NS_XHTML1,
121     local_name => $ln);
122     my $class = $source->get_attribute_value ('class', default => '');
123     $node->set_attribute (class => $class) if $class;
124     $apply_template_children->($source => $node);
125 wakaba 1.4 } elsif ({qw/ins 1 del 1 insert 1 delete 1/}->{$ln}) {
126 wakaba 1.2 my $node = $result->append_new_node
127     (type => '#element',
128     namespace_uri => $NS_XHTML1,
129 wakaba 1.4 local_name => {qw/ins ins insert ins
130     delete del del del/}->{$ln});
131 wakaba 1.2 my $class = $source->get_attribute_value ('class', default => '');
132     $node->set_attribute (class => $class) if $class;
133     ## TODO: cite
134     $apply_template_children->($source => $node);
135     } elsif ({qw/table 1 tbody 1 tr 1 td 1 blockquote 1 ul 1 ol 1
136     li 1 pre 1 dl 1 dt 1 dd 1 em 1 strong 1/}->{$ln}) {
137     my $node = $result->append_new_node
138     (type => '#element',
139     namespace_uri => $NS_XHTML1,
140     local_name => $ln);
141     if ($ln eq 'td') {
142     my $colspan = $source->get_attribute_value ('colspan', default => 0);
143     $node->set_attribute (colspan => $colspan) if $colspan;
144     } elsif ($ln eq 'pre') {
145     $node->set_attribute (space => 'preserve',
146     namespace_uri => NS_xml_URI);
147     }
148     $apply_template_children->($source => $node);
149     } elsif ($ln eq 'anchor') {
150     local $opt->{o}->{var}->{sw09__anchor_content} = sub {
151     $apply_template_children->($source => shift);
152     };
153     SuikaWiki::Plugin->module_package ('WikiLinking')
154     ->to_wikipage_in_html ({
155 wakaba 1.4 label => SuikaWiki::Plugin->module_package ('WikiResource')
156     ->get_text
157     (name =>
158     'Link:SuikaWiki/0.9:toWikiPage:SourceLabel',
159     param => $opt->{o},
160     wiki => $opt->{o}->{wiki}),
161 wakaba 1.2 } => {
162     ## TODO:
163     page_name_relative => [split m#//#, $source->inner_text],
164 wakaba 1.4 page_anchor_no => $source->get_attribute_value
165     ('anchor',
166     namespace_uri => $NS_SW09),
167 wakaba 1.2 }, {
168     o => $opt->{o},
169     parent => $result,
170     });
171     } elsif ($ln eq 'p') {
172     $apply_template_children->($source => $result->append_new_node
173     (type => '#element',
174     namespace_uri => $NS_XHTML1,
175     local_name => 'p'));
176     } elsif ($ln eq 'h') {
177     my $node;
178     if ($opt->{o}->{var}->{ws__section_depth} > 6) {
179     $node = $result->append_new_node
180     (type => '#element',
181     namespace_uri => $NS_XHTML1,
182     local_name => 'div');
183     $node->set_attribute (class => 'heading h'.$opt->{o}->{var}
184     ->{ws__section_depth});
185     } else {
186     $node = $result->append_new_node
187     (type => '#element',
188     namespace_uri => $NS_XHTML1,
189     local_name => 'h'.$opt->{o}->{var}
190     ->{ws__section_depth});
191     }
192     $apply_template_children->($source => $node);
193 wakaba 1.4 SuikaWiki::Plugin->module_package ('WikiStruct')
194     ->set_section_id ($result, undef, $opt->{o}->{wiki},
195     title => $source->inner_text);
196 wakaba 1.2 } elsif ($ln eq 'ruby' or $ln eq 'rubyb') {
197     my @child;
198     for (@{$source->child_nodes}) {
199     if ({qw/rb 1 rt 1/}->{$_->local_name}) {
200     push @child, $_;
201     }
202     }
203     for ($result->append_new_node (type => '#element',
204     namespace_uri => $NS_XHTML1,
205     local_name => 'ruby')) {
206     if ($ln eq 'rubyb') {
207     my $class = join ' ',
208     'descriptive',
209     split /\s+/, $source->get_attribute_value
210     ('class', default => '');
211     $_->set_attribute (class => $class) if $class;
212     } else {
213     my $class = $source->get_attribute_value ('class', default => '');
214     $_->set_attribute (class => $class) if $class;
215     }
216     $apply_template_children->($child[0]
217     => $_->append_new_node (type => '#element',
218     namespace_uri => $NS_XHTML1,
219     local_name => 'rb'));
220     $_->append_new_node (type => '#element',
221     namespace_uri => $NS_XHTML1,
222     local_name => 'rp')
223     ->append_text ('(');
224     if ($child[1]) {
225     $apply_template_children->($child[1]
226     => $_->append_new_node (type => '#element',
227     namespace_uri => $NS_XHTML1,
228     local_name => 'rt'));
229     } else {
230     $_->append_new_node (type => '#element',
231     namespace_uri => $NS_XHTML1,
232     local_name => 'rt');
233     }
234     if ($child[2]) {
235     $_->append_new_node (type => '#element',
236     namespace_uri => $NS_XHTML1,
237     local_name => 'rp')
238     ->append_text ('/');
239     $apply_template_children->($child[2]
240     => $_->append_new_node (type => '#element',
241     namespace_uri => $NS_XHTML1,
242     local_name => 'rt'));
243     }
244     $_->append_new_node (type => '#element',
245     namespace_uri => $NS_XHTML1,
246     local_name => 'rp')
247     ->append_text (')');
248     }
249     } elsif ($ln eq 'abbr') {
250     my (@b);
251     for (@{$source->child_nodes}) {
252     push @b, $_ if {qw/rb 1 rt 1/}->{$_->local_name};
253     }
254     my $node = $result->append_new_node
255     (type => '#element',
256     namespace_uri => $NS_XHTML1,
257     local_name => 'abbr');
258     $node->set_attribute (title => $b[1]->inner_text) if $b[1];
259     $apply_template_children->($b[0] => $node);
260     } elsif ($ln eq 'q') {
261     my $node = $result->append_new_node
262     (type => '#element',
263     namespace_uri => $NS_XHTML1,
264     local_name => 'q');
265     ## TODO: cite
266     $apply_template_children->($source => $node);
267     } elsif ($ln eq 'weak') {
268     my $node = $result->append_new_node
269     (type => '#element',
270     namespace_uri => $NS_XHTML1,
271     local_name => 'span');
272     $node->set_attribute (class => 'weak');
273     $apply_template_children->($source => $node);
274     } elsif ({qw/section 1 bodytext 1/}->{$ln}) {
275     my $node = $result->append_new_node
276     (type => '#element',
277     namespace_uri => $NS_XHTML1,
278     local_name => 'div');
279     $node->set_attribute (class => $ln);
280     local $opt->{o}->{var}->{ws__section_depth}
281     = $opt->{o}->{var}->{ws__section_depth} + 1;
282     $apply_template_children->($source => $node);
283     } elsif ($ln eq 'anchor-end') {
284     my $node = $result->append_new_node
285     (type => '#element',
286     namespace_uri => $NS_XHTML1,
287     local_name => 'a');
288     $node->set_attribute (id => 'anchor-'.$source->get_attribute_value
289 wakaba 1.4 ('anchor', default => '0',
290     namespace_uri => $NS_SW09));
291 wakaba 1.2 $node->append_text ($source->inner_text);
292     } elsif ($ln eq 'anchor-internal') {
293     my $node = $result->append_new_node
294     (type => '#element',
295     namespace_uri => $NS_XHTML1,
296     local_name => 'a');
297     $node->set_attribute (href => '#anchor-'.$source->get_attribute_value
298 wakaba 1.4 ('anchor',
299     namespace_uri => $NS_SW09, default => '0'));
300 wakaba 1.2 $node->set_attribute (class => 'wiki-anchor');
301     $node->append_text ($source->inner_text);
302 wakaba 1.3 } elsif ($ln eq 'anchor-external') {
303     local $opt->{o}->{var}->{sw09__anchor_content} = sub {
304     $apply_template_children->($source => shift);
305     };
306     SuikaWiki::Plugin->module_package ('WikiLinking')
307     ->to_resource_in_html (
308     {
309 wakaba 1.4 label => SuikaWiki::Plugin->module_package ('WikiResource')
310     ->get_text (name =>
311     'Link:SuikaWiki/0.9:toResource:SourceLabel',
312     param => $opt->{o},
313     wiki => $opt->{o}->{wiki}),
314 wakaba 1.3 }, {
315     resource_scheme =>
316 wakaba 1.4 $source->get_attribute_value ('resScheme',
317     namespace_uri => $NS_SW09,
318 wakaba 1.3 default => 'URI'),
319     resource_parameter =>
320 wakaba 1.4 $source->get_attribute_value ('resParameter',
321     namespace_uri => $NS_SW09,
322     default => ''),
323 wakaba 1.3 }, {
324     o => $opt->{o},
325     parent => $result,
326     });
327 wakaba 1.4 } elsif ($ln eq 'form') {
328 wakaba 1.5 my $ref = $source->get_attribute_value ('ref', default => 'form');
329     if ($ref eq 'form') {
330     SuikaWiki::Plugin->module_package ('WikiFormCore')
331     ->make_content_form_in_html
332     ($result,
333     $source->get_attribute_value
334     ('input', default => ''),
335     option => $source->get_attribute_value
336     ('option'),
337     name => $source->get_attribute_value ('id'),
338     o => $opt->{o},
339     wiki => $opt->{o}->{wiki},
340     output => {
341     page => $opt->{page},
342     });
343     } elsif ($ref eq 'comment') {
344     SuikaWiki::Plugin->module_package ('WikiFormCore')
345     ->make_content_form_in_html
346     ($result,
347     $WIKIRESOURCE->get
348     (name => 'SuikaWiki/0.9:form:comment:input',
349     o => $opt->{o}, wiki => $opt->{o}->{wiki}),
350     option => $WIKIRESOURCE->get
351     (name => 'SuikaWiki/0.9:form:comment:option',
352     o => $opt->{o}, wiki => $opt->{o}->{wiki}),
353     name => $source->get_attribute_value ('id'),
354     o => $opt->{o},
355     wiki => $opt->{o}->{wiki},
356     output => {
357     page => $opt->{page},
358     });
359     } else {
360     ## TODO:
361     }
362 wakaba 1.2 } elsif ($ln eq 'dr') {
363     $apply_template_children->($source => $result);
364     } elsif ($ln eq 'document') {
365     my $body;
366     for (@{$source->child_nodes}) {
367     $body = $_ and last if $_->local_name eq 'body';
368     }
369     my $body_block = $result->append_new_node
370     (type => '#element',
371     namespace_uri => $NS_XHTML1,
372     local_name => 'div');
373     $body_block->set_attribute (class => 'block SuikaWiki-0-9');
374     $apply_template_children->($body => $body_block);
375     } else {
376     my $node = $result->append_new_node
377     (type => '#element',
378     namespace_uri => $NS_XHTML1,
379     local_name => 'span');
380     $node->set_attribute (class => 'warn');
381     for ($node->append_new_node
382     (type => '#element',
383     namespace_uri => $NS_XHTML1,
384     local_name => 'ins')
385     ->append_new_node
386     (type => '#element',
387     namespace_uri => $NS_XHTML1,
388     local_name => 'code')) {
389     $_->set_attribute (class => 'XML element');
390     $_->append_text ("<".$source->namespace_uri.">:$ln");
391     }
392     $apply_template_children->($source => $node);
393     }
394     };
395    
396     $apply_template_children->($xml => $opt->{-parent});
397    
398 wakaba 1.5 if ($opt->{-with_annotation_input}) {
399     SuikaWiki::Plugin->module_package ('WikiFormCore')
400     ->make_content_form_in_html
401     ($opt->{-parent},
402     $WIKIRESOURCE->get
403     (name => 'SuikaWiki/0.9:form:footannotate:input',
404     o => $opt->{o}, wiki => $opt->{o}->{wiki}),
405     option => $WIKIRESOURCE->get
406     (name => 'SuikaWiki/0.9:form:footannotate:option',
407     o => $opt->{o}, wiki => $opt->{o}->{wiki}),
408     o => $opt->{o},
409     wiki => $opt->{o}->{wiki},
410     output => {
411     page => $opt->{page},
412     });
413     }
414    
415 wakaba 1.1
416     @Converter:
417     @@Type:
418     @@@@: application/x-suikawiki+xml
419     @@@version: 0.9
420     @@Description:
421     @@@@: Converting SuikaWiki/0.9 text format to XML format
422     @@@lang: en
423     @@Main:
424 wakaba 1.4 my $xml = __FUNCPACK__->get_xml_tree (text => $source, opt => $opt,
425     wiki => $self->{wiki});
426     ## TODO: Make a clone
427     $opt->{-parent}->append_node ($xml);
428    
429     @NextIndex:
430     @@Name: anchor
431     @@Main:
432     my $xml = __FUNCPACK__->get_xml_tree (text => $source, opt => \%opt,
433     wiki => $self->{wiki});
434     (__FUNCPACK__->get_last_anchor_index ($xml)) + 1;
435    
436     @WikiForm:
437     @@Main:
438     ## Text format -> XML format
439     my $xml = __FUNCPACK__->get_xml_tree (text => $source, opt => \%opt,
440     wiki => $self->{wiki});
441     local $opt{o}->{var}->{sw09__anchor_index};
442     local $opt{o}->{var}->{sw09__document_tree} = $xml;
443    
444     my $form;
445     if ($opt{o}->{form}->{output}->{id}) {
446     $form = __FUNCPACK__->get_element_by_id
447     ($xml, $opt{o}->{form}->{output}->{id});
448     undef $form unless ref $form and
449     $form->namespace_uri eq $NS_SW09 and
450     $form->local_name eq 'form';
451     } else {
452     $form = __FUNCPACK__->get_nth_element
453     ($xml, $NS_SW09 => 'form',
454     $opt{o}->{form}->{output}->{index});
455     }
456    
457 wakaba 1.5 my $ref;
458     if (ref $form) {
459     $ref = $form->get_attribute_value ('ref', default => 'form');
460     } else {
461     $ref = '#footannotate';
462 wakaba 1.4 }
463    
464 wakaba 1.5
465 wakaba 1.4 ## WikiForm Option
466 wakaba 1.5 if ($ref eq 'form') {
467     $opt{option} ||= $form->get_attribute_value ('option');
468     } elsif ($ref eq 'comment') {
469     $opt{option} ||= $WIKIRESOURCE->get
470     (name => 'SuikaWiki/0.9:form:comment:option',
471     o => $opt{o}, wiki => $opt{o}->{wiki});
472     } elsif ($ref eq '#footannotate') {
473     $opt{option} ||= $WIKIRESOURCE->get
474     (name => 'SuikaWiki/0.9:form:footannotate:option',
475     o => $opt{o}, wiki => $opt{o}->{wiki});
476     } else {
477     ## TODO:
478     }
479 wakaba 1.4 SuikaWiki::Plugin->module_package ('WikiFormCore')
480     ->set_option ($opt{option} => $opt{o}) if $opt{option};
481    
482     ## Replace Output Template
483     my $result;
484 wakaba 1.5 if ($ref eq 'form') {
485     $opt{template} ||= $form->get_attribute_value
486     ('template', default => '');
487     } elsif ($ref eq 'comment') {
488     $opt{template} ||= $WIKIRESOURCE->get
489     (name => 'SuikaWiki/0.9:form:comment:template',
490     o => $opt{o}, wiki => $opt{o}->{wiki});
491     } elsif ($ref eq '#footannotate') {
492     $opt{template} ||= $WIKIRESOURCE->get
493     (name => 'SuikaWiki/0.9:form:footannotate:template',
494     o => $opt{o}, wiki => $opt{o}->{wiki});
495     }
496 wakaba 1.4 try {
497     $result = SuikaWiki::Plugin->text_formatter ('form_template')
498     ->replace ($opt{template}, param => $opt{o});
499     } catch Message::Util::Formatter::error with {
500     my $err = shift;
501     SuikaWiki::Plugin->module_package ('Error')
502     ->reporting_formatting_template_error
503     ($err, $err->{option}->{param}->{wiki});
504     ##TODO:
505     throw SuikaWiki::View::Implementation::error -type => 'ERROR_REPORTED';
506     };
507    
508     ## Insert
509     if (length $result) {
510 wakaba 1.5 if ($ref eq '#footannotate') {
511     my $parent;
512     for (@{$xml->child_nodes}) {
513     if ($_->node_type eq '#element' and
514     $_->local_name eq 'document') {
515     for (@{$_->child_nodes}) {
516     if ($_->node_type eq '#element' and
517     $_->local_name eq 'body') {
518     $parent = $_;
519     last;
520     }
521     }
522     }
523     }
524     CORE::die "Buggy implementation: no body element".$xml unless ref $parent;
525    
526     $parent->append_new_node (type => '#element',
527     namespace_uri => $NS_SW09,
528     local_name => 'text')
529     ->append_text ($result);
530 wakaba 1.4 } else {
531 wakaba 1.5 my $parent = $form->parent_node;
532     CORE::die "Byggy implementation: No parent of form" unless ref $parent;
533     my $children = $parent->child_nodes;
534    
535     $result .= "\x0A" unless substr ($result, -1) eq "\x0A";
536     $parent->append_new_node (type => '#element',
537     namespace_uri => $NS_SW09,
538     local_name => 'text')
539     ->append_text ($result);
540     my $node = pop @{$children};
541     my $form_str = overload::StrVal ($form);
542     my $i = 0;
543     for (@{$children}) {
544     last if overload::StrVal ($_) eq $form_str;
545     $i++;
546     }
547     if ($opt{o}->{form}->{output}->{reverse}) {
548     splice @{$children}, $i + 1, 0, $node;
549     } else {
550     splice @{$children}, $i, 0, $node;
551     }
552 wakaba 1.4 }
553 wakaba 1.5 } else {
554     ## TODO:
555 wakaba 1.4 }
556    
557     ## XML format -> Text format
558     my $text = __FUNCPACK__->xml_to_text ($xml, {%opt});
559    
560     my %fragment = (fragment => $opt{o}->{form}->{output}->{id}
561     || 'wikiform-'.$opt{o}->{form}->{output}->{index});
562     if (not $opt{o}->{form}->{output}->{reverse} and
563     $opt{o}->{var}->{sw09__anchor_index}) {
564     %fragment = (anchor_no => $opt{o}->{var}->{sw09__anchor_index});
565     }
566    
567     my $action = [
568     {
569     type => 'write',
570     content => $text,
571 wakaba 1.5 update_lastmodified => time,
572 wakaba 1.4 },
573     {
574     type => 'view',
575     %fragment,
576     },
577     ];
578    
579 wakaba 1.5 @HeadSummary:
580     @@Main:
581     my $xml = __FUNCPACK__->get_xml_tree (text => $source, opt => \%opt,
582     wiki => $self->{wiki});
583     return $xml->inner_text;
584    
585 wakaba 1.4 FormattingRule:
586     @Category[list]:form-template
587     @Name: index
588     @Description:
589     @@@: Next anchor index number
590     @@lang:en
591     @After:
592     if ($o->{var}->{sw09__anchor_index}) {
593     ++$o->{var}->{sw09__anchor_index};
594     } else {
595     $o->{var}->{sw09__anchor_index}
596     = 1 + __FUNCPACK__->get_last_anchor_index
597     ($o->{var}->{sw09__document_tree});
598     }
599     $p->{-result} .= $o->{var}->{sw09__anchor_index};
600    
601     Function:
602     @Name: get_last_anchor_index
603     @Main:
604     my (undef, $xml) = @_;
605     my $anchor = 0;
606     my $get_anchor_no;
607     $get_anchor_no = sub {
608     my $node = shift;
609     for my $child (@{$node->child_nodes}) {
610     if ($child->node_type eq '#element') {
611     if ($child->namespace_uri => $NS_SW09 and
612     $child->local_name eq 'anchor-end') {
613     my $a = $child->get_attribute_value ('anchor', default => 0,
614     namespace_uri => $NS_SW09);
615     $anchor = 0+$a if $anchor < 0+$a;
616     } else {
617     $get_anchor_no->($child);
618     }
619     } elsif ($child->node_type eq '#document' or
620     $child->node_type eq '#fragment') {
621     $get_anchor_no->($child);
622     }
623     }
624     };
625     $get_anchor_no->($xml);
626     $anchor;
627    
628    
629     Function:
630     @Name: get_xml_tree
631     @Main:
632     my (undef, %opt) = @_;
633     if ($opt{opt}->{page}) {
634     unless ($__FUNCPACK__::DBLoaded) {
635     $opt{wiki}->{db}->_set_prop_db (sw09__xml_tree => {-db_open => sub {
636     require SuikaWiki::DB::Hash;
637     new SuikaWiki::DB::Hash;
638     }});
639     $__FUNCPACK__::DBLoaded++;
640     }
641    
642     my $xml = new Message::Markup::XML::Node type => '#fragment';
643     __FUNCPACK__->text_to_xml (${$opt{text}}, {%{$opt{opt}}, -parent => $xml});
644    
645     $opt{wiki}->{db}->set (sw09__xml_tree => $opt{opt}->{page} => $xml);
646     $xml;
647     } else {
648     my $xml = new Message::Markup::XML::Node type => '#fragment';
649     __FUNCPACK__->text_to_xml (${$opt{text}}, {%{$opt{opt}}, -parent => $xml});
650     $xml;
651     }
652    
653    
654     Function:
655     @Name: xml_to_text
656     @Main:
657     my (undef, $src, $opt) = @_;
658    
659    
660     my %is_block = (
661     qw/p 1 blockquote 1 pre 1 ul 1 ol 1 dl 1 section 1 h 1
662     bodytext 1 document 1 head 1 body 1 table 1 text 1 form 1
663     insert 1 delete 1/
664     );
665    
666     my %x2t;
667     %x2t = (
668     anchor => sub {
669     my $source = shift;
670     my $result = '[['
671     . $x2t{'#inline'}->($source, no_newline => 1)
672     . ']';
673     my $anchor = $source->get_attribute_value
674     ('anchor',
675     namespace_uri => $NS_SW09,
676     default => '');
677     if (length $anchor) {
678     $result .= '>>'.(0+$anchor);
679     } else {
680     $anchor = $source->get_attribute_value
681     ('resScheme',
682     namespace_uri => $NS_SW09);
683     if ($anchor) {
684     my $param = $source->get_attribute_value
685     ('resParameter',
686     namespace_uri => $NS_SW09);
687     if ($anchor eq 'URI' and $param =~ /^[0-9A-Za-z_+.%-]+:/) {
688     $result .= '<' . $param . '>';
689     } else {
690     $result .= '<' . $anchor . ':' . $param . '>';
691     }
692     }
693     }
694     $result . ']';
695     },
696     li => sub {
697     my $source = shift;
698     my $result = ({qw/ul - ol =/}->{$opt->{o}->{var}->{sw09__list_type}}
699     x $opt->{o}->{var}->{sw09__list_depth})
700     . ' ' . $x2t{'#flow'}->($source);
701     $result;
702     },
703     dt => sub {
704     ':' . $x2t{'#inline'}->(return, no_newline => 1) . ':';
705     },
706     h => sub {
707     ("*" x ($opt->{o}->{var}->{ws__section_depth} - 1))
708     . " "
709     . $x2t{'#inline'}->(shift, no_newline => 1);
710     },
711     'anchor-end' => sub {
712     return shift->inner_text;
713     },
714     'anchor-internal' => sub {
715     return shift->inner_text;
716     },
717     'anchor-external' => sub {
718     return '<'.shift->inner_text.'>';
719     },
720     form => sub {
721     my $source = shift;
722     my $ref = $source->get_attribute_value ('ref', default => 'form');
723     my $result = '[[#'.$ref;
724     my $name = $source->get_attribute_value ('id');
725     $name =~ s/([()\\])/\\$1/g;
726     $result .= '(' . $name . ')' if $name;
727     ## General WikiForm
728     if ($ref eq 'form') {
729     $result .= ":'";
730     my $input = $source->get_attribute_value ('input', default => '');
731     $input =~ s/(['\\])/\\$1/g;
732     $result .= $input . "':'";
733     my $template = $source->get_attribute_value ('template', default => '');
734     $template =~ s/(['\\])/\\$1/g;
735     $result .= $template . "'";
736     my $option = $source->get_attribute_value ('option');
737     if ($option) {
738     $option =~ s/(['\\])/\\$1/g;
739     $result .= ":'" . $option . "'";
740     }
741     ## Specific WikiForm
742     } else {
743     my $param = $source->get_attribute_value ('parameter');
744     if ($param) {
745     $result .= ':' . $param;
746     }
747     }
748     $result .= ']]';
749     },
750     pre => sub {
751     my $source = shift;
752     my $result = '[PRE';
753     my $class = $source->get_attribute_value ('class');
754     if ($class) {
755     $class =~ s/([\\()])/\\$1/g;
756     $result .= '(' . $class . ')';
757     }
758     $result .= "[\x0A"
759     . $x2t{'#inline'}->($source);
760     $result .= "\x0A" unless substr ($result, -1) eq "\x0A";
761     $result .= "]PRE]\x0A";
762     },
763     insert => sub {
764     my $source = shift;
765     my $result = '[INS';
766     my $class = $source->get_attribute_value ('class');
767     if ($class) {
768     $class =~ s/([\\()])/\\$1/g;
769     $result .= '(' . $class . ')';
770     }
771     local $opt->{o}->{var}->{sw09__list_depth} = 0;
772     $result .= "[\x0A"
773     . $x2t{'#block'}->($source);
774     $result .= "\x0A" unless substr ($result, -1) eq "\x0A";
775     $result .= "]INS]\x0A";
776     },
777     delete => sub {
778     my $source = shift;
779     my $result = '[DEL';
780     my $class = $source->get_attribute_value ('class');
781     if ($class) {
782     $class =~ s/([\\()])/\\$1/g;
783     $result .= '(' . $class . ')';
784     }
785     local $opt->{o}->{var}->{sw09__list_depth} = 0;
786     $result .= "[\x0A"
787     . $x2t{'#block'}->($source);
788     $result .= "\x0A" unless substr ($result, -1) eq "\x0A";
789     $result .= "]DEL]\x0A";
790     },
791     document => sub {
792     my $source = shift;
793     my $result = '';
794     for (@{$source->child_nodes}) {
795     $result .= ($x2t{$_->local_name} or $x2t{'#undef'})->($_)
796     if $_->node_type eq '#element';
797     }
798     $result;
799     },
800     head => sub {
801     my $source = shift;
802     my $result = '#?SuikaWiki/0.9';
803     for (@{$source->child_nodes}) {
804     if ($_->node_type eq '#element' and
805     $_->local_name eq 'parameter') {
806     $result .= ' '.$x2t{parameter}->($_);
807     }
808     }
809     $result . "\x0A";
810     },
811     parameter => sub {
812     my $source = shift;
813     my $result = $source->get_attribute_value ('name', default => '')
814     . '="';
815     my @v;
816     for (@{$source->child_nodes}) {
817     push @v, $x2t{value}->($_) if $_->node_type eq '#element' and
818     $_->local_name eq 'value';
819     }
820     $result .= join ',', @v;
821     $result . '"';
822     },
823     value => sub {
824     my $value = $x2t{'#inline'}->(shift, no_newline => 1);
825     $value =~ s/(["\\])/\\$1/g;
826     $value =~ tr/\x0A\x0D/ /;
827     $value;
828     },
829     section => sub {
830     local $opt->{o}->{var}->{ws__section_depth}
831     = $opt->{o}->{var}->{ws__section_depth} + 1;
832     $x2t{'#block'}->(shift);
833     },
834     body => sub {
835     local $opt->{o}->{var}->{ws__section_depth} = 1;
836     $x2t{'#block'}->(shift);
837     },
838     text => sub {
839     my ($source, %opt) = @_;
840     my $result .= '';
841     for (@{$source->child_nodes}) {
842     if ($_->node_type eq '#text') {
843     $result .= $_->inner_text;
844     } elsif ($_->node_type eq '#element') {
845     $result .= ($x2t{$_->local_name} or $x2t{'#undef'})->($_);
846     }
847     }
848     $result;
849     },
850     dr => sub {
851     my $result = $x2t{'#list'}->(shift);
852     if ($result) {
853     $result . "\x0A";
854     } else {
855     "::\x0A";
856     }
857     },
858     dt => sub {
859     ':' . $x2t{'#inline'}->(shift, no_newline => 1) . ':';
860     },
861     dd => sub {
862     $x2t{'#inline'}->(shift);
863     },
864     tr => sub {
865     my $result = $x2t{'#list'}->(shift);
866     if ($result) {
867     substr ($result, 1) . "\x0A";
868     } else {
869     "',\x0A";
870     }
871     },
872     td => sub {
873     my $source = shift;
874     my $result = $x2t{'#inline'}->($source, no_newline => 1);
875     if ($result =~ /[,"\\]/ or $result =~ /==/) {
876     $result =~ s/(["\\])/\\$1/g;
877     $result = '"' . $result . '"';
878     }
879     my $colspan = $source->get_attribute_value ('colspan', default => 1);
880     $result .= ("\t,==" x ($colspan - 1)) if $colspan > 1;
881     "\t," . $result;
882     },
883     em => sub {
884     "''" . $x2t{'#inline'}->($_, no_newline => 1) . "''";
885     },
886     strong => => sub {
887     "'''" . $x2t{'#inline'}->($_, no_newline => 1) . "'''";
888     },
889     rb => sub {
890     $x2t{'#inline'}->(shift, no_newline => 1);
891     },
892     rt => sub {
893     '] [' . $x2t{'#inline'}->(shift, no_newline => 1);
894     },
895     replace => sub {
896     '__&&' . shift->get_attribute_value ('by', default => '') . '&&__';
897     },
898     bodytext => sub {
899     my ($source, %opt) = @_;
900     local $opt->{o}->{var}->{sw09__bq_depth}
901     = $opt->{o}->{var}->{sw09__bq_depth} + 1;
902     my @result;
903     for (@{$source->child_nodes}) {
904     if ($_->node_type eq '#element') {
905     my $ln = $_->local_name;
906     push @result, [($x2t{$ln} or $x2t{'#undef'})->($_),
907     $ln];
908     }
909     }
910     my $result = '';
911     my $prev = '';
912     for (@result) {
913     my $s = $_->[0];
914     if ($_->[1] eq 'p') {
915     $result .= "\x0A" if length $result and
916     substr ($result, -1) ne "\x0A";
917     $result .= ('>' x $opt->{o}->{var}->{sw09__bq_depth}) . ' ';
918     } elsif ($_->[1] eq 'form' or $_->[1] eq 'replace') {
919     $result .= "\x0A" if length $result and
920     substr ($result, -1) ne "\x0A";
921     $result .= ('>' x $opt->{o}->{var}->{sw09__bq_depth})."\x0A";
922     } elsif ($_->[1] eq 'blockquote' or $_->[1] eq 'text') {
923     $result .= "\x0A" if length $result and
924     substr ($result, -1) ne "\x0A";
925     } else {
926     unless ($prev eq 'text') {
927     $result .= "\x0A" if length $result and
928     substr ($result, -1) ne "\x0A";
929     }
930     $result .= ('>' x $opt->{o}->{var}->{sw09__bq_depth})."\x0A";
931     }
932     $result .= $s;
933     $prev = $_->[1];
934     }
935     $result;
936     },
937     '#block' => sub {
938     my ($source, %opt) = @_;
939     my @result;
940     for (@{$source->child_nodes}) {
941     if ($_->node_type eq '#element') {
942     my $ln = $_->local_name;
943     push @result, [($x2t{$ln} or $x2t{'#undef'})->($_),
944     $ln];
945     }
946     }
947     my $result = '';
948     my $prev = '';
949     for (@result) {
950     my $s = $_->[0];
951     if ($_->[1] eq 'form') {
952     $result .= "\x0A" if length $result and
953     substr ($result, -1) ne "\x0A";
954     $result .= "\x0A";
955     } elsif ($_->[1] eq 'replace') {
956     $result .= "\x0A" if length $result and
957     substr ($result, -1) ne "\x0A";
958     } elsif ($_->[1] eq 'text') {
959     $result .= "\x0A" if length $result and
960     substr ($result, -1) ne "\x0A";
961     $result .= "\x0A" if $prev eq 'p';
962     } else {
963     if ($prev ne 'text' and $prev ne 'replace') {
964     $result .= "\x0A" if length $result and
965     substr ($result, -1) ne "\x0A";
966     $result .= "\x0A";
967     }
968     }
969     $result .= $s;
970     $prev = $_->[1];
971     }
972     $result;
973     },
974     '#flow' => sub {
975     my ($source, %opt) = @_;
976     my @result;
977     for (@{$source->child_nodes}) {
978     if ($_->node_type eq '#element') {
979     my $ln = $_->local_name;
980     if ($is_block{$ln}) {
981     push @result, [($x2t{$ln} or $x2t{'#undef'})->($_),
982     $ln];
983     } else {
984     if (@result and ($result[$#result]->[1] eq '#inline')) {
985     $result[$#result]->[0]
986     .= ($x2t{$ln} or $x2t{'#undef'})->($_);
987     } else {
988     push @result, [($x2t{$ln} or $x2t{'#undef'})->($_),
989     '#inline'];
990     }
991     }
992     } elsif ($_->node_type eq '#text') {
993     if (@result and ($result[$#result]->[1] eq '#inline')) {
994     $result[$#result]->[0] .= $_->inner_text;
995     } else {
996     push @result, [$_->inner_text, '#inline'];
997     }
998     }
999     }
1000     my $result = '';
1001     my $prev = '';
1002     for (@result) {
1003     my $s = $_->[0];
1004     if ($_->[1] eq '#inline') {
1005     if ($prev ne 'text' and $prev ne 'form' and $prev ne 'replace') {
1006     $result .= "\x0A" if length $result and
1007     substr ($result, -1) ne "\x0A";
1008     }
1009     $s =~ s/\x0D\x0A/\x0A/g;
1010     $s =~ s/\x0D/\x0A/g;
1011     $s =~ s/\x0A\x0A+/\x0A/g;
1012     $s =~ s/\x0A/\x20/g if $opt{no_newline};
1013     } elsif ($_->[1] eq 'form' or $_->[1] eq 'replace') {
1014     if ($prev ne '#inline') {
1015     $result .= "\x0A" if length $result and
1016     substr ($result, -1) ne "\x0A";
1017     }
1018     } elsif ($_->[1] eq 'text') {
1019     $result .= "\x0A" if length $result and
1020     substr ($result, -1) ne "\x0A";
1021     } else {
1022     unless ($prev eq 'text') {
1023     $result .= "\x0A" if length $result and
1024     substr ($result, -1) ne "\x0A";
1025     }
1026     }
1027     $result .= $s;
1028     $prev = $_->[1];
1029     }
1030     $result;
1031     },
1032     '#inline' => sub {
1033     my ($source, %opt) = @_;
1034     my $result .= '';
1035     for (@{$source->child_nodes}) {
1036     if ($_->node_type eq '#text') {
1037     $result .= $_->inner_text;
1038     } elsif ($_->node_type eq '#element') {
1039     $result .= ($x2t{$_->local_name} or $x2t{'#undef'})->($_);
1040     }
1041     }
1042     $result =~ s/\x0D\x0A/\x0A/g;
1043     $result =~ s/\x0D/\x0A/g;
1044     $result =~ s/\x0A\x0A+/\x0A/g;
1045     $result =~ s/\x0A/\x20/g if $opt{no_newline};
1046     $result;
1047     },
1048     '#list' => sub {
1049     my ($source, %opt) = @_;
1050     my $result .= '';
1051     for (@{$source->child_nodes}) {
1052     if ($_->node_type eq '#element') {
1053     $result .= ($x2t{$_->local_name} or $x2t{'#undef'})->($_);
1054     }
1055     }
1056     $result;
1057     },
1058     '#undef' => sub {
1059     my $source = shift;
1060     ## TODO:
1061     "<".$source->namespace_uri.">:".$source->local_name
1062     . $x2t{'#inline'}->($source);
1063     },
1064     );
1065     for (qw/blockquote dl tbody table/) {
1066     $x2t{$_} = sub { $x2t{'#list'}->(shift) };
1067     }
1068     for (qw/p dd/) {
1069     $x2t{$_} = sub { $x2t{'#flow'}->(shift) };
1070     }
1071     for my $type (qw/ul ol/) {
1072     $x2t{$type} = sub {
1073     my $source = shift;
1074     local $opt->{o}->{var}->{sw09__list_type} = $type;
1075     local $opt->{o}->{var}->{sw09__list_depth}
1076     = $opt->{o}->{var}->{sw09__list_depth} + 1;
1077     my @result;
1078     for (@{$source->child_nodes}) {
1079     push @result, $x2t{$_->local_name}->($_)
1080     if $_->node_type eq '#element';
1081     }
1082     my $result = '';
1083     for (@result) {
1084     $result .= "\x0A" unless substr ($result, -1) eq "\x0A";
1085     $result .= $_;
1086     }
1087     substr ($result, 1);
1088     };
1089     }
1090     for my $type (qw/code samp var dfn kbd sub sup weak q ruby rubyb
1091     abbr ins del/) {
1092     $x2t{$type} = sub {
1093     my $source = shift;
1094     my $result = '['.uc $type;
1095     my $class = $source->get_attribute_value ('class', default => '');
1096     if ($class) {
1097     $class =~ s/([()\\])/\\$1/g;
1098     $result .= '(' . $class . ')';
1099     }
1100     $result .= '['
1101     . $x2t{'#inline'}->($source, no_newline => 1)
1102     . ']';
1103     my $anchor = $source->get_attribute_value
1104     ('anchor',
1105     namespace_uri => $NS_SW09,
1106     default => '');
1107     if (length $anchor) {
1108     $result .= '>>'.(0+$anchor);
1109     } else {
1110     $anchor = $source->get_attribute_value
1111     ('resScheme',
1112     namespace_uri => $NS_SW09);
1113     if ($anchor) {
1114     my $param = $source->get_attribute_value
1115     ('resParameter',
1116     namespace_uri => $NS_SW09);
1117     if ($anchor eq 'URI' and $param =~ /^[0-9A-Za-z_+.%-]+:/) {
1118     $result .= '<' . $param . '>';
1119     } else {
1120     $result .= '<' . $anchor . ':' . $param . '>';
1121     }
1122     }
1123     }
1124     $result .= ']';
1125     $result;
1126     };
1127     }
1128    
1129     $x2t{'#list'}->($src);
1130    
1131     Function:
1132     @Name: get_nth_element
1133     @Main:
1134     my (undef, $node, $ns => $ln, $n) = @_;
1135     return $n if $n < 1;
1136     if ($node->node_type eq '#element' and
1137     $node->namespace_uri eq $ns and
1138     $node->local_name eq $ln) {
1139     return $node unless --$n;
1140     }
1141     for (@{$node->child_nodes}) {
1142     if ($_->node_type eq '#element') {
1143     if ($_->namespace_uri eq $ns and
1144     $_->local_name eq $ln) {
1145     return $_ unless --$n;
1146     } else {
1147     $n = __FUNCPACK__->get_nth_element ($_, $ns => $ln, $n);
1148     return $n if ref $n;
1149     }
1150     } elsif ($_->node_type eq '#fragment' or $_->node_type eq '#document') {
1151     $n = __FUNCPACK__->get_nth_element ($_, $ns => $ln, $n);
1152     return $n if ref $n;
1153     }
1154     }
1155     return $n;
1156    
1157     Function:
1158     @Name: get_element_by_id
1159     @Main:
1160     my (undef, $node, $id) = @_;
1161     return $node if $node->node_type eq '#element'
1162     and $node->get_attribute_value ('id', default_value => '')
1163     eq $id;
1164     for (@{$node->child_nodes}) {
1165     if ({'#element'=>1, '#fragment'=>1, '#document'=>1}->{$_->node_type}) {
1166     my $r = __FUNCPACK__->get_element_by_id ($_, $id);
1167     return $r if $r;
1168     }
1169     }
1170 wakaba 1.1
1171     Function:
1172     @Name: text_to_xml
1173     @Description:
1174     @@@:
1175     Converting SuikaWiki/0.9 text format to XML representation
1176     @@lang: en
1177     @Main:
1178     my (undef, $source, $opt) = @_;
1179     $source =~ s/\x0D\x0A/\x0A/g;
1180     $source =~ tr/\x0D/\x0A/;
1181     $source .= "\x0A";
1182     my $root = $opt->{-parent}
1183     ->append_new_node (type => '#element',
1184     namespace_uri => $NS_SW09,
1185     local_name => 'document');
1186     my $head = $root->append_new_node (type => '#element',
1187     namespace_uri => $NS_XHTML2,
1188     local_name => 'head');
1189     if ($source =~ s#^\#\?SuikaWiki/0\.9\b((?>.*))\s*##) {
1190     my $param = $1;
1191     while ($param =~ /\G\s+([a-z-]+)="((?>[^"\\]*)(?>(?>[^"\\]+|\\.)*))"/g) {
1192     my ($name, $value) = ($1, $2);
1193     $value =~ s/\\(.)/$1/g;
1194     for ($head->append_new_node (type => '#element',
1195     namespace_uri => $NS_SW09,
1196 wakaba 1.4 local_name => 'parameter')) {
1197 wakaba 1.1 $_->set_attribute (name => $name);
1198     for my $value (split /,/, $value) {
1199     $_->append_new_node (type => '#element',
1200     namespace_uri => $NS_SW09,
1201     local_name => 'value')
1202     ->append_text ($value);
1203     }
1204     }
1205     $head->append_text ("\x0A");
1206     }
1207     } else {
1208     ## TODO: warn
1209     }
1210     $root->append_text ("\x0A");
1211    
1212     my $body = $root->append_new_node (type => '#element',
1213     namespace_uri => $NS_XHTML2,
1214     local_name => 'body');
1215 wakaba 1.4 __FUNCPACK__->block_text_to_xml (\$source => $body, opt => $opt);
1216 wakaba 1.1
1217     Function:
1218     @Name:block_text_to_xml
1219     @Description:
1220     @@@:
1221     SuikaWiki/0.9 text format to XML representation convertion - block
1222     level elements
1223     @@lang:en
1224     @Main:
1225     my (undef, $source, $current, %opt) = @_;
1226 wakaba 1.4 my %depth = %{$opt{depth} || {}};
1227 wakaba 1.1 my $back_to_section = sub {
1228     my $cur_type = $current->local_name;
1229     while (not (
1230     $cur_type eq 'section'
1231     or $cur_type eq 'body'
1232     or $cur_type eq 'bodytext'
1233 wakaba 1.4 or $cur_type eq 'insert'
1234     or $cur_type eq 'delete'
1235 wakaba 1.1 )
1236     ) {
1237     $current = $current->parent_node;
1238     $cur_type = $current->local_name;
1239     }
1240     delete $depth{list};
1241     };
1242     my $back_to_real_section = sub {
1243     my $cur_type = $current->local_name;
1244     while (not (
1245     $cur_type eq 'section'
1246     or $cur_type eq 'body'
1247 wakaba 1.4 or $cur_type eq 'insert'
1248     or $cur_type eq 'delete'
1249 wakaba 1.1 )
1250     ) {
1251     $current = $current->parent_node;
1252     $cur_type = $current->local_name;
1253     }
1254     delete $depth{bq};
1255     delete $depth{list};
1256     };
1257     while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
1258     my $line = $1;
1259     if ($line eq '') {
1260     $back_to_real_section->();
1261     } elsif ($line =~ s/^([-=]+)\s*//) {
1262     my $list_type = substr ($1, -1) eq '-' ? 'ul' : 'ol';
1263     my $depth = length $1;
1264     my $parent_type = $current->parent_node->local_name;
1265     ## Parent node is list element
1266     if ($parent_type eq 'ul' or $parent_type eq 'ol') {
1267     if ($depth{list} == $depth) {
1268     if ($parent_type eq $list_type) {
1269     $current = $current->parent_node;
1270     } else {
1271     $current = $current->parent_node
1272     ->parent_node
1273     ->append_new_node
1274     (type => '#element',
1275     namespace_uri => $NS_XHTML2,
1276     local_name => $list_type);
1277     }
1278     } elsif ($depth < $depth{list}) {
1279     for ($depth+1..$depth{list}) {
1280     $current = $current->parent_node->parent_node;
1281     }
1282     $current = $current->parent_node;
1283     if ($current->local_name ne $list_type) {
1284     $current = $current->parent_node
1285     ->append_new_node
1286     (type => '#element',
1287     namespace_uri => $NS_XHTML2,
1288     local_name => $list_type);
1289     }
1290     $depth{list} = $depth;
1291     } else { # $depth{list} < $depth
1292     $current = $current->append_new_node
1293     (type => '#element',
1294     namespace_uri => $NS_XHTML2,
1295     local_name => $list_type);
1296     $depth{list}++;
1297     }
1298     ## Parent node is non-list element
1299     } else {
1300     $current = $current->append_new_node (type => '#element',
1301     namespace_uri => $NS_XHTML2,
1302     local_name => $list_type);
1303     $depth{list} = 1;
1304     }
1305     $current->append_text ("\x0A".(" " x $depth{list}));
1306     $current = $current->append_new_node (type => '#element',
1307     namespace_uri => $NS_XHTML2,
1308     local_name => 'li');
1309 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $current, %opt);
1310 wakaba 1.1 } elsif ($line =~ s/^(\*+)\s*//) {
1311     my $depth = length $1;
1312     $back_to_real_section->();
1313     if ($depth <= $depth{section}) {
1314     for ($depth..$depth{section}) {
1315     $back_to_real_section->();
1316     $current = $current->parent_node;
1317     }
1318     $depth{section} = $depth;
1319     } else { # $depth{section} < $depth
1320     for ($depth{section}+2..$depth) {
1321     $current = $current->append_new_node
1322     (type => '#element',
1323     namespace_uri => $NS_XHTML2,
1324     local_name => 'section');
1325     }
1326     $depth{section} = $depth;
1327     }
1328     $current = $current->append_new_node
1329     (type => '#element',
1330     namespace_uri => $NS_XHTML2,
1331     local_name => 'section');
1332     __FUNCPACK__->inline_text_to_xml (\$line =>
1333     $current->append_new_node (type => '#element',
1334     namespace_uri => $NS_XHTML2,
1335 wakaba 1.4 local_name => 'h'), %opt,
1336 wakaba 1.1 );
1337     } elsif ($line =~ s/^(?!>>[0-9])(>+)\s*//) {
1338     my $depth = length $1;
1339     if ($depth <= $depth{bq}) {
1340     for ($depth+1..$depth{bq}) {
1341     $back_to_section->();
1342     $current = $current->parent_node->parent_node;
1343     }
1344     $back_to_section->();
1345     $current->append_text ("\x0A");
1346     $depth{bq} = $depth;
1347     } else { # $depth{bq} < $depth
1348     $back_to_section->();
1349     for ($depth{bq}+1..$depth) {
1350     $current = $current->append_new_node
1351     (type => '#element',
1352     namespace_uri => $NS_XHTML2,
1353     local_name => 'blockquote')
1354     ->append_new_node
1355     (type => '#element',
1356     namespace_uri => $NS_HTML3,
1357     local_name => 'bodytext');
1358     $current->append_text ("\x0A");
1359     }
1360     $depth{bq} = $depth;
1361     }
1362     if (length $line) {
1363     $current = $current->append_new_node
1364     (type => '#element',
1365     namespace_uri => $NS_XHTML2,
1366     local_name => 'p');
1367 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $current, %opt);
1368 wakaba 1.1 }
1369     } elsif ($line =~ s/^(?>:\s*)([^:]+?)\s*:\s*//) {
1370     my $parent_type = $current->local_name;
1371     if ($parent_type eq 'dd') {
1372     $current = $current->parent_node->parent_node;
1373     $current->append_text ("\x0A");
1374     } else { #if ($parent_type ne 'dl') {
1375     $current = $current->append_new_node (type => '#element',
1376     namespace_uri => $NS_XHTML2,
1377     local_name => 'dl');
1378     }
1379     $current = $current->append_new_node
1380     (type => '#element',
1381     namespace_uri => $NS_SW09,
1382     local_name => 'dr');
1383     __FUNCPACK__->inline_text_to_xml (\"$1" =>
1384     $current->append_new_node (type => '#element',
1385     namespace_uri => $NS_XHTML2,
1386 wakaba 1.4 local_name => 'dt'), %opt,
1387 wakaba 1.1 );
1388     $current->append_text ("\x0A");
1389     $current = $current->append_new_node (type => '#element',
1390     namespace_uri => $NS_XHTML2,
1391     local_name => 'dd');
1392 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $current, %opt);
1393 wakaba 1.1 } elsif ($line =~ /^\[(INS|DEL)(\([^()\\]*\))?\[\s*$/) {
1394     $current->append_text ("\x0A");
1395 wakaba 1.4 my $mod = $current->append_new_node
1396     (type => '#element',
1397     namespace_uri => $NS_SW09,
1398     local_name => {qw/INS insert DEL delete/}->{$1});
1399 wakaba 1.1 $mod->set_attribute (class => $2) if $2;
1400 wakaba 1.4 __FUNCPACK__->block_text_to_xml ($source => $mod, %opt,
1401     'return_by_'.$1 => 1,
1402     depth => \%depth);
1403 wakaba 1.1 } elsif ($line =~ /^\](INS|DEL)\]\s*$/) {
1404     if ($opt{'return_by_'.$1}) {
1405     return;
1406     } else {
1407     ## TODO: warn
1408     }
1409     } elsif ($line =~ /^\[PRE(\([^()\\]*\))?\[\s*$/) {
1410     $current->append_text ("\x0A");
1411     my $pre = $current->append_new_node (type => '#element',
1412     namespace_uri => $NS_XHTML1,
1413     local_name => 'pre');
1414     $pre->set_attribute (class => $1) if $1;
1415     $pre->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI);
1416     my $f = 1;
1417     while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
1418     my $line = $1;
1419     if ($line =~ /^\]PRE\]\s*$/) {
1420     undef $pre;
1421     last;
1422     } else {
1423     $f ? undef $f : $pre->append_text ("\x0A");
1424 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $pre, %opt);
1425 wakaba 1.1 }
1426     }
1427     if (ref $pre) {
1428     # warn unmatched start-tag
1429     }
1430     } elsif ($line =~ /^\s/) {
1431     $current->append_text ("\x0A");
1432     my $pre = $current->append_new_node (type => '#element',
1433     namespace_uri => $NS_XHTML1,
1434     local_name => 'pre');
1435     $pre->set_attribute (space => 'preserve', namespace_uri => NS_xml_URI);
1436 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $pre, %opt);
1437 wakaba 1.1 while ($$source =~ /\G([^\x0A]*)\x0A/gc) {
1438     my $line = $1;
1439     if (length $line == 0) {
1440     pos ($$source) -= 1;
1441     last;
1442 wakaba 1.4 } elsif ($opt{return_by_INS} and $line =~ /^\]INS\]\s*$/) {
1443     return;
1444     } elsif ($opt{return_by_DEL} and $line =~ /^\]DEL\]\s*$/) {
1445     return;
1446 wakaba 1.1 } else {
1447     $pre->append_text ("\x0A");
1448 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$line => $pre, %opt);
1449 wakaba 1.1 }
1450     }
1451     } elsif ($line =~ /^,/) {
1452     $current->append_text ("\x0A");
1453     my $tbody = $current->append_new_node (type => '#element',
1454     namespace_uri => $NS_XHTML2,
1455     local_name => 'table')
1456     ->append_new_node (type => '#element',
1457     namespace_uri => $NS_XHTML2,
1458     local_name => 'tbody');
1459 wakaba 1.4 __FUNCPACK__->tablerow_text_to_xml (\$line => $tbody, %opt);
1460 wakaba 1.1 while ($$source =~ /\G(,[^\x0A]*)\x0A/gc) {
1461 wakaba 1.4 __FUNCPACK__->tablerow_text_to_xml (\"$1" => $tbody, %opt);
1462 wakaba 1.1 }
1463     } else {
1464     my $current_type = $current->local_name;
1465     if ($current_type eq 'section'
1466     or $current_type eq 'body'
1467     or $current_type eq 'bodytext'
1468 wakaba 1.4 or $current_type eq 'insert'
1469     or $current_type eq 'delete') {
1470 wakaba 1.1 $current->append_text ("\x0A");
1471     if ($line =~ s/^__&&([^&]+)&&__//) {
1472     $current->append_new_node (type => '#element',
1473     namespace_uri => $NS_SW09,
1474     local_name => 'replace')
1475     ->set_attribute (by => $1);
1476     } elsif ($line =~ s/^\[\[$Reg_Form_Content_M\]\]//o) {
1477     for ($current->append_new_node (type => '#element',
1478     namespace_uri => $NS_SW09,
1479     local_name => 'form')) {
1480     $_->set_attribute (id => $1) if $1;
1481     my ($i, $t, $o) = ($2, $3 || '', $4 || '');
1482 wakaba 1.4 s/\\(.)/$1/g for ($i, $t, $o);
1483 wakaba 1.1 $_->set_attribute (input => $i);
1484     $_->set_attribute (template => $t);
1485     $_->set_attribute (option => $o);
1486     }
1487     } elsif ($line =~ s/^\[\[$Reg_Embed_Content_M\]\]//o) {
1488     for ($current->append_new_node (type => '#element',
1489     namespace_uri => $NS_SW09,
1490     local_name => 'form')) {
1491     $_->set_attribute (ref => $1);
1492     $_->set_attribute (id => $2) if $2;
1493     $_->set_attribute (parameter => $3) if defined $3;
1494     }
1495     }
1496 wakaba 1.4 if (length $line) {
1497     $current = $current->append_new_node
1498     (type => '#element',
1499     namespace_uri => $NS_XHTML2,
1500     local_name => 'p');
1501     __FUNCPACK__->inline_text_to_xml (\$line => $current, %opt);
1502     }
1503 wakaba 1.1 } else {
1504 wakaba 1.4 $current->append_text ("\x0A"); # replacement of prev.line's \n
1505     __FUNCPACK__->inline_text_to_xml (\$line => $current, %opt);
1506 wakaba 1.1 }
1507     }
1508     }
1509    
1510     if ($opt{return_by_INS} or $opt{return_by_DEL}) {
1511     # warn
1512     }
1513    
1514     Function:
1515     @Name: tablerow_text_to_xml
1516     @Description:
1517     @@@:
1518     SuikaWiki/0.9 text format to XML representation - table row
1519     @@lang:en
1520     @Main:
1521     my (undef, $source => $current, %opt) = @_;
1522     $current->append_text ("\x0A");
1523     $current = $current->append_new_node (type => '#element',
1524     namespace_uri => $NS_XHTML2,
1525     local_name => 'tr');
1526     my $prev_cell;
1527     while ($$source =~ /\G,\s*/gc) {
1528 wakaba 1.4 $$source =~ /\G([^,"][^,]*|"(?>[^"\\]*)(?>(?>[^"\\]+|\\.)*)"\s*)/gc;
1529 wakaba 1.1 my $cell = $1;
1530     if ($cell =~ s/^"//) {
1531     $cell =~ s/"\s*$//g;
1532     $cell =~ s/\\(.)/$1/g;
1533     } else {
1534     $cell =~ s/\s+$//g;
1535     if ($cell eq '==') {
1536     if (ref $prev_cell) {
1537     $prev_cell->set_attribute (colspan =>
1538     $prev_cell->get_attribute_value ('colspan', default => 1)
1539     + 1);
1540     next;
1541     } else {
1542     # TODO: warn
1543     }
1544     }
1545     }
1546     $prev_cell = $current->append_new_node
1547     (type => '#element',
1548     namespace_uri => $NS_XHTML2,
1549     local_name => 'td');
1550 wakaba 1.4 __FUNCPACK__->inline_text_to_xml (\$cell => $prev_cell, %opt);
1551 wakaba 1.1 }
1552     # TODO: warn
1553    
1554     Function:
1555     @Name: inline_text_to_xml
1556     @Description:
1557     @@@:
1558     SuikaWiki/0.9 text format to XML representation - inline level elements
1559     @@lang:en
1560     @Main:
1561     my $ElementDef = {
1562 wakaba 1.5 ABBR => {ln => 'abbr', ns_uri => $NS_XHTML2},
1563 wakaba 1.1 CODE => {ln => 'code', ns_uri => $NS_XHTML2},
1564     DEL => {ln => 'del', ns_uri => $NS_XHTML1},
1565     DFN => {ln => 'dfn', ns_uri => $NS_XHTML2},
1566     INS => {ln => 'ins', ns_uri => $NS_XHTML1},
1567     KBD => {ln => 'kbd', ns_uri => $NS_XHTML2},
1568     Q => {ln => 'q', ns_uri => $NS_XHTML1},
1569     RUBY => {ln => 'ruby', ns_uri => $NS_XHTML2},
1570     RUBYB => {ln => 'rubyb', ns_uri => $NS_SW09},
1571     SAMP => {ln => 'samp', ns_uri => $NS_XHTML2},
1572     SUB => {ln => 'sub', ns_uri => $NS_XHTML2},
1573     SUP => {ln => 'sup', ns_uri => $NS_XHTML2},
1574     VAR => {ln => 'var', ns_uri => $NS_XHTML2},
1575     WEAK => {ln => 'weak', ns_uri => $NS_SW09},
1576     anchor => {ln => 'anchor', ns_uri => $NS_SW09, has_fragment_no => 1},
1577     del => {has_cite => 1},
1578     ins => {has_cite => 1},
1579     q => {has_cite => 1},
1580     rb => {ln => 'rb', ns_uri => $NS_XHTML2, is_nested => 1},
1581     rt => {ln => 'rt', ns_uri => $NS_XHTML2, is_nested => 1},
1582     };
1583    
1584     my (undef, $source => $current, %opt) = @_;
1585     if ($$source =~ /\G\[([0-9]+)\]/gc) {
1586     for ($current->append_new_node (type => '#element',
1587     namespace_uri => $NS_SW09,
1588     local_name => 'anchor-end')) {
1589 wakaba 1.4 $_->set_attribute (anchor => 0+$1,
1590     namespace_uri => $NS_SW09);
1591 wakaba 1.1 $_->append_text ('['.$1.']');
1592     }
1593     }
1594     my $depth = 0;
1595     while (pos $$source < length $$source) {
1596     if ($$source =~ /\G\[\[(?=\#)/gc) {
1597     my $form = $current->append_new_node (type => '#element',
1598     namespace_uri => $NS_SW09,
1599     local_name => 'form');
1600     if ($$source =~ /\G$Reg_Form_Content_M\]\]/ogc) {
1601     $form->set_attribute (id => $1) if $1;
1602 wakaba 1.4 my ($i, $t, $o) = ($2, $3, $4);
1603     s/\\(.)/$1/g for ($i, $t, $o);
1604     $form->set_attribute (input => $i);
1605     $form->set_attribute (template => $t);
1606     $form->set_attribute (option => $o);
1607 wakaba 1.1 } elsif ($$source =~ /\G$Reg_Embed_Content_M\]\]/ogc) {
1608     $form->set_attribute (ref => $1);
1609     $form->set_attribute (id => $2) if $2;
1610     $form->set_attribute (parameter => $3) if defined $3;
1611     } else {
1612     ## TODO: error
1613 wakaba 1.4 SuikaWiki::Plugin->module_package('Error')->report_error_simple ($opt{opt}->{o}->{wiki}, InvalidForm => substr ($$source, pos ($$source)));
1614 wakaba 1.1 }
1615     } elsif ($$source =~ /\G\[(?>([A-Z]+)(?>\(([^)]*)\))?)?\[/gc) {
1616     my $type = $1 || 'anchor';
1617     my $param = $2;
1618     my $def = $ElementDef->{ $type };
1619     unless ($def) {
1620     ## TODO: error
1621 wakaba 1.4 $def = $ElementDef->{CODE};
1622 wakaba 1.1 }
1623     $current = $current->append_new_node (type => '#element',
1624     namespace_uri => $def->{ns_uri},
1625     local_name => $def->{ln});
1626     $current->set_attribute (class => $param) if $param;
1627     if ($type eq 'RUBY' or $type eq 'RUBYB'
1628     or $type eq 'ABBR') {
1629     $current = $current->append_new_node
1630     (type => '#element',
1631     namespace_uri => $ElementDef->{rb}->{ns_uri},
1632     local_name => $ElementDef->{rb}->{ln});
1633     }
1634     $depth++;
1635     } elsif ($$source =~ /\G\](?> <([0-9A-Za-z_+.%-]+):($Reg_URI_Opaque)>
1636     \ | >>([0-9]+) )?
1637     \ \]/gcox) {
1638     my ($scheme, $opaque, $anchor) = ($1, $2, $3);
1639     unless ($depth) {
1640     $current->append_text (substr ($$source, $-[0], $+[0]-$-[0]));
1641     next;
1642     }
1643     my $def = $ElementDef->{$current->local_name} || {};
1644     if (defined $anchor) {
1645 wakaba 1.4 $current->set_attribute (anchor => $anchor + 0,
1646     namespace_uri => $NS_SW09);
1647     } elsif (defined $scheme) {
1648     if ($scheme =~ /[A-Z]/) {
1649     $current->set_attribute (resScheme => $scheme,
1650     namespace_uri => $NS_SW09);
1651     $current->set_attribute (resParameter => $opaque,
1652     namespace_uri => $NS_SW09);
1653 wakaba 1.1 } else {
1654 wakaba 1.4 $current->set_attribute (resScheme => 'URI',
1655 wakaba 1.1 namespace_uri => $NS_SW09);
1656 wakaba 1.4 $current->set_attribute (resParameter => "$scheme:$opaque",
1657 wakaba 1.1 namespace_uri => $NS_SW09);
1658     }
1659     }
1660     $current = $current->parent_node;
1661     $current = $current->parent_node if $def->{is_nested};
1662     $depth--;
1663 wakaba 1.4 } elsif ($$source =~ /\G\]\s*\[/gc) {
1664 wakaba 1.1 if ($current->local_name eq 'rb' or $current->local_name eq 'rt') {
1665     $current = $current->parent_node
1666     ->append_new_node
1667     (type => '#element',
1668     namespace_uri => $ElementDef->{rt}->{ns_uri},
1669     local_name => $ElementDef->{rt}->{ln});
1670     } else {
1671 wakaba 1.4 $current->append_text (substr ($$source, $-[0], $+[0]-$-[0]));
1672 wakaba 1.1 }
1673     } elsif ($$source =~ /\G'''?/gc) {
1674     my $type = $+[0] - $-[0] == 3 ? 'strong' : 'em';
1675     if ($current->local_name eq $type) {
1676     $current = $current->parent_node;
1677     } else {
1678     $current = $current->append_new_node
1679     (type => '#element',
1680     namespace_uri => $NS_XHTML2,
1681     local_name => $type);
1682     }
1683     } elsif ($$source =~ /\G<([0-9A-Za-z_+.%-]+):($Reg_URI_Opaque)>/gc) {
1684     my ($scheme, $data) = ($1, $2);
1685     my $link = $current->append_new_node
1686     (type => '#element',
1687     namespace_uri => $NS_SW09,
1688 wakaba 1.2 local_name => 'anchor-external');
1689 wakaba 1.1 if (substr ($scheme, 0, 1) =~ /[A-Z]/) {
1690 wakaba 1.4 $link->set_attribute (resScheme => $scheme,
1691     namespace_uri => $NS_SW09);
1692     $link->set_attribute (resParameter => $data,
1693     namespace_uri => $NS_SW09);
1694 wakaba 1.1 } else { # URI Reference
1695 wakaba 1.4 $link->set_attribute (resScheme => 'URI',
1696     namespace_uri => $NS_SW09);
1697     $link->set_attribute (resParameter => $scheme.':'.$data,
1698     namespace_uri => $NS_SW09);
1699 wakaba 1.1 }
1700 wakaba 1.3 $link->append_text ($scheme.':'.$data);
1701 wakaba 1.1 } elsif ($$source =~ /\G__&&/gc) {
1702     if ($$source =~ /\G([^&]+)&&__/gc) {
1703     $current->append_new_node
1704     (type => '#element',
1705     namespace_uri => $NS_SW09,
1706 wakaba 1.2 local_name => 'replace')
1707 wakaba 1.1 ->set_attribute (by => $1);
1708     } else {
1709 wakaba 1.2 $current->append_text ('__&&');
1710 wakaba 1.1 }
1711     } elsif ($$source =~ /\G((?>
1712 wakaba 1.4 [^'\[\]<>_]+
1713 wakaba 1.1 | ' (?!')
1714 wakaba 1.4 | \[ (?!\[|[A-Z]+(?>\([^()\\]*
1715     (?>[^()\\]+|\\.)*\))?\[)
1716 wakaba 1.1 | \] (?! \]
1717     | >>[0-9]+\]
1718     | <[0-9A-Za-z_+.%-]+:$Reg_URI_Opaque>\]
1719     | \s*\[ )
1720     | < (?![0-9A-Za-z_+.%-]+:$Reg_URI_Opaque>)
1721     | > (?!>[0-9])
1722     | _ (?!_&&)
1723     )+)/oxgc) {
1724     $current->append_text ($1);
1725     } elsif ($$source =~ /\G>>([0-9]+)/gc) {
1726     for ($current->append_new_node (type => '#element',
1727     namespace_uri => $NS_SW09,
1728 wakaba 1.2 local_name => 'anchor-internal')) {
1729 wakaba 1.4 $_->set_attribute (anchor => 0+$1,
1730     namespace_uri => $NS_SW09);
1731 wakaba 1.1 $_->append_text ('>>'.$1);
1732     }
1733     } else {
1734 wakaba 1.4 CORE::die "Implementation buggy: ", substr ($$source, pos $$source);
1735 wakaba 1.1 }
1736     }
1737    
1738 wakaba 1.2 FormattingRule:
1739 wakaba 1.3 @Category[list]:
1740     page-link
1741     link-to-resource
1742 wakaba 1.2 @Name: sw09--link-anchor-content
1743     @Description:
1744     @@@:
1745     Output content of the anchor element
1746     @@lang:en
1747     @Formatting:
1748     if ($o->{var}->{sw09__anchor_content}) {
1749     $o->{var}->{sw09__anchor_content}->($p->{-parent});
1750     } else {
1751 wakaba 1.4 SuikaWiki::Plugin->module_package ('WikiResource')
1752     ->append_tree
1753     (name => 'Link:SuikaWiki/0.9:link-anchor-content:InvalidContext',
1754     param => $o,
1755     -parent => $p->{-parent},
1756     wiki => $o->{wiki});
1757 wakaba 1.2 }
1758    
1759     Resource:
1760     @Link:SuikaWiki/0.9:link-anchor-content:InvalidContext:
1761 wakaba 1.4 @@@: %percent;sw09--link-anchor-content; cannot be used in this context.
1762 wakaba 1.2 @@lang:en
1763 wakaba 1.3 @Link:SuikaWiki/0.9:toResource:SourceLabel:
1764     @@@:
1765     %select_link_resource_scheme (
1766     URI => {<%link-to-it(
1767     label=>{%link-resource-parameters;}p,
1768     );>},
1769     MAIL => {<%link-to-it(
1770     label => {%link-resource-parameters;}p,
1771     description
1772     => {%res (name=>{Link:MailAddress=});<%link-resource-parameters;>}p,
1773     );>},
1774     otherwise => {<%link-to-it(
1775     label => {%sw09--link-anchor-content;}p,
1776     description => {%res (name=>{Link:URIReference=});<%uri-reference;>}p,
1777     );>},
1778     );
1779     @@lang:en
1780 wakaba 1.2 @Link:SuikaWiki/0.9:toWikiPage:SourceLabel:
1781     @@@:
1782     %link-to-it(
1783     label=>{%sw09--link-anchor-content;%if-linked-wikipage-exist(
1784     true=>{%if-link-has-dest-anchor-no(true=>{>>%link-dest-anchor-no;});},
1785     false=>{%res(name=>{Link:toWikiPage:NotExist:Mark});}
1786     );}p,
1787     description=>{%page-name(absolute);; %if-linked-wikipage-exist(
1788     true=>{%page-headline;},
1789     false=>{(%res(name=>{Link:toWikiPage:NotExist:Description});)},
1790     );}p,
1791     class=>{%if-linked-wikipage-exist(false=>{not-exist});}p,
1792     );
1793 wakaba 1.5 @SuikaWiki/0.9:form:comment:input:
1794     %line (content => {%textarea (id=>msg,size=>20,lines=>3);}p);
1795     %line (content => {
1796     (%text (description => {%res (name => {Form:Description:HumanName});}p,
1797     id => name, size => 6);
1798     [%text (description =>
1799     {%res (name => {Form:Description:MailAddress});}p,
1800     id => mail, size => 5);]
1801     %check (default, id => record-date,
1802     label => {%res (name => {Form:Label:LogDate});}p,
1803     description => {%res (name => {Form:Description:LogDate});}p);)
1804     %submit (label => {%res (name => {Form:Label:Add});}p,
1805     description => {%res (name => {Form:Description:Add});}p);
1806     %we--update-lastmodified-datetime;
1807     }p);
1808     @SuikaWiki/0.9:form:comment:template:
1809     %n
1810     ;[%index;]%n
1811     ;%text(source=>msg);%n;(%name;%text(source=>mail,prefix=>" [",suffix=>"]");%iif(source=>record-date,true=>" [WEAK[%date;]]");)%n;
1812     @SuikaWiki/0.9:form:comment:option:
1813     %require (msg);
1814     @SuikaWiki/0.9:form:footannotate:input:
1815     %line (content => {%textarea (id=>msg,size=>20,lines=>3);}p);
1816     %line (content => {
1817     (%text (description => {%res (name => {Form:Description:HumanName});}p,
1818     id => name, size => 6);
1819     [%text (description =>
1820     {%res (name => {Form:Description:MailAddress});}p,
1821     id => mail, size => 5);]
1822     %check (default, id => record-date,
1823     label => {%res (name => {Form:Label:LogDate});}p,
1824     description => {%res (name => {Form:Description:LogDate});}p);)
1825     %submit (label => {%res (name => {Form:Label:Add});}p,
1826     description => {%res (name => {Form:Description:Add});}p);
1827     %we--update-lastmodified-datetime;
1828     }p);
1829     @SuikaWiki/0.9:form:footannotate:template:
1830     %n
1831     ;[%index;]%n
1832     ;%text(source=>msg);%n
1833     ;(%name;%text(source=>mail,prefix=>" [",suffix=>"]");%iif(source=>record-date,true=>" [WEAK[%date;]]");)%n;
1834     @SuikaWiki/0.9:form:footannotate:option:
1835     %require (msg);
1836 wakaba 1.3
1837 wakaba 1.4 Error:
1838     @Name: text_parse
1839     @Definition:
1840     @@INLINE_NO_CLOSE_TAG:
1841     @@@description:
1842     Close tag of element "%t (name => element_type);" not found.
1843     @@@level: non-fatal
1844     @@BLOCK_NO_CLOSE_TAG:
1845     @@@description:
1846     Close tag of element "%t (name => element_type);" not found.
1847     @@@level: non-fatal
1848     @@INVALID_FORM:
1849     @@@description:
1850     Invalid syntax of WikiForm
1851     @@@level: non-fatal
1852    
1853     Error:
1854     @Name: xml_to_text
1855     @IsA[list]:
1856     ::SuikaWiki::Format::
1857     @Definition:
1858     @@

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24