/[suikacvs]/markup/html/whatpm/Whatpm/SWML/Parser.pm
Suika

Diff of /markup/html/whatpm/Whatpm/SWML/Parser.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by wakaba, Thu Nov 6 06:57:00 2008 UTC revision 1.7 by wakaba, Sat Nov 8 09:27:10 2008 UTC
# Line 1  Line 1 
1  package Whatpm::SWML::Parser;  package Whatpm::SWML::Parser;
2  use strict;  use strict;
3    
4    sub AA_NS () { q<http://pc5.2ch.net/test/read.cgi/hp/1096723178/aavocab#> }
5    sub HTML_NS () { q<http://www.w3.org/1999/xhtml> }
6    sub SW09_NS () { q<urn:x-suika-fam-cx:markup:suikawiki:0:9:> }
7    sub SW10_NS () { q<urn:x-suika-fam-cx:markup:suikawiki:0:10:> }
8    sub XML_NS () { q<http://www.w3.org/XML/1998/namespace> }
9    
10    sub IN_SECTION_IM () { 0 }
11    sub IN_TABLE_ROW_IM () { 1 }
12    sub IN_PARAGRAPH_IM () { 2 }
13    
14    sub BLOCK_START_TAG_TOKEN () { 1 }
15    sub BLOCK_END_TAG_TOKEN () { 2 }
16    sub CHARACTER_TOKEN () { 3 }
17    sub COMMENT_PARAGRAPH_START_TOKEN () { 4 }
18    sub EDITORIAL_NOTE_START_TOKEN () { 5 }
19    sub ELEMENT_TOKEN () { 6 }
20    sub EMPHASIS_TOKEN () { 7 }
21    sub EMPTY_LINE_TOKEN () { 8 }
22    sub END_OF_FILE_TOKEN () { 9 }
23    sub FORM_TOKEN () { 10 }
24    sub HEADING_START_TOKEN () { 11 }
25    sub HEADING_END_TOKEN () { 12 }
26    sub INLINE_START_TAG_TOKEN () { 13 }
27    sub INLINE_MIDDLE_TAG_TOKEN () { 14 }
28    sub INLINE_END_TAG_TOKEN () { 15 }
29    sub LABELED_LIST_START_TOKEN () { 16 }
30    sub LABELED_LIST_MIDDLE_TOKEN () { 17 }
31    sub LIST_START_TOKEN () { 18 }
32    sub PREFORMATTED_START_TOKEN () { 19 }
33    sub PREFORMATTED_END_TOKEN () { 20 }
34    sub QUOTATION_START_TOKEN () { 21 }
35    sub STRONG_TOKEN () { 22 }
36    sub TABLE_ROW_START_TOKEN () { 23 }
37    sub TABLE_ROW_END_TOKEN () { 24 }
38    sub TABLE_CELL_START_TOKEN () { 25 }
39    sub TABLE_CELL_END_TOKEN () { 26 }
40    sub TABLE_COLSPAN_CELL_TOKEN () { 27 }
41    
42  sub new ($) {  sub new ($) {
43    my $self = bless {    my $self = bless {
# Line 13  sub parse_char_string ($$$;$) { Line 50  sub parse_char_string ($$$;$) {
50    my @s = split /\x0D\x0A?|\x0A/, ref $_[0] ? ${$_[0]} : $_[0], -1;    my @s = split /\x0D\x0A?|\x0A/, ref $_[0] ? ${$_[0]} : $_[0], -1;
51    
52    my $doc = $_[1];    my $doc = $_[1];
53    $doc->inner_html    @{$doc->child_nodes} = ();
54        ('<html xmlns="http://www.w3.org/1999/xhtml"><head/><body/></html>');    my $html_el = $doc->create_element_ns (HTML_NS, [undef, 'html']);
55    for ($doc,    $doc->append_child ($html_el);
56         $doc->document_element,    $html_el->set_attribute_ns
57         $doc->document_element->first_child,        ('http://www.w3.org/2000/xmlns/', [undef, 'xmlns'] => HTML_NS);
58         $doc->document_element->last_child) {    my $head_el = $doc->create_element_ns (HTML_NS, [undef, 'head']);
59      $html_el->append_child ($head_el);
60      my $body_el = $doc->create_element_ns (HTML_NS, [undef, 'body']);
61      $html_el->append_child ($body_el);
62      for ($doc, $html_el, $head_el, $body_el) {
63      $_->set_user_data (manakai_source_line => 1);      $_->set_user_data (manakai_source_line => 1);
64      $_->set_user_data (manakai_source_column => 1);      $_->set_user_data (manakai_source_column => 1);
65    }    }
   $self->{oe} = {node => $doc->document_element->last_child,  
                  section_depth => 0,  
                  quotation_depth => 0,  
                  list_depth => 0};  
66        
67    my $_onerror = $_[2] || sub {    my $_onerror = $_[2] || sub {
68      my %opt = @_;      my %opt = @_;
# Line 55  sub parse_char_string ($$$;$) { Line 92  sub parse_char_string ($$$;$) {
92    my $tokenize_text = sub {    my $tokenize_text = sub {
93      my $s = shift; # ref      my $s = shift; # ref
94    
95        my $nest_level = 0;
96    
97      if ($$s =~ s/^\[([0-9]+)\]//) {      if ($$s =~ s/^\[([0-9]+)\]//) {
98        push @nt, {type => ELEMENT_TOKEN,        push @nt, {type => ELEMENT_TOKEN,
99                   local_name => 'anchor-end', namespace => $SW09_NS,                   local_name => 'anchor-end', namespace => SW09_NS,
100                   anchor => $1, content => '[' . $1 . ']'};                   anchor => $1, content => '[' . $1 . ']'};
101        $column += $+[0] - $-[0];        $column += $+[0] - $-[0];
102      }      }
103            
104      while (length $$s) {      while (length $$s) {
105        if ($$s =~ s/^\[\[#([a-z-}+)//) {        if ($$s =~ s/^\[\[#([a-z-]+)//) {
106          $column = $+[0] - $-[0];          $column = $+[0] - $-[0];
107          my $t = {type => FORM_TOKEN, name => $1,          my $t = {type => FORM_TOKEN, name => $1,
108                   line => $line, column => $column};                   line => $line, column => $column};
# Line 72  sub parse_char_string ($$$;$) { Line 111  sub parse_char_string ($$$;$) {
111            $column += $+[0] - $-[0];            $column += $+[0] - $-[0];
112          }          }
113          my @param;          my @param;
114          while ($$s =~ s/^:/) {          while ($$s =~ s/^://) {
115            if ($$s =~ s/^'((?>[^'\\]|\\.)*)//) {            if ($$s =~ s/^'((?>[^'\\]|\\.)*)//) {
116              $column += 1 + $+[0] - $-[0];              $column += 1 + $+[0] - $-[0];
117              my $n = $1;              my $n = $1;
# Line 80  sub parse_char_string ($$$;$) { Line 119  sub parse_char_string ($$$;$) {
119              push @param, $n;              push @param, $n;
120              $column++ if $$s =~ s/\A\\\z//;              $column++ if $$s =~ s/\A\\\z//;
121              $column++ if $$s =~ s/^'//;              $column++ if $$s =~ s/^'//;
122            } elsif ($$s =~ s/^([^':][^:]*)//) {            } elsif ($$s =~ s/^([^':\]][^:\]]*)//) {
123              $column += 1 + $+[0] - $-[0];              $column += 1 + $+[0] - $-[0];
124              push @param, $1;              push @param, $1;
125            }            }
# Line 91  sub parse_char_string ($$$;$) { Line 130  sub parse_char_string ($$$;$) {
130        } elsif ($$s =~ s/^\[\[//) {        } elsif ($$s =~ s/^\[\[//) {
131          push @nt, {type => INLINE_START_TAG_TOKEN};          push @nt, {type => INLINE_START_TAG_TOKEN};
132          $column += 2;          $column += 2;
133        } elsif ($$s =~ s/^\[([A-Z]+)(?>\(([^()\\]*)\))?(?>\@[0-9A-Za-z-]*)?\[//) {          $nest_level++;
134          } elsif ($$s =~ s/^\[([A-Z]+)(?>\(([^()\\]*)\))?(?>\@([0-9A-Za-z-]*))?\[//) {
135          push @nt, {type => INLINE_START_TAG_TOKEN,          push @nt, {type => INLINE_START_TAG_TOKEN,
136                     tag_name => $1, classes => $2, language => $3,                     tag_name => $1, classes => $2, language => $3,
137                     line => $line, column => $column};                     line => $line, column => $column};
138          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
139            $nest_level++;
140        } elsif ($$s =~ s/^\]\]//) {        } elsif ($$s =~ s/^\]\]//) {
141          push @nt, {type => INLINE_END_TAG_TOKEN,          push @nt, {type => INLINE_END_TAG_TOKEN,
142                     line => $line, column => $column};                     line => $line, column => $column};
143          $column += 2;          $column += 2;
144            $nest_level-- if $nest_level > 0;
145        } elsif ($$s =~ s/^(\]?)<([0-9A-Za-z%+._-]+)://) {        } elsif ($$s =~ s/^(\]?)<([0-9A-Za-z%+._-]+)://) {
146          my $t = {type => $1 ? INLINE_END_TAG_TOKEN : ELEMENT_TOKEN,          my $t = {type => $1 ? INLINE_END_TAG_TOKEN : ELEMENT_TOKEN,
147                   res_scheme => $2, res_parameter => '',                   res_scheme => $2, res_parameter => '',
# Line 114  sub parse_char_string ($$$;$) { Line 156  sub parse_char_string ($$$;$) {
156              $t->{res_parameter} .= $1;              $t->{res_parameter} .= $1;
157              $column += $+[0] - $-[0];              $column += $+[0] - $-[0];
158              $column++ if $$s =~ s/\A\\\z//;              $column++ if $$s =~ s/\A\\\z//;
159              $column++ if $$s =~ s/^"//;              $t->{res_parameter} .= '"' and $column++ if $$s =~ s/^"//;
160            } else {            } else {
161              last;              last;
162            }            }
# Line 130  sub parse_char_string ($$$;$) { Line 172  sub parse_char_string ($$$;$) {
172                    
173          if ($t->{type} == INLINE_END_TAG_TOKEN) {          if ($t->{type} == INLINE_END_TAG_TOKEN) {
174            $column++ if $$s =~ s/^\]//;            $column++ if $$s =~ s/^\]//;
175              $nest_level-- if $nest_level > 0;
176          } else {          } else {
177            $t->{local_name} = 'anchor-external';            $t->{local_name} = 'anchor-external';
178            $t->{namespace} = $SW09_NS;            $t->{namespace} = SW09_NS;
179          }          }
180          push @nt, $t;          push @nt, $t;
181        } elsif ($$s =~ s/^\]>>([0-9]+)\]//) {        } elsif ($$s =~ s/^\]>>([0-9]+)\]//) {
# Line 140  sub parse_char_string ($$$;$) { Line 183  sub parse_char_string ($$$;$) {
183                     anchor => $1,                     anchor => $1,
184                   line => $line, column => $column};                   line => $line, column => $column};
185          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
186        } elsif ($$s =~ s/^\][\x09\x20]*(?>\@([0-9a-zA-Z-]*))?\[//) {          $nest_level-- if $nest_level > 0;
187          } elsif ($nest_level > 0 and
188                   $$s =~ s/^\][\x09\x20]*(?>\@([0-9a-zA-Z-]*))?\[//) {
189          push @nt, {type => INLINE_MIDDLE_TAG_TOKEN,          push @nt, {type => INLINE_MIDDLE_TAG_TOKEN,
190                     language => $1,                     language => $1,
191                     line => $line, column => $column};                     line => $line, column => $column};
192          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
193        } elsif ($$s =~ s/\^''('?)//) {        } elsif ($$s =~ s/^''('?)//) {
194          push @nt, {type => $1 ? STRONG_TOKEN : EMPHASIS_TOKEN,          push @nt, {type => $1 ? STRONG_TOKEN : EMPHASIS_TOKEN,
195                     line => $line, column => $column};                     line => $line, column => $column};
196          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
197        } elsif ($$s =~ s/^>>([0-9]+)//) {        } elsif ($$s =~ s/^>>([0-9]+)//) {
198          push @nt, {type => ELEMENT_TOKEN,          push @nt, {type => ELEMENT_TOKEN,
199                     local_name => 'anchor-internal', namespace => $SW09_NS,                     local_name => 'anchor-internal', namespace => SW09_NS,
200                     anchor => $1,                     anchor => $1, content => '>>' . $1,
201                     line => $line, column => $column};                     line => $line, column => $column};
202          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
203        } elsif ($$s =~ s/^__&&//) {        } elsif ($$s =~ s/^__&&//) {
204          if ($$s =~ s/^(.+?)&&__//) {          if ($$s =~ s/^(.+?)&&__//) {
205            push @nt, {type => ELEMENT_TOKEN,            push @nt, {type => ELEMENT_TOKEN,
206                       local_name => 'replace', namespace => $SW09_NS,                       local_name => 'replace', namespace => SW09_NS,
207                       by => $1,                       by => $1,
208                       line => $line, column => $column};                       line => $line, column => $column};
209            $column += 4 + $+[0] - $-[0];            $column += 4 + $+[0] - $-[0];
# Line 168  sub parse_char_string ($$$;$) { Line 213  sub parse_char_string ($$$;$) {
213                       line => $line, column => $column};                       line => $line, column => $column};
214            $column += 4;            $column += 4;
215          }          }
216        } elsif ($$s =~ s/^([^<>\['_]+)//) {        } elsif ($$s =~ s/^([^<>\[\]'_]+)//) {
217          push @nt, {type => CHARACTER_TOKEN, data => $1,          push @nt, {type => CHARACTER_TOKEN, data => $1,
218                     line => $line, column => $column};                     line => $line, column => $column};
219          $column += $+[0] - $-[0];          $column += $+[0] - $-[0];
# Line 221  sub parse_char_string ($$$;$) { Line 266  sub parse_char_string ($$$;$) {
266          }          }
267        }        }
268        return shift @nt;        return shift @nt;
269      } elsif ($s =~ s/^(\*+)\s*//) {      } elsif ($s =~ s/^(\*+)[\x09\x20]*//) {
270        push @nt, {type => HEADING_START_TOKEN, depth => length $1,        push @nt, {type => HEADING_START_TOKEN, depth => length $1,
271                   line => $line, column => $column};                   line => $line, column => $column};
272        $column += $+[0] - $-[0];        $column += $+[0] - $-[0];
# Line 230  sub parse_char_string ($$$;$) { Line 275  sub parse_char_string ($$$;$) {
275                   line => $line, column => $column};                   line => $line, column => $column};
276        undef $continuous_line;        undef $continuous_line;
277        return shift @nt;        return shift @nt;
278      } elsif ($s =~ s/^([-=]+)\s*//) {      } elsif ($s =~ s/^([-=]+)[\x09\x20]*//) {
279        push @nt, {type => LIST_START_TOKEN, depth => $1,        push @nt, {type => LIST_START_TOKEN, depth => $1,
280                   line => $line, column => $column};                   line => $line, column => $column};
281        $column += $+[0] - $-[0];        $column += $+[0] - $-[0];
# Line 251  sub parse_char_string ($$$;$) { Line 296  sub parse_char_string ($$$;$) {
296          $name =~ s/\A[\x09\x20]*//;          $name =~ s/\A[\x09\x20]*//;
297          $column += 1 + $+[0] - $-[0];          $column += 1 + $+[0] - $-[0];
298          $name =~ s/[\x09\x20]+\z//;          $name =~ s/[\x09\x20]+\z//;
299          $tokenize_text->(\$s);          $tokenize_text->(\$name);
300          $column = $real_column;          $column = $real_column;
301          push @nt, {type => LABELED_LIST_MIDDLE_TOKEN,          push @nt, {type => LABELED_LIST_MIDDLE_TOKEN,
302                     line => $line, column => $column};                     line => $line, column => $column};
303          $column += $+[0] - $-[0] if $data =~ s/^:[\x09\x20]*//;          $column += $+[0] - $-[0] if $s =~ s/^:[\x09\x20]*//;
304          $tokenize_text->(\$s);          $tokenize_text->(\$s);
305        }        }
306        $continuous_line = 1;        $continuous_line = 1;
# Line 268  sub parse_char_string ($$$;$) { Line 313  sub parse_char_string ($$$;$) {
313              if $continuous_line;              if $continuous_line;
314          $s = '>>' . $s;          $s = '>>' . $s;
315          $tokenize_text->(\$s);          $tokenize_text->(\$s);
316            $continuous_line = 1;
317        } else {        } else {
318          push @nt, {type => QUOTATION_START_TOKEN, depth => $depth,          push @nt, {type => QUOTATION_START_TOKEN, depth => $depth,
319                     line => $line, column => $column};                     line => $line, column => $column};
# Line 277  sub parse_char_string ($$$;$) { Line 323  sub parse_char_string ($$$;$) {
323            push @nt, {type => EDITORIAL_NOTE_START_TOKEN,            push @nt, {type => EDITORIAL_NOTE_START_TOKEN,
324                       line => $line, column => $column};                       line => $line, column => $column};
325            $column += $+[0] - $-[0];            $column += $+[0] - $-[0];
326              $continuous_line = 1;
327          } elsif ($s =~ s/^;;[\x09\x20]*//) {          } elsif ($s =~ s/^;;[\x09\x20]*//) {
328            push @nt, {type => COMMENT_PARAGRAPH_START_TOKEN,            push @nt, {type => COMMENT_PARAGRAPH_START_TOKEN,
329                       line => $line, column => $column};                       line => $line, column => $column};
330            $column += $+[0] - $-[0];            $column += $+[0] - $-[0];
331              $continuous_line = 1;
332            } elsif (length $s) {
333              $continuous_line = 1;
334            } else {
335              $continuous_line = 0;
336          }          }
337          $tokenize_text->(\$s);          $tokenize_text->(\$s);
338        }        }
       $continuous_line = 1;  
339        return shift @nt;        return shift @nt;
340      } elsif ($s =~ /\A\[(INS|DEL)(?>\(([^()\\]*)\))?\[[\x09\x20]*\z/) {      } elsif ($s =~ /\A\[(INS|DEL)(?>\(([^()\\]*)\))?\[[\x09\x20]*\z/) {
341        undef $continuous_line;        undef $continuous_line;
# Line 303  sub parse_char_string ($$$;$) { Line 354  sub parse_char_string ($$$;$) {
354            push @nt, {type => BLOCK_END_TAG_TOKEN, tag_name => 'PRE',            push @nt, {type => BLOCK_END_TAG_TOKEN, tag_name => 'PRE',
355                       line => $line, column => $column};                       line => $line, column => $column};
356            undef $continuous_line;            undef $continuous_line;
357            break;            last;
358          } else {          } else {
359            push @nt, {type => CHARACTER_TOKEN, data => "\x0A",            push @nt, {type => CHARACTER_TOKEN, data => "\x0A",
360                       line => $line, column => $column}                       line => $line, column => $column}
# Line 325  sub parse_char_string ($$$;$) { Line 376  sub parse_char_string ($$$;$) {
376                   line => $line, column => $column};                   line => $line, column => $column};
377        $column += $+[0] - $-[0];        $column += $+[0] - $-[0];
378        $tokenize_text->(\$s);        $tokenize_text->(\$s);
379        undef $continuous_line;        $continuous_line = 1;
380        return shift @nt;        return shift @nt;
381      } elsif ($s =~ /\A\](INS|DEL)\][\x09\x20]*\z/) {      } elsif ($s =~ /\A\](INS|DEL)\][\x09\x20]*\z/) {
382        $continuous_line = 1;        $continuous_line = 1;
# Line 379  sub parse_char_string ($$$;$) { Line 430  sub parse_char_string ($$$;$) {
430        undef $continuous_line;        undef $continuous_line;
431        return shift @nt;        return shift @nt;
432      } elsif ($s eq '__IMAGE__') {      } elsif ($s eq '__IMAGE__') {
433        my $image = $doc->create_element_ns ($NS_SW09, 'image');        my $image = $doc->create_element_ns (SW09_NS, [undef, 'image']);
434        $_->set_user_data (manakai_source_line => $line);        $image->set_user_data (manakai_source_line => $line);
435        $_->set_user_data (manakai_source_column => 1);        $image->set_user_data (manakai_source_column => 1);
436        $image->text_content (join "\x0A", $s, @s);        $image->text_content (join "\x0A", $s, @s);
437        ($line, $column) = ($line + @s, 1);        ($line, $column) = ($line + @s, 1);
438        @s = ();        @s = ();
# Line 395  sub parse_char_string ($$$;$) { Line 446  sub parse_char_string ($$$;$) {
446        $continuous_line = 1;        $continuous_line = 1;
447        return shift @nt;        return shift @nt;
448      }      }
449    }; # $get_next_token_body    }; # $get_next_token
450    
451    ## NOTE: The "initial" mode.    ## NOTE: The "initial" mode.
452    if (@s and $s[0] =~ /^#\?/) {    if (@s and $s[0] =~ s/^#\?//) {
453      ## NOTE: "Parse a magic line".      ## NOTE: "Parse a magic line".
454    
455      my $s = shift @s;      my $s = shift @s;
456        if ($s =~ s/^([^\x09\x20]+)//) {
457          $column += $+[0] - $-[0];
458          my ($name, $version) = split m#/#, $1, 2;
459          my $el = $doc->document_element;
460          $el->set_attribute_ns (SW09_NS, ['sw', 'Name'] => $name);
461          $el->set_attribute_ns (SW09_NS, ['sw', 'Version'] => $version)
462              if defined $version;
463        }
464    
465      ## TODO:...      while (length $s) {
466          $column += $+[0] - $-[0] and next if $s =~ s/^[\x09\x20]+//;
467          my $name = '';
468          if ($s =~ s/^([^=]*)=//) {
469            $name = $1;
470            $column += length $name + 1;
471          }
472          my $param = $doc->create_element_ns (SW09_NS, [undef, 'parameter']);
473          $param->set_attribute_ns (undef, [undef, 'name'] => $name);
474          $param->set_user_data (manakai_source_line => $line);
475          $param->set_user_data (manakai_source_column => $column);
476          $head_el->append_child ($param);
477    
478          $column++ if $s =~ s/^"//;
479          if ($s =~ s/^([^"]*)//) {
480            my $values = $1;
481            $column += length $values;
482            $values =~ tr/\\//d;
483            my @values = split /,/, $values, -1;
484            push @values, '' unless length $values;
485            for (@values) {
486              my $value = $doc->create_element_ns (SW09_NS, [undef, 'value']);
487              $value->text_content ($_);
488              $value->set_user_data (manakai_source_line => $line);
489              $value->set_user_data (manakai_source_column => $column);
490              $param->append_child ($value);
491            }
492          }
493          $column++ if $s =~ s/^"//;
494        }
495    
496      $line = 2;      $line = 2;
497      $column = 0;      $column = 1;
498    }    }
499    
500    ## NOTE: Switched to the "body" mode.    ## NOTE: Switched to the "body" mode.
   $get_next_token->();  
501    
502      my $oe = [{node => $body_el,
503                 section_depth => 0,
504                 quotation_depth => 0,
505                 list_depth => 0}];
506      my $structural_elements = {
507        body => 1, section => 1, insert => 1, delete => 1, blockquote => 1,
508        h1 => 1, ul => 1, ol => 1, dl => 1, li => 1, dt => 1, dd => 1,
509        table => 1, tbody => 1, tr => 1, td => 1, p => 1, 'comment-p' => 1,
510        ed => 1, pre => 1,
511      };
512    
513      my $im = IN_SECTION_IM;
514      $token = $get_next_token->();
515    
516      A: {
517        if ($im == IN_PARAGRAPH_IM) {
518          if ($token->{type} == CHARACTER_TOKEN) {
519            $oe->[-1]->{node}->manakai_append_text ($token->{data});
520            $token = $get_next_token->();
521            redo A;
522          } elsif ($token->{type} == INLINE_START_TAG_TOKEN) {
523            if (not defined $token->{tag_name}) {
524              my $el = $doc->create_element_ns (SW09_NS, [undef, 'anchor']);
525              $oe->[-1]->{node}->append_child ($el);
526              push @$oe, {%{$oe->[-1]}, node => $el};
527              $el->set_user_data (manakai_source_line => $token->{line});
528              $el->set_user_data (manakai_source_column => $token->{column});
529              
530              $token = $get_next_token->();
531              redo A;
532            } else {
533              my $type = {
534                          AA => [AA_NS, 'aa'],
535                          ABBR => [HTML_NS, 'abbr'],
536                          CITE => [HTML_NS, 'cite'],
537                          CODE => [HTML_NS, 'code'],
538                          CSECTION => [SW10_NS, 'csection'],
539                          DEL => [HTML_NS, 'del'],
540                          DFN => [HTML_NS, 'dfn'],
541                          INS => [HTML_NS, 'ins'],
542                          KBD => [HTML_NS, 'kbd'],
543                          KEY => [SW10_NS, 'key'],
544                          Q => [HTML_NS, 'q'],
545                          QN => [SW10_NS, 'qn'],
546                          RUBY => [HTML_NS, 'ruby'],
547                          RUBYB => [SW09_NS, 'rubyb'],
548                          SAMP => [HTML_NS, 'samp'],
549                          SPAN => [HTML_NS, 'span'],
550                          SRC => [SW10_NS, 'src'],
551                          SUB => [HTML_NS, 'sub'],
552                          SUP => [HTML_NS, 'sup'],
553                          TIME => [HTML_NS, 'time'],
554                          VAR => [HTML_NS, 'var'],
555                          WEAK => [SW09_NS, 'weak'],
556                         }->{$token->{tag_name}} || [SW10_NS, $token->{tag_name}];
557              my $el = $doc->create_element_ns ($type->[0], [undef, $type->[1]]);
558              $oe->[-1]->{node}->append_child ($el);
559              push @$oe, {%{$oe->[-1]}, node => $el};
560              $el->set_user_data (manakai_source_line => $token->{line});
561              $el->set_user_data (manakai_source_column => $token->{column});
562    
563              $el->set_attribute_ns (undef, [undef, 'class'] => $token->{classes})
564                  if defined $token->{classes};
565              $el->set_attribute_ns (XML_NS, ['xml', 'lang'] => $token->{language})
566                  if defined $token->{language};
567              
568              $token = $get_next_token->();
569              redo A;
570            }
571          } elsif ($token->{type} == INLINE_MIDDLE_TAG_TOKEN) {
572            my ($ns, $ln, $pop) = @{{
573              rt => [HTML_NS, 'rt', 1],
574              title => [SW10_NS, 'attrvalue', 1],
575              nsuri => [SW10_NS, 'attrvalue', 1],
576              qn => [SW10_NS, 'nsuri'],
577              ruby => [HTML_NS, 'rt'],
578              rubyb => [HTML_NS, 'rt'],
579            }->{$oe->[-1]->{node}->manakai_local_name} || [SW10_NS, 'title']};
580            pop @$oe if $pop;
581    
582            my $el = $doc->create_element_ns ($ns, [undef, $ln]);
583            $oe->[-1]->{node}->append_child ($el);
584            push @$oe, {%{$oe->[-1]}, node => $el};
585            $el->set_user_data (manakai_source_line => $token->{line});
586            $el->set_user_data (manakai_source_column => $token->{column});
587    
588            $el->set_attribute_ns (XML_NS, ['xml', 'lang'] => $token->{language})
589                if defined $token->{language};
590    
591            $token = $get_next_token->();
592            redo A;
593          } elsif ($token->{type} == INLINE_END_TAG_TOKEN) {
594            pop @$oe if {
595              rt => 1, title => 1, nsuri => 1, attrvalue => 1,
596            }->{$oe->[-1]->{node}->manakai_local_name};
597            
598            if ({%$structural_elements,
599                 strong => 1, em => 1}->{$oe->[-1]->{node}->manakai_local_name}) {
600              unless (defined $token->{res_scheme} or defined $token->{anchor}) {
601                $oe->[-1]->{node}->manakai_append_text (']]');
602                push @$oe, $oe->[-1];
603              } else {
604                my $el = $doc->create_element_ns
605                    (SW09_NS,
606                     [undef, defined $token->{res_scheme}
607                          ? 'anchor-external' : 'anchor-internal']);
608                $oe->[-1]->{node}->append_child ($el);
609                push @$oe, {%{$oe->[-1]}, node => $el};
610                $el->set_user_data (manakai_source_line => $token->{line});
611                $el->set_user_data (manakai_source_column => $token->{column});
612                $el->text_content (']]');
613              }
614            }
615            
616            $oe->[-1]->{node}->set_attribute_ns (SW09_NS, ['sw', 'anchor'],
617                                                 $token->{anchor})
618                if defined $token->{anchor};
619            $oe->[-1]->{node}->set_attribute_ns (SW09_NS, ['sw', 'resScheme'],
620                                                 $token->{res_scheme})
621                if defined $token->{res_scheme};
622            $oe->[-1]->{node}->set_attribute_ns (SW09_NS, ['sw', 'resParameter'],
623                                                 $token->{res_parameter})
624                if defined $token->{res_parameter};
625            
626            pop @$oe;
627            
628            $token = $get_next_token->();
629            redo A;
630          } elsif ($token->{type} == STRONG_TOKEN) {
631            if ($oe->[-1]->{node}->manakai_local_name eq 'strong') {
632              pop @$oe;
633            } else {
634              my $el = $doc->create_element_ns (HTML_NS, [undef, 'strong']);
635              $oe->[-1]->{node}->append_child ($el);
636              push @$oe, {%{$oe->[-1]}, node => $el};
637              $el->set_user_data (manakai_source_line => $token->{line});
638              $el->set_user_data (manakai_source_column => $token->{column});
639            }
640            $token = $get_next_token->();
641            redo A;
642          } elsif ($token->{type} == EMPHASIS_TOKEN) {
643            if ($oe->[-1]->{node}->manakai_local_name eq 'em') {
644              pop @$oe;
645            } else {
646              my $el = $doc->create_element_ns (HTML_NS, [undef, 'em']);
647              $oe->[-1]->{node}->append_child ($el);
648              push @$oe, {%{$oe->[-1]}, node => $el};
649              $el->set_user_data (manakai_source_line => $token->{line});
650              $el->set_user_data (manakai_source_column => $token->{column});
651            }
652            $token = $get_next_token->();
653            redo A;
654          } elsif ($token->{type} == FORM_TOKEN) {
655            ## There is an exact code clone.
656            if ($token->{name} eq 'form') {
657              my $el = $doc->create_element_ns (SW09_NS, [undef, 'form']);
658              $oe->[-1]->{node}->append_child ($el);
659              $el->set_user_data (manakai_source_line => $token->{line});
660              $el->set_user_data (manakai_source_column => $token->{column});
661    
662              $el->set_attribute_ns (undef, [undef, 'id']
663                                         => $token->{id}) if defined $token->{id};
664              $el->set_attribute_ns (undef, [undef, 'input']
665                                         => shift @{$token->{parameters}})
666                  if @{$token->{parameters}};
667              $el->set_attribute_ns (undef, [undef, 'template']
668                                         => shift @{$token->{parameters}})
669                  if @{$token->{parameters}};
670              $el->set_attribute_ns (undef, [undef, 'option']
671                                         => shift @{$token->{parameters}})
672                  if @{$token->{parameters}};
673              $el->set_attribute_ns (undef, [undef, 'parameter']
674                                         => join ':', @{$token->{parameters}})
675                  if @{$token->{parameters}};
676              
677              $token = $get_next_token->();
678              redo A;
679            } else {
680              my $el = $doc->create_element_ns (SW09_NS, [undef, 'form']);
681              $oe->[-1]->{node}->append_child ($el);
682              $el->set_user_data (manakai_source_line => $token->{line});
683              $el->set_user_data (manakai_source_column => $token->{column});
684    
685              $el->set_attribute_ns (undef, [undef, 'ref']
686                                         => $token->{name});
687              $el->set_attribute_ns (undef, [undef, 'id']
688                                         => $token->{id}) if defined $token->{id};
689              $el->set_attribute_ns (undef, [undef, 'parameter']
690                                         => join ':', @{$token->{parameters}})
691                  if @{$token->{parameters}};
692              
693              $token = $get_next_token->();
694              redo A;
695            }
696          } elsif ($token->{type} == ELEMENT_TOKEN) {
697            ## NOTE: There is an exact code clone.
698            my $el = $doc->create_element_ns
699                ($token->{namespace}, [undef, $token->{local_name}]);
700            $oe->[-1]->{node}->append_child ($el);
701            $el->set_user_data (manakai_source_line => $token->{line});
702            $el->set_user_data (manakai_source_column => $token->{column});
703    
704            $el->set_attribute_ns (SW09_NS, ['sw', 'anchor'], $token->{anchor})
705                if defined $token->{anchor};
706            $el->set_attribute_ns (undef, [undef, 'by']
707                                       => $token->{by}) if defined $token->{by};
708            $el->set_attribute_ns (SW09_NS, ['sw', 'resScheme'],
709                                       $token->{res_scheme})
710                if defined $token->{res_scheme};
711            $el->set_attribute_ns (SW09_NS, ['sw', 'resParameter'],
712                                   $token->{res_parameter})
713                if defined $token->{res_parameter};
714            $el->text_content ($token->{content}) if defined $token->{content};
715    
716            $token = $get_next_token->();
717            redo A;
718          } elsif ($token->{type} == LABELED_LIST_MIDDLE_TOKEN) {
719            pop @$oe while not $structural_elements
720                ->{$oe->[-1]->{node}->manakai_local_name};
721            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'dt';
722            
723            my $el = $doc->create_element_ns (HTML_NS, [undef, 'dd']);
724            $oe->[-1]->{node}->append_child ($el);
725            push @$oe, {%{$oe->[-1]}, node => $el};
726            $el->set_user_data (manakai_source_line => $token->{line});
727            $el->set_user_data (manakai_source_column => $token->{column});
728    
729            $token = $get_next_token->();
730            redo A;
731          } elsif ($token->{type} == HEADING_END_TOKEN) {
732            pop @$oe while not $structural_elements
733                ->{$oe->[-1]->{node}->manakai_local_name};
734            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'h1';
735            
736            $im = IN_SECTION_IM;
737            $token = $get_next_token->();
738            redo A;
739          } elsif ($token->{type} == TABLE_CELL_END_TOKEN) {
740            pop @$oe while not $structural_elements
741                ->{$oe->[-1]->{node}->manakai_local_name};
742            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'td';
743            
744            $im = IN_TABLE_ROW_IM;
745            $token = $get_next_token->();
746            redo A;
747          } elsif (($token->{type} == BLOCK_END_TAG_TOKEN and
748                    $token->{tag_name} eq 'PRE') or
749                   $token->{type} == PREFORMATTED_END_TOKEN) {
750            pop @$oe while not $structural_elements
751                ->{$oe->[-1]->{node}->manakai_local_name};
752            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'pre';
753    
754            $im = IN_SECTION_IM;
755            $token = $get_next_token->();
756            redo A;
757          } else {
758            pop @$oe while not $structural_elements
759                ->{$oe->[-1]->{node}->manakai_local_name};
760            
761            $im = IN_SECTION_IM;
762            ## Reconsume.
763            redo A;
764          }
765        } elsif ($im == IN_SECTION_IM) {
766          if ($token->{type} == HEADING_START_TOKEN) {
767            B: {
768              pop @$oe and redo B
769                  if not {body => 1, section => 1, insert => 1, delete => 1}
770                      ->{$oe->[-1]->{node}->manakai_local_name} or
771                     $token->{depth} <= $oe->[-1]->{section_depth};
772              if ($token->{depth} > $oe->[-1]->{section_depth} + 1) {
773                my $el = $doc->create_element_ns (HTML_NS, [undef, 'section']);
774                $oe->[-1]->{node}->append_child ($el);
775                push @$oe, {node => $el,
776                            section_depth => $oe->[-1]->{section_depth} + 1,
777                            quotation_depth => 0, list_depth => 0};
778                redo B;
779              }
780            } # B
781    
782            my $el = $doc->create_element_ns (HTML_NS, [undef, 'section']);
783            $oe->[-1]->{node}->append_child ($el);
784            push @$oe, {node => $el,
785                        section_depth => $oe->[-1]->{section_depth} + 1,
786                        quotation_depth => 0, list_depth => 0};
787    
788            my $el2 = $doc->create_element_ns (HTML_NS, [undef, 'h1']);
789            $oe->[-1]->{node}->append_child ($el2);
790            push @$oe, {%{$oe->[-1]}, node => $el2};
791    
792            $im = IN_PARAGRAPH_IM;
793            $token = $get_next_token->();
794            redo A;
795          } elsif ($token->{type} == BLOCK_START_TAG_TOKEN and
796                   ($token->{tag_name} eq 'INS' or
797                    $token->{tag_name} eq 'DEL')) {
798            my $el = $doc->create_element_ns
799                (SW09_NS,
800                 [undef, $token->{tag_name} eq 'INS' ? 'insert' : 'delete']);
801            $oe->[-1]->{node}->append_child ($el);
802            push @$oe, {node => $el, section_depth => 0,
803                        quotation_depth => 0, list_depth => 0};
804            $el->set_attribute_ns (undef, [undef, 'class'] => $token->{classes})
805                if defined $token->{classes};
806            $token = $get_next_token->();
807            redo A;
808          } elsif ($token->{type} == QUOTATION_START_TOKEN) {
809            B: {
810              pop @$oe and redo B
811                  if not {body => 1, section => 1, insert => 1, delete => 1,
812                      blockquote => 1}
813                      ->{$oe->[-1]->{node}->manakai_local_name} or
814                     $token->{depth} < $oe->[-1]->{quotation_depth};
815              if ($token->{depth} > $oe->[-1]->{quotation_depth}) {
816                my $el = $doc->create_element_ns (HTML_NS, [undef, 'blockquote']);
817                $oe->[-1]->{node}->append_child ($el);
818                push @$oe, {node => $el, section_depth => 0,
819                            quotation_depth => $oe->[-1]->{quotation_depth} + 1,
820                            list_depth => 0};
821                redo B;
822              }
823            } # B
824    
825            $token = $get_next_token->();
826            redo A;
827          } elsif ($token->{type} == LIST_START_TOKEN) {
828            my $depth = length $token->{depth};
829            my $list_type = substr ($token->{depth}, -1, 1) eq '-' ? 'ul' : 'ol';
830            B: {
831              pop @$oe and redo B if $oe->[-1]->{list_depth} > $depth;
832              pop @$oe and redo B if $oe->[-1]->{list_depth} == $depth and
833                  $list_type ne $oe->[-1]->{node}->manakai_local_name;
834              if ($oe->[-1]->{list_depth} < $depth) {
835                my $type = substr $token->{depth}, $oe->[-1]->{list_depth}, 1;
836                my $el = $doc->create_element_ns
837                    (HTML_NS, [undef, $type eq '-' ? 'ul' : 'ol']);
838                $oe->[-1]->{node}->append_child ($el);
839                push @$oe, {%{$oe->[-1]}, node => $el,
840                            list_depth => $oe->[-1]->{list_depth} + 1};
841                if ($oe->[-1]->{list_depth} < $depth) {
842                  my $el = $doc->create_element_ns (HTML_NS, [undef, 'li']);
843                  $oe->[-1]->{node}->append_child ($el);
844                  push @$oe, {%{$oe->[-1]}, node => $el};
845                }
846                redo B;
847              }
848            } # B
849            
850            my $el = $doc->create_element_ns (HTML_NS, [undef, 'li']);
851            $oe->[-1]->{node}->append_child ($el);
852            push @$oe, {%{$oe->[-1]}, node => $el};
853    
854            $im = IN_PARAGRAPH_IM;
855            $token = $get_next_token->();
856            redo A;
857          } elsif ($token->{type} == LABELED_LIST_START_TOKEN) {
858            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'dd';
859            if ($oe->[-1]->{node}->manakai_local_name ne 'dl') {
860              my $el = $doc->create_element_ns (HTML_NS, [undef, 'dl']);
861              $oe->[-1]->{node}->append_child ($el);
862              push @$oe, {%{$oe->[-1]}, node => $el};
863            }
864            
865            my $el = $doc->create_element_ns (HTML_NS, [undef, 'dt']);
866            $oe->[-1]->{node}->append_child ($el);
867            push @$oe, {%{$oe->[-1]}, node => $el};
868            
869            $im = IN_PARAGRAPH_IM;
870            $token = $get_next_token->();
871            redo A;
872          } elsif ($token->{type} == TABLE_ROW_START_TOKEN) {
873            my $el = $doc->create_element_ns (HTML_NS, [undef, 'table']);
874            $oe->[-1]->{node}->append_child ($el);
875            push @$oe, {%{$oe->[-1]}, node => $el};
876    
877            $el = $doc->create_element_ns (HTML_NS, [undef, 'tbody']);
878            $oe->[-1]->{node}->append_child ($el);
879            push @$oe, {%{$oe->[-1]}, node => $el};
880    
881            $el = $doc->create_element_ns (HTML_NS, [undef, 'tr']);
882            $oe->[-1]->{node}->append_child ($el);
883            push @$oe, {%{$oe->[-1]}, node => $el};
884            
885            $im = IN_TABLE_ROW_IM;
886            $token = $get_next_token->();
887            redo A;
888          } elsif (($token->{type} == BLOCK_START_TAG_TOKEN and
889                    $token->{tag_name} eq 'PRE') or
890                   $token->{type} == PREFORMATTED_START_TOKEN) {
891            my $el = $doc->create_element_ns (HTML_NS, [undef, 'pre']);
892            $oe->[-1]->{node}->append_child ($el);
893            push @$oe, {%{$oe->[-1]}, node => $el};
894    
895            $el->set_attribute_ns (undef, [undef, 'class'] => $token->{classes})
896                if defined $token->{classes};
897    
898            $im = IN_PARAGRAPH_IM;
899            $token = $get_next_token->();
900            redo A;
901          } elsif ($token->{type} == COMMENT_PARAGRAPH_START_TOKEN) {
902            my $el = $doc->create_element_ns (SW10_NS, [undef, 'comment-p']);
903            $oe->[-1]->{node}->append_child ($el);
904            push @$oe, {%{$oe->[-1]}, node => $el};
905            
906            $im = IN_PARAGRAPH_IM;
907            $token = $get_next_token->();
908            redo A;
909          } elsif ($token->{type} == EDITORIAL_NOTE_START_TOKEN) {
910            my $el = $doc->create_element_ns (SW10_NS, [undef, 'ed']);
911            $oe->[-1]->{node}->append_child ($el);
912            push @$oe, {%{$oe->[-1]}, node => $el};
913    
914            $im = IN_PARAGRAPH_IM;
915            $token = $get_next_token->();
916            redo A;
917          } elsif ($token->{type} == EMPTY_LINE_TOKEN) {
918            pop @$oe while not {body => 1, section => 1, insert => 1, delete => 1}
919                ->{$oe->[-1]->{node}->manakai_local_name};
920            $token = $get_next_token->();
921            redo A;
922          } elsif ($token->{type} == BLOCK_END_TAG_TOKEN) {
923            if ($token->{tag_name} eq 'INS') {
924              for (reverse 1..$#$oe) {
925                if ($oe->[$_]->{node}->manakai_local_name eq 'insert') {
926                  splice @$oe, $_;
927                  last;
928                }
929              }
930            } elsif ($token->{tag_name} eq 'DEL') {
931              for (reverse 1..$#$oe) {
932                if ($oe->[$_]->{node}->manakai_local_name eq 'delete') {
933                  splice @$oe, $_;
934                  last;
935                }
936              }
937            } else {
938              ## NOTE: Ignore the token.
939            }
940            undef $continuous_line;
941            $token = $get_next_token->();
942            redo A;
943          } elsif ($token->{type} == FORM_TOKEN) {
944            ## There is an exact code clone.
945            if ($token->{name} eq 'form') {
946              my $el = $doc->create_element_ns (SW09_NS, [undef, 'form']);
947              $oe->[-1]->{node}->append_child ($el);
948              $el->set_user_data (manakai_source_line => $token->{line});
949              $el->set_user_data (manakai_source_column => $token->{column});
950    
951              $el->set_attribute_ns (undef, [undef, 'id']
952                                         => $token->{id}) if defined $token->{id};
953              $el->set_attribute_ns (undef, [undef, 'input']
954                                         => shift @{$token->{parameters}})
955                  if @{$token->{parameters}};
956              $el->set_attribute_ns (undef, [undef, 'template']
957                                         => shift @{$token->{parameters}})
958                  if @{$token->{parameters}};
959              $el->set_attribute_ns (undef, [undef, 'option']
960                                         => shift @{$token->{parameters}})
961                  if @{$token->{parameters}};
962              $el->set_attribute_ns (undef, [undef, 'parameter']
963                                         => join ':', @{$token->{parameters}})
964                  if @{$token->{parameters}};
965              
966              $token = $get_next_token->();
967              redo A;
968            } else {
969              my $el = $doc->create_element_ns (SW09_NS, [undef, 'form']);
970              $oe->[-1]->{node}->append_child ($el);
971              $el->set_user_data (manakai_source_line => $token->{line});
972              $el->set_user_data (manakai_source_column => $token->{column});
973    
974              $el->set_attribute_ns (undef, [undef, 'ref'] => $token->{name});
975              $el->set_attribute_ns (undef, [undef, 'id']
976                                         => $token->{id}) if defined $token->{id};
977              $el->set_attribute_ns (undef, [undef, 'parameter']
978                                         => join ':', @{$token->{parameters}})
979                  if @{$token->{parameters}};
980              
981              $token = $get_next_token->();
982              redo A;
983            }
984          } elsif ($token->{type} == ELEMENT_TOKEN and
985                   $token->{local_name} eq 'replace') {
986            ## NOTE: There is an exact code clone.
987            my $el = $doc->create_element_ns
988                ($token->{namespace}, [undef, $token->{local_name}]);
989            $oe->[-1]->{node}->append_child ($el);
990            $el->set_user_data (manakai_source_line => $token->{line});
991            $el->set_user_data (manakai_source_column => $token->{column});
992    
993            $el->set_attribute_ns (SW09_NS, ['sw', 'anchor'], $token->{anchor})
994                if defined $token->{anchor};
995            $el->set_attribute_ns (undef, [undef, 'by']
996                                       => $token->{by}) if defined $token->{by};
997            $el->set_attribute_ns (SW09_NS, ['sw', 'resScheme'],
998                                   $token->{res_scheme})
999                if defined $token->{res_scheme};
1000            $el->set_attribute_ns (SW09_NS, ['sw', 'resParameter'],
1001                                   $token->{res_parameter})
1002                if defined $token->{res_parameter};
1003            $el->text_content ($token->{content}) if defined $token->{content};
1004    
1005            $token = $get_next_token->();
1006            redo A;
1007          } elsif ($token->{type} == END_OF_FILE_TOKEN) {
1008            return;
1009          } elsif ({LABELED_LIST_MIDDLE_TOKEN => 1,
1010                    HEADING_END_TOKEN => 1,
1011                    PREFORMATTED_END_TOKEN => 1,
1012                    TABLE_ROW_END_TOKEN => 1,
1013                    TABLE_CELL_START_TOKEN => 1,
1014                    TABLE_CELL_END_TOKEN => 1,
1015                    TABLE_COLSPAN_CELL_TOKEN => 1}->{$token->{type}}) {
1016            ## NOTE: Ignore the token.
1017          } else {
1018            unless ({dd => 1,
1019                    li => 1,
1020                     'comment-p' => 1,
1021                     ed => 1}->{$oe->[-1]->{node}->manakai_local_name}) {
1022              my $el = $doc->create_element_ns (HTML_NS, [undef, 'p']);
1023              $oe->[-1]->{node}->append_child ($el);
1024              push @$oe, {%{$oe->[-1]}, node => $el};
1025            }
1026            
1027            $im = IN_PARAGRAPH_IM;
1028            ## Reprocess.
1029            redo A;
1030          }
1031        } elsif ($im == IN_TABLE_ROW_IM) {
1032          if ($token->{type} == TABLE_CELL_START_TOKEN) {
1033            my $el = $doc->create_element_ns (HTML_NS, [undef, 'td']);
1034            $oe->[-1]->{node}->append_child ($el);
1035            push @$oe, {%{$oe->[-1]}, node => $el};
1036            $el->set_user_data (manakai_source_line => $token->{line});
1037            $el->set_user_data (manakai_source_column => $token->{column});
1038    
1039            $im = IN_PARAGRAPH_IM;
1040            $token = $get_next_token->();
1041            redo A;
1042          } elsif ($token->{type} == TABLE_COLSPAN_CELL_TOKEN) {
1043            my $lc = $oe->[-1]->{node}->last_child;
1044            if ($lc and $lc->manakai_local_name eq 'td') {
1045              $lc->set_attribute_ns
1046                  (undef, [undef, 'colspan'],
1047                   ($lc->get_attribute_ns (undef, 'colspan') || 1) + 1);
1048            } else {
1049              my $el = $doc->create_element_ns (HTML_NS, [undef, 'td']);
1050              $oe->[-1]->{node}->append_child ($el);
1051              $el->set_user_data (manakai_source_line => $token->{line});
1052              $el->set_user_data (manakai_source_column => $token->{column});
1053            }
1054    
1055            $token = $get_next_token->();
1056            redo A;
1057          } elsif ($token->{type} == TABLE_ROW_END_TOKEN) {
1058            pop @$oe if $oe->[-1]->{node}->manakai_local_name eq 'tr';
1059            $token = $get_next_token->();
1060            redo A;
1061          } elsif ($token->{type} == TABLE_ROW_START_TOKEN) {
1062            my $el = $doc->create_element_ns (HTML_NS, [undef, 'tr']);
1063            $oe->[-1]->{node}->append_child ($el);
1064            push @$oe, {%{$oe->[-1]}, node => $el};
1065            $el->set_user_data (manakai_source_line => $token->{line});
1066            $el->set_user_data (manakai_source_column => $token->{column});
1067    
1068            $token = $get_next_token->();
1069            redo A;
1070          } else {
1071            $im = IN_SECTION_IM;
1072            ## Reprocess.
1073            redo A;
1074          }
1075        } else {
1076          die "$0: Unknown insertion mode: $im";
1077        }
1078      } # A
1079  } # parse_char_string  } # parse_char_string
1080    
1081  1;  1;

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.7

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24