/[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.17 by wakaba, Sun Oct 19 04:39:25 2008 UTC revision 1.30 by wakaba, Sun Aug 16 05:24:47 2009 UTC
# Line 177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO Line 177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO
177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }
178  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }
179  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }
180  sub BOGUS_MD_STATE () { 85 }  sub BEFORE_NDATA_STATE () { 85 }
181    sub NDATA_STATE () { 86 }
182    sub AFTER_NDATA_STATE () { 87 }
183    sub BEFORE_NOTATION_NAME_STATE () { 88 }
184    sub NOTATION_NAME_STATE () { 89 }
185    sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
186    sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 91 }
187    sub ENTITY_VALUE_ENTITY_STATE () { 92 }
188    sub AFTER_ELEMENT_NAME_STATE () { 93 }
189    sub BEFORE_ELEMENT_CONTENT_STATE () { 94 }
190    sub CONTENT_KEYWORD_STATE () { 95 }
191    sub AFTER_CM_GROUP_OPEN_STATE () { 96 }
192    sub CM_ELEMENT_NAME_STATE () { 97 }
193    sub AFTER_CM_ELEMENT_NAME_STATE () { 98 }
194    sub AFTER_CM_GROUP_CLOSE_STATE () { 99 }
195    sub AFTER_MD_DEF_STATE () { 100 }
196    sub BOGUS_MD_STATE () { 101 }
197    
198  ## Tree constructor state constants (see Whatpm::HTML for the full  ## Tree constructor state constants (see Whatpm::HTML for the full
199  ## list and descriptions)  ## list and descriptions)
# Line 932  sub _get_next_token ($) { Line 948  sub _get_next_token ($) {
948          if ({          if ({
949               0x0022 => 1, # "               0x0022 => 1, # "
950               0x0027 => 1, # '               0x0027 => 1, # '
951                 0x003C => 1, # <
952               0x003D => 1, # =               0x003D => 1, # =
953              }->{$self->{nc}}) {              }->{$self->{nc}}) {
954            !!!cp (55);            !!!cp (55);
# Line 1054  sub _get_next_token ($) { Line 1071  sub _get_next_token ($) {
1071    
1072          redo A;          redo A;
1073        } else {        } else {
1074          if ($self->{nc} == 0x0022 or # "          if ({
1075              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1076                 0x0027 => 1, # '
1077                 0x003C => 1, # <
1078                }->{$self->{nc}}) {
1079            !!!cp (69);            !!!cp (69);
1080            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1081            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1166  sub _get_next_token ($) { Line 1186  sub _get_next_token ($) {
1186            !!!cp (78.2);            !!!cp (78.2);
1187          }          }
1188    
1189          if ($self->{nc} == 0x0022 or # "          if ({
1190              $self->{nc} == 0x0027) { # '               0x0022 => 1, # "
1191                 0x0027 => 1, # '
1192                 0x003C => 1, # <
1193                }->{$self->{nc}}) {
1194            !!!cp (78);            !!!cp (78);
1195            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1196            !!!parse-error (type => 'bad attribute name');            !!!parse-error (type => 'bad attribute name');
# Line 1254  sub _get_next_token ($) { Line 1277  sub _get_next_token ($) {
1277    
1278          redo A;          redo A;
1279        } else {        } else {
1280          if ($self->{nc} == 0x003D) { # =          if ($self->{nc} == 0x003D or $self->{nc} == 0x003C) { # =, <
1281            !!!cp (93);            !!!cp (93);
1282            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1283            !!!parse-error (type => 'bad attribute value');            !!!parse-error (type => 'bad attribute value');
# Line 1300  sub _get_next_token ($) { Line 1323  sub _get_next_token ($) {
1323          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1324          !!!next-input-character;          !!!next-input-character;
1325          redo A;          redo A;
1326          } elsif ($self->{is_xml} and
1327                   $is_space->{$self->{nc}}) {
1328            !!!cp (97.1);
1329            $self->{ca}->{value} .= ' ';
1330            ## Stay in the state.
1331            !!!next-input-character;
1332            redo A;
1333        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1334          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1335          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1347  sub _get_next_token ($) { Line 1377  sub _get_next_token ($) {
1377          }          }
1378          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1379          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1380                                q["&<],                                qq["&<\x09\x0C\x20],
1381                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1382    
1383          ## Stay in the state          ## Stay in the state
# Line 1384  sub _get_next_token ($) { Line 1414  sub _get_next_token ($) {
1414          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1415          !!!next-input-character;          !!!next-input-character;
1416          redo A;          redo A;
1417          } elsif ($self->{is_xml} and
1418                   $is_space->{$self->{nc}}) {
1419            !!!cp (103.1);
1420            $self->{ca}->{value} .= ' ';
1421            ## Stay in the state.
1422            !!!next-input-character;
1423            redo A;
1424        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1425          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1426          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1431  sub _get_next_token ($) { Line 1468  sub _get_next_token ($) {
1468          }          }
1469          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1470          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1471                                q['&<],                                qq['&<\x09\x0C\x20],
1472                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1473    
1474          ## Stay in the state          ## Stay in the state
# Line 1543  sub _get_next_token ($) { Line 1580  sub _get_next_token ($) {
1580               0x0022 => 1, # "               0x0022 => 1, # "
1581               0x0027 => 1, # '               0x0027 => 1, # '
1582               0x003D => 1, # =               0x003D => 1, # =
1583                 0x003C => 1, # <
1584              }->{$self->{nc}}) {              }->{$self->{nc}}) {
1585            !!!cp (115);            !!!cp (115);
1586            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1552  sub _get_next_token ($) { Line 1590  sub _get_next_token ($) {
1590          }          }
1591          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1592          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1593                                q["'=& >],                                qq["'=& \x09\x0C>],
1594                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1595    
1596          ## Stay in the state          ## Stay in the state
# Line 2088  sub _get_next_token ($) { Line 2126  sub _get_next_token ($) {
2126          redo A;          redo A;
2127        } else {        } else {
2128          !!!cp (154);          !!!cp (154);
         ## XML5: Not a parse error.  
         !!!parse-error (type => 'dash in comment',  
                         line => $self->{line_prev},  
                         column => $self->{column_prev});  
2129          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2130          $self->{state} = COMMENT_STATE;          $self->{state} = COMMENT_STATE;
2131          !!!next-input-character;          !!!next-input-character;
# Line 2103  sub _get_next_token ($) { Line 2137  sub _get_next_token ($) {
2137          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2138          !!!next-input-character;          !!!next-input-character;
2139          redo A;          redo A;
2140          } elsif ($self->{nc} == -1) {
2141            !!!cp (155.1);
2142            !!!parse-error (type => 'unclosed DOCTYPE');
2143            $self->{ct}->{quirks} = 1;
2144    
2145            $self->{state} = DATA_STATE;
2146            ## Reconsume.
2147            !!!emit ($self->{ct}); # DOCTYPE (quirks)
2148    
2149            redo A;
2150        } else {        } else {
2151          !!!cp (156);          !!!cp (156);
2152          ## XML5: Unless EOF, swith to the bogus comment state.          ## XML5: Swith to the bogus comment state.
2153          !!!parse-error (type => 'no space before DOCTYPE name');          !!!parse-error (type => 'no space before DOCTYPE name');
2154          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2155          ## reconsume          ## reconsume
# Line 2130  sub _get_next_token ($) { Line 2174  sub _get_next_token ($) {
2174          !!!emit ($self->{ct}); # DOCTYPE (quirks)          !!!emit ($self->{ct}); # DOCTYPE (quirks)
2175    
2176          redo A;          redo A;
2177          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2178            !!!cp (158.1);
2179            $self->{ct}->{name} # DOCTYPE
2180                = chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2181            delete $self->{ct}->{quirks};
2182            $self->{state} = DOCTYPE_NAME_STATE;
2183            !!!next-input-character;
2184            redo A;
2185        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2186          !!!cp (159);          !!!cp (159);
2187          !!!parse-error (type => 'no DOCTYPE name');          !!!parse-error (type => 'no DOCTYPE name');
# Line 2176  sub _get_next_token ($) { Line 2228  sub _get_next_token ($) {
2228          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2229    
2230          redo A;          redo A;
2231          } elsif (0x0041 <= $self->{nc} and $self->{nc} <= 0x005A) { # A..Z
2232            !!!cp (162.1);
2233            $self->{ct}->{name} # DOCTYPE
2234                .= chr ($self->{nc} + ($self->{is_xml} ? 0 : 0x0020));
2235            delete $self->{ct}->{quirks};
2236            ## Stay in the state.
2237            !!!next-input-character;
2238            redo A;
2239        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2240          !!!cp (163);          !!!cp (163);
2241          !!!parse-error (type => 'unclosed DOCTYPE');          !!!parse-error (type => 'unclosed DOCTYPE');
# Line 2197  sub _get_next_token ($) { Line 2257  sub _get_next_token ($) {
2257          redo A;          redo A;
2258        } else {        } else {
2259          !!!cp (164);          !!!cp (164);
2260          $self->{ct}->{name}          $self->{ct}->{name} .= chr ($self->{nc}); # DOCTYPE
2261            .= chr ($self->{nc}); # DOCTYPE          ## Stay in the state.
         ## Stay in the state  
2262          !!!next-input-character;          !!!next-input-character;
2263          redo A;          redo A;
2264        }        }
# Line 2256  sub _get_next_token ($) { Line 2315  sub _get_next_token ($) {
2315          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
2316          !!!next-input-character;          !!!next-input-character;
2317          redo A;          redo A;
2318  ## TODO: " and ' for ENTITY        } elsif ($self->{nc} == 0x0022 and # "
2319                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2320                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2321            !!!cp (167.21);
2322            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
2323            $self->{ct}->{value} = ''; # ENTITY
2324            !!!next-input-character;
2325            redo A;
2326          } elsif ($self->{nc} == 0x0027 and # '
2327                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2328                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2329            !!!cp (167.22);
2330            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
2331            $self->{ct}->{value} = ''; # ENTITY
2332            !!!next-input-character;
2333            redo A;
2334        } elsif ($self->{is_xml} and        } elsif ($self->{is_xml} and
2335                 $self->{ct}->{type} == DOCTYPE_TOKEN and                 $self->{ct}->{type} == DOCTYPE_TOKEN and
2336                 $self->{nc} == 0x005B) { # [                 $self->{nc} == 0x005B) { # [
# Line 2812  sub _get_next_token ($) { Line 2886  sub _get_next_token ($) {
2886        }        }
2887      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2888        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2889          !!!cp (215);          if ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN) {
2890          ## Stay in the state            !!!cp (215.1);
2891              $self->{state} = BEFORE_NDATA_STATE;
2892            } else {
2893              !!!cp (215);
2894              ## Stay in the state
2895            }
2896          !!!next-input-character;          !!!next-input-character;
2897          redo A;          redo A;
2898        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
# Line 2829  sub _get_next_token ($) { Line 2908  sub _get_next_token ($) {
2908          !!!next-input-character;          !!!next-input-character;
2909          !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION          !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2910          redo A;          redo A;
2911  ## TODO: "NDATA"        } elsif ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN and
2912                   ($self->{nc} == 0x004E or # N
2913                    $self->{nc} == 0x006E)) { # n
2914            !!!cp (216.2);
2915            !!!parse-error (type => 'no space before NDATA'); ## TODO: type
2916            $self->{state} = NDATA_STATE;
2917            $self->{kwd} = chr $self->{nc};
2918            !!!next-input-character;
2919            redo A;
2920        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2921          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2922            !!!cp (217);            !!!cp (217);
# Line 2871  sub _get_next_token ($) { Line 2958  sub _get_next_token ($) {
2958          !!!next-input-character;          !!!next-input-character;
2959          redo A;          redo A;
2960        }        }
2961        } elsif ($self->{state} == BEFORE_NDATA_STATE) {
2962          if ($is_space->{$self->{nc}}) {
2963            !!!cp (218.3);
2964            ## Stay in the state.
2965            !!!next-input-character;
2966            redo A;
2967          } elsif ($self->{nc} == 0x003E) { # >
2968            !!!cp (218.4);
2969            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2970            !!!next-input-character;
2971            !!!emit ($self->{ct}); # ENTITY
2972            redo A;
2973          } elsif ($self->{nc} == 0x004E or # N
2974                   $self->{nc} == 0x006E) { # n
2975            !!!cp (218.5);
2976            $self->{state} = NDATA_STATE;
2977            $self->{kwd} = chr $self->{nc};
2978            !!!next-input-character;
2979            redo A;
2980          } elsif ($self->{nc} == -1) {
2981            !!!cp (218.6);
2982            !!!parse-error (type => 'unclosed md'); ## TODO: type
2983            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2984            ## reconsume
2985            !!!emit ($self->{ct}); # ENTITY
2986            redo A;
2987          } else {
2988            !!!cp (218.7);
2989            !!!parse-error (type => 'string after SYSTEM literal');
2990            $self->{state} = BOGUS_MD_STATE;
2991            !!!next-input-character;
2992            redo A;
2993          }
2994      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {
2995        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
2996          !!!cp (219);          !!!cp (219);
# Line 3001  sub _get_next_token ($) { Line 3121  sub _get_next_token ($) {
3121              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3122              $self->{entity_add} => 1,              $self->{entity_add} => 1,
3123            }->{$self->{nc}}) {            }->{$self->{nc}}) {
3124          !!!cp (1001);          if ($self->{is_xml}) {
3125              !!!cp (1001.1);
3126              !!!parse-error (type => 'bare ero',
3127                              line => $self->{line_prev},
3128                              column => $self->{column_prev}
3129                                  + ($self->{nc} == -1 ? 1 : 0));
3130            } else {
3131              !!!cp (1001);
3132              ## No error
3133            }
3134          ## Don't consume          ## Don't consume
         ## No error  
3135          ## Return nothing.          ## Return nothing.
3136          #          #
3137        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 3012  sub _get_next_token ($) { Line 3140  sub _get_next_token ($) {
3140          $self->{kwd} = '#';          $self->{kwd} = '#';
3141          !!!next-input-character;          !!!next-input-character;
3142          redo A;          redo A;
3143        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
3144                   (0x0041 <= $self->{nc} and
3145                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
3146                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
3147                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 3056  sub _get_next_token ($) { Line 3185  sub _get_next_token ($) {
3185          redo A;          redo A;
3186        }        }
3187      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
3188        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
           $self->{nc} == 0x0058) { # X  
3189          !!!cp (995);          !!!cp (995);
3190          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
3191          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3192          !!!next-input-character;          !!!next-input-character;
3193          redo A;          redo A;
3194          } elsif ($self->{nc} == 0x0058) { # X
3195            !!!cp (995.1);
3196            if ($self->{is_xml}) {
3197              !!!parse-error (type => 'uppercase hcro'); ## TODO: type
3198            }
3199            $self->{state} = HEXREF_X_STATE;
3200            $self->{kwd} .= chr $self->{nc};
3201            !!!next-input-character;
3202            redo A;
3203        } elsif (0x0030 <= $self->{nc} and        } elsif (0x0030 <= $self->{nc} and
3204                 $self->{nc} <= 0x0039) { # 0..9                 $self->{nc} <= 0x0039) { # 0..9
3205          !!!cp (994);          !!!cp (994);
# Line 3123  sub _get_next_token ($) { Line 3260  sub _get_next_token ($) {
3260        my $code = $self->{kwd};        my $code = $self->{kwd};
3261        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3262        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3263        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3264              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3265              ($self->{is_xml} and $code == 0x0000)) {
3266          !!!cp (1015);          !!!cp (1015);
3267          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3268                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3236  sub _get_next_token ($) { Line 3375  sub _get_next_token ($) {
3375        my $code = $self->{kwd};        my $code = $self->{kwd};
3376        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3377        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3378        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3379              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3380              ($self->{is_xml} and $code == 0x0000)) {
3381          !!!cp (1008);          !!!cp (1008);
3382          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3383                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3270  sub _get_next_token ($) { Line 3411  sub _get_next_token ($) {
3411          redo A;          redo A;
3412        }        }
3413      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
3414        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
3415            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
3416            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
3417              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
3418             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
3419              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
3420             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
3421              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
3422             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
3423                    {
3424                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3425                      $self->{entity_add} => 1,
3426                    }->{$self->{nc}}))) {
3427          our $EntityChar;          our $EntityChar;
3428          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3429          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
3430                $self->{ge}->{$self->{kwd}}) {
3431            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
3432              !!!cp (1020);              if (defined $self->{ge}->{$self->{kwd}}) {
3433              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
3434                    !!!cp (1020.1);
3435                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
3436                  } else {
3437                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
3438                      !!!cp (1020.2);
3439                      !!!parse-error (type => 'unparsed entity', ## TODO: type
3440                                      value => $self->{kwd});
3441                    } else {
3442                      !!!cp (1020.3);
3443                    }
3444                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
3445                  }
3446                } else {
3447                  if ($self->{is_xml}) {
3448                    !!!cp (1020.4);
3449                    !!!parse-error (type => 'entity not declared', ## TODO: type
3450                                    value => $self->{kwd},
3451                                    level => {
3452                                              'amp;' => $self->{level}->{warn},
3453                                              'quot;' => $self->{level}->{warn},
3454                                              'lt;' => $self->{level}->{warn},
3455                                              'gt;' => $self->{level}->{warn},
3456                                              'apos;' => $self->{level}->{warn},
3457                                             }->{$self->{kwd}} ||
3458                                             $self->{level}->{must});
3459                  } else {
3460                    !!!cp (1020);
3461                  }
3462                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
3463                }
3464              $self->{entity__match} = 1;              $self->{entity__match} = 1;
3465              !!!next-input-character;              !!!next-input-character;
3466              #              #
# Line 3530  sub _get_next_token ($) { Line 3706  sub _get_next_token ($) {
3706          ## XML5: Not defined yet.          ## XML5: Not defined yet.
3707    
3708          ## TODO:          ## TODO:
3709    
3710            if (not $self->{stop_processing} and
3711                not $self->{document}->xml_standalone) {
3712              !!!parse-error (type => 'stop processing', ## TODO: type
3713                              level => $self->{level}->{info});
3714              $self->{stop_processing} = 1;
3715            }
3716    
3717          !!!next-input-character;          !!!next-input-character;
3718          redo A;          redo A;
3719        } elsif ($self->{nc} == 0x005D) { # ]        } elsif ($self->{nc} == 0x005D) { # ]
# Line 3764  sub _get_next_token ($) { Line 3948  sub _get_next_token ($) {
3948          }          }
3949          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
3950                         line => $self->{line_prev},                         line => $self->{line_prev},
3951                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
3952          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
3953          !!!next-input-character;          !!!next-input-character;
3954          redo A;          redo A;
# Line 3812  sub _get_next_token ($) { Line 3996  sub _get_next_token ($) {
3996          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
3997                         attrdefs => [],                         attrdefs => [],
3998                         line => $self->{line_prev},                         line => $self->{line_prev},
3999                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
4000          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4001          !!!next-input-character;          !!!next-input-character;
4002          redo A;          redo A;
# Line 3861  sub _get_next_token ($) { Line 4045  sub _get_next_token ($) {
4045          }          }
4046          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
4047                         line => $self->{line_prev},                         line => $self->{line_prev},
4048                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
4049          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4050          !!!next-input-character;          !!!next-input-character;
4051          redo A;          redo A;
# Line 3973  sub _get_next_token ($) { Line 4157  sub _get_next_token ($) {
4157          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4158            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4159          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4160            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
4161          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
4162            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4163          }          }
# Line 4502  sub _get_next_token ($) { Line 4685  sub _get_next_token ($) {
4685          ## Reconsume.          ## Reconsume.
4686          redo A;          redo A;
4687        }        }
4688        } elsif ($self->{state} == NDATA_STATE) {
4689          ## ASCII case-insensitive
4690          if ($self->{nc} == [
4691                undef,
4692                0x0044, # D
4693                0x0041, # A
4694                0x0054, # T
4695              ]->[length $self->{kwd}] or
4696              $self->{nc} == [
4697                undef,
4698                0x0064, # d
4699                0x0061, # a
4700                0x0074, # t
4701              ]->[length $self->{kwd}]) {
4702            !!!cp (172.2);
4703            ## Stay in the state.
4704            $self->{kwd} .= chr $self->{nc};
4705            !!!next-input-character;
4706            redo A;
4707          } elsif ((length $self->{kwd}) == 4 and
4708                   ($self->{nc} == 0x0041 or # A
4709                    $self->{nc} == 0x0061)) { # a
4710            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
4711              !!!cp (172.3);
4712              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4713                              text => 'NDATA',
4714                              line => $self->{line_prev},
4715                              column => $self->{column_prev} - 4);
4716            } else {
4717              !!!cp (172.4);
4718            }
4719            $self->{state} = AFTER_NDATA_STATE;
4720            !!!next-input-character;
4721            redo A;
4722          } else {
4723            !!!parse-error (type => 'string after literal', ## TODO: type
4724                            line => $self->{line_prev},
4725                            column => $self->{column_prev} + 1
4726                                - length $self->{kwd});
4727            !!!cp (172.5);
4728            $self->{state} = BOGUS_MD_STATE;
4729            ## Reconsume.
4730            redo A;
4731          }
4732        } elsif ($self->{state} == AFTER_NDATA_STATE) {
4733          if ($is_space->{$self->{nc}}) {
4734            $self->{state} = BEFORE_NOTATION_NAME_STATE;
4735            !!!next-input-character;
4736            redo A;
4737          } elsif ($self->{nc} == 0x003E) { # >
4738            !!!parse-error (type => 'no notation name'); ## TODO: type
4739            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4740            !!!next-input-character;
4741            !!!emit ($self->{ct}); # ENTITY
4742            redo A;
4743          } elsif ($self->{nc} == -1) {
4744            !!!parse-error (type => 'unclosed md'); ## TODO: type
4745            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4746            !!!next-input-character;
4747            !!!emit ($self->{ct}); # ENTITY
4748            redo A;
4749          } else {
4750            !!!parse-error (type => 'string after literal', ## TODO: type
4751                            line => $self->{line_prev},
4752                            column => $self->{column_prev} + 1
4753                                - length $self->{kwd});
4754            $self->{state} = BOGUS_MD_STATE;
4755            ## Reconsume.
4756            redo A;
4757          }
4758        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
4759          if ($is_space->{$self->{nc}}) {
4760            ## Stay in the state.
4761            !!!next-input-character;
4762            redo A;
4763          } elsif ($self->{nc} == 0x003E) { # >
4764            !!!parse-error (type => 'no notation name'); ## TODO: type
4765            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4766            !!!next-input-character;
4767            !!!emit ($self->{ct}); # ENTITY
4768            redo A;
4769          } elsif ($self->{nc} == -1) {
4770            !!!parse-error (type => 'unclosed md'); ## TODO: type
4771            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4772            !!!next-input-character;
4773            !!!emit ($self->{ct}); # ENTITY
4774            redo A;
4775          } else {
4776            $self->{ct}->{notation} = chr $self->{nc}; # ENTITY
4777            $self->{state} = NOTATION_NAME_STATE;
4778            !!!next-input-character;
4779            redo A;
4780          }
4781        } elsif ($self->{state} == NOTATION_NAME_STATE) {
4782          if ($is_space->{$self->{nc}}) {
4783            $self->{state} = AFTER_MD_DEF_STATE;
4784            !!!next-input-character;
4785            redo A;
4786          } elsif ($self->{nc} == 0x003E) { # >
4787            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4788            !!!next-input-character;
4789            !!!emit ($self->{ct}); # ENTITY
4790            redo A;
4791          } elsif ($self->{nc} == -1) {
4792            !!!parse-error (type => 'unclosed md'); ## TODO: type
4793            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4794            !!!next-input-character;
4795            !!!emit ($self->{ct}); # ENTITY
4796            redo A;
4797          } else {
4798            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
4799            ## Stay in the state.
4800            !!!next-input-character;
4801            redo A;
4802          }
4803        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
4804          if ($self->{nc} == 0x0022) { # "
4805            $self->{state} = AFTER_MD_DEF_STATE;
4806            !!!next-input-character;
4807            redo A;
4808          } elsif ($self->{nc} == 0x0026) { # &
4809            $self->{prev_state} = $self->{state};
4810            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4811            $self->{entity_add} = 0x0022; # "
4812            !!!next-input-character;
4813            redo A;
4814    ## TODO: %
4815          } elsif ($self->{nc} == -1) {
4816            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4817            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4818            ## Reconsume.
4819            !!!emit ($self->{ct}); # ENTITY
4820            redo A;
4821          } else {
4822            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4823            !!!next-input-character;
4824            redo A;
4825          }
4826        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
4827          if ($self->{nc} == 0x0027) { # '
4828            $self->{state} = AFTER_MD_DEF_STATE;
4829            !!!next-input-character;
4830            redo A;
4831          } elsif ($self->{nc} == 0x0026) { # &
4832            $self->{prev_state} = $self->{state};
4833            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4834            $self->{entity_add} = 0x0027; # '
4835            !!!next-input-character;
4836            redo A;
4837    ## TODO: %
4838          } elsif ($self->{nc} == -1) {
4839            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4840            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4841            ## Reconsume.
4842            !!!emit ($self->{ct}); # ENTITY
4843            redo A;
4844          } else {
4845            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4846            !!!next-input-character;
4847            redo A;
4848          }
4849        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
4850          if ($is_space->{$self->{nc}} or
4851              {
4852                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4853                $self->{entity_add} => 1,
4854              }->{$self->{nc}}) {
4855            !!!parse-error (type => 'bare ero',
4856                            line => $self->{line_prev},
4857                            column => $self->{column_prev}
4858                                + ($self->{nc} == -1 ? 1 : 0));
4859            ## Don't consume
4860            ## Return nothing.
4861            #
4862          } elsif ($self->{nc} == 0x0023) { # #
4863            $self->{ca} = $self->{ct};
4864            $self->{state} = ENTITY_HASH_STATE;
4865            $self->{kwd} = '#';
4866            !!!next-input-character;
4867            redo A;
4868          } else {
4869            #
4870          }
4871    
4872          $self->{ct}->{value} .= '&';
4873          $self->{state} = $self->{prev_state};
4874          ## Reconsume.
4875          redo A;
4876        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
4877          if ($is_space->{$self->{nc}}) {
4878            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
4879            !!!next-input-character;
4880            redo A;
4881          } elsif ($self->{nc} == 0x0028) { # (
4882            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4883            $self->{ct}->{content} = ['('];
4884            $self->{group_depth} = 1;
4885            !!!next-input-character;
4886            redo A;
4887          } elsif ($self->{nc} == 0x003E) { # >
4888            !!!parse-error (type => 'no md def'); ## TODO: type
4889            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4890            !!!next-input-character;
4891            !!!emit ($self->{ct}); # ELEMENT
4892            redo A;
4893          } elsif ($self->{nc} == -1) {
4894            !!!parse-error (type => 'unclosed md'); ## TODO: type
4895            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4896            !!!next-input-character;
4897            !!!emit ($self->{ct}); # ELEMENT
4898            redo A;
4899          } else {
4900            $self->{ct}->{content} = [chr $self->{nc}];
4901            $self->{state} = CONTENT_KEYWORD_STATE;
4902            !!!next-input-character;
4903            redo A;
4904          }
4905        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
4906          if ($is_space->{$self->{nc}}) {
4907            $self->{state} = AFTER_MD_DEF_STATE;
4908            !!!next-input-character;
4909            redo A;
4910          } elsif ($self->{nc} == 0x003E) { # >
4911            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4912            !!!next-input-character;
4913            !!!emit ($self->{ct}); # ELEMENT
4914            redo A;
4915          } elsif ($self->{nc} == -1) {
4916            !!!parse-error (type => 'unclosed md'); ## TODO: type
4917            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4918            !!!next-input-character;
4919            !!!emit ($self->{ct}); # ELEMENT
4920            redo A;
4921          } else {
4922            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
4923            ## Stay in the state.
4924            !!!next-input-character;
4925            redo A;
4926          }
4927        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
4928          if ($is_space->{$self->{nc}}) {
4929            ## Stay in the state.
4930            !!!next-input-character;
4931            redo A;
4932          } elsif ($self->{nc} == 0x0028) { # (
4933            $self->{group_depth}++;
4934            push @{$self->{ct}->{content}}, chr $self->{nc};
4935            ## Stay in the state.
4936            !!!next-input-character;
4937            redo A;
4938          } elsif ($self->{nc} == 0x007C or # |
4939                   $self->{nc} == 0x002C) { # ,
4940            !!!parse-error (type => 'empty element name'); ## TODO: type
4941            ## Stay in the state.
4942            !!!next-input-character;
4943            redo A;
4944          } elsif ($self->{nc} == 0x0029) { # )
4945            !!!parse-error (type => 'empty element name'); ## TODO: type
4946            push @{$self->{ct}->{content}}, chr $self->{nc};
4947            $self->{group_depth}--;
4948            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4949            !!!next-input-character;
4950            redo A;
4951          } elsif ($self->{nc} == 0x003E) { # >
4952            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4953            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4954            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4955            !!!next-input-character;
4956            !!!emit ($self->{ct}); # ELEMENT
4957            redo A;
4958          } elsif ($self->{nc} == -1) {
4959            !!!parse-error (type => 'unclosed md'); ## TODO: type
4960            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4961            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4962            !!!next-input-character;
4963            !!!emit ($self->{ct}); # ELEMENT
4964            redo A;
4965          } else {
4966            push @{$self->{ct}->{content}}, chr $self->{nc};
4967            $self->{state} = CM_ELEMENT_NAME_STATE;
4968            !!!next-input-character;
4969            redo A;
4970          }
4971        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
4972          if ($is_space->{$self->{nc}}) {
4973            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4974            !!!next-input-character;
4975            redo A;
4976          } elsif ($self->{nc} == 0x002A or # *
4977                   $self->{nc} == 0x002B or # +
4978                   $self->{nc} == 0x003F) { # ?
4979            push @{$self->{ct}->{content}}, chr $self->{nc};
4980            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4981            !!!next-input-character;
4982            redo A;
4983          } elsif ($self->{nc} == 0x007C or # |
4984                   $self->{nc} == 0x002C) { # ,
4985            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
4986            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4987            !!!next-input-character;
4988            redo A;
4989          } elsif ($self->{nc} == 0x0029) { # )
4990            $self->{group_depth}--;
4991            push @{$self->{ct}->{content}}, chr $self->{nc};
4992            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4993            !!!next-input-character;
4994            redo A;
4995          } elsif ($self->{nc} == 0x003E) { # >
4996            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4997            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4998            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4999            !!!next-input-character;
5000            !!!emit ($self->{ct}); # ELEMENT
5001            redo A;
5002          } elsif ($self->{nc} == -1) {
5003            !!!parse-error (type => 'unclosed md'); ## TODO: type
5004            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5005            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5006            !!!next-input-character;
5007            !!!emit ($self->{ct}); # ELEMENT
5008            redo A;
5009          } else {
5010            $self->{ct}->{content}->[-1] .= chr $self->{nc};
5011            ## Stay in the state.
5012            !!!next-input-character;
5013            redo A;
5014          }
5015        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
5016          if ($is_space->{$self->{nc}}) {
5017            ## Stay in the state.
5018            !!!next-input-character;
5019            redo A;
5020          } elsif ($self->{nc} == 0x007C or # |
5021                   $self->{nc} == 0x002C) { # ,
5022            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5023            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5024            !!!next-input-character;
5025            redo A;
5026          } elsif ($self->{nc} == 0x0029) { # )
5027            $self->{group_depth}--;
5028            push @{$self->{ct}->{content}}, chr $self->{nc};
5029            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5030            !!!next-input-character;
5031            redo A;
5032          } elsif ($self->{nc} == 0x003E) { # >
5033            !!!parse-error (type => 'unclosed cm group'); ## 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          } elsif ($self->{nc} == -1) {
5040            !!!parse-error (type => 'unclosed md'); ## TODO: type
5041            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5042            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5043            !!!next-input-character;
5044            !!!emit ($self->{ct}); # ELEMENT
5045            redo A;
5046          } else {
5047            !!!parse-error (type => 'after element name'); ## TODO: type
5048            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5049            $self->{state} = BOGUS_MD_STATE;
5050            !!!next-input-character;
5051            redo A;
5052          }
5053        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
5054          if ($is_space->{$self->{nc}}) {
5055            if ($self->{group_depth}) {
5056              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5057            } else {
5058              $self->{state} = AFTER_MD_DEF_STATE;
5059            }
5060            !!!next-input-character;
5061            redo A;
5062          } elsif ($self->{nc} == 0x002A or # *
5063                   $self->{nc} == 0x002B or # +
5064                   $self->{nc} == 0x003F) { # ?
5065            push @{$self->{ct}->{content}}, chr $self->{nc};
5066            if ($self->{group_depth}) {
5067              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5068            } else {
5069              $self->{state} = AFTER_MD_DEF_STATE;
5070            }
5071            !!!next-input-character;
5072            redo A;
5073          } elsif ($self->{nc} == 0x0029) { # )
5074            if ($self->{group_depth}) {
5075              $self->{group_depth}--;
5076              push @{$self->{ct}->{content}}, chr $self->{nc};
5077              ## Stay in the state.
5078              !!!next-input-character;
5079              redo A;
5080            } else {
5081              !!!parse-error (type => 'string after md def'); ## TODO: type
5082              $self->{state} = BOGUS_MD_STATE;
5083              ## Reconsume.
5084              redo A;
5085            }
5086          } elsif ($self->{nc} == 0x003E) { # >
5087            if ($self->{group_depth}) {
5088              !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5089              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5090            }
5091            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5092            !!!next-input-character;
5093            !!!emit ($self->{ct}); # ELEMENT
5094            redo A;
5095          } elsif ($self->{nc} == -1) {
5096            !!!parse-error (type => 'unclosed md'); ## TODO: type
5097            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5098            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5099            !!!next-input-character;
5100            !!!emit ($self->{ct}); # ELEMENT
5101            redo A;
5102          } else {
5103            if ($self->{group_depth}) {
5104              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5105            } else {
5106              !!!parse-error (type => 'string after md def'); ## TODO: type
5107              $self->{state} = BOGUS_MD_STATE;
5108            }
5109            ## Reconsume.
5110            redo A;
5111          }
5112        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
5113          if ($is_space->{$self->{nc}}) {
5114            ## Stay in the state.
5115            !!!next-input-character;
5116            redo A;
5117          } elsif ($self->{nc} == 0x003E) { # >
5118            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5119            !!!next-input-character;
5120            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5121            redo A;
5122          } elsif ($self->{nc} == -1) {
5123            !!!parse-error (type => 'unclosed md'); ## TODO: type
5124            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5125            !!!next-input-character;
5126            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5127            redo A;
5128          } else {
5129            !!!parse-error (type => 'string after md def'); ## TODO: type
5130            $self->{state} = BOGUS_MD_STATE;
5131            ## Reconsume.
5132            redo A;
5133          }
5134      } elsif ($self->{state} == BOGUS_MD_STATE) {      } elsif ($self->{state} == BOGUS_MD_STATE) {
5135        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
5136          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.30

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24