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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24