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

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

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.20 by wakaba, Sun Oct 19 08:20:29 2008 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 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 3182  sub _get_next_token ($) { Line 3199  sub _get_next_token ($) {
3199        
3200          redo A;          redo A;
3201        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
3202            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3203              
3204              $self->{state} = DATA_STATE;
3205              $self->{s_kwd} = '';
3206            } else {
3207              
3208              $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md def'); ## TODO: type
3209              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3210            }
3211                    
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
3212                    
3213      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3214        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3196  sub _get_next_token ($) { Line 3220  sub _get_next_token ($) {
3220        $self->{set_nc}->($self);        $self->{set_nc}->($self);
3221      }      }
3222        
3223            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         return  ($self->{ct}); # DOCTYPE  
   
3224          redo A;          redo A;
3225        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
3226            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3227              
3228              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');
3229              $self->{state} = DATA_STATE;
3230              $self->{s_kwd} = '';
3231              $self->{ct}->{quirks} = 1;
3232            } else {
3233              
3234              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
3235              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3236            }
3237                    
3238          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');          ## Reconsume.
3239          $self->{state} = DATA_STATE;          return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{s_kwd} = '';  
         ## reconsume  
   
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3240          redo A;          redo A;
3241        } elsif ($self->{nc} == 0x0050 or # P        } elsif ($self->{nc} == 0x0050 or # P
3242                 $self->{nc} == 0x0070) { # p                 $self->{nc} == 0x0070) { # p
# Line 3245  sub _get_next_token ($) { Line 3272  sub _get_next_token ($) {
3272      }      }
3273        
3274          redo A;          redo A;
3275        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{nc} == 0x0022 and # "
3276                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
3277                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
3278            
3279            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
3280            $self->{ct}->{value} = ''; # ENTITY
3281            
3282        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3283          $self->{line_prev} = $self->{line};
3284          $self->{column_prev} = $self->{column};
3285          $self->{column}++;
3286          $self->{nc}
3287              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
3288        } else {
3289          $self->{set_nc}->($self);
3290        }
3291      
3292            redo A;
3293          } elsif ($self->{nc} == 0x0027 and # '
3294                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
3295                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
3296            
3297            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
3298            $self->{ct}->{value} = ''; # ENTITY
3299            
3300        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3301          $self->{line_prev} = $self->{line};
3302          $self->{column_prev} = $self->{column};
3303          $self->{column}++;
3304          $self->{nc}
3305              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
3306        } else {
3307          $self->{set_nc}->($self);
3308        }
3309      
3310            redo A;
3311          } elsif ($self->{is_xml} and
3312                   $self->{ct}->{type} == DOCTYPE_TOKEN and
3313                   $self->{nc} == 0x005B) { # [
3314                    
3315          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3316          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 3264  sub _get_next_token ($) { Line 3329  sub _get_next_token ($) {
3329          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
3330          redo A;          redo A;
3331        } else {        } else {
3332                    $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name'); ## TODO: type
3333          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name');  
3334          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3335              
3336              $self->{ct}->{quirks} = 1;
3337              $self->{state} = BOGUS_DOCTYPE_STATE;
3338            } else {
3339              
3340              $self->{state} = BOGUS_MD_STATE;
3341            }
3342    
         $self->{state} = BOGUS_DOCTYPE_STATE;  
3343                    
3344      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3345        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3340  sub _get_next_token ($) { Line 3411  sub _get_next_token ($) {
3411        
3412          redo A;          redo A;
3413        } else {        } else {
3414                    $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name', ## TODO: type
         $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name',  
3415                          line => $self->{line_prev},                          line => $self->{line_prev},
3416                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
3417          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3418              
3419          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
3420              $self->{state} = BOGUS_DOCTYPE_STATE;
3421            } else {
3422              
3423              $self->{state} = BOGUS_MD_STATE;
3424            }
3425          ## Reconsume.          ## Reconsume.
3426          redo A;          redo A;
3427        }        }
# Line 3408  sub _get_next_token ($) { Line 3483  sub _get_next_token ($) {
3483        
3484          redo A;          redo A;
3485        } else {        } else {
3486                    $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name', ## TODO: type
         $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after DOCTYPE name',  
3487                          line => $self->{line_prev},                          line => $self->{line_prev},
3488                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
3489          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3490              
3491          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
3492              $self->{state} = BOGUS_DOCTYPE_STATE;
3493            } else {
3494              
3495              $self->{state} = BOGUS_MD_STATE;
3496            }
3497          ## Reconsume.          ## Reconsume.
3498          redo A;          redo A;
3499        }        }
# Line 3467  sub _get_next_token ($) { Line 3546  sub _get_next_token ($) {
3546        
3547          redo A;          redo A;
3548        } elsif ($self->{nc} eq 0x003E) { # >        } elsif ($self->{nc} eq 0x003E) { # >
           
3549          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no PUBLIC literal');
3550            
3551          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3552          $self->{s_kwd} = '';            
3553              $self->{state} = DATA_STATE;
3554              $self->{s_kwd} = '';
3555              $self->{ct}->{quirks} = 1;
3556            } else {
3557              
3558              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3559            }
3560            
3561                    
3562      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3563        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3483  sub _get_next_token ($) { Line 3569  sub _get_next_token ($) {
3569        $self->{set_nc}->($self);        $self->{set_nc}->($self);
3570      }      }
3571        
3572            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3573          redo A;          redo A;
3574        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
3575            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3576              
3577              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');
3578              $self->{state} = DATA_STATE;
3579              $self->{s_kwd} = '';
3580              $self->{ct}->{quirks} = 1;
3581            } else {
3582              
3583              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
3584              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3585            }
3586                    
         $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');  
   
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
3587          ## reconsume          ## reconsume
   
         $self->{ct}->{quirks} = 1;  
3588          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
   
3589          redo A;          redo A;
3590        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
3591                   $self->{ct}->{type} == DOCTYPE_TOKEN and
3592                   $self->{nc} == 0x005B) { # [
3593                    
3594          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no PUBLIC literal');
3595          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 3520  sub _get_next_token ($) { Line 3609  sub _get_next_token ($) {
3609          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
3610          redo A;          redo A;
3611        } else {        } else {
           
3612          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after PUBLIC');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after PUBLIC');
         $self->{ct}->{quirks} = 1;  
3613    
3614          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3615              
3616              $self->{ct}->{quirks} = 1;
3617              $self->{state} = BOGUS_DOCTYPE_STATE;
3618            } else {
3619              
3620              $self->{state} = BOGUS_MD_STATE;
3621            }
3622    
3623                    
3624      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3625        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3555  sub _get_next_token ($) { Line 3650  sub _get_next_token ($) {
3650        
3651          redo A;          redo A;
3652        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
           
3653          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');
3654    
3655          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3656          $self->{s_kwd} = '';            
3657              $self->{state} = DATA_STATE;
3658              $self->{s_kwd} = '';
3659              $self->{ct}->{quirks} = 1;
3660            } else {
3661              
3662              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3663            }
3664    
3665                    
3666      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3667        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3571  sub _get_next_token ($) { Line 3673  sub _get_next_token ($) {
3673        $self->{set_nc}->($self);        $self->{set_nc}->($self);
3674      }      }
3675        
3676            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3677          redo A;          redo A;
3678        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
           
3679          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');
3680    
3681          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3682          $self->{s_kwd} = '';            
3683          ## reconsume            $self->{state} = DATA_STATE;
3684              $self->{s_kwd} = '';
3685          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
3686            } else {
3687              
3688              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3689            }
3690            
3691            ## Reconsume.
3692          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
   
3693          redo A;          redo A;
3694        } else {        } else {
3695                    
3696          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
3697          $self->{read_until}->($self->{ct}->{pubid}, q[">],          $self->{read_until}->($self->{ct}->{pubid}, q[">],
3698                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
3699    
# Line 3626  sub _get_next_token ($) { Line 3728  sub _get_next_token ($) {
3728        
3729          redo A;          redo A;
3730        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
           
3731          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');
3732    
3733          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3734          $self->{s_kwd} = '';            
3735              $self->{state} = DATA_STATE;
3736              $self->{s_kwd} = '';
3737              $self->{ct}->{quirks} = 1;
3738            } else {
3739              
3740              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3741            }
3742    
3743                    
3744      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3745        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3642  sub _get_next_token ($) { Line 3751  sub _get_next_token ($) {
3751        $self->{set_nc}->($self);        $self->{set_nc}->($self);
3752      }      }
3753        
3754            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3755          redo A;          redo A;
3756        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
           
3757          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed PUBLIC literal');
3758    
3759          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3760          $self->{s_kwd} = '';            
3761              $self->{state} = DATA_STATE;
3762              $self->{s_kwd} = '';
3763              $self->{ct}->{quirks} = 1;
3764            } else {
3765              
3766              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3767            }
3768          
3769          ## reconsume          ## reconsume
3770            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3771          redo A;          redo A;
3772        } else {        } else {
3773                    
3774          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
3775          $self->{read_until}->($self->{ct}->{pubid}, q['>],          $self->{read_until}->($self->{ct}->{pubid}, q['>],
3776                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
3777    
# Line 3698  sub _get_next_token ($) { Line 3807  sub _get_next_token ($) {
3807          redo A;          redo A;
3808        } elsif ($self->{nc} == 0x0022) { # "        } elsif ($self->{nc} == 0x0022) { # "
3809                    
3810          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
3811          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
3812                    
3813      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 3714  sub _get_next_token ($) { Line 3823  sub _get_next_token ($) {
3823          redo A;          redo A;
3824        } elsif ($self->{nc} == 0x0027) { # '        } elsif ($self->{nc} == 0x0027) { # '
3825                    
3826          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
3827          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
3828                    
3829      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 3729  sub _get_next_token ($) { Line 3838  sub _get_next_token ($) {
3838        
3839          redo A;          redo A;
3840        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
3841          if ($self->{is_xml}) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3842                        if ($self->{is_xml}) {
3843            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');              
3844                $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');
3845              } else {
3846                
3847              }
3848              $self->{state} = DATA_STATE;
3849              $self->{s_kwd} = '';
3850          } else {          } else {
3851                        if ($self->{ct}->{type} == NOTATION_TOKEN) {
3852                
3853              } else {
3854                
3855                $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');            
3856              }
3857              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3858          }          }
3859          $self->{state} = DATA_STATE;          
         $self->{s_kwd} = '';  
3860                    
3861      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3862        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3748  sub _get_next_token ($) { Line 3868  sub _get_next_token ($) {
3868        $self->{set_nc}->($self);        $self->{set_nc}->($self);
3869      }      }
3870        
3871            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         return  ($self->{ct}); # DOCTYPE  
   
3872          redo A;          redo A;
3873        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
3874            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3875              
3876              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');
3877              
3878              $self->{state} = DATA_STATE;
3879              $self->{s_kwd} = '';
3880              $self->{ct}->{quirks} = 1;
3881            } else {
3882              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
3883              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
3884            }
3885                    
         $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');  
   
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
3886          ## reconsume          ## reconsume
3887            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
3888          redo A;          redo A;
3889        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
3890                   $self->{ct}->{type} == DOCTYPE_TOKEN and
3891                   $self->{nc} == 0x005B) { # [
3892                    
3893          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');
3894          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 3784  sub _get_next_token ($) { Line 3908  sub _get_next_token ($) {
3908          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
3909          redo A;          redo A;
3910        } else {        } else {
           
3911          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after PUBLIC literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after PUBLIC literal');
         $self->{ct}->{quirks} = 1;  
3912    
3913          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3914              
3915              $self->{ct}->{quirks} = 1;
3916              $self->{state} = BOGUS_DOCTYPE_STATE;
3917            } else {
3918              
3919              $self->{state} = BOGUS_MD_STATE;
3920            }
3921    
3922                    
3923      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3924        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3851  sub _get_next_token ($) { Line 3981  sub _get_next_token ($) {
3981        
3982          redo A;          redo A;
3983        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
           
3984          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
3985                    
3986      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3987        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3867  sub _get_next_token ($) { Line 3994  sub _get_next_token ($) {
3994      }      }
3995        
3996    
3997          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
3998          return  ($self->{ct}); # DOCTYPE            
3999              $self->{state} = DATA_STATE;
4000              $self->{s_kwd} = '';
4001              $self->{ct}->{quirks} = 1;
4002            } else {
4003              
4004              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4005            }
4006    
4007            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
4008          redo A;          redo A;
4009        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
4010            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4011              
4012              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');
4013              $self->{state} = DATA_STATE;
4014              $self->{s_kwd} = '';
4015              $self->{ct}->{quirks} = 1;
4016            } else {
4017              
4018              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
4019              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4020            }
4021                    
         $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');  
   
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
4022          ## reconsume          ## reconsume
4023            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
4024          redo A;          redo A;
4025        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
4026                   $self->{ct}->{type} == DOCTYPE_TOKEN and
4027                   $self->{nc} == 0x005B) { # [
4028                    
4029          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no SYSTEM literal');
4030    
# Line 3904  sub _get_next_token ($) { Line 4045  sub _get_next_token ($) {
4045          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
4046          redo A;          redo A;
4047        } else {        } else {
           
4048          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after SYSTEM');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after SYSTEM');
         $self->{ct}->{quirks} = 1;  
4049    
4050          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4051                        
4052              $self->{ct}->{quirks} = 1;
4053              $self->{state} = BOGUS_DOCTYPE_STATE;
4054            } else {
4055              
4056              $self->{state} = BOGUS_MD_STATE;
4057            }
4058    
4059                    
4060      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4061        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3939  sub _get_next_token ($) { Line 4086  sub _get_next_token ($) {
4086        
4087          redo A;          redo A;
4088        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >
           
4089          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');
4090    
4091          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4092          $self->{s_kwd} = '';            
4093              $self->{state} = DATA_STATE;
4094              $self->{s_kwd} = '';
4095              $self->{ct}->{quirks} = 1;
4096            } else {
4097              
4098              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4099            }
4100            
4101                    
4102      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4103        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 3955  sub _get_next_token ($) { Line 4109  sub _get_next_token ($) {
4109        $self->{set_nc}->($self);        $self->{set_nc}->($self);
4110      }      }
4111        
4112            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
4113          redo A;          redo A;
4114        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
           
4115          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');
4116    
4117          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4118          $self->{s_kwd} = '';            
4119              $self->{state} = DATA_STATE;
4120              $self->{s_kwd} = '';
4121              $self->{ct}->{quirks} = 1;
4122            } else {
4123              
4124              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4125            }
4126            
4127          ## reconsume          ## reconsume
4128            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         return  ($self->{ct}); # DOCTYPE  
   
4129          redo A;          redo A;
4130        } else {        } else {
4131                    
4132          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
4133          $self->{read_until}->($self->{ct}->{sysid}, q[">],          $self->{read_until}->($self->{ct}->{sysid}, q[">],
4134                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
4135    
# Line 4032  sub _get_next_token ($) { Line 4186  sub _get_next_token ($) {
4186    
4187          redo A;          redo A;
4188        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
           
4189          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed SYSTEM literal');
4190    
4191          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4192          $self->{s_kwd} = '';            
4193          ## reconsume            $self->{state} = DATA_STATE;
4194              $self->{s_kwd} = '';
4195          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
4196          return  ($self->{ct}); # DOCTYPE          } else {
4197              
4198              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4199            }
4200    
4201            ## reconsume
4202            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
4203          redo A;          redo A;
4204        } else {        } else {
4205                    
4206          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
4207          $self->{read_until}->($self->{ct}->{sysid}, q['>],          $self->{read_until}->($self->{ct}->{sysid}, q['>],
4208                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
4209    
# Line 4066  sub _get_next_token ($) { Line 4223  sub _get_next_token ($) {
4223        }        }
4224      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
4225        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4226                    if ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN) {
4227          ## Stay in the state            
4228              $self->{state} = BEFORE_NDATA_STATE;
4229            } else {
4230              
4231              ## Stay in the state
4232            }
4233                    
4234      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4235        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 4081  sub _get_next_token ($) { Line 4243  sub _get_next_token ($) {
4243        
4244          redo A;          redo A;
4245        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
4246            if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4247              
4248              $self->{state} = DATA_STATE;
4249              $self->{s_kwd} = '';
4250            } else {
4251              
4252              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4253            }
4254    
4255                    
4256          $self->{state} = DATA_STATE;      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4257          $self->{s_kwd} = '';        $self->{line_prev} = $self->{line};
4258          $self->{column_prev} = $self->{column};
4259          $self->{column}++;
4260          $self->{nc}
4261              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4262        } else {
4263          $self->{set_nc}->($self);
4264        }
4265      
4266            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
4267            redo A;
4268          } elsif ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN and
4269                   ($self->{nc} == 0x004E or # N
4270                    $self->{nc} == 0x006E)) { # n
4271            
4272            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no space before NDATA'); ## TODO: type
4273            $self->{state} = NDATA_STATE;
4274            $self->{kwd} = chr $self->{nc};
4275                    
4276      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4277        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 4095  sub _get_next_token ($) { Line 4283  sub _get_next_token ($) {
4283        $self->{set_nc}->($self);        $self->{set_nc}->($self);
4284      }      }
4285        
   
         return  ($self->{ct}); # DOCTYPE  
   
4286          redo A;          redo A;
4287        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
4288                    if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4289          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');            
4290          $self->{state} = DATA_STATE;            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed DOCTYPE');
4291          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
4292          ## reconsume            $self->{s_kwd} = '';
4293              $self->{ct}->{quirks} = 1;
4294          $self->{ct}->{quirks} = 1;          } else {
4295          return  ($self->{ct}); # DOCTYPE            
4296              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
4297              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4298            }
4299    
4300            ## reconsume
4301            return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
4302          redo A;          redo A;
4303        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
4304                   $self->{ct}->{type} == DOCTYPE_TOKEN and
4305                   $self->{nc} == 0x005B) { # [
4306                    
4307          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4308          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 4129  sub _get_next_token ($) { Line 4321  sub _get_next_token ($) {
4321          return  ($self->{ct}); # DOCTYPE          return  ($self->{ct}); # DOCTYPE
4322          redo A;          redo A;
4323        } else {        } else {
           
4324          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after SYSTEM literal');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after SYSTEM literal');
         #$self->{ct}->{quirks} = 1;  
4325    
4326          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4327              
4328              #$self->{ct}->{quirks} = 1;
4329              $self->{state} = BOGUS_DOCTYPE_STATE;
4330            } else {
4331              
4332              $self->{state} = BOGUS_MD_STATE;
4333            }
4334    
4335            
4336        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4337          $self->{line_prev} = $self->{line};
4338          $self->{column_prev} = $self->{column};
4339          $self->{column}++;
4340          $self->{nc}
4341              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4342        } else {
4343          $self->{set_nc}->($self);
4344        }
4345      
4346            redo A;
4347          }
4348        } elsif ($self->{state} == BEFORE_NDATA_STATE) {
4349          if ($is_space->{$self->{nc}}) {
4350            
4351            ## Stay in the state.
4352            
4353        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4354          $self->{line_prev} = $self->{line};
4355          $self->{column_prev} = $self->{column};
4356          $self->{column}++;
4357          $self->{nc}
4358              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4359        } else {
4360          $self->{set_nc}->($self);
4361        }
4362      
4363            redo A;
4364          } elsif ($self->{nc} == 0x003E) { # >
4365            
4366            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4367            
4368        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4369          $self->{line_prev} = $self->{line};
4370          $self->{column_prev} = $self->{column};
4371          $self->{column}++;
4372          $self->{nc}
4373              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4374        } else {
4375          $self->{set_nc}->($self);
4376        }
4377      
4378            return  ($self->{ct}); # ENTITY
4379            redo A;
4380          } elsif ($self->{nc} == 0x004E or # N
4381                   $self->{nc} == 0x006E) { # n
4382            
4383            $self->{state} = NDATA_STATE;
4384            $self->{kwd} = chr $self->{nc};
4385            
4386        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4387          $self->{line_prev} = $self->{line};
4388          $self->{column_prev} = $self->{column};
4389          $self->{column}++;
4390          $self->{nc}
4391              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4392        } else {
4393          $self->{set_nc}->($self);
4394        }
4395      
4396            redo A;
4397          } elsif ($self->{nc} == -1) {
4398            
4399            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
4400            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4401            ## reconsume
4402            return  ($self->{ct}); # ENTITY
4403            redo A;
4404          } else {
4405            
4406            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after SYSTEM literal');
4407            $self->{state} = BOGUS_MD_STATE;
4408                    
4409      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4410        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 5358  sub _get_next_token ($) { Line 5629  sub _get_next_token ($) {
5629      }      }
5630        
5631          redo A;          redo A;
5632        } elsif ($self->{nc} == 0x0045) { # E        } elsif ($self->{nc} == 0x0045 or # E
5633                   $self->{nc} == 0x0065) { # e
5634          $self->{state} = MD_E_STATE;          $self->{state} = MD_E_STATE;
5635          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
5636                    
# Line 5373  sub _get_next_token ($) { Line 5645  sub _get_next_token ($) {
5645      }      }
5646        
5647          redo A;          redo A;
5648        } elsif ($self->{nc} == 0x0041) { # A        } elsif ($self->{nc} == 0x0041 or # A
5649                   $self->{nc} == 0x0061) { # a
5650          $self->{state} = MD_ATTLIST_STATE;          $self->{state} = MD_ATTLIST_STATE;
5651          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
5652                    
# Line 5388  sub _get_next_token ($) { Line 5661  sub _get_next_token ($) {
5661      }      }
5662        
5663          redo A;          redo A;
5664        } elsif ($self->{nc} == 0x004E) { # N        } elsif ($self->{nc} == 0x004E or # N
5665                   $self->{nc} == 0x006E) { # n
5666          $self->{state} = MD_NOTATION_STATE;          $self->{state} = MD_NOTATION_STATE;
5667          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
5668                    
# Line 5416  sub _get_next_token ($) { Line 5690  sub _get_next_token ($) {
5690        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.
5691        redo A;        redo A;
5692      } elsif ($self->{state} == MD_E_STATE) {      } elsif ($self->{state} == MD_E_STATE) {
5693        if ($self->{nc} == 0x004E) { # N        if ($self->{nc} == 0x004E or # N
5694              $self->{nc} == 0x006E) { # n
5695          $self->{state} = MD_ENTITY_STATE;          $self->{state} = MD_ENTITY_STATE;
5696          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5697                    
# Line 5431  sub _get_next_token ($) { Line 5706  sub _get_next_token ($) {
5706      }      }
5707        
5708          redo A;          redo A;
5709        } elsif ($self->{nc} == 0x004C) { # L        } elsif ($self->{nc} == 0x004C or # L
5710                   $self->{nc} == 0x006C) { # l
5711          ## XML5: <!ELEMENT> not supported.          ## XML5: <!ELEMENT> not supported.
5712          $self->{state} = MD_ELEMENT_STATE;          $self->{state} = MD_ELEMENT_STATE;
5713          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
# Line 5459  sub _get_next_token ($) { Line 5735  sub _get_next_token ($) {
5735          redo A;          redo A;
5736        }        }
5737      } elsif ($self->{state} == MD_ENTITY_STATE) {      } elsif ($self->{state} == MD_ENTITY_STATE) {
5738        if ($self->{nc} == {        if ($self->{nc} == [
5739              'EN' => 0x0054, # T              undef,
5740              'ENT' => 0x0049, # I              undef,
5741              'ENTI' => 0x0054, # T              0x0054, # T
5742            }->{$self->{kwd}}) {              0x0049, # I
5743                0x0054, # T
5744              ]->[length $self->{kwd}] or
5745              $self->{nc} == [
5746                undef,
5747                undef,
5748                0x0074, # t
5749                0x0069, # i
5750                0x0074, # t
5751              ]->[length $self->{kwd}]) {
5752          ## Stay in the state.          ## Stay in the state.
5753          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5754                    
# Line 5478  sub _get_next_token ($) { Line 5763  sub _get_next_token ($) {
5763      }      }
5764        
5765          redo A;          redo A;
5766        } elsif ($self->{kwd} eq 'ENTIT' and        } elsif ((length $self->{kwd}) == 5 and
5767                 $self->{nc} == 0x0059) { # Y                 ($self->{nc} == 0x0059 or # Y
5768          $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '', text => '',                  $self->{nc} == 0x0079)) { # y
5769            if ($self->{kwd} ne 'ENTIT' or $self->{nc} == 0x0079) {
5770              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
5771                              text => 'ENTITY',
5772                              line => $self->{line_prev},
5773                              column => $self->{column_prev} - 4);
5774            }
5775            $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '',
5776                         line => $self->{line_prev},                         line => $self->{line_prev},
5777                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
5778          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
# Line 5508  sub _get_next_token ($) { Line 5800  sub _get_next_token ($) {
5800          redo A;          redo A;
5801        }        }
5802      } elsif ($self->{state} == MD_ELEMENT_STATE) {      } elsif ($self->{state} == MD_ELEMENT_STATE) {
5803        if ($self->{nc} == {        if ($self->{nc} == [
5804              'EL' => 0x0045, # E             undef,
5805              'ELE' => 0x004D, # M             undef,
5806              'ELEM' => 0x0045, # E             0x0045, # E
5807              'ELEME' => 0x004E, # N             0x004D, # M
5808            }->{$self->{kwd}}) {             0x0045, # E
5809               0x004E, # N
5810              ]->[length $self->{kwd}] or
5811              $self->{nc} == [
5812               undef,
5813               undef,
5814               0x0065, # e
5815               0x006D, # m
5816               0x0065, # e
5817               0x006E, # n
5818              ]->[length $self->{kwd}]) {
5819          ## Stay in the state.          ## Stay in the state.
5820          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5821                    
# Line 5528  sub _get_next_token ($) { Line 5830  sub _get_next_token ($) {
5830      }      }
5831        
5832          redo A;          redo A;
5833        } elsif ($self->{kwd} eq 'ELEMEN' and        } elsif ((length $self->{kwd}) == 6 and
5834                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
5835                    $self->{nc} == 0x0074)) { # t
5836            if ($self->{kwd} ne 'ELEMEN' or $self->{nc} == 0x0074) {
5837              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
5838                              text => 'ELEMENT',
5839                              line => $self->{line_prev},
5840                              column => $self->{column_prev} - 5);
5841            }
5842          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
5843                         line => $self->{line_prev},                         line => $self->{line_prev},
5844                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
# Line 5558  sub _get_next_token ($) { Line 5867  sub _get_next_token ($) {
5867          redo A;          redo A;
5868        }        }
5869      } elsif ($self->{state} == MD_ATTLIST_STATE) {      } elsif ($self->{state} == MD_ATTLIST_STATE) {
5870        if ($self->{nc} == {        if ($self->{nc} == [
5871              'A' => 0x0054, # T             undef,
5872              'AT' => 0x0054, # T             0x0054, # T
5873              'ATT' => 0x004C, # L             0x0054, # T
5874              'ATTL' => 0x0049, # I             0x004C, # L
5875              'ATTLI' => 0x0053, # S             0x0049, # I
5876            }->{$self->{kwd}}) {             0x0053, # S
5877              ]->[length $self->{kwd}] or
5878              $self->{nc} == [
5879               undef,
5880               0x0074, # t
5881               0x0074, # t
5882               0x006C, # l
5883               0x0069, # i
5884               0x0073, # s
5885              ]->[length $self->{kwd}]) {
5886          ## Stay in the state.          ## Stay in the state.
5887          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5888                    
# Line 5579  sub _get_next_token ($) { Line 5897  sub _get_next_token ($) {
5897      }      }
5898        
5899          redo A;          redo A;
5900        } elsif ($self->{kwd} eq 'ATTLIS' and        } elsif ((length $self->{kwd}) == 6 and
5901                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
5902                    $self->{nc} == 0x0074)) { # t
5903            if ($self->{kwd} ne 'ATTLIS' or $self->{nc} == 0x0074) {
5904              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
5905                              text => 'ATTLIST',
5906                              line => $self->{line_prev},
5907                              column => $self->{column_prev} - 5);
5908            }
5909          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
5910                         attrdefs => [],                         attrdefs => [],
5911                         line => $self->{line_prev},                         line => $self->{line_prev},
# Line 5610  sub _get_next_token ($) { Line 5935  sub _get_next_token ($) {
5935          redo A;          redo A;
5936        }        }
5937      } elsif ($self->{state} == MD_NOTATION_STATE) {      } elsif ($self->{state} == MD_NOTATION_STATE) {
5938        if ($self->{nc} == {        if ($self->{nc} == [
5939              'N' => 0x004F, # O             undef,
5940              'NO' => 0x0054, # T             0x004F, # O
5941              'NOT' => 0x0041, # A             0x0054, # T
5942              'NOTA' => 0x0054, # T             0x0041, # A
5943              'NOTAT' => 0x0049, # I             0x0054, # T
5944              'NOTATI' => 0x004F, # O             0x0049, # I
5945            }->{$self->{kwd}}) {             0x004F, # O
5946              ]->[length $self->{kwd}] or
5947              $self->{nc} == [
5948               undef,
5949               0x006F, # o
5950               0x0074, # t
5951               0x0061, # a
5952               0x0074, # t
5953               0x0069, # i
5954               0x006F, # o
5955              ]->[length $self->{kwd}]) {
5956          ## Stay in the state.          ## Stay in the state.
5957          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5958                    
# Line 5632  sub _get_next_token ($) { Line 5967  sub _get_next_token ($) {
5967      }      }
5968        
5969          redo A;          redo A;
5970        } elsif ($self->{kwd} eq 'NOTATIO' and        } elsif ((length $self->{kwd}) == 7 and
5971                 $self->{nc} == 0x004E) { # N                 ($self->{nc} == 0x004E or # N
5972                    $self->{nc} == 0x006E)) { # n
5973            if ($self->{kwd} ne 'NOTATIO' or $self->{nc} == 0x006E) {
5974              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
5975                              text => 'NOTATION',
5976                              line => $self->{line_prev},
5977                              column => $self->{column_prev} - 6);
5978            }
5979          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
5980                         line => $self->{line_prev},                         line => $self->{line_prev},
5981                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
# Line 5845  sub _get_next_token ($) { Line 6187  sub _get_next_token ($) {
6187        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".
6188                
6189        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
6190          ## TODO:          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
6191          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
6192            } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
6193              $self->{state} = AFTER_ELEMENT_NAME_STATE;
6194            } else { # ENTITY/NOTATION
6195              $self->{state} = AFTER_DOCTYPE_NAME_STATE;
6196            }
6197                    
6198      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
6199        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 5863  sub _get_next_token ($) { Line 6210  sub _get_next_token ($) {
6210          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
6211            #            #
6212          } else {          } else {
6213            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md body'); ## TODO: type            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md def'); ## TODO: type
6214          }          }
6215          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
6216                    
# Line 6853  sub _get_next_token ($) { Line 7200  sub _get_next_token ($) {
7200        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
7201          ## XML5: No parse error.          ## XML5: No parse error.
7202          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no default type'); ## TODO: type          $self->{parse_error}->(level => $self->{level}->{must}, type => 'no default type'); ## TODO: type
7203          $self->{state} = BOGUS_COMMENT_STATE;          $self->{state} = BOGUS_MD_STATE;
         $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded  
7204          ## Reconsume.          ## Reconsume.
7205          redo A;          redo A;
7206        } elsif ($self->{nc} == 0x0022) { # "        } elsif ($self->{nc} == 0x0022) { # "
# Line 7141  sub _get_next_token ($) { Line 7487  sub _get_next_token ($) {
7487          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
7488          ## Reconsume.          ## Reconsume.
7489          redo A;          redo A;
7490        }              }
7491        } elsif ($self->{state} == NDATA_STATE) {
7492          ## ASCII case-insensitive
7493          if ($self->{nc} == [
7494                undef,
7495                0x0044, # D
7496                0x0041, # A
7497                0x0054, # T
7498              ]->[length $self->{kwd}] or
7499              $self->{nc} == [
7500                undef,
7501                0x0064, # d
7502                0x0061, # a
7503                0x0074, # t
7504              ]->[length $self->{kwd}]) {
7505            
7506            ## Stay in the state.
7507            $self->{kwd} .= chr $self->{nc};
7508            
7509        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7510          $self->{line_prev} = $self->{line};
7511          $self->{column_prev} = $self->{column};
7512          $self->{column}++;
7513          $self->{nc}
7514              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7515        } else {
7516          $self->{set_nc}->($self);
7517        }
7518      
7519            redo A;
7520          } elsif ((length $self->{kwd}) == 4 and
7521                   ($self->{nc} == 0x0041 or # A
7522                    $self->{nc} == 0x0061)) { # a
7523            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
7524              
7525              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
7526                              text => 'NDATA',
7527                              line => $self->{line_prev},
7528                              column => $self->{column_prev} - 4);
7529            } else {
7530              
7531            }
7532            $self->{state} = AFTER_NDATA_STATE;
7533            
7534        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7535          $self->{line_prev} = $self->{line};
7536          $self->{column_prev} = $self->{column};
7537          $self->{column}++;
7538          $self->{nc}
7539              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7540        } else {
7541          $self->{set_nc}->($self);
7542        }
7543      
7544            redo A;
7545          } else {
7546            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after literal', ## TODO: type
7547                            line => $self->{line_prev},
7548                            column => $self->{column_prev} + 1
7549                                - length $self->{kwd});
7550            
7551            $self->{state} = BOGUS_MD_STATE;
7552            ## Reconsume.
7553            redo A;
7554          }
7555        } elsif ($self->{state} == AFTER_NDATA_STATE) {
7556          if ($is_space->{$self->{nc}}) {
7557            $self->{state} = BEFORE_NOTATION_NAME_STATE;
7558            
7559        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7560          $self->{line_prev} = $self->{line};
7561          $self->{column_prev} = $self->{column};
7562          $self->{column}++;
7563          $self->{nc}
7564              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7565        } else {
7566          $self->{set_nc}->($self);
7567        }
7568      
7569            redo A;
7570          } elsif ($self->{nc} == 0x003E) { # >
7571            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no notation name'); ## TODO: type
7572            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7573            
7574        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7575          $self->{line_prev} = $self->{line};
7576          $self->{column_prev} = $self->{column};
7577          $self->{column}++;
7578          $self->{nc}
7579              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7580        } else {
7581          $self->{set_nc}->($self);
7582        }
7583      
7584            return  ($self->{ct}); # ENTITY
7585            redo A;
7586          } elsif ($self->{nc} == -1) {
7587            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7588            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7589            
7590        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7591          $self->{line_prev} = $self->{line};
7592          $self->{column_prev} = $self->{column};
7593          $self->{column}++;
7594          $self->{nc}
7595              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7596        } else {
7597          $self->{set_nc}->($self);
7598        }
7599      
7600            return  ($self->{ct}); # ENTITY
7601            redo A;
7602          } else {
7603            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after literal', ## TODO: type
7604                            line => $self->{line_prev},
7605                            column => $self->{column_prev} + 1
7606                                - length $self->{kwd});
7607            $self->{state} = BOGUS_MD_STATE;
7608            ## Reconsume.
7609            redo A;
7610          }
7611        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
7612          if ($is_space->{$self->{nc}}) {
7613            ## Stay in the state.
7614            
7615        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7616          $self->{line_prev} = $self->{line};
7617          $self->{column_prev} = $self->{column};
7618          $self->{column}++;
7619          $self->{nc}
7620              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7621        } else {
7622          $self->{set_nc}->($self);
7623        }
7624      
7625            redo A;
7626          } elsif ($self->{nc} == 0x003E) { # >
7627            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no notation name'); ## TODO: type
7628            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7629            
7630        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7631          $self->{line_prev} = $self->{line};
7632          $self->{column_prev} = $self->{column};
7633          $self->{column}++;
7634          $self->{nc}
7635              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7636        } else {
7637          $self->{set_nc}->($self);
7638        }
7639      
7640            return  ($self->{ct}); # ENTITY
7641            redo A;
7642          } elsif ($self->{nc} == -1) {
7643            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7644            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7645            
7646        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7647          $self->{line_prev} = $self->{line};
7648          $self->{column_prev} = $self->{column};
7649          $self->{column}++;
7650          $self->{nc}
7651              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7652        } else {
7653          $self->{set_nc}->($self);
7654        }
7655      
7656            return  ($self->{ct}); # ENTITY
7657            redo A;
7658          } else {
7659            $self->{ct}->{notation} = chr $self->{nc}; # ENTITY
7660            $self->{state} = NOTATION_NAME_STATE;
7661            
7662        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7663          $self->{line_prev} = $self->{line};
7664          $self->{column_prev} = $self->{column};
7665          $self->{column}++;
7666          $self->{nc}
7667              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7668        } else {
7669          $self->{set_nc}->($self);
7670        }
7671      
7672            redo A;
7673          }
7674        } elsif ($self->{state} == NOTATION_NAME_STATE) {
7675          if ($is_space->{$self->{nc}}) {
7676            $self->{state} = AFTER_MD_DEF_STATE;
7677            
7678        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7679          $self->{line_prev} = $self->{line};
7680          $self->{column_prev} = $self->{column};
7681          $self->{column}++;
7682          $self->{nc}
7683              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7684        } else {
7685          $self->{set_nc}->($self);
7686        }
7687      
7688            redo A;
7689          } elsif ($self->{nc} == 0x003E) { # >
7690            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7691            
7692        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7693          $self->{line_prev} = $self->{line};
7694          $self->{column_prev} = $self->{column};
7695          $self->{column}++;
7696          $self->{nc}
7697              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7698        } else {
7699          $self->{set_nc}->($self);
7700        }
7701      
7702            return  ($self->{ct}); # ENTITY
7703            redo A;
7704          } elsif ($self->{nc} == -1) {
7705            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7706            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7707            
7708        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7709          $self->{line_prev} = $self->{line};
7710          $self->{column_prev} = $self->{column};
7711          $self->{column}++;
7712          $self->{nc}
7713              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7714        } else {
7715          $self->{set_nc}->($self);
7716        }
7717      
7718            return  ($self->{ct}); # ENTITY
7719            redo A;
7720          } else {
7721            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
7722            ## Stay in the state.
7723            
7724        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7725          $self->{line_prev} = $self->{line};
7726          $self->{column_prev} = $self->{column};
7727          $self->{column}++;
7728          $self->{nc}
7729              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7730        } else {
7731          $self->{set_nc}->($self);
7732        }
7733      
7734            redo A;
7735          }
7736        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
7737          if ($self->{nc} == 0x0022) { # "
7738            $self->{state} = AFTER_MD_DEF_STATE;
7739            
7740        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7741          $self->{line_prev} = $self->{line};
7742          $self->{column_prev} = $self->{column};
7743          $self->{column}++;
7744          $self->{nc}
7745              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7746        } else {
7747          $self->{set_nc}->($self);
7748        }
7749      
7750            redo A;
7751          } elsif ($self->{nc} == 0x0026) { # &
7752            $self->{prev_state} = $self->{state};
7753            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7754            $self->{entity_add} = 0x0022; # "
7755            
7756        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7757          $self->{line_prev} = $self->{line};
7758          $self->{column_prev} = $self->{column};
7759          $self->{column}++;
7760          $self->{nc}
7761              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7762        } else {
7763          $self->{set_nc}->($self);
7764        }
7765      
7766            redo A;
7767    ## TODO: %
7768          } elsif ($self->{nc} == -1) {
7769            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7770            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7771            ## Reconsume.
7772            return  ($self->{ct}); # ENTITY
7773            redo A;
7774          } else {
7775            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7776            
7777        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7778          $self->{line_prev} = $self->{line};
7779          $self->{column_prev} = $self->{column};
7780          $self->{column}++;
7781          $self->{nc}
7782              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7783        } else {
7784          $self->{set_nc}->($self);
7785        }
7786      
7787            redo A;
7788          }
7789        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
7790          if ($self->{nc} == 0x0027) { # '
7791            $self->{state} = AFTER_MD_DEF_STATE;
7792            
7793        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7794          $self->{line_prev} = $self->{line};
7795          $self->{column_prev} = $self->{column};
7796          $self->{column}++;
7797          $self->{nc}
7798              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7799        } else {
7800          $self->{set_nc}->($self);
7801        }
7802      
7803            redo A;
7804          } elsif ($self->{nc} == 0x0026) { # &
7805            $self->{prev_state} = $self->{state};
7806            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7807            $self->{entity_add} = 0x0027; # '
7808            
7809        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7810          $self->{line_prev} = $self->{line};
7811          $self->{column_prev} = $self->{column};
7812          $self->{column}++;
7813          $self->{nc}
7814              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7815        } else {
7816          $self->{set_nc}->($self);
7817        }
7818      
7819            redo A;
7820    ## TODO: %
7821          } elsif ($self->{nc} == -1) {
7822            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7823            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7824            ## Reconsume.
7825            return  ($self->{ct}); # ENTITY
7826            redo A;
7827          } else {
7828            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7829            
7830        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7831          $self->{line_prev} = $self->{line};
7832          $self->{column_prev} = $self->{column};
7833          $self->{column}++;
7834          $self->{nc}
7835              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7836        } else {
7837          $self->{set_nc}->($self);
7838        }
7839      
7840            redo A;
7841          }
7842        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
7843          ## TODO: XMLize
7844    
7845          if ($is_space->{$self->{nc}} or
7846              {
7847                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
7848                $self->{entity_add} => 1,
7849              }->{$self->{nc}}) {
7850            ## Don't consume
7851            ## No error
7852            ## Return nothing.
7853            #
7854          } elsif ($self->{nc} == 0x0023) { # #
7855            $self->{ca} = $self->{ct};
7856            $self->{state} = ENTITY_HASH_STATE;
7857            $self->{kwd} = '#';
7858            
7859        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7860          $self->{line_prev} = $self->{line};
7861          $self->{column_prev} = $self->{column};
7862          $self->{column}++;
7863          $self->{nc}
7864              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7865        } else {
7866          $self->{set_nc}->($self);
7867        }
7868      
7869            redo A;
7870          } elsif ((0x0041 <= $self->{nc} and
7871                    $self->{nc} <= 0x005A) or # A..Z
7872                   (0x0061 <= $self->{nc} and
7873                    $self->{nc} <= 0x007A)) { # a..z
7874            #
7875          } else {
7876            $self->{parse_error}->(level => $self->{level}->{must}, type => 'bare ero');
7877            ## Return nothing.
7878            #
7879          }
7880    
7881          $self->{ct}->{value} .= '&';
7882          $self->{state} = $self->{prev_state};
7883          ## Reconsume.
7884          redo A;
7885        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
7886          if ($is_space->{$self->{nc}}) {
7887            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
7888            
7889        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7890          $self->{line_prev} = $self->{line};
7891          $self->{column_prev} = $self->{column};
7892          $self->{column}++;
7893          $self->{nc}
7894              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7895        } else {
7896          $self->{set_nc}->($self);
7897        }
7898      
7899            redo A;
7900          } elsif ($self->{nc} == 0x0028) { # (
7901            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
7902            $self->{ct}->{content} = ['('];
7903            $self->{group_depth} = 1;
7904            
7905        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7906          $self->{line_prev} = $self->{line};
7907          $self->{column_prev} = $self->{column};
7908          $self->{column}++;
7909          $self->{nc}
7910              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7911        } else {
7912          $self->{set_nc}->($self);
7913        }
7914      
7915            redo A;
7916          } elsif ($self->{nc} == 0x003E) { # >
7917            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md def'); ## TODO: type
7918            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7919            
7920        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7921          $self->{line_prev} = $self->{line};
7922          $self->{column_prev} = $self->{column};
7923          $self->{column}++;
7924          $self->{nc}
7925              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7926        } else {
7927          $self->{set_nc}->($self);
7928        }
7929      
7930            return  ($self->{ct}); # ELEMENT
7931            redo A;
7932          } elsif ($self->{nc} == -1) {
7933            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7934            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7935            
7936        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7937          $self->{line_prev} = $self->{line};
7938          $self->{column_prev} = $self->{column};
7939          $self->{column}++;
7940          $self->{nc}
7941              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7942        } else {
7943          $self->{set_nc}->($self);
7944        }
7945      
7946            return  ($self->{ct}); # ELEMENT
7947            redo A;
7948          } else {
7949            $self->{ct}->{content} = [chr $self->{nc}];
7950            $self->{state} = CONTENT_KEYWORD_STATE;
7951            
7952        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7953          $self->{line_prev} = $self->{line};
7954          $self->{column_prev} = $self->{column};
7955          $self->{column}++;
7956          $self->{nc}
7957              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7958        } else {
7959          $self->{set_nc}->($self);
7960        }
7961      
7962            redo A;
7963          }
7964        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
7965          if ($is_space->{$self->{nc}}) {
7966            $self->{state} = AFTER_MD_DEF_STATE;
7967            
7968        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7969          $self->{line_prev} = $self->{line};
7970          $self->{column_prev} = $self->{column};
7971          $self->{column}++;
7972          $self->{nc}
7973              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7974        } else {
7975          $self->{set_nc}->($self);
7976        }
7977      
7978            redo A;
7979          } elsif ($self->{nc} == 0x003E) { # >
7980            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7981            
7982        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7983          $self->{line_prev} = $self->{line};
7984          $self->{column_prev} = $self->{column};
7985          $self->{column}++;
7986          $self->{nc}
7987              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7988        } else {
7989          $self->{set_nc}->($self);
7990        }
7991      
7992            return  ($self->{ct}); # ELEMENT
7993            redo A;
7994          } elsif ($self->{nc} == -1) {
7995            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7996            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7997            
7998        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7999          $self->{line_prev} = $self->{line};
8000          $self->{column_prev} = $self->{column};
8001          $self->{column}++;
8002          $self->{nc}
8003              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8004        } else {
8005          $self->{set_nc}->($self);
8006        }
8007      
8008            return  ($self->{ct}); # ELEMENT
8009            redo A;
8010          } else {
8011            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
8012            ## Stay in the state.
8013            
8014        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8015          $self->{line_prev} = $self->{line};
8016          $self->{column_prev} = $self->{column};
8017          $self->{column}++;
8018          $self->{nc}
8019              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8020        } else {
8021          $self->{set_nc}->($self);
8022        }
8023      
8024            redo A;
8025          }
8026        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
8027          if ($is_space->{$self->{nc}}) {
8028            ## Stay in the state.
8029            
8030        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8031          $self->{line_prev} = $self->{line};
8032          $self->{column_prev} = $self->{column};
8033          $self->{column}++;
8034          $self->{nc}
8035              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8036        } else {
8037          $self->{set_nc}->($self);
8038        }
8039      
8040            redo A;
8041          } elsif ($self->{nc} == 0x0028) { # (
8042            $self->{group_depth}++;
8043            push @{$self->{ct}->{content}}, chr $self->{nc};
8044            ## Stay in the state.
8045            
8046        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8047          $self->{line_prev} = $self->{line};
8048          $self->{column_prev} = $self->{column};
8049          $self->{column}++;
8050          $self->{nc}
8051              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8052        } else {
8053          $self->{set_nc}->($self);
8054        }
8055      
8056            redo A;
8057          } elsif ($self->{nc} == 0x007C or # |
8058                   $self->{nc} == 0x002C) { # ,
8059            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8060            ## Stay in the state.
8061            
8062        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8063          $self->{line_prev} = $self->{line};
8064          $self->{column_prev} = $self->{column};
8065          $self->{column}++;
8066          $self->{nc}
8067              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8068        } else {
8069          $self->{set_nc}->($self);
8070        }
8071      
8072            redo A;
8073          } elsif ($self->{nc} == 0x0029) { # )
8074            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8075            push @{$self->{ct}->{content}}, chr $self->{nc};
8076            $self->{group_depth}--;
8077            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8078            
8079        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8080          $self->{line_prev} = $self->{line};
8081          $self->{column_prev} = $self->{column};
8082          $self->{column}++;
8083          $self->{nc}
8084              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8085        } else {
8086          $self->{set_nc}->($self);
8087        }
8088      
8089            redo A;
8090          } elsif ($self->{nc} == 0x003E) { # >
8091            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8092            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8093            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8094            
8095        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8096          $self->{line_prev} = $self->{line};
8097          $self->{column_prev} = $self->{column};
8098          $self->{column}++;
8099          $self->{nc}
8100              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8101        } else {
8102          $self->{set_nc}->($self);
8103        }
8104      
8105            return  ($self->{ct}); # ELEMENT
8106            redo A;
8107          } elsif ($self->{nc} == -1) {
8108            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8109            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8110            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8111            
8112        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8113          $self->{line_prev} = $self->{line};
8114          $self->{column_prev} = $self->{column};
8115          $self->{column}++;
8116          $self->{nc}
8117              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8118        } else {
8119          $self->{set_nc}->($self);
8120        }
8121      
8122            return  ($self->{ct}); # ELEMENT
8123            redo A;
8124          } else {
8125            push @{$self->{ct}->{content}}, chr $self->{nc};
8126            $self->{state} = CM_ELEMENT_NAME_STATE;
8127            
8128        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8129          $self->{line_prev} = $self->{line};
8130          $self->{column_prev} = $self->{column};
8131          $self->{column}++;
8132          $self->{nc}
8133              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8134        } else {
8135          $self->{set_nc}->($self);
8136        }
8137      
8138            redo A;
8139          }
8140        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
8141          if ($is_space->{$self->{nc}}) {
8142            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8143            
8144        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8145          $self->{line_prev} = $self->{line};
8146          $self->{column_prev} = $self->{column};
8147          $self->{column}++;
8148          $self->{nc}
8149              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8150        } else {
8151          $self->{set_nc}->($self);
8152        }
8153      
8154            redo A;
8155          } elsif ($self->{nc} == 0x002A or # *
8156                   $self->{nc} == 0x002B or # +
8157                   $self->{nc} == 0x003F) { # ?
8158            push @{$self->{ct}->{content}}, chr $self->{nc};
8159            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8160            
8161        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8162          $self->{line_prev} = $self->{line};
8163          $self->{column_prev} = $self->{column};
8164          $self->{column}++;
8165          $self->{nc}
8166              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8167        } else {
8168          $self->{set_nc}->($self);
8169        }
8170      
8171            redo A;
8172          } elsif ($self->{nc} == 0x007C or # |
8173                   $self->{nc} == 0x002C) { # ,
8174            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8175            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8176            
8177        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8178          $self->{line_prev} = $self->{line};
8179          $self->{column_prev} = $self->{column};
8180          $self->{column}++;
8181          $self->{nc}
8182              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8183        } else {
8184          $self->{set_nc}->($self);
8185        }
8186      
8187            redo A;
8188          } elsif ($self->{nc} == 0x0029) { # )
8189            $self->{group_depth}--;
8190            push @{$self->{ct}->{content}}, chr $self->{nc};
8191            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8192            
8193        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8194          $self->{line_prev} = $self->{line};
8195          $self->{column_prev} = $self->{column};
8196          $self->{column}++;
8197          $self->{nc}
8198              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8199        } else {
8200          $self->{set_nc}->($self);
8201        }
8202      
8203            redo A;
8204          } elsif ($self->{nc} == 0x003E) { # >
8205            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8206            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8207            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8208            
8209        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8210          $self->{line_prev} = $self->{line};
8211          $self->{column_prev} = $self->{column};
8212          $self->{column}++;
8213          $self->{nc}
8214              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8215        } else {
8216          $self->{set_nc}->($self);
8217        }
8218      
8219            return  ($self->{ct}); # ELEMENT
8220            redo A;
8221          } elsif ($self->{nc} == -1) {
8222            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8223            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8224            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8225            
8226        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8227          $self->{line_prev} = $self->{line};
8228          $self->{column_prev} = $self->{column};
8229          $self->{column}++;
8230          $self->{nc}
8231              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8232        } else {
8233          $self->{set_nc}->($self);
8234        }
8235      
8236            return  ($self->{ct}); # ELEMENT
8237            redo A;
8238          } else {
8239            $self->{ct}->{content}->[-1] .= chr $self->{nc};
8240            ## Stay in the state.
8241            
8242        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8243          $self->{line_prev} = $self->{line};
8244          $self->{column_prev} = $self->{column};
8245          $self->{column}++;
8246          $self->{nc}
8247              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8248        } else {
8249          $self->{set_nc}->($self);
8250        }
8251      
8252            redo A;
8253          }
8254        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
8255          if ($is_space->{$self->{nc}}) {
8256            ## Stay in the state.
8257            
8258        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8259          $self->{line_prev} = $self->{line};
8260          $self->{column_prev} = $self->{column};
8261          $self->{column}++;
8262          $self->{nc}
8263              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8264        } else {
8265          $self->{set_nc}->($self);
8266        }
8267      
8268            redo A;
8269          } elsif ($self->{nc} == 0x007C or # |
8270                   $self->{nc} == 0x002C) { # ,
8271            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8272            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8273            
8274        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8275          $self->{line_prev} = $self->{line};
8276          $self->{column_prev} = $self->{column};
8277          $self->{column}++;
8278          $self->{nc}
8279              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8280        } else {
8281          $self->{set_nc}->($self);
8282        }
8283      
8284            redo A;
8285          } elsif ($self->{nc} == 0x0029) { # )
8286            $self->{group_depth}--;
8287            push @{$self->{ct}->{content}}, chr $self->{nc};
8288            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8289            
8290        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8291          $self->{line_prev} = $self->{line};
8292          $self->{column_prev} = $self->{column};
8293          $self->{column}++;
8294          $self->{nc}
8295              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8296        } else {
8297          $self->{set_nc}->($self);
8298        }
8299      
8300            redo A;
8301          } elsif ($self->{nc} == 0x003E) { # >
8302            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8303            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8304            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8305            
8306        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8307          $self->{line_prev} = $self->{line};
8308          $self->{column_prev} = $self->{column};
8309          $self->{column}++;
8310          $self->{nc}
8311              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8312        } else {
8313          $self->{set_nc}->($self);
8314        }
8315      
8316            return  ($self->{ct}); # ELEMENT
8317            redo A;
8318          } elsif ($self->{nc} == -1) {
8319            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8320            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8321            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8322            
8323        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8324          $self->{line_prev} = $self->{line};
8325          $self->{column_prev} = $self->{column};
8326          $self->{column}++;
8327          $self->{nc}
8328              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8329        } else {
8330          $self->{set_nc}->($self);
8331        }
8332      
8333            return  ($self->{ct}); # ELEMENT
8334            redo A;
8335          } else {
8336            $self->{parse_error}->(level => $self->{level}->{must}, type => 'after element name'); ## TODO: type
8337            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8338            $self->{state} = BOGUS_MD_STATE;
8339            
8340        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8341          $self->{line_prev} = $self->{line};
8342          $self->{column_prev} = $self->{column};
8343          $self->{column}++;
8344          $self->{nc}
8345              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8346        } else {
8347          $self->{set_nc}->($self);
8348        }
8349      
8350            redo A;
8351          }
8352        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
8353          if ($is_space->{$self->{nc}}) {
8354            if ($self->{group_depth}) {
8355              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8356            } else {
8357              $self->{state} = AFTER_MD_DEF_STATE;
8358            }
8359            
8360        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8361          $self->{line_prev} = $self->{line};
8362          $self->{column_prev} = $self->{column};
8363          $self->{column}++;
8364          $self->{nc}
8365              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8366        } else {
8367          $self->{set_nc}->($self);
8368        }
8369      
8370            redo A;
8371          } elsif ($self->{nc} == 0x002A or # *
8372                   $self->{nc} == 0x002B or # +
8373                   $self->{nc} == 0x003F) { # ?
8374            push @{$self->{ct}->{content}}, chr $self->{nc};
8375            if ($self->{group_depth}) {
8376              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8377            } else {
8378              $self->{state} = AFTER_MD_DEF_STATE;
8379            }
8380            
8381        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8382          $self->{line_prev} = $self->{line};
8383          $self->{column_prev} = $self->{column};
8384          $self->{column}++;
8385          $self->{nc}
8386              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8387        } else {
8388          $self->{set_nc}->($self);
8389        }
8390      
8391            redo A;
8392          } elsif ($self->{nc} == 0x0029) { # )
8393            if ($self->{group_depth}) {
8394              $self->{group_depth}--;
8395              push @{$self->{ct}->{content}}, chr $self->{nc};
8396              ## Stay in the state.
8397              
8398        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8399          $self->{line_prev} = $self->{line};
8400          $self->{column_prev} = $self->{column};
8401          $self->{column}++;
8402          $self->{nc}
8403              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8404        } else {
8405          $self->{set_nc}->($self);
8406        }
8407      
8408              redo A;
8409            } else {
8410              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8411              $self->{state} = BOGUS_MD_STATE;
8412              ## Reconsume.
8413              redo A;
8414            }
8415          } elsif ($self->{nc} == 0x003E) { # >
8416            if ($self->{group_depth}) {
8417              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8418              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8419            }
8420            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8421            
8422        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8423          $self->{line_prev} = $self->{line};
8424          $self->{column_prev} = $self->{column};
8425          $self->{column}++;
8426          $self->{nc}
8427              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8428        } else {
8429          $self->{set_nc}->($self);
8430        }
8431      
8432            return  ($self->{ct}); # ELEMENT
8433            redo A;
8434          } elsif ($self->{nc} == -1) {
8435            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8436            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8437            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8438            
8439        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8440          $self->{line_prev} = $self->{line};
8441          $self->{column_prev} = $self->{column};
8442          $self->{column}++;
8443          $self->{nc}
8444              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8445        } else {
8446          $self->{set_nc}->($self);
8447        }
8448      
8449            return  ($self->{ct}); # ELEMENT
8450            redo A;
8451          } else {
8452            if ($self->{group_depth}) {
8453              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8454            } else {
8455              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8456              $self->{state} = BOGUS_MD_STATE;
8457            }
8458            ## Reconsume.
8459            redo A;
8460          }
8461        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
8462          if ($is_space->{$self->{nc}}) {
8463            ## Stay in the state.
8464            
8465        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8466          $self->{line_prev} = $self->{line};
8467          $self->{column_prev} = $self->{column};
8468          $self->{column}++;
8469          $self->{nc}
8470              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8471        } else {
8472          $self->{set_nc}->($self);
8473        }
8474      
8475            redo A;
8476          } elsif ($self->{nc} == 0x003E) { # >
8477            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8478            
8479        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8480          $self->{line_prev} = $self->{line};
8481          $self->{column_prev} = $self->{column};
8482          $self->{column}++;
8483          $self->{nc}
8484              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8485        } else {
8486          $self->{set_nc}->($self);
8487        }
8488      
8489            return  ($self->{ct}); # ENTITY/ELEMENT
8490            redo A;
8491          } elsif ($self->{nc} == -1) {
8492            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8493            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8494            
8495        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8496          $self->{line_prev} = $self->{line};
8497          $self->{column_prev} = $self->{column};
8498          $self->{column}++;
8499          $self->{nc}
8500              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8501        } else {
8502          $self->{set_nc}->($self);
8503        }
8504      
8505            return  ($self->{ct}); # ENTITY/ELEMENT
8506            redo A;
8507          } else {
8508            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8509            $self->{state} = BOGUS_MD_STATE;
8510            ## Reconsume.
8511            redo A;
8512          }
8513        } elsif ($self->{state} == BOGUS_MD_STATE) {
8514          if ($self->{nc} == 0x003E) { # >
8515            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8516            
8517        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8518          $self->{line_prev} = $self->{line};
8519          $self->{column_prev} = $self->{column};
8520          $self->{column}++;
8521          $self->{nc}
8522              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8523        } else {
8524          $self->{set_nc}->($self);
8525        }
8526      
8527            return  ($self->{ct}); # ATTLIST/ENTITY/NOTATION
8528            redo A;
8529          } elsif ($self->{nc} == -1) {
8530            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8531            ## Reconsume.
8532            return  ($self->{ct}); # ATTLIST/ENTITY/NOTATION
8533            redo A;
8534          } else {
8535            ## Stay in the state.
8536            
8537        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8538          $self->{line_prev} = $self->{line};
8539          $self->{column_prev} = $self->{column};
8540          $self->{column}++;
8541          $self->{nc}
8542              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8543        } else {
8544          $self->{set_nc}->($self);
8545        }
8546      
8547            redo A;
8548          }
8549      } else {      } else {
8550        die "$0: $self->{state}: Unknown state";        die "$0: $self->{state}: Unknown state";
8551      }      }

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24