/[suikacvs]/markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src
Suika

Diff of /markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src

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

revision 1.19 by wakaba, Sun Oct 19 07:19:00 2008 UTC revision 1.33 by wakaba, Sat Sep 5 10:41:07 2009 UTC
# Line 105  sub COMMENT_START_STATE () { 14 } Line 105  sub COMMENT_START_STATE () { 14 }
105  sub COMMENT_START_DASH_STATE () { 15 }  sub COMMENT_START_DASH_STATE () { 15 }
106  sub COMMENT_STATE () { 16 }  sub COMMENT_STATE () { 16 }
107  sub COMMENT_END_STATE () { 17 }  sub COMMENT_END_STATE () { 17 }
108    sub COMMENT_END_BANG_STATE () { 102 }
109    sub COMMENT_END_SPACE_STATE () { 103 } ## LAST
110  sub COMMENT_END_DASH_STATE () { 18 }  sub COMMENT_END_DASH_STATE () { 18 }
111  sub BOGUS_COMMENT_STATE () { 19 }  sub BOGUS_COMMENT_STATE () { 19 }
112  sub DOCTYPE_STATE () { 20 }  sub DOCTYPE_STATE () { 20 }
# Line 182  sub NDATA_STATE () { 86 } Line 184  sub NDATA_STATE () { 86 }
184  sub AFTER_NDATA_STATE () { 87 }  sub AFTER_NDATA_STATE () { 87 }
185  sub BEFORE_NOTATION_NAME_STATE () { 88 }  sub BEFORE_NOTATION_NAME_STATE () { 88 }
186  sub NOTATION_NAME_STATE () { 89 }  sub NOTATION_NAME_STATE () { 89 }
187  sub AFTER_NOTATION_NAME_STATE () { 90 }  sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
188  sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 91 }  sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 91 }
189  sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 92 }  sub ENTITY_VALUE_ENTITY_STATE () { 92 }
190  sub ENTITY_VALUE_ENTITY_STATE () { 93 }  sub AFTER_ELEMENT_NAME_STATE () { 93 }
191  sub BOGUS_MD_STATE () { 94 }  sub BEFORE_ELEMENT_CONTENT_STATE () { 94 }
192    sub CONTENT_KEYWORD_STATE () { 95 }
193    sub AFTER_CM_GROUP_OPEN_STATE () { 96 }
194    sub CM_ELEMENT_NAME_STATE () { 97 }
195    sub AFTER_CM_ELEMENT_NAME_STATE () { 98 }
196    sub AFTER_CM_GROUP_CLOSE_STATE () { 99 }
197    sub AFTER_MD_DEF_STATE () { 100 }
198    sub BOGUS_MD_STATE () { 101 }
199    
200  ## Tree constructor state constants (see Whatpm::HTML for the full  ## Tree constructor state constants (see Whatpm::HTML for the full
201  ## list and descriptions)  ## list and descriptions)
# Line 853  sub _get_next_token ($) { Line 862  sub _get_next_token ($) {
862          $self->{s_kwd} = '';          $self->{s_kwd} = '';
863          # reconsume          # reconsume
864    
865          !!!emit ($self->{ct}); # start tag or end tag          ## Discard the token.
866            #!!!emit ($self->{ct}); # start tag or end tag
867    
868          redo A;          redo A;
869        } elsif ($self->{nc} == 0x002F) { # /        } elsif ($self->{nc} == 0x002F) { # /
# Line 934  sub _get_next_token ($) { Line 944  sub _get_next_token ($) {
944          $self->{s_kwd} = '';          $self->{s_kwd} = '';
945          # reconsume          # reconsume
946    
947          !!!emit ($self->{ct}); # start tag or end tag          ## Discard the token.
948            #!!!emit ($self->{ct}); # start tag or end tag
949    
950          redo A;          redo A;
951        } else {        } else {
952          if ({          if ({
953               0x0022 => 1, # "               0x0022 => 1, # "
954               0x0027 => 1, # '               0x0027 => 1, # '
955                 0x003C => 1, # <
956               0x003D => 1, # =               0x003D => 1, # =
957              }->{$self->{nc}}) {              }->{$self->{nc}}) {
958            !!!cp (55);            !!!cp (55);
# Line 1059  sub _get_next_token ($) { Line 1071  sub _get_next_token ($) {
1071          $self->{s_kwd} = '';          $self->{s_kwd} = '';
1072          # reconsume          # reconsume
1073    
1074          !!!emit ($self->{ct}); # start tag or end tag          ## Discard the token.
1075            #!!!emit ($self->{ct}); # start tag or end tag
1076    
1077          redo A;          redo A;
1078        } else {        } else {
1079          if ($self->{nc} == 0x0022 or # "          if ({
1080              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1081                 0x0027 => 1, # '
1082                 0x003C => 1, # <
1083                }->{$self->{nc}}) {
1084            !!!cp (69);            !!!cp (69);
1085            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1086            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1163  sub _get_next_token ($) { Line 1179  sub _get_next_token ($) {
1179          $self->{state} = DATA_STATE;          $self->{state} = DATA_STATE;
1180          # reconsume          # reconsume
1181    
1182          !!!emit ($self->{ct}); # start tag or end tag          ## Discard the token.
1183            #!!!emit ($self->{ct}); # start tag or end tag
1184    
1185          redo A;          redo A;
1186        } else {        } else {
# Line 1175  sub _get_next_token ($) { Line 1192  sub _get_next_token ($) {
1192            !!!cp (78.2);            !!!cp (78.2);
1193          }          }
1194    
1195          if ($self->{nc} == 0x0022 or # "          if ({
1196              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1197                 0x0027 => 1, # '
1198                 0x003C => 1, # <
1199                }->{$self->{nc}}) {
1200            !!!cp (78);            !!!cp (78);
1201            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1202            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1259  sub _get_next_token ($) { Line 1279  sub _get_next_token ($) {
1279          $self->{s_kwd} = '';          $self->{s_kwd} = '';
1280          ## reconsume          ## reconsume
1281    
1282          !!!emit ($self->{ct}); # start tag or end tag          ## Discard the token.
1283            #!!!emit ($self->{ct}); # start tag or end tag
1284    
1285          redo A;          redo A;
1286        } else {        } else {
1287          if ($self->{nc} == 0x003D) { # =          if ($self->{nc} == 0x003D or $self->{nc} == 0x003C) { # =, <
1288            !!!cp (93);            !!!cp (93);
1289            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1290            !!!parse-error (type => 'bad attribute value');            !!!parse-error (type => 'bad attribute value');
# Line 1309  sub _get_next_token ($) { Line 1330  sub _get_next_token ($) {
1330          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1331          !!!next-input-character;          !!!next-input-character;
1332          redo A;          redo A;
1333          } elsif ($self->{is_xml} and
1334                   $is_space->{$self->{nc}}) {
1335            !!!cp (97.1);
1336            $self->{ca}->{value} .= ' ';
1337            ## Stay in the state.
1338            !!!next-input-character;
1339            redo A;
1340        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1341          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1342          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1333  sub _get_next_token ($) { Line 1361  sub _get_next_token ($) {
1361            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1362            $self->{s_kwd} = '';            $self->{s_kwd} = '';
1363            ## reconsume            ## reconsume
1364            !!!emit ($self->{ct}); # end tag  
1365              ## Discard the token.
1366              #!!!emit ($self->{ct}); # end tag
1367    
1368            redo A;            redo A;
1369          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1370            ## XML5: No parse error above; not defined yet.            ## XML5: No parse error above; not defined yet.
1371            push @{$self->{ct}->{attrdefs}}, $self->{ca};            push @{$self->{ct}->{attrdefs}}, $self->{ca};
1372            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1373            ## Reconsume.            ## Reconsume.
1374            !!!emit ($self->{ct}); # ATTLIST  
1375              ## Discard the token.
1376              #!!!emit ($self->{ct}); # ATTLIST
1377    
1378            redo A;            redo A;
1379          } else {          } else {
1380            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
# Line 1356  sub _get_next_token ($) { Line 1390  sub _get_next_token ($) {
1390          }          }
1391          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1392          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1393                                q["&<],                                qq["&<\x09\x0C\x20],
1394                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1395    
1396          ## Stay in the state          ## Stay in the state
# Line 1393  sub _get_next_token ($) { Line 1427  sub _get_next_token ($) {
1427          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1428          !!!next-input-character;          !!!next-input-character;
1429          redo A;          redo A;
1430          } elsif ($self->{is_xml} and
1431                   $is_space->{$self->{nc}}) {
1432            !!!cp (103.1);
1433            $self->{ca}->{value} .= ' ';
1434            ## Stay in the state.
1435            !!!next-input-character;
1436            redo A;
1437        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1438          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1439          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1402  sub _get_next_token ($) { Line 1443  sub _get_next_token ($) {
1443            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1444            $self->{s_kwd} = '';            $self->{s_kwd} = '';
1445            ## reconsume            ## reconsume
1446            !!!emit ($self->{ct}); # start tag  
1447              ## Discard the token.
1448              #!!!emit ($self->{ct}); # start tag
1449    
1450            redo A;            redo A;
1451          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1452            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1417  sub _get_next_token ($) { Line 1461  sub _get_next_token ($) {
1461            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1462            $self->{s_kwd} = '';            $self->{s_kwd} = '';
1463            ## reconsume            ## reconsume
1464            !!!emit ($self->{ct}); # end tag  
1465              ## Discard the token.
1466              #!!!emit ($self->{ct}); # end tag
1467    
1468            redo A;            redo A;
1469          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1470            ## XML5: No parse error above; not defined yet.            ## XML5: No parse error above; not defined yet.
1471            push @{$self->{ct}->{attrdefs}}, $self->{ca};            push @{$self->{ct}->{attrdefs}}, $self->{ca};
1472            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1473            ## Reconsume.            ## Reconsume.
1474            !!!emit ($self->{ct}); # ATTLIST  
1475              ## Discard the token.
1476              #!!!emit ($self->{ct}); # ATTLIST
1477    
1478            redo A;            redo A;
1479          } else {          } else {
1480            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
# Line 1440  sub _get_next_token ($) { Line 1490  sub _get_next_token ($) {
1490          }          }
1491          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1492          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1493                                q['&<],                                qq['&<\x09\x0C\x20],
1494                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1495    
1496          ## Stay in the state          ## Stay in the state
# Line 1519  sub _get_next_token ($) { Line 1569  sub _get_next_token ($) {
1569            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1570            $self->{s_kwd} = '';            $self->{s_kwd} = '';
1571            ## reconsume            ## reconsume
1572            !!!emit ($self->{ct}); # start tag  
1573              ## Discard the token.
1574              #!!!emit ($self->{ct}); # start tag
1575              
1576            redo A;            redo A;
1577          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1578            !!!parse-error (type => 'unclosed tag');            !!!parse-error (type => 'unclosed tag');
# Line 1535  sub _get_next_token ($) { Line 1588  sub _get_next_token ($) {
1588            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1589            $self->{s_kwd} = '';            $self->{s_kwd} = '';
1590            ## reconsume            ## reconsume
1591            !!!emit ($self->{ct}); # end tag  
1592              ## Discard the token.
1593              #!!!emit ($self->{ct}); # end tag
1594    
1595            redo A;            redo A;
1596          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {          } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1597            !!!parse-error (type => 'unclosed md'); ## TODO: type            !!!parse-error (type => 'unclosed md'); ## TODO: type
1598            push @{$self->{ct}->{attrdefs}}, $self->{ca};            push @{$self->{ct}->{attrdefs}}, $self->{ca};
1599            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1600            ## Reconsume.            ## Reconsume.
1601            !!!emit ($self->{ct}); # ATTLIST  
1602              ## Discard the token.
1603              #!!!emit ($self->{ct}); # ATTLIST
1604    
1605            redo A;            redo A;
1606          } else {          } else {
1607            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
# Line 1552  sub _get_next_token ($) { Line 1611  sub _get_next_token ($) {
1611               0x0022 => 1, # "               0x0022 => 1, # "
1612               0x0027 => 1, # '               0x0027 => 1, # '
1613               0x003D => 1, # =               0x003D => 1, # =
1614                 0x003C => 1, # <
1615              }->{$self->{nc}}) {              }->{$self->{nc}}) {
1616            !!!cp (115);            !!!cp (115);
1617            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1561  sub _get_next_token ($) { Line 1621  sub _get_next_token ($) {
1621          }          }
1622          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1623          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1624                                q["'=& >],                                qq["'=& \x09\x0C>],
1625                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1626    
1627          ## Stay in the state          ## Stay in the state
# Line 1621  sub _get_next_token ($) { Line 1681  sub _get_next_token ($) {
1681          $self->{state} = DATA_STATE;          $self->{state} = DATA_STATE;
1682          $self->{s_kwd} = '';          $self->{s_kwd} = '';
1683          ## Reconsume.          ## Reconsume.
1684          !!!emit ($self->{ct}); # start tag or end tag  
1685            ## Discard the token.
1686            #!!!emit ($self->{ct}); # start tag or end tag
1687    
1688          redo A;          redo A;
1689        } else {        } else {
1690          !!!cp ('124.1');          !!!cp ('124.1');
# Line 1678  sub _get_next_token ($) { Line 1741  sub _get_next_token ($) {
1741          $self->{state} = DATA_STATE;          $self->{state} = DATA_STATE;
1742          $self->{s_kwd} = '';          $self->{s_kwd} = '';
1743          ## Reconsume.          ## Reconsume.
1744          !!!emit ($self->{ct}); # start tag or end tag  
1745            ## Discard the token.
1746            #!!!emit ($self->{ct}); # start tag or end tag
1747    
1748          redo A;          redo A;
1749        } else {        } else {
1750          !!!cp ('124.4');          !!!cp ('124.4');
# Line 2053  sub _get_next_token ($) { Line 2119  sub _get_next_token ($) {
2119          !!!next-input-character;          !!!next-input-character;
2120          redo A;          redo A;
2121        }        }
2122      } elsif ($self->{state} == COMMENT_END_STATE) {      } elsif ($self->{state} == COMMENT_END_STATE or
2123                 $self->{state} == COMMENT_END_BANG_STATE) {
2124        ## XML5: "Comment end state" and "DOCTYPE comment end state".        ## XML5: "Comment end state" and "DOCTYPE comment end state".
2125          ## (No comment end bang state.)
2126    
2127        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
2128          if ($self->{in_subset}) {          if ($self->{in_subset}) {
# Line 2071  sub _get_next_token ($) { Line 2139  sub _get_next_token ($) {
2139    
2140          redo A;          redo A;
2141        } elsif ($self->{nc} == 0x002D) { # -        } elsif ($self->{nc} == 0x002D) { # -
2142          !!!cp (152);          if ($self->{state} == COMMENT_END_BANG_STATE) {
2143          ## XML5: Not a parse error.            !!!cp (154.3);
2144          !!!parse-error (type => 'dash in comment',            $self->{ct}->{data} .= '--!'; # comment
2145                          line => $self->{line_prev},            $self->{state} = COMMENT_END_DASH_STATE;
2146                          column => $self->{column_prev});          } else {
2147          $self->{ct}->{data} .= '-'; # comment            !!!cp (152);
2148          ## Stay in the state            ## XML5: Not a parse error.
2149              !!!parse-error (type => 'dash in comment',
2150                              line => $self->{line_prev},
2151                              column => $self->{column_prev});
2152              $self->{ct}->{data} .= '-'; # comment
2153              ## Stay in the state
2154            }
2155            !!!next-input-character;
2156            redo A;
2157          } elsif ($self->{state} != COMMENT_END_BANG_STATE and
2158                   $is_space->{$self->{nc}}) {
2159            !!!cp (152.1);
2160            !!!parse-error (type => 'comment end space'); # XXX error type
2161            $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2162            $self->{state} = COMMENT_END_SPACE_STATE;
2163            !!!next-input-character;
2164            redo A;
2165          } elsif ($self->{state} != COMMENT_END_BANG_STATE and
2166                   $self->{nc} == 0x0021) { # !
2167            !!!cp (152.2);
2168            !!!parse-error (type => 'comment end bang'); # XXX error type
2169            $self->{state} = COMMENT_END_BANG_STATE;
2170          !!!next-input-character;          !!!next-input-character;
2171          redo A;          redo A;
2172        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
# Line 2090  sub _get_next_token ($) { Line 2179  sub _get_next_token ($) {
2179            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2180            $self->{s_kwd} = '';            $self->{s_kwd} = '';
2181          }          }
2182          ## reconsume          ## Reconsume.
2183    
2184          !!!emit ($self->{ct}); # comment          !!!emit ($self->{ct}); # comment
2185    
2186          redo A;          redo A;
2187        } else {        } else {
2188          !!!cp (154);          !!!cp (154);
2189          ## XML5: Not a parse error.          if ($self->{state} == COMMENT_END_BANG_STATE) {
2190          !!!parse-error (type => 'dash in comment',            $self->{ct}->{data} .= '--!' . chr ($self->{nc}); # comment
2191                          line => $self->{line_prev},          } else {
2192                          column => $self->{column_prev});            $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2193          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment          }
2194          $self->{state} = COMMENT_STATE;          $self->{state} = COMMENT_STATE;
2195          !!!next-input-character;          !!!next-input-character;
2196          redo A;          redo A;
2197        }        }
2198        } elsif ($self->{state} == COMMENT_END_SPACE_STATE) {
2199          ## XML5: Not exist.
2200    
2201          if ($self->{nc} == 0x003E) { # >
2202            if ($self->{in_subset}) {
2203              !!!cp (154.4);
2204              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2205            } else {
2206              !!!cp (154.5);
2207              $self->{state} = DATA_STATE;
2208              $self->{s_kwd} = '';
2209            }
2210            !!!next-input-character;
2211    
2212            !!!emit ($self->{ct}); # comment
2213    
2214            redo A;
2215          } elsif ($is_space->{$self->{nc}}) {
2216            !!!cp (154.6);
2217            $self->{ct}->{data} .= chr ($self->{nc}); # comment
2218            ## Stay in the state.
2219            !!!next-input-character;
2220            redo A;
2221          } elsif ($self->{nc} == -1) {
2222            !!!parse-error (type => 'unclosed comment');
2223            if ($self->{in_subset}) {
2224              !!!cp (154.7);
2225              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2226            } else {
2227              !!!cp (154.8);
2228              $self->{state} = DATA_STATE;
2229              $self->{s_kwd} = '';
2230            }
2231            ## Reconsume.
2232    
2233            !!!emit ($self->{ct}); # comment
2234    
2235            redo A;
2236          } else {
2237            !!!cp (154.9);
2238            $self->{ct}->{data} .= chr ($self->{nc}); # comment
2239            $self->{state} = COMMENT_STATE;
2240            !!!next-input-character;
2241            redo A;
2242          }
2243      } elsif ($self->{state} == DOCTYPE_STATE) {      } elsif ($self->{state} == DOCTYPE_STATE) {
2244        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2245          !!!cp (155);          !!!cp (155);
2246          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2247          !!!next-input-character;          !!!next-input-character;
2248          redo A;          redo A;
2249          } elsif ($self->{nc} == -1) {
2250            !!!cp (155.1);
2251            !!!parse-error (type => 'unclosed DOCTYPE');
2252            $self->{ct}->{quirks} = 1;
2253    
2254            $self->{state} = DATA_STATE;
2255            ## Reconsume.
2256            !!!emit ($self->{ct}); # DOCTYPE (quirks)
2257    
2258            redo A;
2259        } else {        } else {
2260          !!!cp (156);          !!!cp (156);
2261          ## XML5: Unless EOF, swith to the bogus comment state.          ## XML5: Swith to the bogus comment state.
2262          !!!parse-error (type => 'no space before DOCTYPE name');          !!!parse-error (type => 'no space before DOCTYPE name');
2263          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2264          ## reconsume          ## reconsume
# Line 2139  sub _get_next_token ($) { Line 2283  sub _get_next_token ($) {
2283          !!!emit ($self->{ct}); # DOCTYPE (quirks)          !!!emit ($self->{ct}); # DOCTYPE (quirks)
2284    
2285          redo A;          redo A;
2286          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2287            !!!cp (158.1);
2288            $self->{ct}->{name} # DOCTYPE
2289                = chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2290            delete $self->{ct}->{quirks};
2291            $self->{state} = DOCTYPE_NAME_STATE;
2292            !!!next-input-character;
2293            redo A;
2294        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2295          !!!cp (159);          !!!cp (159);
2296          !!!parse-error (type => 'no DOCTYPE name');          !!!parse-error (type => 'no DOCTYPE name');
# Line 2185  sub _get_next_token ($) { Line 2337  sub _get_next_token ($) {
2337          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2338    
2339          redo A;          redo A;
2340          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2341            !!!cp (162.1);
2342            $self->{ct}->{name} # DOCTYPE
2343                .= chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2344            delete $self->{ct}->{quirks};
2345            ## Stay in the state.
2346            !!!next-input-character;
2347            redo A;
2348        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2349          !!!cp (163);          !!!cp (163);
2350          !!!parse-error (type => 'unclosed DOCTYPE');          !!!parse-error (type => 'unclosed DOCTYPE');
# Line 2206  sub _get_next_token ($) { Line 2366  sub _get_next_token ($) {
2366          redo A;          redo A;
2367        } else {        } else {
2368          !!!cp (164);          !!!cp (164);
2369          $self->{ct}->{name}          $self->{ct}->{name} .= chr ($self->{nc}); # DOCTYPE
2370            .= chr ($self->{nc}); # DOCTYPE          ## Stay in the state.
         ## Stay in the state  
2371          !!!next-input-character;          !!!next-input-character;
2372          redo A;          redo A;
2373        }        }
# Line 3071  sub _get_next_token ($) { Line 3230  sub _get_next_token ($) {
3230              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3231              $self->{entity_add} => 1,              $self->{entity_add} => 1,
3232            }->{$self->{nc}}) {            }->{$self->{nc}}) {
3233          !!!cp (1001);          if ($self->{is_xml}) {
3234              !!!cp (1001.1);
3235              !!!parse-error (type => 'bare ero',
3236                              line => $self->{line_prev},
3237                              column => $self->{column_prev}
3238                                  + ($self->{nc} == -1 ? 1 : 0));
3239            } else {
3240              !!!cp (1001);
3241              ## No error
3242            }
3243          ## Don't consume          ## Don't consume
         ## No error  
3244          ## Return nothing.          ## Return nothing.
3245          #          #
3246        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 3082  sub _get_next_token ($) { Line 3249  sub _get_next_token ($) {
3249          $self->{kwd} = '#';          $self->{kwd} = '#';
3250          !!!next-input-character;          !!!next-input-character;
3251          redo A;          redo A;
3252        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
3253                   (0x0041 <= $self->{nc} and
3254                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
3255                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
3256                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 3126  sub _get_next_token ($) { Line 3294  sub _get_next_token ($) {
3294          redo A;          redo A;
3295        }        }
3296      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
3297        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
           $self->{nc} == 0x0058) { # X  
3298          !!!cp (995);          !!!cp (995);
3299          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
3300          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3301          !!!next-input-character;          !!!next-input-character;
3302          redo A;          redo A;
3303          } elsif ($self->{nc} == 0x0058) { # X
3304            !!!cp (995.1);
3305            if ($self->{is_xml}) {
3306              !!!parse-error (type => 'uppercase hcro'); ## TODO: type
3307            }
3308            $self->{state} = HEXREF_X_STATE;
3309            $self->{kwd} .= chr $self->{nc};
3310            !!!next-input-character;
3311            redo A;
3312        } elsif (0x0030 <= $self->{nc} and        } elsif (0x0030 <= $self->{nc} and
3313                 $self->{nc} <= 0x0039) { # 0..9                 $self->{nc} <= 0x0039) { # 0..9
3314          !!!cp (994);          !!!cp (994);
# Line 3193  sub _get_next_token ($) { Line 3369  sub _get_next_token ($) {
3369        my $code = $self->{kwd};        my $code = $self->{kwd};
3370        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3371        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3372        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3373              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3374              ($self->{is_xml} and $code == 0x0000)) {
3375          !!!cp (1015);          !!!cp (1015);
3376          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3377                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3306  sub _get_next_token ($) { Line 3484  sub _get_next_token ($) {
3484        my $code = $self->{kwd};        my $code = $self->{kwd};
3485        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3486        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3487        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3488              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3489              ($self->{is_xml} and $code == 0x0000)) {
3490          !!!cp (1008);          !!!cp (1008);
3491          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3492                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3340  sub _get_next_token ($) { Line 3520  sub _get_next_token ($) {
3520          redo A;          redo A;
3521        }        }
3522      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
3523        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
3524            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
3525            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
3526              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
3527             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
3528              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
3529             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
3530              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
3531             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
3532                    {
3533                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3534                      $self->{entity_add} => 1,
3535                    }->{$self->{nc}}))) {
3536          our $EntityChar;          our $EntityChar;
3537          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3538          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
3539                $self->{ge}->{$self->{kwd}}) {
3540            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
3541              !!!cp (1020);              if (defined $self->{ge}->{$self->{kwd}}) {
3542              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
3543                    !!!cp (1020.1);
3544                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
3545                  } else {
3546                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
3547                      !!!cp (1020.2);
3548                      !!!parse-error (type => 'unparsed entity', ## TODO: type
3549                                      value => $self->{kwd});
3550                    } else {
3551                      !!!cp (1020.3);
3552                    }
3553                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
3554                  }
3555                } else {
3556                  if ($self->{is_xml}) {
3557                    !!!cp (1020.4);
3558                    !!!parse-error (type => 'entity not declared', ## TODO: type
3559                                    value => $self->{kwd},
3560                                    level => {
3561                                              'amp;' => $self->{level}->{warn},
3562                                              'quot;' => $self->{level}->{warn},
3563                                              'lt;' => $self->{level}->{warn},
3564                                              'gt;' => $self->{level}->{warn},
3565                                              'apos;' => $self->{level}->{warn},
3566                                             }->{$self->{kwd}} ||
3567                                             $self->{level}->{must});
3568                  } else {
3569                    !!!cp (1020);
3570                  }
3571                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
3572                }
3573              $self->{entity__match} = 1;              $self->{entity__match} = 1;
3574              !!!next-input-character;              !!!next-input-character;
3575              #              #
# Line 3600  sub _get_next_token ($) { Line 3815  sub _get_next_token ($) {
3815          ## XML5: Not defined yet.          ## XML5: Not defined yet.
3816    
3817          ## TODO:          ## TODO:
3818    
3819            if (not $self->{stop_processing} and
3820                not $self->{document}->xml_standalone) {
3821              !!!parse-error (type => 'stop processing', ## TODO: type
3822                              level => $self->{level}->{info});
3823              $self->{stop_processing} = 1;
3824            }
3825    
3826          !!!next-input-character;          !!!next-input-character;
3827          redo A;          redo A;
3828        } elsif ($self->{nc} == 0x005D) { # ]        } elsif ($self->{nc} == 0x005D) { # ]
# Line 3834  sub _get_next_token ($) { Line 4057  sub _get_next_token ($) {
4057          }          }
4058          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
4059                         line => $self->{line_prev},                         line => $self->{line_prev},
4060                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
4061          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4062          !!!next-input-character;          !!!next-input-character;
4063          redo A;          redo A;
# Line 3882  sub _get_next_token ($) { Line 4105  sub _get_next_token ($) {
4105          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
4106                         attrdefs => [],                         attrdefs => [],
4107                         line => $self->{line_prev},                         line => $self->{line_prev},
4108                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
4109          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4110          !!!next-input-character;          !!!next-input-character;
4111          redo A;          redo A;
# Line 3931  sub _get_next_token ($) { Line 4154  sub _get_next_token ($) {
4154          }          }
4155          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
4156                         line => $self->{line_prev},                         line => $self->{line_prev},
4157                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
4158          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4159          !!!next-input-character;          !!!next-input-character;
4160          redo A;          redo A;
# Line 4043  sub _get_next_token ($) { Line 4266  sub _get_next_token ($) {
4266          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4267            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4268          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4269            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
4270          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
4271            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4272          }          }
# Line 4667  sub _get_next_token ($) { Line 4889  sub _get_next_token ($) {
4889        }        }
4890      } elsif ($self->{state} == NOTATION_NAME_STATE) {      } elsif ($self->{state} == NOTATION_NAME_STATE) {
4891        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4892          $self->{state} = AFTER_NOTATION_NAME_STATE;          $self->{state} = AFTER_MD_DEF_STATE;
4893          !!!next-input-character;          !!!next-input-character;
4894          redo A;          redo A;
4895        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
# Line 4689  sub _get_next_token ($) { Line 4911  sub _get_next_token ($) {
4911        }        }
4912      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
4913        if ($self->{nc} == 0x0022) { # "        if ($self->{nc} == 0x0022) { # "
4914          $self->{state} = AFTER_NOTATION_NAME_STATE;          $self->{state} = AFTER_MD_DEF_STATE;
4915          !!!next-input-character;          !!!next-input-character;
4916          redo A;          redo A;
4917        } elsif ($self->{nc} == 0x0026) { # &        } elsif ($self->{nc} == 0x0026) { # &
# Line 4712  sub _get_next_token ($) { Line 4934  sub _get_next_token ($) {
4934        }        }
4935      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
4936        if ($self->{nc} == 0x0027) { # '        if ($self->{nc} == 0x0027) { # '
4937          $self->{state} = AFTER_NOTATION_NAME_STATE;          $self->{state} = AFTER_MD_DEF_STATE;
4938          !!!next-input-character;          !!!next-input-character;
4939          redo A;          redo A;
4940        } elsif ($self->{nc} == 0x0026) { # &        } elsif ($self->{nc} == 0x0026) { # &
# Line 4734  sub _get_next_token ($) { Line 4956  sub _get_next_token ($) {
4956          redo A;          redo A;
4957        }        }
4958      } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {      } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
       ## TODO: XMLize  
   
4959        if ($is_space->{$self->{nc}} or        if ($is_space->{$self->{nc}} or
4960            {            {
4961              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4962              $self->{entity_add} => 1,              $self->{entity_add} => 1,
4963            }->{$self->{nc}}) {            }->{$self->{nc}}) {
4964            !!!parse-error (type => 'bare ero',
4965                            line => $self->{line_prev},
4966                            column => $self->{column_prev}
4967                                + ($self->{nc} == -1 ? 1 : 0));
4968          ## Don't consume          ## Don't consume
         ## No error  
4969          ## Return nothing.          ## Return nothing.
4970          #          #
4971        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 4751  sub _get_next_token ($) { Line 4974  sub _get_next_token ($) {
4974          $self->{kwd} = '#';          $self->{kwd} = '#';
4975          !!!next-input-character;          !!!next-input-character;
4976          redo A;          redo A;
       } elsif ((0x0041 <= $self->{nc} and  
                 $self->{nc} <= 0x005A) or # A..Z  
                (0x0061 <= $self->{nc} and  
                 $self->{nc} <= 0x007A)) { # a..z  
         #  
4977        } else {        } else {
         !!!parse-error (type => 'bare ero');  
         ## Return nothing.  
4978          #          #
4979        }        }
4980    
# Line 4766  sub _get_next_token ($) { Line 4982  sub _get_next_token ($) {
4982        $self->{state} = $self->{prev_state};        $self->{state} = $self->{prev_state};
4983        ## Reconsume.        ## Reconsume.
4984        redo A;        redo A;
4985      } elsif ($self->{state} == AFTER_NOTATION_NAME_STATE) {      } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
4986          if ($is_space->{$self->{nc}}) {
4987            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
4988            !!!next-input-character;
4989            redo A;
4990          } elsif ($self->{nc} == 0x0028) { # (
4991            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4992            $self->{ct}->{content} = ['('];
4993            $self->{group_depth} = 1;
4994            !!!next-input-character;
4995            redo A;
4996          } elsif ($self->{nc} == 0x003E) { # >
4997            !!!parse-error (type => 'no md def'); ## TODO: type
4998            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4999            !!!next-input-character;
5000            !!!emit ($self->{ct}); # ELEMENT
5001            redo A;
5002          } elsif ($self->{nc} == -1) {
5003            !!!parse-error (type => 'unclosed md'); ## TODO: type
5004            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5005            !!!next-input-character;
5006            !!!emit ($self->{ct}); # ELEMENT
5007            redo A;
5008          } else {
5009            $self->{ct}->{content} = [chr $self->{nc}];
5010            $self->{state} = CONTENT_KEYWORD_STATE;
5011            !!!next-input-character;
5012            redo A;
5013          }
5014        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
5015          if ($is_space->{$self->{nc}}) {
5016            $self->{state} = AFTER_MD_DEF_STATE;
5017            !!!next-input-character;
5018            redo A;
5019          } elsif ($self->{nc} == 0x003E) { # >
5020            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5021            !!!next-input-character;
5022            !!!emit ($self->{ct}); # ELEMENT
5023            redo A;
5024          } elsif ($self->{nc} == -1) {
5025            !!!parse-error (type => 'unclosed md'); ## TODO: type
5026            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5027            !!!next-input-character;
5028            !!!emit ($self->{ct}); # ELEMENT
5029            redo A;
5030          } else {
5031            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
5032            ## Stay in the state.
5033            !!!next-input-character;
5034            redo A;
5035          }
5036        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
5037        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
5038          ## Stay in the state.          ## Stay in the state.
5039          !!!next-input-character;          !!!next-input-character;
5040          redo A;          redo A;
5041          } elsif ($self->{nc} == 0x0028) { # (
5042            $self->{group_depth}++;
5043            push @{$self->{ct}->{content}}, chr $self->{nc};
5044            ## Stay in the state.
5045            !!!next-input-character;
5046            redo A;
5047          } elsif ($self->{nc} == 0x007C or # |
5048                   $self->{nc} == 0x002C) { # ,
5049            !!!parse-error (type => 'empty element name'); ## TODO: type
5050            ## Stay in the state.
5051            !!!next-input-character;
5052            redo A;
5053          } elsif ($self->{nc} == 0x0029) { # )
5054            !!!parse-error (type => 'empty element name'); ## TODO: type
5055            push @{$self->{ct}->{content}}, chr $self->{nc};
5056            $self->{group_depth}--;
5057            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5058            !!!next-input-character;
5059            redo A;
5060        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
5061            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5062            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5063          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5064          !!!next-input-character;          !!!next-input-character;
5065          !!!emit ($self->{ct}); # ENTITY          !!!emit ($self->{ct}); # ELEMENT
5066          redo A;          redo A;
5067        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
5068          !!!parse-error (type => 'unclosed md'); ## TODO: type          !!!parse-error (type => 'unclosed md'); ## TODO: type
5069            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5070          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5071          !!!next-input-character;          !!!next-input-character;
5072          !!!emit ($self->{ct}); # ENTITY          !!!emit ($self->{ct}); # ELEMENT
5073            redo A;
5074          } else {
5075            push @{$self->{ct}->{content}}, chr $self->{nc};
5076            $self->{state} = CM_ELEMENT_NAME_STATE;
5077            !!!next-input-character;
5078            redo A;
5079          }
5080        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
5081          if ($is_space->{$self->{nc}}) {
5082            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5083            !!!next-input-character;
5084            redo A;
5085          } elsif ($self->{nc} == 0x002A or # *
5086                   $self->{nc} == 0x002B or # +
5087                   $self->{nc} == 0x003F) { # ?
5088            push @{$self->{ct}->{content}}, chr $self->{nc};
5089            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5090            !!!next-input-character;
5091            redo A;
5092          } elsif ($self->{nc} == 0x007C or # |
5093                   $self->{nc} == 0x002C) { # ,
5094            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5095            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5096            !!!next-input-character;
5097            redo A;
5098          } elsif ($self->{nc} == 0x0029) { # )
5099            $self->{group_depth}--;
5100            push @{$self->{ct}->{content}}, chr $self->{nc};
5101            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5102            !!!next-input-character;
5103            redo A;
5104          } elsif ($self->{nc} == 0x003E) { # >
5105            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5106            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5107            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5108            !!!next-input-character;
5109            !!!emit ($self->{ct}); # ELEMENT
5110            redo A;
5111          } elsif ($self->{nc} == -1) {
5112            !!!parse-error (type => 'unclosed md'); ## TODO: type
5113            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5114            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5115            !!!next-input-character;
5116            !!!emit ($self->{ct}); # ELEMENT
5117            redo A;
5118          } else {
5119            $self->{ct}->{content}->[-1] .= chr $self->{nc};
5120            ## Stay in the state.
5121            !!!next-input-character;
5122            redo A;
5123          }
5124        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
5125          if ($is_space->{$self->{nc}}) {
5126            ## Stay in the state.
5127            !!!next-input-character;
5128            redo A;
5129          } elsif ($self->{nc} == 0x007C or # |
5130                   $self->{nc} == 0x002C) { # ,
5131            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5132            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5133            !!!next-input-character;
5134            redo A;
5135          } elsif ($self->{nc} == 0x0029) { # )
5136            $self->{group_depth}--;
5137            push @{$self->{ct}->{content}}, chr $self->{nc};
5138            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5139            !!!next-input-character;
5140            redo A;
5141          } elsif ($self->{nc} == 0x003E) { # >
5142            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5143            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5144            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5145            !!!next-input-character;
5146            !!!emit ($self->{ct}); # ELEMENT
5147            redo A;
5148          } elsif ($self->{nc} == -1) {
5149            !!!parse-error (type => 'unclosed md'); ## TODO: type
5150            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5151            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5152            !!!next-input-character;
5153            !!!emit ($self->{ct}); # ELEMENT
5154            redo A;
5155          } else {
5156            !!!parse-error (type => 'after element name'); ## TODO: type
5157            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5158            $self->{state} = BOGUS_MD_STATE;
5159            !!!next-input-character;
5160            redo A;
5161          }
5162        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
5163          if ($is_space->{$self->{nc}}) {
5164            if ($self->{group_depth}) {
5165              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5166            } else {
5167              $self->{state} = AFTER_MD_DEF_STATE;
5168            }
5169            !!!next-input-character;
5170            redo A;
5171          } elsif ($self->{nc} == 0x002A or # *
5172                   $self->{nc} == 0x002B or # +
5173                   $self->{nc} == 0x003F) { # ?
5174            push @{$self->{ct}->{content}}, chr $self->{nc};
5175            if ($self->{group_depth}) {
5176              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5177            } else {
5178              $self->{state} = AFTER_MD_DEF_STATE;
5179            }
5180            !!!next-input-character;
5181            redo A;
5182          } elsif ($self->{nc} == 0x0029) { # )
5183            if ($self->{group_depth}) {
5184              $self->{group_depth}--;
5185              push @{$self->{ct}->{content}}, chr $self->{nc};
5186              ## Stay in the state.
5187              !!!next-input-character;
5188              redo A;
5189            } else {
5190              !!!parse-error (type => 'string after md def'); ## TODO: type
5191              $self->{state} = BOGUS_MD_STATE;
5192              ## Reconsume.
5193              redo A;
5194            }
5195          } elsif ($self->{nc} == 0x003E) { # >
5196            if ($self->{group_depth}) {
5197              !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5198              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5199            }
5200            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5201            !!!next-input-character;
5202            !!!emit ($self->{ct}); # ELEMENT
5203            redo A;
5204          } elsif ($self->{nc} == -1) {
5205            !!!parse-error (type => 'unclosed md'); ## TODO: type
5206            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5207            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5208            !!!next-input-character;
5209            !!!emit ($self->{ct}); # ELEMENT
5210            redo A;
5211          } else {
5212            if ($self->{group_depth}) {
5213              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5214            } else {
5215              !!!parse-error (type => 'string after md def'); ## TODO: type
5216              $self->{state} = BOGUS_MD_STATE;
5217            }
5218            ## Reconsume.
5219            redo A;
5220          }
5221        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
5222          if ($is_space->{$self->{nc}}) {
5223            ## Stay in the state.
5224            !!!next-input-character;
5225            redo A;
5226          } elsif ($self->{nc} == 0x003E) { # >
5227            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5228            !!!next-input-character;
5229            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5230            redo A;
5231          } elsif ($self->{nc} == -1) {
5232            !!!parse-error (type => 'unclosed md'); ## TODO: type
5233            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5234            !!!next-input-character;
5235            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5236          redo A;          redo A;
5237        } else {        } else {
5238          !!!parse-error (type => 'string after notation name'); ## TODO: type          !!!parse-error (type => 'string after md def'); ## TODO: type
5239          $self->{state} = BOGUS_MD_STATE;          $self->{state} = BOGUS_MD_STATE;
5240          ## Reconsume.          ## Reconsume.
5241          redo A;          redo A;

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.33

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24