/[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.17 by wakaba, Sun Oct 19 04:39:25 2008 UTC revision 1.22 by wakaba, Sun Oct 19 10:12:54 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 BOGUS_MD_STATE () { 85 }  sub BEFORE_NDATA_STATE () { 85 }
181    sub NDATA_STATE () { 86 }
182    sub AFTER_NDATA_STATE () { 87 }
183    sub BEFORE_NOTATION_NAME_STATE () { 88 }
184    sub NOTATION_NAME_STATE () { 89 }
185    sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
186    sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 91 }
187    sub ENTITY_VALUE_ENTITY_STATE () { 92 }
188    sub AFTER_ELEMENT_NAME_STATE () { 93 }
189    sub BEFORE_ELEMENT_CONTENT_STATE () { 94 }
190    sub CONTENT_KEYWORD_STATE () { 95 }
191    sub AFTER_CM_GROUP_OPEN_STATE () { 96 }
192    sub CM_ELEMENT_NAME_STATE () { 97 }
193    sub AFTER_CM_ELEMENT_NAME_STATE () { 98 }
194    sub AFTER_CM_GROUP_CLOSE_STATE () { 99 }
195    sub AFTER_MD_DEF_STATE () { 100 }
196    sub BOGUS_MD_STATE () { 101 }
197    
198  ## Tree constructor state constants (see Whatpm::HTML for the full  ## Tree constructor state constants (see Whatpm::HTML for the full
199  ## list and descriptions)  ## list and descriptions)
# Line 3256  sub _get_next_token ($) { Line 3272  sub _get_next_token ($) {
3272      }      }
3273        
3274          redo A;          redo A;
3275  ## TODO: " and ' for ENTITY        } 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        } elsif ($self->{is_xml} and
3312                 $self->{ct}->{type} == DOCTYPE_TOKEN and                 $self->{ct}->{type} == DOCTYPE_TOKEN and
3313                 $self->{nc} == 0x005B) { # [                 $self->{nc} == 0x005B) { # [
# Line 4172  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 4209  sub _get_next_token ($) { Line 4265  sub _get_next_token ($) {
4265        
4266          return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION          return  ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
4267          redo A;          redo A;
4268  ## TODO: "NDATA"        } 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}) {
4277          $self->{line_prev} = $self->{line};
4278          $self->{column_prev} = $self->{column};
4279          $self->{column}++;
4280          $self->{nc}
4281              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4282        } else {
4283          $self->{set_nc}->($self);
4284        }
4285      
4286            redo A;
4287        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
4288          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
4289                        
# Line 4271  sub _get_next_token ($) { Line 4345  sub _get_next_token ($) {
4345        
4346          redo A;          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}) {
4410          $self->{line_prev} = $self->{line};
4411          $self->{column_prev} = $self->{column};
4412          $self->{column}++;
4413          $self->{nc}
4414              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4415        } else {
4416          $self->{set_nc}->($self);
4417        }
4418      
4419            redo A;
4420          }
4421      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {
4422        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
4423                    
# Line 4481  sub _get_next_token ($) { Line 4628  sub _get_next_token ($) {
4628              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4629              $self->{entity_add} => 1,              $self->{entity_add} => 1,
4630            }->{$self->{nc}}) {            }->{$self->{nc}}) {
4631                    if ($self->{is_xml}) {
4632              
4633              $self->{parse_error}->(level => $self->{level}->{must}, type => 'bare ero',
4634                              line => $self->{line_prev},
4635                              column => $self->{column_prev}
4636                                  + ($self->{nc} == -1 ? 1 : 0));
4637            } else {
4638              
4639              ## No error
4640            }
4641          ## Don't consume          ## Don't consume
         ## No error  
4642          ## Return nothing.          ## Return nothing.
4643          #          #
4644        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 4502  sub _get_next_token ($) { Line 4657  sub _get_next_token ($) {
4657      }      }
4658        
4659          redo A;          redo A;
4660        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
4661                   (0x0041 <= $self->{nc} and
4662                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
4663                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
4664                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 4556  sub _get_next_token ($) { Line 4712  sub _get_next_token ($) {
4712          redo A;          redo A;
4713        }        }
4714      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
4715        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
4716            $self->{nc} == 0x0058) { # X          
4717            $self->{state} = HEXREF_X_STATE;
4718            $self->{kwd} .= chr $self->{nc};
4719                    
4720        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4721          $self->{line_prev} = $self->{line};
4722          $self->{column_prev} = $self->{column};
4723          $self->{column}++;
4724          $self->{nc}
4725              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4726        } else {
4727          $self->{set_nc}->($self);
4728        }
4729      
4730            redo A;
4731          } elsif ($self->{nc} == 0x0058) { # X
4732            
4733            if ($self->{is_xml}) {
4734              $self->{parse_error}->(level => $self->{level}->{must}, type => 'uppercase hcro'); ## TODO: type
4735            }
4736          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
4737          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
4738                    
# Line 4850  sub _get_next_token ($) { Line 5024  sub _get_next_token ($) {
5024          redo A;          redo A;
5025        }        }
5026      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
5027        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
5028            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
5029            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
5030              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
5031             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
5032              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
5033             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
5034              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
5035             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
5036                    {
5037                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
5038                      $self->{entity_add} => 1,
5039                    }->{$self->{nc}}))) {
5040          our $EntityChar;          our $EntityChar;
5041          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5042          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
5043                $self->{ge}->{$self->{kwd}}) {
5044            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
5045                            if (defined $self->{ge}->{$self->{kwd}}) {
5046              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
5047                    
5048                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
5049                  } else {
5050                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
5051                      
5052                      $self->{parse_error}->(level => $self->{level}->{must}, type => 'unparsed entity', ## TODO: type
5053                                      value => $self->{kwd});
5054                    } else {
5055                      
5056                    }
5057                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
5058                  }
5059                } else {
5060                  if ($self->{is_xml}) {
5061                    
5062                    $self->{parse_error}->(level => $self->{level}->{must}, type => 'entity not declared', ## TODO: type
5063                                    value => $self->{kwd},
5064                                    level => {
5065                                              'amp;' => $self->{level}->{warn},
5066                                              'quot;' => $self->{level}->{warn},
5067                                              'lt;' => $self->{level}->{warn},
5068                                              'gt;' => $self->{level}->{warn},
5069                                              'apos;' => $self->{level}->{warn},
5070                                             }->{$self->{kwd}} ||
5071                                             $self->{level}->{must});
5072                  } else {
5073                    
5074                  }
5075                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
5076                }
5077              $self->{entity__match} = 1;              $self->{entity__match} = 1;
5078                            
5079      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 6043  sub _get_next_token ($) { Line 6252  sub _get_next_token ($) {
6252          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
6253            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
6254          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
6255            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
6256          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
6257            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
6258          }          }
# Line 7342  sub _get_next_token ($) { Line 7550  sub _get_next_token ($) {
7550          ## Reconsume.          ## Reconsume.
7551          redo A;          redo A;
7552        }        }
7553        } elsif ($self->{state} == NDATA_STATE) {
7554          ## ASCII case-insensitive
7555          if ($self->{nc} == [
7556                undef,
7557                0x0044, # D
7558                0x0041, # A
7559                0x0054, # T
7560              ]->[length $self->{kwd}] or
7561              $self->{nc} == [
7562                undef,
7563                0x0064, # d
7564                0x0061, # a
7565                0x0074, # t
7566              ]->[length $self->{kwd}]) {
7567            
7568            ## Stay in the state.
7569            $self->{kwd} .= chr $self->{nc};
7570            
7571        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7572          $self->{line_prev} = $self->{line};
7573          $self->{column_prev} = $self->{column};
7574          $self->{column}++;
7575          $self->{nc}
7576              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7577        } else {
7578          $self->{set_nc}->($self);
7579        }
7580      
7581            redo A;
7582          } elsif ((length $self->{kwd}) == 4 and
7583                   ($self->{nc} == 0x0041 or # A
7584                    $self->{nc} == 0x0061)) { # a
7585            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
7586              
7587              $self->{parse_error}->(level => $self->{level}->{must}, type => 'lowercase keyword', ## TODO: type
7588                              text => 'NDATA',
7589                              line => $self->{line_prev},
7590                              column => $self->{column_prev} - 4);
7591            } else {
7592              
7593            }
7594            $self->{state} = AFTER_NDATA_STATE;
7595            
7596        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7597          $self->{line_prev} = $self->{line};
7598          $self->{column_prev} = $self->{column};
7599          $self->{column}++;
7600          $self->{nc}
7601              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7602        } else {
7603          $self->{set_nc}->($self);
7604        }
7605      
7606            redo A;
7607          } else {
7608            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after literal', ## TODO: type
7609                            line => $self->{line_prev},
7610                            column => $self->{column_prev} + 1
7611                                - length $self->{kwd});
7612            
7613            $self->{state} = BOGUS_MD_STATE;
7614            ## Reconsume.
7615            redo A;
7616          }
7617        } elsif ($self->{state} == AFTER_NDATA_STATE) {
7618          if ($is_space->{$self->{nc}}) {
7619            $self->{state} = BEFORE_NOTATION_NAME_STATE;
7620            
7621        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7622          $self->{line_prev} = $self->{line};
7623          $self->{column_prev} = $self->{column};
7624          $self->{column}++;
7625          $self->{nc}
7626              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7627        } else {
7628          $self->{set_nc}->($self);
7629        }
7630      
7631            redo A;
7632          } elsif ($self->{nc} == 0x003E) { # >
7633            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no notation name'); ## TODO: type
7634            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7635            
7636        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7637          $self->{line_prev} = $self->{line};
7638          $self->{column_prev} = $self->{column};
7639          $self->{column}++;
7640          $self->{nc}
7641              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7642        } else {
7643          $self->{set_nc}->($self);
7644        }
7645      
7646            return  ($self->{ct}); # ENTITY
7647            redo A;
7648          } elsif ($self->{nc} == -1) {
7649            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7650            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7651            
7652        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7653          $self->{line_prev} = $self->{line};
7654          $self->{column_prev} = $self->{column};
7655          $self->{column}++;
7656          $self->{nc}
7657              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7658        } else {
7659          $self->{set_nc}->($self);
7660        }
7661      
7662            return  ($self->{ct}); # ENTITY
7663            redo A;
7664          } else {
7665            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after literal', ## TODO: type
7666                            line => $self->{line_prev},
7667                            column => $self->{column_prev} + 1
7668                                - length $self->{kwd});
7669            $self->{state} = BOGUS_MD_STATE;
7670            ## Reconsume.
7671            redo A;
7672          }
7673        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
7674          if ($is_space->{$self->{nc}}) {
7675            ## Stay in the state.
7676            
7677        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7678          $self->{line_prev} = $self->{line};
7679          $self->{column_prev} = $self->{column};
7680          $self->{column}++;
7681          $self->{nc}
7682              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7683        } else {
7684          $self->{set_nc}->($self);
7685        }
7686      
7687            redo A;
7688          } elsif ($self->{nc} == 0x003E) { # >
7689            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no notation name'); ## TODO: type
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            $self->{state} = NOTATION_NAME_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} == NOTATION_NAME_STATE) {
7737          if ($is_space->{$self->{nc}}) {
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} == 0x003E) { # >
7752            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7753            
7754        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7755          $self->{line_prev} = $self->{line};
7756          $self->{column_prev} = $self->{column};
7757          $self->{column}++;
7758          $self->{nc}
7759              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7760        } else {
7761          $self->{set_nc}->($self);
7762        }
7763      
7764            return  ($self->{ct}); # ENTITY
7765            redo A;
7766          } elsif ($self->{nc} == -1) {
7767            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7768            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7769            
7770        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7771          $self->{line_prev} = $self->{line};
7772          $self->{column_prev} = $self->{column};
7773          $self->{column}++;
7774          $self->{nc}
7775              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7776        } else {
7777          $self->{set_nc}->($self);
7778        }
7779      
7780            return  ($self->{ct}); # ENTITY
7781            redo A;
7782          } else {
7783            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
7784            ## Stay in the state.
7785            
7786        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7787          $self->{line_prev} = $self->{line};
7788          $self->{column_prev} = $self->{column};
7789          $self->{column}++;
7790          $self->{nc}
7791              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7792        } else {
7793          $self->{set_nc}->($self);
7794        }
7795      
7796            redo A;
7797          }
7798        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
7799          if ($self->{nc} == 0x0022) { # "
7800            $self->{state} = AFTER_MD_DEF_STATE;
7801            
7802        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7803          $self->{line_prev} = $self->{line};
7804          $self->{column_prev} = $self->{column};
7805          $self->{column}++;
7806          $self->{nc}
7807              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7808        } else {
7809          $self->{set_nc}->($self);
7810        }
7811      
7812            redo A;
7813          } elsif ($self->{nc} == 0x0026) { # &
7814            $self->{prev_state} = $self->{state};
7815            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7816            $self->{entity_add} = 0x0022; # "
7817            
7818        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7819          $self->{line_prev} = $self->{line};
7820          $self->{column_prev} = $self->{column};
7821          $self->{column}++;
7822          $self->{nc}
7823              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7824        } else {
7825          $self->{set_nc}->($self);
7826        }
7827      
7828            redo A;
7829    ## TODO: %
7830          } elsif ($self->{nc} == -1) {
7831            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7832            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7833            ## Reconsume.
7834            return  ($self->{ct}); # ENTITY
7835            redo A;
7836          } else {
7837            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7838            
7839        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7840          $self->{line_prev} = $self->{line};
7841          $self->{column_prev} = $self->{column};
7842          $self->{column}++;
7843          $self->{nc}
7844              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7845        } else {
7846          $self->{set_nc}->($self);
7847        }
7848      
7849            redo A;
7850          }
7851        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
7852          if ($self->{nc} == 0x0027) { # '
7853            $self->{state} = AFTER_MD_DEF_STATE;
7854            
7855        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7856          $self->{line_prev} = $self->{line};
7857          $self->{column_prev} = $self->{column};
7858          $self->{column}++;
7859          $self->{nc}
7860              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7861        } else {
7862          $self->{set_nc}->($self);
7863        }
7864      
7865            redo A;
7866          } elsif ($self->{nc} == 0x0026) { # &
7867            $self->{prev_state} = $self->{state};
7868            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7869            $self->{entity_add} = 0x0027; # '
7870            
7871        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7872          $self->{line_prev} = $self->{line};
7873          $self->{column_prev} = $self->{column};
7874          $self->{column}++;
7875          $self->{nc}
7876              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7877        } else {
7878          $self->{set_nc}->($self);
7879        }
7880      
7881            redo A;
7882    ## TODO: %
7883          } elsif ($self->{nc} == -1) {
7884            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7885            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7886            ## Reconsume.
7887            return  ($self->{ct}); # ENTITY
7888            redo A;
7889          } else {
7890            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7891            
7892        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7893          $self->{line_prev} = $self->{line};
7894          $self->{column_prev} = $self->{column};
7895          $self->{column}++;
7896          $self->{nc}
7897              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7898        } else {
7899          $self->{set_nc}->($self);
7900        }
7901      
7902            redo A;
7903          }
7904        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
7905          if ($is_space->{$self->{nc}} or
7906              {
7907                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
7908                $self->{entity_add} => 1,
7909              }->{$self->{nc}}) {
7910            $self->{parse_error}->(level => $self->{level}->{must}, type => 'bare ero',
7911                            line => $self->{line_prev},
7912                            column => $self->{column_prev}
7913                                + ($self->{nc} == -1 ? 1 : 0));
7914            ## Don't consume
7915            ## Return nothing.
7916            #
7917          } elsif ($self->{nc} == 0x0023) { # #
7918            $self->{ca} = $self->{ct};
7919            $self->{state} = ENTITY_HASH_STATE;
7920            $self->{kwd} = '#';
7921            
7922        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7923          $self->{line_prev} = $self->{line};
7924          $self->{column_prev} = $self->{column};
7925          $self->{column}++;
7926          $self->{nc}
7927              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7928        } else {
7929          $self->{set_nc}->($self);
7930        }
7931      
7932            redo A;
7933          } else {
7934            #
7935          }
7936    
7937          $self->{ct}->{value} .= '&';
7938          $self->{state} = $self->{prev_state};
7939          ## Reconsume.
7940          redo A;
7941        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
7942          if ($is_space->{$self->{nc}}) {
7943            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
7944            
7945        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7946          $self->{line_prev} = $self->{line};
7947          $self->{column_prev} = $self->{column};
7948          $self->{column}++;
7949          $self->{nc}
7950              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7951        } else {
7952          $self->{set_nc}->($self);
7953        }
7954      
7955            redo A;
7956          } elsif ($self->{nc} == 0x0028) { # (
7957            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
7958            $self->{ct}->{content} = ['('];
7959            $self->{group_depth} = 1;
7960            
7961        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7962          $self->{line_prev} = $self->{line};
7963          $self->{column_prev} = $self->{column};
7964          $self->{column}++;
7965          $self->{nc}
7966              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7967        } else {
7968          $self->{set_nc}->($self);
7969        }
7970      
7971            redo A;
7972          } elsif ($self->{nc} == 0x003E) { # >
7973            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md def'); ## TODO: type
7974            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7975            
7976        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7977          $self->{line_prev} = $self->{line};
7978          $self->{column_prev} = $self->{column};
7979          $self->{column}++;
7980          $self->{nc}
7981              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7982        } else {
7983          $self->{set_nc}->($self);
7984        }
7985      
7986            return  ($self->{ct}); # ELEMENT
7987            redo A;
7988          } elsif ($self->{nc} == -1) {
7989            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
7990            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7991            
7992        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7993          $self->{line_prev} = $self->{line};
7994          $self->{column_prev} = $self->{column};
7995          $self->{column}++;
7996          $self->{nc}
7997              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7998        } else {
7999          $self->{set_nc}->($self);
8000        }
8001      
8002            return  ($self->{ct}); # ELEMENT
8003            redo A;
8004          } else {
8005            $self->{ct}->{content} = [chr $self->{nc}];
8006            $self->{state} = CONTENT_KEYWORD_STATE;
8007            
8008        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8009          $self->{line_prev} = $self->{line};
8010          $self->{column_prev} = $self->{column};
8011          $self->{column}++;
8012          $self->{nc}
8013              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8014        } else {
8015          $self->{set_nc}->($self);
8016        }
8017      
8018            redo A;
8019          }
8020        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
8021          if ($is_space->{$self->{nc}}) {
8022            $self->{state} = AFTER_MD_DEF_STATE;
8023            
8024        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8025          $self->{line_prev} = $self->{line};
8026          $self->{column_prev} = $self->{column};
8027          $self->{column}++;
8028          $self->{nc}
8029              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8030        } else {
8031          $self->{set_nc}->($self);
8032        }
8033      
8034            redo A;
8035          } elsif ($self->{nc} == 0x003E) { # >
8036            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8037            
8038        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8039          $self->{line_prev} = $self->{line};
8040          $self->{column_prev} = $self->{column};
8041          $self->{column}++;
8042          $self->{nc}
8043              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8044        } else {
8045          $self->{set_nc}->($self);
8046        }
8047      
8048            return  ($self->{ct}); # ELEMENT
8049            redo A;
8050          } elsif ($self->{nc} == -1) {
8051            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8052            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8053            
8054        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8055          $self->{line_prev} = $self->{line};
8056          $self->{column_prev} = $self->{column};
8057          $self->{column}++;
8058          $self->{nc}
8059              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8060        } else {
8061          $self->{set_nc}->($self);
8062        }
8063      
8064            return  ($self->{ct}); # ELEMENT
8065            redo A;
8066          } else {
8067            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
8068            ## Stay in the state.
8069            
8070        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8071          $self->{line_prev} = $self->{line};
8072          $self->{column_prev} = $self->{column};
8073          $self->{column}++;
8074          $self->{nc}
8075              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8076        } else {
8077          $self->{set_nc}->($self);
8078        }
8079      
8080            redo A;
8081          }
8082        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
8083          if ($is_space->{$self->{nc}}) {
8084            ## Stay in the state.
8085            
8086        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8087          $self->{line_prev} = $self->{line};
8088          $self->{column_prev} = $self->{column};
8089          $self->{column}++;
8090          $self->{nc}
8091              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8092        } else {
8093          $self->{set_nc}->($self);
8094        }
8095      
8096            redo A;
8097          } elsif ($self->{nc} == 0x0028) { # (
8098            $self->{group_depth}++;
8099            push @{$self->{ct}->{content}}, chr $self->{nc};
8100            ## Stay in the state.
8101            
8102        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8103          $self->{line_prev} = $self->{line};
8104          $self->{column_prev} = $self->{column};
8105          $self->{column}++;
8106          $self->{nc}
8107              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8108        } else {
8109          $self->{set_nc}->($self);
8110        }
8111      
8112            redo A;
8113          } elsif ($self->{nc} == 0x007C or # |
8114                   $self->{nc} == 0x002C) { # ,
8115            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8116            ## Stay in the state.
8117            
8118        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8119          $self->{line_prev} = $self->{line};
8120          $self->{column_prev} = $self->{column};
8121          $self->{column}++;
8122          $self->{nc}
8123              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8124        } else {
8125          $self->{set_nc}->($self);
8126        }
8127      
8128            redo A;
8129          } elsif ($self->{nc} == 0x0029) { # )
8130            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8131            push @{$self->{ct}->{content}}, chr $self->{nc};
8132            $self->{group_depth}--;
8133            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8134            
8135        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8136          $self->{line_prev} = $self->{line};
8137          $self->{column_prev} = $self->{column};
8138          $self->{column}++;
8139          $self->{nc}
8140              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8141        } else {
8142          $self->{set_nc}->($self);
8143        }
8144      
8145            redo A;
8146          } elsif ($self->{nc} == 0x003E) { # >
8147            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8148            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8149            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8150            
8151        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8152          $self->{line_prev} = $self->{line};
8153          $self->{column_prev} = $self->{column};
8154          $self->{column}++;
8155          $self->{nc}
8156              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8157        } else {
8158          $self->{set_nc}->($self);
8159        }
8160      
8161            return  ($self->{ct}); # ELEMENT
8162            redo A;
8163          } elsif ($self->{nc} == -1) {
8164            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8165            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8166            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8167            
8168        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8169          $self->{line_prev} = $self->{line};
8170          $self->{column_prev} = $self->{column};
8171          $self->{column}++;
8172          $self->{nc}
8173              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8174        } else {
8175          $self->{set_nc}->($self);
8176        }
8177      
8178            return  ($self->{ct}); # ELEMENT
8179            redo A;
8180          } else {
8181            push @{$self->{ct}->{content}}, chr $self->{nc};
8182            $self->{state} = CM_ELEMENT_NAME_STATE;
8183            
8184        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8185          $self->{line_prev} = $self->{line};
8186          $self->{column_prev} = $self->{column};
8187          $self->{column}++;
8188          $self->{nc}
8189              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8190        } else {
8191          $self->{set_nc}->($self);
8192        }
8193      
8194            redo A;
8195          }
8196        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
8197          if ($is_space->{$self->{nc}}) {
8198            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8199            
8200        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8201          $self->{line_prev} = $self->{line};
8202          $self->{column_prev} = $self->{column};
8203          $self->{column}++;
8204          $self->{nc}
8205              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8206        } else {
8207          $self->{set_nc}->($self);
8208        }
8209      
8210            redo A;
8211          } elsif ($self->{nc} == 0x002A or # *
8212                   $self->{nc} == 0x002B or # +
8213                   $self->{nc} == 0x003F) { # ?
8214            push @{$self->{ct}->{content}}, chr $self->{nc};
8215            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8216            
8217        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8218          $self->{line_prev} = $self->{line};
8219          $self->{column_prev} = $self->{column};
8220          $self->{column}++;
8221          $self->{nc}
8222              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8223        } else {
8224          $self->{set_nc}->($self);
8225        }
8226      
8227            redo A;
8228          } elsif ($self->{nc} == 0x007C or # |
8229                   $self->{nc} == 0x002C) { # ,
8230            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8231            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8232            
8233        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8234          $self->{line_prev} = $self->{line};
8235          $self->{column_prev} = $self->{column};
8236          $self->{column}++;
8237          $self->{nc}
8238              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8239        } else {
8240          $self->{set_nc}->($self);
8241        }
8242      
8243            redo A;
8244          } elsif ($self->{nc} == 0x0029) { # )
8245            $self->{group_depth}--;
8246            push @{$self->{ct}->{content}}, chr $self->{nc};
8247            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8248            
8249        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8250          $self->{line_prev} = $self->{line};
8251          $self->{column_prev} = $self->{column};
8252          $self->{column}++;
8253          $self->{nc}
8254              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8255        } else {
8256          $self->{set_nc}->($self);
8257        }
8258      
8259            redo A;
8260          } elsif ($self->{nc} == 0x003E) { # >
8261            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8262            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8263            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8264            
8265        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8266          $self->{line_prev} = $self->{line};
8267          $self->{column_prev} = $self->{column};
8268          $self->{column}++;
8269          $self->{nc}
8270              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8271        } else {
8272          $self->{set_nc}->($self);
8273        }
8274      
8275            return  ($self->{ct}); # ELEMENT
8276            redo A;
8277          } elsif ($self->{nc} == -1) {
8278            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8279            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8280            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8281            
8282        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8283          $self->{line_prev} = $self->{line};
8284          $self->{column_prev} = $self->{column};
8285          $self->{column}++;
8286          $self->{nc}
8287              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8288        } else {
8289          $self->{set_nc}->($self);
8290        }
8291      
8292            return  ($self->{ct}); # ELEMENT
8293            redo A;
8294          } else {
8295            $self->{ct}->{content}->[-1] .= chr $self->{nc};
8296            ## Stay in the state.
8297            
8298        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8299          $self->{line_prev} = $self->{line};
8300          $self->{column_prev} = $self->{column};
8301          $self->{column}++;
8302          $self->{nc}
8303              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8304        } else {
8305          $self->{set_nc}->($self);
8306        }
8307      
8308            redo A;
8309          }
8310        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
8311          if ($is_space->{$self->{nc}}) {
8312            ## Stay in the state.
8313            
8314        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8315          $self->{line_prev} = $self->{line};
8316          $self->{column_prev} = $self->{column};
8317          $self->{column}++;
8318          $self->{nc}
8319              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8320        } else {
8321          $self->{set_nc}->($self);
8322        }
8323      
8324            redo A;
8325          } elsif ($self->{nc} == 0x007C or # |
8326                   $self->{nc} == 0x002C) { # ,
8327            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8328            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8329            
8330        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8331          $self->{line_prev} = $self->{line};
8332          $self->{column_prev} = $self->{column};
8333          $self->{column}++;
8334          $self->{nc}
8335              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8336        } else {
8337          $self->{set_nc}->($self);
8338        }
8339      
8340            redo A;
8341          } elsif ($self->{nc} == 0x0029) { # )
8342            $self->{group_depth}--;
8343            push @{$self->{ct}->{content}}, chr $self->{nc};
8344            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8345            
8346        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8347          $self->{line_prev} = $self->{line};
8348          $self->{column_prev} = $self->{column};
8349          $self->{column}++;
8350          $self->{nc}
8351              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8352        } else {
8353          $self->{set_nc}->($self);
8354        }
8355      
8356            redo A;
8357          } elsif ($self->{nc} == 0x003E) { # >
8358            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8359            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8360            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8361            
8362        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8363          $self->{line_prev} = $self->{line};
8364          $self->{column_prev} = $self->{column};
8365          $self->{column}++;
8366          $self->{nc}
8367              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8368        } else {
8369          $self->{set_nc}->($self);
8370        }
8371      
8372            return  ($self->{ct}); # ELEMENT
8373            redo A;
8374          } elsif ($self->{nc} == -1) {
8375            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8376            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8377            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8378            
8379        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8380          $self->{line_prev} = $self->{line};
8381          $self->{column_prev} = $self->{column};
8382          $self->{column}++;
8383          $self->{nc}
8384              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8385        } else {
8386          $self->{set_nc}->($self);
8387        }
8388      
8389            return  ($self->{ct}); # ELEMENT
8390            redo A;
8391          } else {
8392            $self->{parse_error}->(level => $self->{level}->{must}, type => 'after element name'); ## TODO: type
8393            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8394            $self->{state} = BOGUS_MD_STATE;
8395            
8396        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8397          $self->{line_prev} = $self->{line};
8398          $self->{column_prev} = $self->{column};
8399          $self->{column}++;
8400          $self->{nc}
8401              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8402        } else {
8403          $self->{set_nc}->($self);
8404        }
8405      
8406            redo A;
8407          }
8408        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
8409          if ($is_space->{$self->{nc}}) {
8410            if ($self->{group_depth}) {
8411              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8412            } else {
8413              $self->{state} = AFTER_MD_DEF_STATE;
8414            }
8415            
8416        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8417          $self->{line_prev} = $self->{line};
8418          $self->{column_prev} = $self->{column};
8419          $self->{column}++;
8420          $self->{nc}
8421              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8422        } else {
8423          $self->{set_nc}->($self);
8424        }
8425      
8426            redo A;
8427          } elsif ($self->{nc} == 0x002A or # *
8428                   $self->{nc} == 0x002B or # +
8429                   $self->{nc} == 0x003F) { # ?
8430            push @{$self->{ct}->{content}}, chr $self->{nc};
8431            if ($self->{group_depth}) {
8432              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8433            } else {
8434              $self->{state} = AFTER_MD_DEF_STATE;
8435            }
8436            
8437        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8438          $self->{line_prev} = $self->{line};
8439          $self->{column_prev} = $self->{column};
8440          $self->{column}++;
8441          $self->{nc}
8442              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8443        } else {
8444          $self->{set_nc}->($self);
8445        }
8446      
8447            redo A;
8448          } elsif ($self->{nc} == 0x0029) { # )
8449            if ($self->{group_depth}) {
8450              $self->{group_depth}--;
8451              push @{$self->{ct}->{content}}, chr $self->{nc};
8452              ## Stay in the state.
8453              
8454        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8455          $self->{line_prev} = $self->{line};
8456          $self->{column_prev} = $self->{column};
8457          $self->{column}++;
8458          $self->{nc}
8459              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8460        } else {
8461          $self->{set_nc}->($self);
8462        }
8463      
8464              redo A;
8465            } else {
8466              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8467              $self->{state} = BOGUS_MD_STATE;
8468              ## Reconsume.
8469              redo A;
8470            }
8471          } elsif ($self->{nc} == 0x003E) { # >
8472            if ($self->{group_depth}) {
8473              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8474              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8475            }
8476            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8477            
8478        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8479          $self->{line_prev} = $self->{line};
8480          $self->{column_prev} = $self->{column};
8481          $self->{column}++;
8482          $self->{nc}
8483              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8484        } else {
8485          $self->{set_nc}->($self);
8486        }
8487      
8488            return  ($self->{ct}); # ELEMENT
8489            redo A;
8490          } elsif ($self->{nc} == -1) {
8491            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8492            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
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}); # ELEMENT
8506            redo A;
8507          } else {
8508            if ($self->{group_depth}) {
8509              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8510            } else {
8511              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8512              $self->{state} = BOGUS_MD_STATE;
8513            }
8514            ## Reconsume.
8515            redo A;
8516          }
8517        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
8518          if ($is_space->{$self->{nc}}) {
8519            ## Stay in the state.
8520            
8521        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8522          $self->{line_prev} = $self->{line};
8523          $self->{column_prev} = $self->{column};
8524          $self->{column}++;
8525          $self->{nc}
8526              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8527        } else {
8528          $self->{set_nc}->($self);
8529        }
8530      
8531            redo A;
8532          } elsif ($self->{nc} == 0x003E) { # >
8533            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8534            
8535        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8536          $self->{line_prev} = $self->{line};
8537          $self->{column_prev} = $self->{column};
8538          $self->{column}++;
8539          $self->{nc}
8540              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8541        } else {
8542          $self->{set_nc}->($self);
8543        }
8544      
8545            return  ($self->{ct}); # ENTITY/ELEMENT
8546            redo A;
8547          } elsif ($self->{nc} == -1) {
8548            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8549            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8550            
8551        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8552          $self->{line_prev} = $self->{line};
8553          $self->{column_prev} = $self->{column};
8554          $self->{column}++;
8555          $self->{nc}
8556              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8557        } else {
8558          $self->{set_nc}->($self);
8559        }
8560      
8561            return  ($self->{ct}); # ENTITY/ELEMENT
8562            redo A;
8563          } else {
8564            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8565            $self->{state} = BOGUS_MD_STATE;
8566            ## Reconsume.
8567            redo A;
8568          }
8569      } elsif ($self->{state} == BOGUS_MD_STATE) {      } elsif ($self->{state} == BOGUS_MD_STATE) {
8570        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
8571          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24