/[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.15 by wakaba, Sat Oct 18 08:05:29 2008 UTC revision 1.32 by wakaba, Sat Sep 5 09:57:55 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 177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO Line 179  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO
179  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }
180  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }
181  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }
182    sub BEFORE_NDATA_STATE () { 85 }
183    sub NDATA_STATE () { 86 }
184    sub AFTER_NDATA_STATE () { 87 }
185    sub BEFORE_NOTATION_NAME_STATE () { 88 }
186    sub NOTATION_NAME_STATE () { 89 }
187    sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
188    sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 91 }
189    sub ENTITY_VALUE_ENTITY_STATE () { 92 }
190    sub AFTER_ELEMENT_NAME_STATE () { 93 }
191    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 931  sub _get_next_token ($) { Line 950  sub _get_next_token ($) {
950          if ({          if ({
951               0x0022 => 1, # "               0x0022 => 1, # "
952               0x0027 => 1, # '               0x0027 => 1, # '
953                 0x003C => 1, # <
954               0x003D => 1, # =               0x003D => 1, # =
955              }->{$self->{nc}}) {              }->{$self->{nc}}) {
956            !!!cp (55);            !!!cp (55);
# Line 1053  sub _get_next_token ($) { Line 1073  sub _get_next_token ($) {
1073    
1074          redo A;          redo A;
1075        } else {        } else {
1076          if ($self->{nc} == 0x0022 or # "          if ({
1077              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1078                 0x0027 => 1, # '
1079                 0x003C => 1, # <
1080                }->{$self->{nc}}) {
1081            !!!cp (69);            !!!cp (69);
1082            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1083            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1165  sub _get_next_token ($) { Line 1188  sub _get_next_token ($) {
1188            !!!cp (78.2);            !!!cp (78.2);
1189          }          }
1190    
1191          if ($self->{nc} == 0x0022 or # "          if ({
1192              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1193                 0x0027 => 1, # '
1194                 0x003C => 1, # <
1195                }->{$self->{nc}}) {
1196            !!!cp (78);            !!!cp (78);
1197            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1198            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1253  sub _get_next_token ($) { Line 1279  sub _get_next_token ($) {
1279    
1280          redo A;          redo A;
1281        } else {        } else {
1282          if ($self->{nc} == 0x003D) { # =          if ($self->{nc} == 0x003D or $self->{nc} == 0x003C) { # =, <
1283            !!!cp (93);            !!!cp (93);
1284            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1285            !!!parse-error (type => 'bad attribute value');            !!!parse-error (type => 'bad attribute value');
# Line 1299  sub _get_next_token ($) { Line 1325  sub _get_next_token ($) {
1325          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1326          !!!next-input-character;          !!!next-input-character;
1327          redo A;          redo A;
1328          } elsif ($self->{is_xml} and
1329                   $is_space->{$self->{nc}}) {
1330            !!!cp (97.1);
1331            $self->{ca}->{value} .= ' ';
1332            ## Stay in the state.
1333            !!!next-input-character;
1334            redo A;
1335        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1336          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1337          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1346  sub _get_next_token ($) { Line 1379  sub _get_next_token ($) {
1379          }          }
1380          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1381          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1382                                q["&<],                                qq["&<\x09\x0C\x20],
1383                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1384    
1385          ## Stay in the state          ## Stay in the state
# Line 1383  sub _get_next_token ($) { Line 1416  sub _get_next_token ($) {
1416          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1417          !!!next-input-character;          !!!next-input-character;
1418          redo A;          redo A;
1419          } elsif ($self->{is_xml} and
1420                   $is_space->{$self->{nc}}) {
1421            !!!cp (103.1);
1422            $self->{ca}->{value} .= ' ';
1423            ## Stay in the state.
1424            !!!next-input-character;
1425            redo A;
1426        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1427          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1428          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1430  sub _get_next_token ($) { Line 1470  sub _get_next_token ($) {
1470          }          }
1471          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1472          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1473                                q['&<],                                qq['&<\x09\x0C\x20],
1474                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1475    
1476          ## Stay in the state          ## Stay in the state
# Line 1542  sub _get_next_token ($) { Line 1582  sub _get_next_token ($) {
1582               0x0022 => 1, # "               0x0022 => 1, # "
1583               0x0027 => 1, # '               0x0027 => 1, # '
1584               0x003D => 1, # =               0x003D => 1, # =
1585                 0x003C => 1, # <
1586              }->{$self->{nc}}) {              }->{$self->{nc}}) {
1587            !!!cp (115);            !!!cp (115);
1588            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1551  sub _get_next_token ($) { Line 1592  sub _get_next_token ($) {
1592          }          }
1593          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1594          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1595                                q["'=& >],                                qq["'=& \x09\x0C>],
1596                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1597    
1598          ## Stay in the state          ## Stay in the state
# Line 2043  sub _get_next_token ($) { Line 2084  sub _get_next_token ($) {
2084          !!!next-input-character;          !!!next-input-character;
2085          redo A;          redo A;
2086        }        }
2087      } elsif ($self->{state} == COMMENT_END_STATE) {      } elsif ($self->{state} == COMMENT_END_STATE or
2088                 $self->{state} == COMMENT_END_BANG_STATE) {
2089        ## XML5: "Comment end state" and "DOCTYPE comment end state".        ## XML5: "Comment end state" and "DOCTYPE comment end state".
2090          ## (No comment end bang state.)
2091    
2092        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
2093          if ($self->{in_subset}) {          if ($self->{in_subset}) {
# Line 2061  sub _get_next_token ($) { Line 2104  sub _get_next_token ($) {
2104    
2105          redo A;          redo A;
2106        } elsif ($self->{nc} == 0x002D) { # -        } elsif ($self->{nc} == 0x002D) { # -
2107          !!!cp (152);          if ($self->{state} == COMMENT_END_BANG_STATE) {
2108          ## XML5: Not a parse error.            !!!cp (154.3);
2109          !!!parse-error (type => 'dash in comment',            $self->{ct}->{data} .= '--!'; # comment
2110                          line => $self->{line_prev},            $self->{state} = COMMENT_END_DASH_STATE;
2111                          column => $self->{column_prev});          } else {
2112          $self->{ct}->{data} .= '-'; # comment            !!!cp (152);
2113          ## Stay in the state            ## XML5: Not a parse error.
2114              !!!parse-error (type => 'dash in comment',
2115                              line => $self->{line_prev},
2116                              column => $self->{column_prev});
2117              $self->{ct}->{data} .= '-'; # comment
2118              ## Stay in the state
2119            }
2120            !!!next-input-character;
2121            redo A;
2122          } elsif ($self->{state} != COMMENT_END_BANG_STATE and
2123                   $is_space->{$self->{nc}}) {
2124            !!!cp (152.1);
2125            !!!parse-error (type => 'comment end space'); # XXX error type
2126            $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2127            $self->{state} = COMMENT_END_SPACE_STATE;
2128            !!!next-input-character;
2129            redo A;
2130          } elsif ($self->{state} != COMMENT_END_BANG_STATE and
2131                   $self->{nc} == 0x0021) { # !
2132            !!!cp (152.2);
2133            !!!parse-error (type => 'comment end bang'); # XXX error type
2134            $self->{state} = COMMENT_END_BANG_STATE;
2135          !!!next-input-character;          !!!next-input-character;
2136          redo A;          redo A;
2137        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
# Line 2080  sub _get_next_token ($) { Line 2144  sub _get_next_token ($) {
2144            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2145            $self->{s_kwd} = '';            $self->{s_kwd} = '';
2146          }          }
2147          ## reconsume          ## Reconsume.
2148    
2149          !!!emit ($self->{ct}); # comment          !!!emit ($self->{ct}); # comment
2150    
2151          redo A;          redo A;
2152        } else {        } else {
2153          !!!cp (154);          !!!cp (154);
2154          ## XML5: Not a parse error.          if ($self->{state} == COMMENT_END_BANG_STATE) {
2155          !!!parse-error (type => 'dash in comment',            $self->{ct}->{data} .= '--!' . chr ($self->{nc}); # comment
2156                          line => $self->{line_prev},          } else {
2157                          column => $self->{column_prev});            $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2158          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment          }
2159          $self->{state} = COMMENT_STATE;          $self->{state} = COMMENT_STATE;
2160          !!!next-input-character;          !!!next-input-character;
2161          redo A;          redo A;
2162        }        }
2163        } elsif ($self->{state} == COMMENT_END_SPACE_STATE) {
2164          ## XML5: Not exist.
2165    
2166          if ($self->{nc} == 0x003E) { # >
2167            if ($self->{in_subset}) {
2168              !!!cp (154.4);
2169              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2170            } else {
2171              !!!cp (154.5);
2172              $self->{state} = DATA_STATE;
2173              $self->{s_kwd} = '';
2174            }
2175            !!!next-input-character;
2176    
2177            !!!emit ($self->{ct}); # comment
2178    
2179            redo A;
2180          } elsif ($is_space->{$self->{nc}}) {
2181            !!!cp (154.6);
2182            $self->{ct}->{data} .= chr ($self->{nc}); # comment
2183            ## Stay in the state.
2184            !!!next-input-character;
2185            redo A;
2186          } elsif ($self->{nc} == -1) {
2187            !!!parse-error (type => 'unclosed comment');
2188            if ($self->{in_subset}) {
2189              !!!cp (154.7);
2190              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2191            } else {
2192              !!!cp (154.8);
2193              $self->{state} = DATA_STATE;
2194              $self->{s_kwd} = '';
2195            }
2196            ## Reconsume.
2197    
2198            !!!emit ($self->{ct}); # comment
2199    
2200            redo A;
2201          } else {
2202            !!!cp (154.9);
2203            $self->{ct}->{data} .= chr ($self->{nc}); # comment
2204            $self->{state} = COMMENT_STATE;
2205            !!!next-input-character;
2206            redo A;
2207          }
2208      } elsif ($self->{state} == DOCTYPE_STATE) {      } elsif ($self->{state} == DOCTYPE_STATE) {
2209        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2210          !!!cp (155);          !!!cp (155);
2211          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2212          !!!next-input-character;          !!!next-input-character;
2213          redo A;          redo A;
2214          } elsif ($self->{nc} == -1) {
2215            !!!cp (155.1);
2216            !!!parse-error (type => 'unclosed DOCTYPE');
2217            $self->{ct}->{quirks} = 1;
2218    
2219            $self->{state} = DATA_STATE;
2220            ## Reconsume.
2221            !!!emit ($self->{ct}); # DOCTYPE (quirks)
2222    
2223            redo A;
2224        } else {        } else {
2225          !!!cp (156);          !!!cp (156);
2226          ## XML5: Unless EOF, swith to the bogus comment state.          ## XML5: Swith to the bogus comment state.
2227          !!!parse-error (type => 'no space before DOCTYPE name');          !!!parse-error (type => 'no space before DOCTYPE name');
2228          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2229          ## reconsume          ## reconsume
# Line 2129  sub _get_next_token ($) { Line 2248  sub _get_next_token ($) {
2248          !!!emit ($self->{ct}); # DOCTYPE (quirks)          !!!emit ($self->{ct}); # DOCTYPE (quirks)
2249    
2250          redo A;          redo A;
2251          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2252            !!!cp (158.1);
2253            $self->{ct}->{name} # DOCTYPE
2254                = chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2255            delete $self->{ct}->{quirks};
2256            $self->{state} = DOCTYPE_NAME_STATE;
2257            !!!next-input-character;
2258            redo A;
2259        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2260          !!!cp (159);          !!!cp (159);
2261          !!!parse-error (type => 'no DOCTYPE name');          !!!parse-error (type => 'no DOCTYPE name');
# Line 2175  sub _get_next_token ($) { Line 2302  sub _get_next_token ($) {
2302          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2303    
2304          redo A;          redo A;
2305          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2306            !!!cp (162.1);
2307            $self->{ct}->{name} # DOCTYPE
2308                .= chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2309            delete $self->{ct}->{quirks};
2310            ## Stay in the state.
2311            !!!next-input-character;
2312            redo A;
2313        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2314          !!!cp (163);          !!!cp (163);
2315          !!!parse-error (type => 'unclosed DOCTYPE');          !!!parse-error (type => 'unclosed DOCTYPE');
# Line 2196  sub _get_next_token ($) { Line 2331  sub _get_next_token ($) {
2331          redo A;          redo A;
2332        } else {        } else {
2333          !!!cp (164);          !!!cp (164);
2334          $self->{ct}->{name}          $self->{ct}->{name} .= chr ($self->{nc}); # DOCTYPE
2335            .= chr ($self->{nc}); # DOCTYPE          ## Stay in the state.
         ## Stay in the state  
2336          !!!next-input-character;          !!!next-input-character;
2337          redo A;          redo A;
2338        }        }
# Line 2212  sub _get_next_token ($) { Line 2346  sub _get_next_token ($) {
2346          !!!next-input-character;          !!!next-input-character;
2347          redo A;          redo A;
2348        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2349          !!!cp (166);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2350          $self->{state} = DATA_STATE;            !!!cp (166);
2351          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2352              $self->{s_kwd} = '';
2353            } else {
2354              !!!cp (166.1);
2355              !!!parse-error (type => 'no md def'); ## TODO: type
2356              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2357            }
2358            
2359          !!!next-input-character;          !!!next-input-character;
2360            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         !!!emit ($self->{ct}); # DOCTYPE  
   
2361          redo A;          redo A;
2362        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2363          !!!cp (167);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2364          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (167);
2365          $self->{state} = DATA_STATE;            !!!parse-error (type => 'unclosed DOCTYPE');
2366          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2367          ## reconsume            $self->{s_kwd} = '';
2368              $self->{ct}->{quirks} = 1;
2369          $self->{ct}->{quirks} = 1;          } else {
2370          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (167.12);
2371              !!!parse-error (type => 'unclosed md'); ## TODO: type
2372              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2373            }
2374            
2375            ## Reconsume.
2376            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2377          redo A;          redo A;
2378        } elsif ($self->{nc} == 0x0050 or # P        } elsif ($self->{nc} == 0x0050 or # P
2379                 $self->{nc} == 0x0070) { # p                 $self->{nc} == 0x0070) { # p
# Line 2245  sub _get_next_token ($) { Line 2389  sub _get_next_token ($) {
2389          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
2390          !!!next-input-character;          !!!next-input-character;
2391          redo A;          redo A;
2392        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{nc} == 0x0022 and # "
2393                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2394                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2395            !!!cp (167.21);
2396            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
2397            $self->{ct}->{value} = ''; # ENTITY
2398            !!!next-input-character;
2399            redo A;
2400          } elsif ($self->{nc} == 0x0027 and # '
2401                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2402                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2403            !!!cp (167.22);
2404            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
2405            $self->{ct}->{value} = ''; # ENTITY
2406            !!!next-input-character;
2407            redo A;
2408          } elsif ($self->{is_xml} and
2409                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2410                   $self->{nc} == 0x005B) { # [
2411          !!!cp (167.3);          !!!cp (167.3);
2412          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2413          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 2254  sub _get_next_token ($) { Line 2416  sub _get_next_token ($) {
2416          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2417          redo A;          redo A;
2418        } else {        } else {
2419          !!!cp (180);          !!!parse-error (type => 'string after DOCTYPE name'); ## TODO: type
2420          !!!parse-error (type => 'string after DOCTYPE name');  
2421          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2422              !!!cp (180);
2423              $self->{ct}->{quirks} = 1;
2424              $self->{state} = BOGUS_DOCTYPE_STATE;
2425            } else {
2426              !!!cp (180.1);
2427              $self->{state} = BOGUS_MD_STATE;
2428            }
2429    
         $self->{state} = BOGUS_DOCTYPE_STATE;  
2430          !!!next-input-character;          !!!next-input-character;
2431          redo A;          redo A;
2432        }        }
# Line 2300  sub _get_next_token ($) { Line 2468  sub _get_next_token ($) {
2468          !!!next-input-character;          !!!next-input-character;
2469          redo A;          redo A;
2470        } else {        } else {
2471          !!!cp (169);          !!!parse-error (type => 'string after DOCTYPE name', ## TODO: type
         !!!parse-error (type => 'string after DOCTYPE name',  
2472                          line => $self->{line_prev},                          line => $self->{line_prev},
2473                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
2474          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2475              !!!cp (169);
2476          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
2477              $self->{state} = BOGUS_DOCTYPE_STATE;
2478            } else {
2479              !!!cp (169.1);
2480              $self->{state} = BOGUS_MD_STATE;
2481            }
2482          ## Reconsume.          ## Reconsume.
2483          redo A;          redo A;
2484        }        }
# Line 2348  sub _get_next_token ($) { Line 2520  sub _get_next_token ($) {
2520          !!!next-input-character;          !!!next-input-character;
2521          redo A;          redo A;
2522        } else {        } else {
2523          !!!cp (172);          !!!parse-error (type => 'string after DOCTYPE name', ## TODO: type
         !!!parse-error (type => 'string after DOCTYPE name',  
2524                          line => $self->{line_prev},                          line => $self->{line_prev},
2525                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
2526          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2527              !!!cp (172);
2528          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
2529              $self->{state} = BOGUS_DOCTYPE_STATE;
2530            } else {
2531              !!!cp (172.1);
2532              $self->{state} = BOGUS_MD_STATE;
2533            }
2534          ## Reconsume.          ## Reconsume.
2535          redo A;          redo A;
2536        }        }
# Line 2377  sub _get_next_token ($) { Line 2553  sub _get_next_token ($) {
2553          !!!next-input-character;          !!!next-input-character;
2554          redo A;          redo A;
2555        } elsif ($self->{nc} eq 0x003E) { # >        } elsif ($self->{nc} eq 0x003E) { # >
         !!!cp (184);  
2556          !!!parse-error (type => 'no PUBLIC literal');          !!!parse-error (type => 'no PUBLIC literal');
2557            
2558          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2559          $self->{s_kwd} = '';            !!!cp (184);
2560              $self->{state} = DATA_STATE;
2561              $self->{s_kwd} = '';
2562              $self->{ct}->{quirks} = 1;
2563            } else {
2564              !!!cp (184.1);
2565              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2566            }
2567            
2568          !!!next-input-character;          !!!next-input-character;
2569            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2570          redo A;          redo A;
2571        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2572          !!!cp (185);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2573          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (185);
2574              !!!parse-error (type => 'unclosed DOCTYPE');
2575          $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2576          $self->{s_kwd} = '';            $self->{s_kwd} = '';
2577              $self->{ct}->{quirks} = 1;
2578            } else {
2579              !!!cp (185.1);
2580              !!!parse-error (type => 'unclosed md'); ## TODO: type
2581              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2582            }
2583            
2584          ## reconsume          ## reconsume
   
         $self->{ct}->{quirks} = 1;  
2585          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
   
2586          redo A;          redo A;
2587        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2588                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2589                   $self->{nc} == 0x005B) { # [
2590          !!!cp (186.1);          !!!cp (186.1);
2591          !!!parse-error (type => 'no PUBLIC literal');          !!!parse-error (type => 'no PUBLIC literal');
2592          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 2410  sub _get_next_token ($) { Line 2596  sub _get_next_token ($) {
2596          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2597          redo A;          redo A;
2598        } else {        } else {
         !!!cp (186);  
2599          !!!parse-error (type => 'string after PUBLIC');          !!!parse-error (type => 'string after PUBLIC');
         $self->{ct}->{quirks} = 1;  
2600    
2601          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2602              !!!cp (186);
2603              $self->{ct}->{quirks} = 1;
2604              $self->{state} = BOGUS_DOCTYPE_STATE;
2605            } else {
2606              !!!cp (186.2);
2607              $self->{state} = BOGUS_MD_STATE;
2608            }
2609    
2610          !!!next-input-character;          !!!next-input-character;
2611          redo A;          redo A;
2612        }        }
# Line 2425  sub _get_next_token ($) { Line 2617  sub _get_next_token ($) {
2617          !!!next-input-character;          !!!next-input-character;
2618          redo A;          redo A;
2619        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (188);  
2620          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2621    
2622          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2623          $self->{s_kwd} = '';            !!!cp (188);
2624          !!!next-input-character;            $self->{state} = DATA_STATE;
2625              $self->{s_kwd} = '';
2626          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2627          !!!emit ($self->{ct}); # DOCTYPE          } else {
2628              !!!cp (188.1);
2629              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2630            }
2631    
2632            !!!next-input-character;
2633            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2634          redo A;          redo A;
2635        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (189);  
2636          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2637    
2638          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2639          $self->{s_kwd} = '';            !!!cp (189);
2640          ## reconsume            $self->{state} = DATA_STATE;
2641              $self->{s_kwd} = '';
2642          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2643            } else {
2644              !!!cp (189.1);
2645              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2646            }
2647            
2648            ## Reconsume.
2649          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
   
2650          redo A;          redo A;
2651        } else {        } else {
2652          !!!cp (190);          !!!cp (190);
2653          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2654          $self->{read_until}->($self->{ct}->{pubid}, q[">],          $self->{read_until}->($self->{ct}->{pubid}, q[">],
2655                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
2656    
# Line 2466  sub _get_next_token ($) { Line 2665  sub _get_next_token ($) {
2665          !!!next-input-character;          !!!next-input-character;
2666          redo A;          redo A;
2667        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (192);  
2668          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2669    
2670          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2671          $self->{s_kwd} = '';            !!!cp (192);
2672          !!!next-input-character;            $self->{state} = DATA_STATE;
2673              $self->{s_kwd} = '';
2674          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2675          !!!emit ($self->{ct}); # DOCTYPE          } else {
2676              !!!cp (192.1);
2677              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2678            }
2679    
2680            !!!next-input-character;
2681            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2682          redo A;          redo A;
2683        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (193);  
2684          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2685    
2686          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2687          $self->{s_kwd} = '';            !!!cp (193);
2688              $self->{state} = DATA_STATE;
2689              $self->{s_kwd} = '';
2690              $self->{ct}->{quirks} = 1;
2691            } else {
2692              !!!cp (193.1);
2693              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2694            }
2695          
2696          ## reconsume          ## reconsume
2697            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2698          redo A;          redo A;
2699        } else {        } else {
2700          !!!cp (194);          !!!cp (194);
2701          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2702          $self->{read_until}->($self->{ct}->{pubid}, q['>],          $self->{read_until}->($self->{ct}->{pubid}, q['>],
2703                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
2704    
# Line 2508  sub _get_next_token ($) { Line 2714  sub _get_next_token ($) {
2714          redo A;          redo A;
2715        } elsif ($self->{nc} == 0x0022) { # "        } elsif ($self->{nc} == 0x0022) { # "
2716          !!!cp (196);          !!!cp (196);
2717          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
2718          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
2719          !!!next-input-character;          !!!next-input-character;
2720          redo A;          redo A;
2721        } elsif ($self->{nc} == 0x0027) { # '        } elsif ($self->{nc} == 0x0027) { # '
2722          !!!cp (197);          !!!cp (197);
2723          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
2724          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
2725          !!!next-input-character;          !!!next-input-character;
2726          redo A;          redo A;
2727        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2728          if ($self->{is_xml}) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2729            !!!cp (198.1);            if ($self->{is_xml}) {
2730            !!!parse-error (type => 'no SYSTEM literal');              !!!cp (198.1);
2731                !!!parse-error (type => 'no SYSTEM literal');
2732              } else {
2733                !!!cp (198);
2734              }
2735              $self->{state} = DATA_STATE;
2736              $self->{s_kwd} = '';
2737          } else {          } else {
2738            !!!cp (198);            if ($self->{ct}->{type} == NOTATION_TOKEN) {
2739                !!!cp (198.2);
2740              } else {
2741                !!!cp (198.3);
2742                !!!parse-error (type => 'no SYSTEM literal');            
2743              }
2744              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2745          }          }
2746          $self->{state} = DATA_STATE;          
         $self->{s_kwd} = '';  
2747          !!!next-input-character;          !!!next-input-character;
2748            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         !!!emit ($self->{ct}); # DOCTYPE  
   
2749          redo A;          redo A;
2750        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2751          !!!cp (199);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2752          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (199);
2753              !!!parse-error (type => 'unclosed DOCTYPE');
2754          $self->{state} = DATA_STATE;            
2755          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2756              $self->{s_kwd} = '';
2757              $self->{ct}->{quirks} = 1;
2758            } else {
2759              !!!parse-error (type => 'unclosed md'); ## TODO: type
2760              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2761            }
2762            
2763          ## reconsume          ## reconsume
2764            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2765          redo A;          redo A;
2766        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2767                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2768                   $self->{nc} == 0x005B) { # [
2769          !!!cp (200.1);          !!!cp (200.1);
2770          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
2771          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 2554  sub _get_next_token ($) { Line 2775  sub _get_next_token ($) {
2775          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2776          redo A;          redo A;
2777        } else {        } else {
         !!!cp (200);  
2778          !!!parse-error (type => 'string after PUBLIC literal');          !!!parse-error (type => 'string after PUBLIC literal');
         $self->{ct}->{quirks} = 1;  
2779    
2780          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2781              !!!cp (200);
2782              $self->{ct}->{quirks} = 1;
2783              $self->{state} = BOGUS_DOCTYPE_STATE;
2784            } else {
2785              !!!cp (200.2);
2786              $self->{state} = BOGUS_MD_STATE;
2787            }
2788    
2789          !!!next-input-character;          !!!next-input-character;
2790          redo A;          redo A;
2791        }        }
# Line 2581  sub _get_next_token ($) { Line 2808  sub _get_next_token ($) {
2808          !!!next-input-character;          !!!next-input-character;
2809          redo A;          redo A;
2810        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (204);  
2811          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
2812          !!!next-input-character;          !!!next-input-character;
2813    
2814          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2815          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (204);
2816              $self->{state} = DATA_STATE;
2817              $self->{s_kwd} = '';
2818              $self->{ct}->{quirks} = 1;
2819            } else {
2820              !!!cp (204.1);
2821              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2822            }
2823    
2824            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2825          redo A;          redo A;
2826        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2827          !!!cp (205);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2828          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (205);
2829              !!!parse-error (type => 'unclosed DOCTYPE');
2830          $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2831          $self->{s_kwd} = '';            $self->{s_kwd} = '';
2832              $self->{ct}->{quirks} = 1;
2833            } else {
2834              !!!cp (205.1);
2835              !!!parse-error (type => 'unclosed md'); ## TODO: type
2836              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2837            }
2838            
2839          ## reconsume          ## reconsume
2840            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2841          redo A;          redo A;
2842        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2843                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2844                   $self->{nc} == 0x005B) { # [
2845          !!!cp (206.1);          !!!cp (206.1);
2846          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
2847    
# Line 2614  sub _get_next_token ($) { Line 2852  sub _get_next_token ($) {
2852          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2853          redo A;          redo A;
2854        } else {        } else {
         !!!cp (206);  
2855          !!!parse-error (type => 'string after SYSTEM');          !!!parse-error (type => 'string after SYSTEM');
         $self->{ct}->{quirks} = 1;  
2856    
2857          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2858              !!!cp (206);          
2859              $self->{ct}->{quirks} = 1;
2860              $self->{state} = BOGUS_DOCTYPE_STATE;
2861            } else {
2862              !!!cp (206.2);
2863              $self->{state} = BOGUS_MD_STATE;
2864            }
2865    
2866          !!!next-input-character;          !!!next-input-character;
2867          redo A;          redo A;
2868        }        }
# Line 2629  sub _get_next_token ($) { Line 2873  sub _get_next_token ($) {
2873          !!!next-input-character;          !!!next-input-character;
2874          redo A;          redo A;
2875        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >
         !!!cp (208);  
2876          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2877    
2878          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2879          $self->{s_kwd} = '';            !!!cp (208);
2880              $self->{state} = DATA_STATE;
2881              $self->{s_kwd} = '';
2882              $self->{ct}->{quirks} = 1;
2883            } else {
2884              !!!cp (208.1);
2885              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2886            }
2887            
2888          !!!next-input-character;          !!!next-input-character;
2889            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2890          redo A;          redo A;
2891        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (209);  
2892          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2893    
2894          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2895          $self->{s_kwd} = '';            !!!cp (209);
2896              $self->{state} = DATA_STATE;
2897              $self->{s_kwd} = '';
2898              $self->{ct}->{quirks} = 1;
2899            } else {
2900              !!!cp (209.1);
2901              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2902            }
2903            
2904          ## reconsume          ## reconsume
2905            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2906          redo A;          redo A;
2907        } else {        } else {
2908          !!!cp (210);          !!!cp (210);
2909          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2910          $self->{read_until}->($self->{ct}->{sysid}, q[">],          $self->{read_until}->($self->{ct}->{sysid}, q[">],
2911                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
2912    
# Line 2682  sub _get_next_token ($) { Line 2933  sub _get_next_token ($) {
2933    
2934          redo A;          redo A;
2935        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (213);  
2936          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2937    
2938          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2939          $self->{s_kwd} = '';            !!!cp (213);
2940          ## reconsume            $self->{state} = DATA_STATE;
2941              $self->{s_kwd} = '';
2942          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2943          !!!emit ($self->{ct}); # DOCTYPE          } else {
2944              !!!cp (213.1);
2945              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2946            }
2947    
2948            ## reconsume
2949            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2950          redo A;          redo A;
2951        } else {        } else {
2952          !!!cp (214);          !!!cp (214);
2953          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2954          $self->{read_until}->($self->{ct}->{sysid}, q['>],          $self->{read_until}->($self->{ct}->{sysid}, q['>],
2955                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
2956    
# Line 2706  sub _get_next_token ($) { Line 2960  sub _get_next_token ($) {
2960        }        }
2961      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2962        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2963          !!!cp (215);          if ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN) {
2964          ## Stay in the state            !!!cp (215.1);
2965              $self->{state} = BEFORE_NDATA_STATE;
2966            } else {
2967              !!!cp (215);
2968              ## Stay in the state
2969            }
2970          !!!next-input-character;          !!!next-input-character;
2971          redo A;          redo A;
2972        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2973          !!!cp (216);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2974          $self->{state} = DATA_STATE;            !!!cp (216);
2975          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2976          !!!next-input-character;            $self->{s_kwd} = '';
2977            } else {
2978          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (216.1);
2979              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2980            }
2981    
2982            !!!next-input-character;
2983            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2984            redo A;
2985          } elsif ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN and
2986                   ($self->{nc} == 0x004E or # N
2987                    $self->{nc} == 0x006E)) { # n
2988            !!!cp (216.2);
2989            !!!parse-error (type => 'no space before NDATA'); ## TODO: type
2990            $self->{state} = NDATA_STATE;
2991            $self->{kwd} = chr $self->{nc};
2992            !!!next-input-character;
2993          redo A;          redo A;
2994        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2995          !!!cp (217);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2996          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (217);
2997          $self->{state} = DATA_STATE;            !!!parse-error (type => 'unclosed DOCTYPE');
2998          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2999          ## reconsume            $self->{s_kwd} = '';
3000              $self->{ct}->{quirks} = 1;
3001          $self->{ct}->{quirks} = 1;          } else {
3002          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (217.1);
3003              !!!parse-error (type => 'unclosed md'); ## TODO: type
3004              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3005            }
3006    
3007            ## reconsume
3008            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
3009          redo A;          redo A;
3010        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
3011                   $self->{ct}->{type} == DOCTYPE_TOKEN and
3012                   $self->{nc} == 0x005B) { # [
3013          !!!cp (218.1);          !!!cp (218.1);
3014          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3015          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 2739  sub _get_next_token ($) { Line 3018  sub _get_next_token ($) {
3018          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
3019          redo A;          redo A;
3020        } else {        } else {
         !!!cp (218);  
3021          !!!parse-error (type => 'string after SYSTEM literal');          !!!parse-error (type => 'string after SYSTEM literal');
         #$self->{ct}->{quirks} = 1;  
3022    
3023          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3024              !!!cp (218);
3025              #$self->{ct}->{quirks} = 1;
3026              $self->{state} = BOGUS_DOCTYPE_STATE;
3027            } else {
3028              !!!cp (218.2);
3029              $self->{state} = BOGUS_MD_STATE;
3030            }
3031    
3032            !!!next-input-character;
3033            redo A;
3034          }
3035        } elsif ($self->{state} == BEFORE_NDATA_STATE) {
3036          if ($is_space->{$self->{nc}}) {
3037            !!!cp (218.3);
3038            ## Stay in the state.
3039            !!!next-input-character;
3040            redo A;
3041          } elsif ($self->{nc} == 0x003E) { # >
3042            !!!cp (218.4);
3043            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3044            !!!next-input-character;
3045            !!!emit ($self->{ct}); # ENTITY
3046            redo A;
3047          } elsif ($self->{nc} == 0x004E or # N
3048                   $self->{nc} == 0x006E) { # n
3049            !!!cp (218.5);
3050            $self->{state} = NDATA_STATE;
3051            $self->{kwd} = chr $self->{nc};
3052            !!!next-input-character;
3053            redo A;
3054          } elsif ($self->{nc} == -1) {
3055            !!!cp (218.6);
3056            !!!parse-error (type => 'unclosed md'); ## TODO: type
3057            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3058            ## reconsume
3059            !!!emit ($self->{ct}); # ENTITY
3060            redo A;
3061          } else {
3062            !!!cp (218.7);
3063            !!!parse-error (type => 'string after SYSTEM literal');
3064            $self->{state} = BOGUS_MD_STATE;
3065          !!!next-input-character;          !!!next-input-character;
3066          redo A;          redo A;
3067        }        }
# Line 2877  sub _get_next_token ($) { Line 3195  sub _get_next_token ($) {
3195              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3196              $self->{entity_add} => 1,              $self->{entity_add} => 1,
3197            }->{$self->{nc}}) {            }->{$self->{nc}}) {
3198          !!!cp (1001);          if ($self->{is_xml}) {
3199              !!!cp (1001.1);
3200              !!!parse-error (type => 'bare ero',
3201                              line => $self->{line_prev},
3202                              column => $self->{column_prev}
3203                                  + ($self->{nc} == -1 ? 1 : 0));
3204            } else {
3205              !!!cp (1001);
3206              ## No error
3207            }
3208          ## Don't consume          ## Don't consume
         ## No error  
3209          ## Return nothing.          ## Return nothing.
3210          #          #
3211        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 2888  sub _get_next_token ($) { Line 3214  sub _get_next_token ($) {
3214          $self->{kwd} = '#';          $self->{kwd} = '#';
3215          !!!next-input-character;          !!!next-input-character;
3216          redo A;          redo A;
3217        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
3218                   (0x0041 <= $self->{nc} and
3219                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
3220                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
3221                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 2932  sub _get_next_token ($) { Line 3259  sub _get_next_token ($) {
3259          redo A;          redo A;
3260        }        }
3261      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
3262        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
           $self->{nc} == 0x0058) { # X  
3263          !!!cp (995);          !!!cp (995);
3264          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
3265          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3266          !!!next-input-character;          !!!next-input-character;
3267          redo A;          redo A;
3268          } elsif ($self->{nc} == 0x0058) { # X
3269            !!!cp (995.1);
3270            if ($self->{is_xml}) {
3271              !!!parse-error (type => 'uppercase hcro'); ## TODO: type
3272            }
3273            $self->{state} = HEXREF_X_STATE;
3274            $self->{kwd} .= chr $self->{nc};
3275            !!!next-input-character;
3276            redo A;
3277        } elsif (0x0030 <= $self->{nc} and        } elsif (0x0030 <= $self->{nc} and
3278                 $self->{nc} <= 0x0039) { # 0..9                 $self->{nc} <= 0x0039) { # 0..9
3279          !!!cp (994);          !!!cp (994);
# Line 2999  sub _get_next_token ($) { Line 3334  sub _get_next_token ($) {
3334        my $code = $self->{kwd};        my $code = $self->{kwd};
3335        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3336        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3337        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3338              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3339              ($self->{is_xml} and $code == 0x0000)) {
3340          !!!cp (1015);          !!!cp (1015);
3341          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3342                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3112  sub _get_next_token ($) { Line 3449  sub _get_next_token ($) {
3449        my $code = $self->{kwd};        my $code = $self->{kwd};
3450        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3451        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3452        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3453              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3454              ($self->{is_xml} and $code == 0x0000)) {
3455          !!!cp (1008);          !!!cp (1008);
3456          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3457                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3146  sub _get_next_token ($) { Line 3485  sub _get_next_token ($) {
3485          redo A;          redo A;
3486        }        }
3487      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
3488        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
3489            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
3490            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
3491              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
3492             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
3493              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
3494             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
3495              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
3496             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
3497                    {
3498                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3499                      $self->{entity_add} => 1,
3500                    }->{$self->{nc}}))) {
3501          our $EntityChar;          our $EntityChar;
3502          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3503          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
3504                $self->{ge}->{$self->{kwd}}) {
3505            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
3506              !!!cp (1020);              if (defined $self->{ge}->{$self->{kwd}}) {
3507              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
3508                    !!!cp (1020.1);
3509                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
3510                  } else {
3511                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
3512                      !!!cp (1020.2);
3513                      !!!parse-error (type => 'unparsed entity', ## TODO: type
3514                                      value => $self->{kwd});
3515                    } else {
3516                      !!!cp (1020.3);
3517                    }
3518                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
3519                  }
3520                } else {
3521                  if ($self->{is_xml}) {
3522                    !!!cp (1020.4);
3523                    !!!parse-error (type => 'entity not declared', ## TODO: type
3524                                    value => $self->{kwd},
3525                                    level => {
3526                                              'amp;' => $self->{level}->{warn},
3527                                              'quot;' => $self->{level}->{warn},
3528                                              'lt;' => $self->{level}->{warn},
3529                                              'gt;' => $self->{level}->{warn},
3530                                              'apos;' => $self->{level}->{warn},
3531                                             }->{$self->{kwd}} ||
3532                                             $self->{level}->{must});
3533                  } else {
3534                    !!!cp (1020);
3535                  }
3536                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
3537                }
3538              $self->{entity__match} = 1;              $self->{entity__match} = 1;
3539              !!!next-input-character;              !!!next-input-character;
3540              #              #
# Line 3406  sub _get_next_token ($) { Line 3780  sub _get_next_token ($) {
3780          ## XML5: Not defined yet.          ## XML5: Not defined yet.
3781    
3782          ## TODO:          ## TODO:
3783    
3784            if (not $self->{stop_processing} and
3785                not $self->{document}->xml_standalone) {
3786              !!!parse-error (type => 'stop processing', ## TODO: type
3787                              level => $self->{level}->{info});
3788              $self->{stop_processing} = 1;
3789            }
3790    
3791          !!!next-input-character;          !!!next-input-character;
3792          redo A;          redo A;
3793        } elsif ($self->{nc} == 0x005D) { # ]        } elsif ($self->{nc} == 0x005D) { # ]
# Line 3508  sub _get_next_token ($) { Line 3890  sub _get_next_token ($) {
3890          $self->{state} = MD_HYPHEN_STATE;          $self->{state} = MD_HYPHEN_STATE;
3891          !!!next-input-character;          !!!next-input-character;
3892          redo A;          redo A;
3893        } elsif ($self->{nc} == 0x0045) { # E        } elsif ($self->{nc} == 0x0045 or # E
3894                   $self->{nc} == 0x0065) { # e
3895          $self->{state} = MD_E_STATE;          $self->{state} = MD_E_STATE;
3896          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3897          !!!next-input-character;          !!!next-input-character;
3898          redo A;          redo A;
3899        } elsif ($self->{nc} == 0x0041) { # A        } elsif ($self->{nc} == 0x0041 or # A
3900                   $self->{nc} == 0x0061) { # a
3901          $self->{state} = MD_ATTLIST_STATE;          $self->{state} = MD_ATTLIST_STATE;
3902          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3903          !!!next-input-character;          !!!next-input-character;
3904          redo A;          redo A;
3905        } elsif ($self->{nc} == 0x004E) { # N        } elsif ($self->{nc} == 0x004E or # N
3906                   $self->{nc} == 0x006E) { # n
3907          $self->{state} = MD_NOTATION_STATE;          $self->{state} = MD_NOTATION_STATE;
3908          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3909          !!!next-input-character;          !!!next-input-character;
# Line 3536  sub _get_next_token ($) { Line 3921  sub _get_next_token ($) {
3921        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.
3922        redo A;        redo A;
3923      } elsif ($self->{state} == MD_E_STATE) {      } elsif ($self->{state} == MD_E_STATE) {
3924        if ($self->{nc} == 0x004E) { # N        if ($self->{nc} == 0x004E or # N
3925              $self->{nc} == 0x006E) { # n
3926          $self->{state} = MD_ENTITY_STATE;          $self->{state} = MD_ENTITY_STATE;
3927          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3928          !!!next-input-character;          !!!next-input-character;
3929          redo A;          redo A;
3930        } elsif ($self->{nc} == 0x004C) { # L        } elsif ($self->{nc} == 0x004C or # L
3931                   $self->{nc} == 0x006C) { # l
3932          ## XML5: <!ELEMENT> not supported.          ## XML5: <!ELEMENT> not supported.
3933          $self->{state} = MD_ELEMENT_STATE;          $self->{state} = MD_ELEMENT_STATE;
3934          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
# Line 3559  sub _get_next_token ($) { Line 3946  sub _get_next_token ($) {
3946          redo A;          redo A;
3947        }        }
3948      } elsif ($self->{state} == MD_ENTITY_STATE) {      } elsif ($self->{state} == MD_ENTITY_STATE) {
3949        if ($self->{nc} == {        if ($self->{nc} == [
3950              'EN' => 0x0054, # T              undef,
3951              'ENT' => 0x0049, # I              undef,
3952              'ENTI' => 0x0054, # T              0x0054, # T
3953            }->{$self->{kwd}}) {              0x0049, # I
3954                0x0054, # T
3955              ]->[length $self->{kwd}] or
3956              $self->{nc} == [
3957                undef,
3958                undef,
3959                0x0074, # t
3960                0x0069, # i
3961                0x0074, # t
3962              ]->[length $self->{kwd}]) {
3963          ## Stay in the state.          ## Stay in the state.
3964          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3965          !!!next-input-character;          !!!next-input-character;
3966          redo A;          redo A;
3967        } elsif ($self->{kwd} eq 'ENTIT' and        } elsif ((length $self->{kwd}) == 5 and
3968                 $self->{nc} == 0x0059) { # Y                 ($self->{nc} == 0x0059 or # Y
3969          $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '', text => '',                  $self->{nc} == 0x0079)) { # y
3970            if ($self->{kwd} ne 'ENTIT' or $self->{nc} == 0x0079) {
3971              !!!parse-error (type => 'lowercase keyword', ## TODO: type
3972                              text => 'ENTITY',
3973                              line => $self->{line_prev},
3974                              column => $self->{column_prev} - 4);
3975            }
3976            $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '',
3977                         line => $self->{line_prev},                         line => $self->{line_prev},
3978                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
3979          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
# Line 3588  sub _get_next_token ($) { Line 3991  sub _get_next_token ($) {
3991          redo A;          redo A;
3992        }        }
3993      } elsif ($self->{state} == MD_ELEMENT_STATE) {      } elsif ($self->{state} == MD_ELEMENT_STATE) {
3994        if ($self->{nc} == {        if ($self->{nc} == [
3995              'EL' => 0x0045, # E             undef,
3996              'ELE' => 0x004D, # M             undef,
3997              'ELEM' => 0x0045, # E             0x0045, # E
3998              'ELEME' => 0x004E, # N             0x004D, # M
3999            }->{$self->{kwd}}) {             0x0045, # E
4000               0x004E, # N
4001              ]->[length $self->{kwd}] or
4002              $self->{nc} == [
4003               undef,
4004               undef,
4005               0x0065, # e
4006               0x006D, # m
4007               0x0065, # e
4008               0x006E, # n
4009              ]->[length $self->{kwd}]) {
4010          ## Stay in the state.          ## Stay in the state.
4011          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
4012          !!!next-input-character;          !!!next-input-character;
4013          redo A;          redo A;
4014        } elsif ($self->{kwd} eq 'ELEMEN' and        } elsif ((length $self->{kwd}) == 6 and
4015                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
4016                    $self->{nc} == 0x0074)) { # t
4017            if ($self->{kwd} ne 'ELEMEN' or $self->{nc} == 0x0074) {
4018              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4019                              text => 'ELEMENT',
4020                              line => $self->{line_prev},
4021                              column => $self->{column_prev} - 5);
4022            }
4023          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
4024                         line => $self->{line_prev},                         line => $self->{line_prev},
4025                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
4026          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4027          !!!next-input-character;          !!!next-input-character;
4028          redo A;          redo A;
# Line 3618  sub _get_next_token ($) { Line 4038  sub _get_next_token ($) {
4038          redo A;          redo A;
4039        }        }
4040      } elsif ($self->{state} == MD_ATTLIST_STATE) {      } elsif ($self->{state} == MD_ATTLIST_STATE) {
4041        if ($self->{nc} == {        if ($self->{nc} == [
4042              'A' => 0x0054, # T             undef,
4043              'AT' => 0x0054, # T             0x0054, # T
4044              'ATT' => 0x004C, # L             0x0054, # T
4045              'ATTL' => 0x0049, # I             0x004C, # L
4046              'ATTLI' => 0x0053, # S             0x0049, # I
4047            }->{$self->{kwd}}) {             0x0053, # S
4048              ]->[length $self->{kwd}] or
4049              $self->{nc} == [
4050               undef,
4051               0x0074, # t
4052               0x0074, # t
4053               0x006C, # l
4054               0x0069, # i
4055               0x0073, # s
4056              ]->[length $self->{kwd}]) {
4057          ## Stay in the state.          ## Stay in the state.
4058          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
4059          !!!next-input-character;          !!!next-input-character;
4060          redo A;          redo A;
4061        } elsif ($self->{kwd} eq 'ATTLIS' and        } elsif ((length $self->{kwd}) == 6 and
4062                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
4063                    $self->{nc} == 0x0074)) { # t
4064            if ($self->{kwd} ne 'ATTLIS' or $self->{nc} == 0x0074) {
4065              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4066                              text => 'ATTLIST',
4067                              line => $self->{line_prev},
4068                              column => $self->{column_prev} - 5);
4069            }
4070          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
4071                         attrdefs => [],                         attrdefs => [],
4072                         line => $self->{line_prev},                         line => $self->{line_prev},
4073                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
4074          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4075          !!!next-input-character;          !!!next-input-character;
4076          redo A;          redo A;
# Line 3650  sub _get_next_token ($) { Line 4086  sub _get_next_token ($) {
4086          redo A;          redo A;
4087        }        }
4088      } elsif ($self->{state} == MD_NOTATION_STATE) {      } elsif ($self->{state} == MD_NOTATION_STATE) {
4089        if ($self->{nc} == {        if ($self->{nc} == [
4090              'N' => 0x004F, # O             undef,
4091              'NO' => 0x0054, # T             0x004F, # O
4092              'NOT' => 0x0041, # A             0x0054, # T
4093              'NOTA' => 0x0054, # T             0x0041, # A
4094              'NOTAT' => 0x0049, # I             0x0054, # T
4095              'NOTATI' => 0x004F, # O             0x0049, # I
4096            }->{$self->{kwd}}) {             0x004F, # O
4097              ]->[length $self->{kwd}] or
4098              $self->{nc} == [
4099               undef,
4100               0x006F, # o
4101               0x0074, # t
4102               0x0061, # a
4103               0x0074, # t
4104               0x0069, # i
4105               0x006F, # o
4106              ]->[length $self->{kwd}]) {
4107          ## Stay in the state.          ## Stay in the state.
4108          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
4109          !!!next-input-character;          !!!next-input-character;
4110          redo A;          redo A;
4111        } elsif ($self->{kwd} eq 'NOTATIO' and        } elsif ((length $self->{kwd}) == 7 and
4112                 $self->{nc} == 0x004E) { # N                 ($self->{nc} == 0x004E or # N
4113                    $self->{nc} == 0x006E)) { # n
4114            if ($self->{kwd} ne 'NOTATIO' or $self->{nc} == 0x006E) {
4115              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4116                              text => 'NOTATION',
4117                              line => $self->{line_prev},
4118                              column => $self->{column_prev} - 6);
4119            }
4120          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
4121                         line => $self->{line_prev},                         line => $self->{line_prev},
4122                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
4123          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4124          !!!next-input-character;          !!!next-input-character;
4125          redo A;          redo A;
# Line 3775  sub _get_next_token ($) { Line 4228  sub _get_next_token ($) {
4228        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".
4229                
4230        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4231          ## TODO:          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4232          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4233            } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4234              $self->{state} = AFTER_ELEMENT_NAME_STATE;
4235            } else { # ENTITY/NOTATION
4236              $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4237            }
4238          !!!next-input-character;          !!!next-input-character;
4239          redo A;          redo A;
4240        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
4241          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4242            #            #
4243          } else {          } else {
4244            !!!parse-error (type => 'no md body'); ## TODO: type            !!!parse-error (type => 'no md def'); ## TODO: type
4245          }          }
4246          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4247          !!!next-input-character;          !!!next-input-character;
# Line 4173  sub _get_next_token ($) { Line 4631  sub _get_next_token ($) {
4631        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4632          ## XML5: No parse error.          ## XML5: No parse error.
4633          !!!parse-error (type => 'no default type'); ## TODO: type          !!!parse-error (type => 'no default type'); ## TODO: type
4634          $self->{state} = BOGUS_COMMENT_STATE;          $self->{state} = BOGUS_MD_STATE;
         $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded  
4635          ## Reconsume.          ## Reconsume.
4636          redo A;          redo A;
4637        } elsif ($self->{nc} == 0x0022) { # "        } elsif ($self->{nc} == 0x0022) { # "
# Line 4301  sub _get_next_token ($) { Line 4758  sub _get_next_token ($) {
4758          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4759          ## Reconsume.          ## Reconsume.
4760          redo A;          redo A;
4761        }              }
4762        } elsif ($self->{state} == NDATA_STATE) {
4763          ## ASCII case-insensitive
4764          if ($self->{nc} == [
4765                undef,
4766                0x0044, # D
4767                0x0041, # A
4768                0x0054, # T
4769              ]->[length $self->{kwd}] or
4770              $self->{nc} == [
4771                undef,
4772                0x0064, # d
4773                0x0061, # a
4774                0x0074, # t
4775              ]->[length $self->{kwd}]) {
4776            !!!cp (172.2);
4777            ## Stay in the state.
4778            $self->{kwd} .= chr $self->{nc};
4779            !!!next-input-character;
4780            redo A;
4781          } elsif ((length $self->{kwd}) == 4 and
4782                   ($self->{nc} == 0x0041 or # A
4783                    $self->{nc} == 0x0061)) { # a
4784            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
4785              !!!cp (172.3);
4786              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4787                              text => 'NDATA',
4788                              line => $self->{line_prev},
4789                              column => $self->{column_prev} - 4);
4790            } else {
4791              !!!cp (172.4);
4792            }
4793            $self->{state} = AFTER_NDATA_STATE;
4794            !!!next-input-character;
4795            redo A;
4796          } else {
4797            !!!parse-error (type => 'string after literal', ## TODO: type
4798                            line => $self->{line_prev},
4799                            column => $self->{column_prev} + 1
4800                                - length $self->{kwd});
4801            !!!cp (172.5);
4802            $self->{state} = BOGUS_MD_STATE;
4803            ## Reconsume.
4804            redo A;
4805          }
4806        } elsif ($self->{state} == AFTER_NDATA_STATE) {
4807          if ($is_space->{$self->{nc}}) {
4808            $self->{state} = BEFORE_NOTATION_NAME_STATE;
4809            !!!next-input-character;
4810            redo A;
4811          } elsif ($self->{nc} == 0x003E) { # >
4812            !!!parse-error (type => 'no notation name'); ## TODO: type
4813            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4814            !!!next-input-character;
4815            !!!emit ($self->{ct}); # ENTITY
4816            redo A;
4817          } elsif ($self->{nc} == -1) {
4818            !!!parse-error (type => 'unclosed md'); ## TODO: type
4819            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4820            !!!next-input-character;
4821            !!!emit ($self->{ct}); # ENTITY
4822            redo A;
4823          } else {
4824            !!!parse-error (type => 'string after literal', ## TODO: type
4825                            line => $self->{line_prev},
4826                            column => $self->{column_prev} + 1
4827                                - length $self->{kwd});
4828            $self->{state} = BOGUS_MD_STATE;
4829            ## Reconsume.
4830            redo A;
4831          }
4832        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
4833          if ($is_space->{$self->{nc}}) {
4834            ## Stay in the state.
4835            !!!next-input-character;
4836            redo A;
4837          } elsif ($self->{nc} == 0x003E) { # >
4838            !!!parse-error (type => 'no notation name'); ## TODO: type
4839            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4840            !!!next-input-character;
4841            !!!emit ($self->{ct}); # ENTITY
4842            redo A;
4843          } elsif ($self->{nc} == -1) {
4844            !!!parse-error (type => 'unclosed md'); ## TODO: type
4845            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4846            !!!next-input-character;
4847            !!!emit ($self->{ct}); # ENTITY
4848            redo A;
4849          } else {
4850            $self->{ct}->{notation} = chr $self->{nc}; # ENTITY
4851            $self->{state} = NOTATION_NAME_STATE;
4852            !!!next-input-character;
4853            redo A;
4854          }
4855        } elsif ($self->{state} == NOTATION_NAME_STATE) {
4856          if ($is_space->{$self->{nc}}) {
4857            $self->{state} = AFTER_MD_DEF_STATE;
4858            !!!next-input-character;
4859            redo A;
4860          } elsif ($self->{nc} == 0x003E) { # >
4861            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4862            !!!next-input-character;
4863            !!!emit ($self->{ct}); # ENTITY
4864            redo A;
4865          } elsif ($self->{nc} == -1) {
4866            !!!parse-error (type => 'unclosed md'); ## TODO: type
4867            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4868            !!!next-input-character;
4869            !!!emit ($self->{ct}); # ENTITY
4870            redo A;
4871          } else {
4872            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
4873            ## Stay in the state.
4874            !!!next-input-character;
4875            redo A;
4876          }
4877        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
4878          if ($self->{nc} == 0x0022) { # "
4879            $self->{state} = AFTER_MD_DEF_STATE;
4880            !!!next-input-character;
4881            redo A;
4882          } elsif ($self->{nc} == 0x0026) { # &
4883            $self->{prev_state} = $self->{state};
4884            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4885            $self->{entity_add} = 0x0022; # "
4886            !!!next-input-character;
4887            redo A;
4888    ## TODO: %
4889          } elsif ($self->{nc} == -1) {
4890            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4891            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4892            ## Reconsume.
4893            !!!emit ($self->{ct}); # ENTITY
4894            redo A;
4895          } else {
4896            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4897            !!!next-input-character;
4898            redo A;
4899          }
4900        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
4901          if ($self->{nc} == 0x0027) { # '
4902            $self->{state} = AFTER_MD_DEF_STATE;
4903            !!!next-input-character;
4904            redo A;
4905          } elsif ($self->{nc} == 0x0026) { # &
4906            $self->{prev_state} = $self->{state};
4907            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4908            $self->{entity_add} = 0x0027; # '
4909            !!!next-input-character;
4910            redo A;
4911    ## TODO: %
4912          } elsif ($self->{nc} == -1) {
4913            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4914            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4915            ## Reconsume.
4916            !!!emit ($self->{ct}); # ENTITY
4917            redo A;
4918          } else {
4919            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4920            !!!next-input-character;
4921            redo A;
4922          }
4923        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
4924          if ($is_space->{$self->{nc}} or
4925              {
4926                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4927                $self->{entity_add} => 1,
4928              }->{$self->{nc}}) {
4929            !!!parse-error (type => 'bare ero',
4930                            line => $self->{line_prev},
4931                            column => $self->{column_prev}
4932                                + ($self->{nc} == -1 ? 1 : 0));
4933            ## Don't consume
4934            ## Return nothing.
4935            #
4936          } elsif ($self->{nc} == 0x0023) { # #
4937            $self->{ca} = $self->{ct};
4938            $self->{state} = ENTITY_HASH_STATE;
4939            $self->{kwd} = '#';
4940            !!!next-input-character;
4941            redo A;
4942          } else {
4943            #
4944          }
4945    
4946          $self->{ct}->{value} .= '&';
4947          $self->{state} = $self->{prev_state};
4948          ## Reconsume.
4949          redo A;
4950        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
4951          if ($is_space->{$self->{nc}}) {
4952            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
4953            !!!next-input-character;
4954            redo A;
4955          } elsif ($self->{nc} == 0x0028) { # (
4956            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4957            $self->{ct}->{content} = ['('];
4958            $self->{group_depth} = 1;
4959            !!!next-input-character;
4960            redo A;
4961          } elsif ($self->{nc} == 0x003E) { # >
4962            !!!parse-error (type => 'no md def'); ## TODO: type
4963            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4964            !!!next-input-character;
4965            !!!emit ($self->{ct}); # ELEMENT
4966            redo A;
4967          } elsif ($self->{nc} == -1) {
4968            !!!parse-error (type => 'unclosed md'); ## TODO: type
4969            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4970            !!!next-input-character;
4971            !!!emit ($self->{ct}); # ELEMENT
4972            redo A;
4973          } else {
4974            $self->{ct}->{content} = [chr $self->{nc}];
4975            $self->{state} = CONTENT_KEYWORD_STATE;
4976            !!!next-input-character;
4977            redo A;
4978          }
4979        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
4980          if ($is_space->{$self->{nc}}) {
4981            $self->{state} = AFTER_MD_DEF_STATE;
4982            !!!next-input-character;
4983            redo A;
4984          } elsif ($self->{nc} == 0x003E) { # >
4985            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4986            !!!next-input-character;
4987            !!!emit ($self->{ct}); # ELEMENT
4988            redo A;
4989          } elsif ($self->{nc} == -1) {
4990            !!!parse-error (type => 'unclosed md'); ## TODO: type
4991            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4992            !!!next-input-character;
4993            !!!emit ($self->{ct}); # ELEMENT
4994            redo A;
4995          } else {
4996            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
4997            ## Stay in the state.
4998            !!!next-input-character;
4999            redo A;
5000          }
5001        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
5002          if ($is_space->{$self->{nc}}) {
5003            ## Stay in the state.
5004            !!!next-input-character;
5005            redo A;
5006          } elsif ($self->{nc} == 0x0028) { # (
5007            $self->{group_depth}++;
5008            push @{$self->{ct}->{content}}, chr $self->{nc};
5009            ## Stay in the state.
5010            !!!next-input-character;
5011            redo A;
5012          } elsif ($self->{nc} == 0x007C or # |
5013                   $self->{nc} == 0x002C) { # ,
5014            !!!parse-error (type => 'empty element name'); ## TODO: type
5015            ## Stay in the state.
5016            !!!next-input-character;
5017            redo A;
5018          } elsif ($self->{nc} == 0x0029) { # )
5019            !!!parse-error (type => 'empty element name'); ## TODO: type
5020            push @{$self->{ct}->{content}}, chr $self->{nc};
5021            $self->{group_depth}--;
5022            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5023            !!!next-input-character;
5024            redo A;
5025          } elsif ($self->{nc} == 0x003E) { # >
5026            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5027            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5028            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5029            !!!next-input-character;
5030            !!!emit ($self->{ct}); # ELEMENT
5031            redo A;
5032          } elsif ($self->{nc} == -1) {
5033            !!!parse-error (type => 'unclosed md'); ## TODO: type
5034            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5035            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5036            !!!next-input-character;
5037            !!!emit ($self->{ct}); # ELEMENT
5038            redo A;
5039          } else {
5040            push @{$self->{ct}->{content}}, chr $self->{nc};
5041            $self->{state} = CM_ELEMENT_NAME_STATE;
5042            !!!next-input-character;
5043            redo A;
5044          }
5045        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
5046          if ($is_space->{$self->{nc}}) {
5047            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5048            !!!next-input-character;
5049            redo A;
5050          } elsif ($self->{nc} == 0x002A or # *
5051                   $self->{nc} == 0x002B or # +
5052                   $self->{nc} == 0x003F) { # ?
5053            push @{$self->{ct}->{content}}, chr $self->{nc};
5054            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5055            !!!next-input-character;
5056            redo A;
5057          } elsif ($self->{nc} == 0x007C or # |
5058                   $self->{nc} == 0x002C) { # ,
5059            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5060            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5061            !!!next-input-character;
5062            redo A;
5063          } elsif ($self->{nc} == 0x0029) { # )
5064            $self->{group_depth}--;
5065            push @{$self->{ct}->{content}}, chr $self->{nc};
5066            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5067            !!!next-input-character;
5068            redo A;
5069          } elsif ($self->{nc} == 0x003E) { # >
5070            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5071            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5072            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5073            !!!next-input-character;
5074            !!!emit ($self->{ct}); # ELEMENT
5075            redo A;
5076          } elsif ($self->{nc} == -1) {
5077            !!!parse-error (type => 'unclosed md'); ## TODO: type
5078            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5079            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5080            !!!next-input-character;
5081            !!!emit ($self->{ct}); # ELEMENT
5082            redo A;
5083          } else {
5084            $self->{ct}->{content}->[-1] .= chr $self->{nc};
5085            ## Stay in the state.
5086            !!!next-input-character;
5087            redo A;
5088          }
5089        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
5090          if ($is_space->{$self->{nc}}) {
5091            ## Stay in the state.
5092            !!!next-input-character;
5093            redo A;
5094          } elsif ($self->{nc} == 0x007C or # |
5095                   $self->{nc} == 0x002C) { # ,
5096            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5097            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5098            !!!next-input-character;
5099            redo A;
5100          } elsif ($self->{nc} == 0x0029) { # )
5101            $self->{group_depth}--;
5102            push @{$self->{ct}->{content}}, chr $self->{nc};
5103            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5104            !!!next-input-character;
5105            redo A;
5106          } elsif ($self->{nc} == 0x003E) { # >
5107            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5108            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5109            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5110            !!!next-input-character;
5111            !!!emit ($self->{ct}); # ELEMENT
5112            redo A;
5113          } elsif ($self->{nc} == -1) {
5114            !!!parse-error (type => 'unclosed md'); ## TODO: type
5115            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5116            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5117            !!!next-input-character;
5118            !!!emit ($self->{ct}); # ELEMENT
5119            redo A;
5120          } else {
5121            !!!parse-error (type => 'after element name'); ## TODO: type
5122            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5123            $self->{state} = BOGUS_MD_STATE;
5124            !!!next-input-character;
5125            redo A;
5126          }
5127        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
5128          if ($is_space->{$self->{nc}}) {
5129            if ($self->{group_depth}) {
5130              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5131            } else {
5132              $self->{state} = AFTER_MD_DEF_STATE;
5133            }
5134            !!!next-input-character;
5135            redo A;
5136          } elsif ($self->{nc} == 0x002A or # *
5137                   $self->{nc} == 0x002B or # +
5138                   $self->{nc} == 0x003F) { # ?
5139            push @{$self->{ct}->{content}}, chr $self->{nc};
5140            if ($self->{group_depth}) {
5141              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5142            } else {
5143              $self->{state} = AFTER_MD_DEF_STATE;
5144            }
5145            !!!next-input-character;
5146            redo A;
5147          } elsif ($self->{nc} == 0x0029) { # )
5148            if ($self->{group_depth}) {
5149              $self->{group_depth}--;
5150              push @{$self->{ct}->{content}}, chr $self->{nc};
5151              ## Stay in the state.
5152              !!!next-input-character;
5153              redo A;
5154            } else {
5155              !!!parse-error (type => 'string after md def'); ## TODO: type
5156              $self->{state} = BOGUS_MD_STATE;
5157              ## Reconsume.
5158              redo A;
5159            }
5160          } elsif ($self->{nc} == 0x003E) { # >
5161            if ($self->{group_depth}) {
5162              !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5163              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5164            }
5165            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5166            !!!next-input-character;
5167            !!!emit ($self->{ct}); # ELEMENT
5168            redo A;
5169          } elsif ($self->{nc} == -1) {
5170            !!!parse-error (type => 'unclosed md'); ## TODO: type
5171            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5172            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5173            !!!next-input-character;
5174            !!!emit ($self->{ct}); # ELEMENT
5175            redo A;
5176          } else {
5177            if ($self->{group_depth}) {
5178              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5179            } else {
5180              !!!parse-error (type => 'string after md def'); ## TODO: type
5181              $self->{state} = BOGUS_MD_STATE;
5182            }
5183            ## Reconsume.
5184            redo A;
5185          }
5186        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
5187          if ($is_space->{$self->{nc}}) {
5188            ## Stay in the state.
5189            !!!next-input-character;
5190            redo A;
5191          } elsif ($self->{nc} == 0x003E) { # >
5192            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5193            !!!next-input-character;
5194            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5195            redo A;
5196          } elsif ($self->{nc} == -1) {
5197            !!!parse-error (type => 'unclosed md'); ## TODO: type
5198            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5199            !!!next-input-character;
5200            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5201            redo A;
5202          } else {
5203            !!!parse-error (type => 'string after md def'); ## TODO: type
5204            $self->{state} = BOGUS_MD_STATE;
5205            ## Reconsume.
5206            redo A;
5207          }
5208        } elsif ($self->{state} == BOGUS_MD_STATE) {
5209          if ($self->{nc} == 0x003E) { # >
5210            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5211            !!!next-input-character;
5212            !!!emit ($self->{ct}); # ATTLIST/ENTITY/NOTATION
5213            redo A;
5214          } elsif ($self->{nc} == -1) {
5215            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5216            ## Reconsume.
5217            !!!emit ($self->{ct}); # ATTLIST/ENTITY/NOTATION
5218            redo A;
5219          } else {
5220            ## Stay in the state.
5221            !!!next-input-character;
5222            redo A;
5223          }
5224      } else {      } else {
5225        die "$0: $self->{state}: Unknown state";        die "$0: $self->{state}: Unknown state";
5226      }      }

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.32

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24