/[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.6 - (hide annotations) (download)
Sun Feb 8 08:49:05 2004 UTC (20 years, 8 months ago) by wakaba
Branch: MAIN
Changes since 1.5: +539 -497 lines
SuikaWiki 3 WikiName & SuikaWikiImage/0.9 support

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24