/[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.18 by wakaba, Sun Oct 19 06:14:57 2008 UTC revision 1.25 by wakaba, Sun Oct 19 15:17:01 2008 UTC
# Line 182  sub NDATA_STATE () { 86 } Line 182  sub NDATA_STATE () { 86 }
182  sub AFTER_NDATA_STATE () { 87 }  sub AFTER_NDATA_STATE () { 87 }
183  sub BEFORE_NOTATION_NAME_STATE () { 88 }  sub BEFORE_NOTATION_NAME_STATE () { 88 }
184  sub NOTATION_NAME_STATE () { 89 }  sub NOTATION_NAME_STATE () { 89 }
185  sub AFTER_NOTATION_NAME_STATE () { 90 }  sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
186  sub BOGUS_MD_STATE () { 91 }  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 1806  sub _get_next_token ($) { Line 1816  sub _get_next_token ($) {
1816      }      }
1817        
1818          redo A;          redo A;
1819          } elsif ($self->{is_xml} and
1820                   $is_space->{$self->{nc}}) {
1821            
1822            $self->{ca}->{value} .= ' ';
1823            ## Stay in the state.
1824            
1825        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
1826          $self->{line_prev} = $self->{line};
1827          $self->{column_prev} = $self->{column};
1828          $self->{column}++;
1829          $self->{nc}
1830              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
1831        } else {
1832          $self->{set_nc}->($self);
1833        }
1834      
1835            redo A;
1836        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1837          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed attribute value');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed attribute value');
1838          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1853  sub _get_next_token ($) { Line 1880  sub _get_next_token ($) {
1880          }          }
1881          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1882          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1883                                q["&<],                                qq["&<\x09\x0C\x20],
1884                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1885    
1886          ## Stay in the state          ## Stay in the state
# Line 1920  sub _get_next_token ($) { Line 1947  sub _get_next_token ($) {
1947      }      }
1948        
1949          redo A;          redo A;
1950          } elsif ($self->{is_xml} and
1951                   $is_space->{$self->{nc}}) {
1952            
1953            $self->{ca}->{value} .= ' ';
1954            ## Stay in the state.
1955            
1956        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
1957          $self->{line_prev} = $self->{line};
1958          $self->{column_prev} = $self->{column};
1959          $self->{column}++;
1960          $self->{nc}
1961              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
1962        } else {
1963          $self->{set_nc}->($self);
1964        }
1965      
1966            redo A;
1967        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1968          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed attribute value');          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed attribute value');
1969          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1967  sub _get_next_token ($) { Line 2011  sub _get_next_token ($) {
2011          }          }
2012          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
2013          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
2014                                q['&<],                                qq['&<\x09\x0C\x20],
2015                                length $self->{ca}->{value});                                length $self->{ca}->{value});
2016    
2017          ## Stay in the state          ## Stay in the state
# Line 2148  sub _get_next_token ($) { Line 2192  sub _get_next_token ($) {
2192          }          }
2193          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
2194          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
2195                                q["'=& >],                                qq["'=& \x09\x0C>],
2196                                length $self->{ca}->{value});                                length $self->{ca}->{value});
2197    
2198          ## Stay in the state          ## Stay in the state
# Line 3262  sub _get_next_token ($) { Line 3306  sub _get_next_token ($) {
3306      }      }
3307        
3308          redo A;          redo A;
3309  ## TODO: " and ' for ENTITY        } elsif ($self->{nc} == 0x0022 and # "
3310                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
3311                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
3312            
3313            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
3314            $self->{ct}->{value} = ''; # ENTITY
3315            
3316        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3317          $self->{line_prev} = $self->{line};
3318          $self->{column_prev} = $self->{column};
3319          $self->{column}++;
3320          $self->{nc}
3321              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
3322        } else {
3323          $self->{set_nc}->($self);
3324        }
3325      
3326            redo A;
3327          } elsif ($self->{nc} == 0x0027 and # '
3328                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
3329                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
3330            
3331            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
3332            $self->{ct}->{value} = ''; # ENTITY
3333            
3334        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
3335          $self->{line_prev} = $self->{line};
3336          $self->{column_prev} = $self->{column};
3337          $self->{column}++;
3338          $self->{nc}
3339              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
3340        } else {
3341          $self->{set_nc}->($self);
3342        }
3343      
3344            redo A;
3345        } elsif ($self->{is_xml} and        } elsif ($self->{is_xml} and
3346                 $self->{ct}->{type} == DOCTYPE_TOKEN and                 $self->{ct}->{type} == DOCTYPE_TOKEN and
3347                 $self->{nc} == 0x005B) { # [                 $self->{nc} == 0x005B) { # [
# Line 4583  sub _get_next_token ($) { Line 4662  sub _get_next_token ($) {
4662              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4663              $self->{entity_add} => 1,              $self->{entity_add} => 1,
4664            }->{$self->{nc}}) {            }->{$self->{nc}}) {
4665                    if ($self->{is_xml}) {
4666              
4667              $self->{parse_error}->(level => $self->{level}->{must}, type => 'bare ero',
4668                              line => $self->{line_prev},
4669                              column => $self->{column_prev}
4670                                  + ($self->{nc} == -1 ? 1 : 0));
4671            } else {
4672              
4673              ## No error
4674            }
4675          ## Don't consume          ## Don't consume
         ## No error  
4676          ## Return nothing.          ## Return nothing.
4677          #          #
4678        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 4604  sub _get_next_token ($) { Line 4691  sub _get_next_token ($) {
4691      }      }
4692        
4693          redo A;          redo A;
4694        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
4695                   (0x0041 <= $self->{nc} and
4696                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
4697                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
4698                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 4658  sub _get_next_token ($) { Line 4746  sub _get_next_token ($) {
4746          redo A;          redo A;
4747        }        }
4748      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
4749        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
4750            $self->{nc} == 0x0058) { # X          
4751            $self->{state} = HEXREF_X_STATE;
4752            $self->{kwd} .= chr $self->{nc};
4753            
4754        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
4755          $self->{line_prev} = $self->{line};
4756          $self->{column_prev} = $self->{column};
4757          $self->{column}++;
4758          $self->{nc}
4759              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
4760        } else {
4761          $self->{set_nc}->($self);
4762        }
4763      
4764            redo A;
4765          } elsif ($self->{nc} == 0x0058) { # X
4766                    
4767            if ($self->{is_xml}) {
4768              $self->{parse_error}->(level => $self->{level}->{must}, type => 'uppercase hcro'); ## TODO: type
4769            }
4770          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
4771          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
4772                    
# Line 4765  sub _get_next_token ($) { Line 4871  sub _get_next_token ($) {
4871        my $code = $self->{kwd};        my $code = $self->{kwd};
4872        my $l = $self->{line_prev};        my $l = $self->{line_prev};
4873        my $c = $self->{column_prev};        my $c = $self->{column_prev};
4874        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
4875              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
4876              ($self->{is_xml} and $code == 0x0000)) {
4877                    
4878          $self->{parse_error}->(level => $self->{level}->{must}, type => 'invalid character reference',          $self->{parse_error}->(level => $self->{level}->{must}, type => 'invalid character reference',
4879                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 4918  sub _get_next_token ($) { Line 5026  sub _get_next_token ($) {
5026        my $code = $self->{kwd};        my $code = $self->{kwd};
5027        my $l = $self->{line_prev};        my $l = $self->{line_prev};
5028        my $c = $self->{column_prev};        my $c = $self->{column_prev};
5029        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
5030              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
5031              ($self->{is_xml} and $code == 0x0000)) {
5032                    
5033          $self->{parse_error}->(level => $self->{level}->{must}, type => 'invalid character reference',          $self->{parse_error}->(level => $self->{level}->{must}, type => 'invalid character reference',
5034                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 4952  sub _get_next_token ($) { Line 5062  sub _get_next_token ($) {
5062          redo A;          redo A;
5063        }        }
5064      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
5065        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
5066            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
5067            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
5068              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
5069             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
5070              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
5071             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
5072              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
5073             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
5074                    {
5075                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
5076                      $self->{entity_add} => 1,
5077                    }->{$self->{nc}}))) {
5078          our $EntityChar;          our $EntityChar;
5079          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
5080          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
5081                $self->{ge}->{$self->{kwd}}) {
5082            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
5083                            if (defined $self->{ge}->{$self->{kwd}}) {
5084              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
5085                    
5086                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
5087                  } else {
5088                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
5089                      
5090                      $self->{parse_error}->(level => $self->{level}->{must}, type => 'unparsed entity', ## TODO: type
5091                                      value => $self->{kwd});
5092                    } else {
5093                      
5094                    }
5095                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
5096                  }
5097                } else {
5098                  if ($self->{is_xml}) {
5099                    
5100                    $self->{parse_error}->(level => $self->{level}->{must}, type => 'entity not declared', ## TODO: type
5101                                    value => $self->{kwd},
5102                                    level => {
5103                                              'amp;' => $self->{level}->{warn},
5104                                              'quot;' => $self->{level}->{warn},
5105                                              'lt;' => $self->{level}->{warn},
5106                                              'gt;' => $self->{level}->{warn},
5107                                              'apos;' => $self->{level}->{warn},
5108                                             }->{$self->{kwd}} ||
5109                                             $self->{level}->{must});
5110                  } else {
5111                    
5112                  }
5113                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
5114                }
5115              $self->{entity__match} = 1;              $self->{entity__match} = 1;
5116                            
5117      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 5362  sub _get_next_token ($) { Line 5507  sub _get_next_token ($) {
5507          ## XML5: Not defined yet.          ## XML5: Not defined yet.
5508    
5509          ## TODO:          ## TODO:
5510    
5511            if (not $self->{stop_processing} and
5512                not $self->{document}->xml_standalone) {
5513              $self->{parse_error}->(level => $self->{level}->{must}, type => 'stop processing', ## TODO: type
5514                              level => $self->{level}->{info});
5515              $self->{stop_processing} = 1;
5516            }
5517    
5518                    
5519      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
5520        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 5796  sub _get_next_token ($) { Line 5949  sub _get_next_token ($) {
5949          }          }
5950          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
5951                         line => $self->{line_prev},                         line => $self->{line_prev},
5952                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
5953          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
5954                    
5955      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 5864  sub _get_next_token ($) { Line 6017  sub _get_next_token ($) {
6017          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
6018                         attrdefs => [],                         attrdefs => [],
6019                         line => $self->{line_prev},                         line => $self->{line_prev},
6020                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
6021          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
6022                    
6023      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 5933  sub _get_next_token ($) { Line 6086  sub _get_next_token ($) {
6086          }          }
6087          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
6088                         line => $self->{line_prev},                         line => $self->{line_prev},
6089                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
6090          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
6091                    
6092      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 6145  sub _get_next_token ($) { Line 6298  sub _get_next_token ($) {
6298          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
6299            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
6300          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
6301            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
6302          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
6303            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
6304          }          }
# Line 7629  sub _get_next_token ($) { Line 7781  sub _get_next_token ($) {
7781        }        }
7782      } elsif ($self->{state} == NOTATION_NAME_STATE) {      } elsif ($self->{state} == NOTATION_NAME_STATE) {
7783        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
7784          $self->{state} = AFTER_NOTATION_NAME_STATE;          $self->{state} = AFTER_MD_DEF_STATE;
7785                    
7786      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7787        $self->{line_prev} = $self->{line};        $self->{line_prev} = $self->{line};
# Line 7689  sub _get_next_token ($) { Line 7841  sub _get_next_token ($) {
7841        
7842          redo A;          redo A;
7843        }        }
7844      } elsif ($self->{state} == AFTER_NOTATION_NAME_STATE) {      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
7845          if ($self->{nc} == 0x0022) { # "
7846            $self->{state} = AFTER_MD_DEF_STATE;
7847            
7848        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7849          $self->{line_prev} = $self->{line};
7850          $self->{column_prev} = $self->{column};
7851          $self->{column}++;
7852          $self->{nc}
7853              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7854        } else {
7855          $self->{set_nc}->($self);
7856        }
7857      
7858            redo A;
7859          } elsif ($self->{nc} == 0x0026) { # &
7860            $self->{prev_state} = $self->{state};
7861            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7862            $self->{entity_add} = 0x0022; # "
7863            
7864        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7865          $self->{line_prev} = $self->{line};
7866          $self->{column_prev} = $self->{column};
7867          $self->{column}++;
7868          $self->{nc}
7869              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7870        } else {
7871          $self->{set_nc}->($self);
7872        }
7873      
7874            redo A;
7875    ## TODO: %
7876          } elsif ($self->{nc} == -1) {
7877            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7878            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7879            ## Reconsume.
7880            return  ($self->{ct}); # ENTITY
7881            redo A;
7882          } else {
7883            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7884            
7885        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7886          $self->{line_prev} = $self->{line};
7887          $self->{column_prev} = $self->{column};
7888          $self->{column}++;
7889          $self->{nc}
7890              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7891        } else {
7892          $self->{set_nc}->($self);
7893        }
7894      
7895            redo A;
7896          }
7897        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
7898          if ($self->{nc} == 0x0027) { # '
7899            $self->{state} = AFTER_MD_DEF_STATE;
7900            
7901        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7902          $self->{line_prev} = $self->{line};
7903          $self->{column_prev} = $self->{column};
7904          $self->{column}++;
7905          $self->{nc}
7906              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7907        } else {
7908          $self->{set_nc}->($self);
7909        }
7910      
7911            redo A;
7912          } elsif ($self->{nc} == 0x0026) { # &
7913            $self->{prev_state} = $self->{state};
7914            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
7915            $self->{entity_add} = 0x0027; # '
7916            
7917        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7918          $self->{line_prev} = $self->{line};
7919          $self->{column_prev} = $self->{column};
7920          $self->{column}++;
7921          $self->{nc}
7922              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7923        } else {
7924          $self->{set_nc}->($self);
7925        }
7926      
7927            redo A;
7928    ## TODO: %
7929          } elsif ($self->{nc} == -1) {
7930            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed entity value'); ## TODO: type
7931            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
7932            ## Reconsume.
7933            return  ($self->{ct}); # ENTITY
7934            redo A;
7935          } else {
7936            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
7937            
7938        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7939          $self->{line_prev} = $self->{line};
7940          $self->{column_prev} = $self->{column};
7941          $self->{column}++;
7942          $self->{nc}
7943              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7944        } else {
7945          $self->{set_nc}->($self);
7946        }
7947      
7948            redo A;
7949          }
7950        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
7951          if ($is_space->{$self->{nc}} or
7952              {
7953                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
7954                $self->{entity_add} => 1,
7955              }->{$self->{nc}}) {
7956            $self->{parse_error}->(level => $self->{level}->{must}, type => 'bare ero',
7957                            line => $self->{line_prev},
7958                            column => $self->{column_prev}
7959                                + ($self->{nc} == -1 ? 1 : 0));
7960            ## Don't consume
7961            ## Return nothing.
7962            #
7963          } elsif ($self->{nc} == 0x0023) { # #
7964            $self->{ca} = $self->{ct};
7965            $self->{state} = ENTITY_HASH_STATE;
7966            $self->{kwd} = '#';
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          } else {
7980            #
7981          }
7982    
7983          $self->{ct}->{value} .= '&';
7984          $self->{state} = $self->{prev_state};
7985          ## Reconsume.
7986          redo A;
7987        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
7988          if ($is_space->{$self->{nc}}) {
7989            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
7990            
7991        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
7992          $self->{line_prev} = $self->{line};
7993          $self->{column_prev} = $self->{column};
7994          $self->{column}++;
7995          $self->{nc}
7996              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
7997        } else {
7998          $self->{set_nc}->($self);
7999        }
8000      
8001            redo A;
8002          } elsif ($self->{nc} == 0x0028) { # (
8003            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8004            $self->{ct}->{content} = ['('];
8005            $self->{group_depth} = 1;
8006            
8007        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8008          $self->{line_prev} = $self->{line};
8009          $self->{column_prev} = $self->{column};
8010          $self->{column}++;
8011          $self->{nc}
8012              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8013        } else {
8014          $self->{set_nc}->($self);
8015        }
8016      
8017            redo A;
8018          } elsif ($self->{nc} == 0x003E) { # >
8019            $self->{parse_error}->(level => $self->{level}->{must}, type => 'no md def'); ## TODO: type
8020            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8021            
8022        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8023          $self->{line_prev} = $self->{line};
8024          $self->{column_prev} = $self->{column};
8025          $self->{column}++;
8026          $self->{nc}
8027              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8028        } else {
8029          $self->{set_nc}->($self);
8030        }
8031      
8032            return  ($self->{ct}); # ELEMENT
8033            redo A;
8034          } elsif ($self->{nc} == -1) {
8035            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
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          } else {
8051            $self->{ct}->{content} = [chr $self->{nc}];
8052            $self->{state} = CONTENT_KEYWORD_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            redo A;
8065          }
8066        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
8067          if ($is_space->{$self->{nc}}) {
8068            $self->{state} = AFTER_MD_DEF_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          } elsif ($self->{nc} == 0x003E) { # >
8082            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8083            
8084        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8085          $self->{line_prev} = $self->{line};
8086          $self->{column_prev} = $self->{column};
8087          $self->{column}++;
8088          $self->{nc}
8089              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8090        } else {
8091          $self->{set_nc}->($self);
8092        }
8093      
8094            return  ($self->{ct}); # ELEMENT
8095            redo A;
8096          } elsif ($self->{nc} == -1) {
8097            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8098            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8099            
8100        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8101          $self->{line_prev} = $self->{line};
8102          $self->{column_prev} = $self->{column};
8103          $self->{column}++;
8104          $self->{nc}
8105              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8106        } else {
8107          $self->{set_nc}->($self);
8108        }
8109      
8110            return  ($self->{ct}); # ELEMENT
8111            redo A;
8112          } else {
8113            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
8114            ## Stay in the state.
8115            
8116        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8117          $self->{line_prev} = $self->{line};
8118          $self->{column_prev} = $self->{column};
8119          $self->{column}++;
8120          $self->{nc}
8121              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8122        } else {
8123          $self->{set_nc}->($self);
8124        }
8125      
8126            redo A;
8127          }
8128        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
8129        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
8130          ## Stay in the state.          ## Stay in the state.
8131                    
# Line 7704  sub _get_next_token ($) { Line 8140  sub _get_next_token ($) {
8140      }      }
8141        
8142          redo A;          redo A;
8143          } elsif ($self->{nc} == 0x0028) { # (
8144            $self->{group_depth}++;
8145            push @{$self->{ct}->{content}}, chr $self->{nc};
8146            ## Stay in the state.
8147            
8148        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8149          $self->{line_prev} = $self->{line};
8150          $self->{column_prev} = $self->{column};
8151          $self->{column}++;
8152          $self->{nc}
8153              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8154        } else {
8155          $self->{set_nc}->($self);
8156        }
8157      
8158            redo A;
8159          } elsif ($self->{nc} == 0x007C or # |
8160                   $self->{nc} == 0x002C) { # ,
8161            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8162            ## Stay in the state.
8163            
8164        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8165          $self->{line_prev} = $self->{line};
8166          $self->{column_prev} = $self->{column};
8167          $self->{column}++;
8168          $self->{nc}
8169              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8170        } else {
8171          $self->{set_nc}->($self);
8172        }
8173      
8174            redo A;
8175          } elsif ($self->{nc} == 0x0029) { # )
8176            $self->{parse_error}->(level => $self->{level}->{must}, type => 'empty element name'); ## TODO: type
8177            push @{$self->{ct}->{content}}, chr $self->{nc};
8178            $self->{group_depth}--;
8179            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8180            
8181        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8182          $self->{line_prev} = $self->{line};
8183          $self->{column_prev} = $self->{column};
8184          $self->{column}++;
8185          $self->{nc}
8186              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8187        } else {
8188          $self->{set_nc}->($self);
8189        }
8190      
8191            redo A;
8192        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
8193            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8194            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8195          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8196                    
8197      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 7717  sub _get_next_token ($) { Line 8204  sub _get_next_token ($) {
8204        $self->{set_nc}->($self);        $self->{set_nc}->($self);
8205      }      }
8206        
8207          return  ($self->{ct}); # ENTITY          return  ($self->{ct}); # ELEMENT
8208          redo A;          redo A;
8209        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
8210          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type          $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8211            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8212          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8213                    
8214      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {      if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
# Line 7733  sub _get_next_token ($) { Line 8221  sub _get_next_token ($) {
8221        $self->{set_nc}->($self);        $self->{set_nc}->($self);
8222      }      }
8223        
8224          return  ($self->{ct}); # ENTITY          return  ($self->{ct}); # ELEMENT
8225          redo A;          redo A;
8226        } else {        } else {
8227          $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after notation name'); ## TODO: type          push @{$self->{ct}->{content}}, chr $self->{nc};
8228            $self->{state} = CM_ELEMENT_NAME_STATE;
8229            
8230        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8231          $self->{line_prev} = $self->{line};
8232          $self->{column_prev} = $self->{column};
8233          $self->{column}++;
8234          $self->{nc}
8235              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8236        } else {
8237          $self->{set_nc}->($self);
8238        }
8239      
8240            redo A;
8241          }
8242        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
8243          if ($is_space->{$self->{nc}}) {
8244            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8245            
8246        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8247          $self->{line_prev} = $self->{line};
8248          $self->{column_prev} = $self->{column};
8249          $self->{column}++;
8250          $self->{nc}
8251              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8252        } else {
8253          $self->{set_nc}->($self);
8254        }
8255      
8256            redo A;
8257          } elsif ($self->{nc} == 0x002A or # *
8258                   $self->{nc} == 0x002B or # +
8259                   $self->{nc} == 0x003F) { # ?
8260            push @{$self->{ct}->{content}}, chr $self->{nc};
8261            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8262            
8263        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8264          $self->{line_prev} = $self->{line};
8265          $self->{column_prev} = $self->{column};
8266          $self->{column}++;
8267          $self->{nc}
8268              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8269        } else {
8270          $self->{set_nc}->($self);
8271        }
8272      
8273            redo A;
8274          } elsif ($self->{nc} == 0x007C or # |
8275                   $self->{nc} == 0x002C) { # ,
8276            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8277            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8278            
8279        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8280          $self->{line_prev} = $self->{line};
8281          $self->{column_prev} = $self->{column};
8282          $self->{column}++;
8283          $self->{nc}
8284              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8285        } else {
8286          $self->{set_nc}->($self);
8287        }
8288      
8289            redo A;
8290          } elsif ($self->{nc} == 0x0029) { # )
8291            $self->{group_depth}--;
8292            push @{$self->{ct}->{content}}, chr $self->{nc};
8293            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8294            
8295        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8296          $self->{line_prev} = $self->{line};
8297          $self->{column_prev} = $self->{column};
8298          $self->{column}++;
8299          $self->{nc}
8300              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8301        } else {
8302          $self->{set_nc}->($self);
8303        }
8304      
8305            redo A;
8306          } elsif ($self->{nc} == 0x003E) { # >
8307            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8308            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8309            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8310            
8311        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8312          $self->{line_prev} = $self->{line};
8313          $self->{column_prev} = $self->{column};
8314          $self->{column}++;
8315          $self->{nc}
8316              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8317        } else {
8318          $self->{set_nc}->($self);
8319        }
8320      
8321            return  ($self->{ct}); # ELEMENT
8322            redo A;
8323          } elsif ($self->{nc} == -1) {
8324            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8325            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8326            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8327            
8328        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8329          $self->{line_prev} = $self->{line};
8330          $self->{column_prev} = $self->{column};
8331          $self->{column}++;
8332          $self->{nc}
8333              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8334        } else {
8335          $self->{set_nc}->($self);
8336        }
8337      
8338            return  ($self->{ct}); # ELEMENT
8339            redo A;
8340          } else {
8341            $self->{ct}->{content}->[-1] .= chr $self->{nc};
8342            ## Stay in the state.
8343            
8344        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8345          $self->{line_prev} = $self->{line};
8346          $self->{column_prev} = $self->{column};
8347          $self->{column}++;
8348          $self->{nc}
8349              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8350        } else {
8351          $self->{set_nc}->($self);
8352        }
8353      
8354            redo A;
8355          }
8356        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
8357          if ($is_space->{$self->{nc}}) {
8358            ## Stay in the state.
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} == 0x007C or # |
8372                   $self->{nc} == 0x002C) { # ,
8373            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
8374            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
8375            
8376        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8377          $self->{line_prev} = $self->{line};
8378          $self->{column_prev} = $self->{column};
8379          $self->{column}++;
8380          $self->{nc}
8381              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8382        } else {
8383          $self->{set_nc}->($self);
8384        }
8385      
8386            redo A;
8387          } elsif ($self->{nc} == 0x0029) { # )
8388            $self->{group_depth}--;
8389            push @{$self->{ct}->{content}}, chr $self->{nc};
8390            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
8391            
8392        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8393          $self->{line_prev} = $self->{line};
8394          $self->{column_prev} = $self->{column};
8395          $self->{column}++;
8396          $self->{nc}
8397              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8398        } else {
8399          $self->{set_nc}->($self);
8400        }
8401      
8402            redo A;
8403          } elsif ($self->{nc} == 0x003E) { # >
8404            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8405            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8406            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8407            
8408        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8409          $self->{line_prev} = $self->{line};
8410          $self->{column_prev} = $self->{column};
8411          $self->{column}++;
8412          $self->{nc}
8413              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8414        } else {
8415          $self->{set_nc}->($self);
8416        }
8417      
8418            return  ($self->{ct}); # ELEMENT
8419            redo A;
8420          } elsif ($self->{nc} == -1) {
8421            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8422            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8423            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8424            
8425        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8426          $self->{line_prev} = $self->{line};
8427          $self->{column_prev} = $self->{column};
8428          $self->{column}++;
8429          $self->{nc}
8430              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8431        } else {
8432          $self->{set_nc}->($self);
8433        }
8434      
8435            return  ($self->{ct}); # ELEMENT
8436            redo A;
8437          } else {
8438            $self->{parse_error}->(level => $self->{level}->{must}, type => 'after element name'); ## TODO: type
8439            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8440            $self->{state} = BOGUS_MD_STATE;
8441            
8442        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8443          $self->{line_prev} = $self->{line};
8444          $self->{column_prev} = $self->{column};
8445          $self->{column}++;
8446          $self->{nc}
8447              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8448        } else {
8449          $self->{set_nc}->($self);
8450        }
8451      
8452            redo A;
8453          }
8454        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
8455          if ($is_space->{$self->{nc}}) {
8456            if ($self->{group_depth}) {
8457              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8458            } else {
8459              $self->{state} = AFTER_MD_DEF_STATE;
8460            }
8461            
8462        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8463          $self->{line_prev} = $self->{line};
8464          $self->{column_prev} = $self->{column};
8465          $self->{column}++;
8466          $self->{nc}
8467              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8468        } else {
8469          $self->{set_nc}->($self);
8470        }
8471      
8472            redo A;
8473          } elsif ($self->{nc} == 0x002A or # *
8474                   $self->{nc} == 0x002B or # +
8475                   $self->{nc} == 0x003F) { # ?
8476            push @{$self->{ct}->{content}}, chr $self->{nc};
8477            if ($self->{group_depth}) {
8478              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8479            } else {
8480              $self->{state} = AFTER_MD_DEF_STATE;
8481            }
8482            
8483        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8484          $self->{line_prev} = $self->{line};
8485          $self->{column_prev} = $self->{column};
8486          $self->{column}++;
8487          $self->{nc}
8488              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8489        } else {
8490          $self->{set_nc}->($self);
8491        }
8492      
8493            redo A;
8494          } elsif ($self->{nc} == 0x0029) { # )
8495            if ($self->{group_depth}) {
8496              $self->{group_depth}--;
8497              push @{$self->{ct}->{content}}, chr $self->{nc};
8498              ## Stay in the state.
8499              
8500        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8501          $self->{line_prev} = $self->{line};
8502          $self->{column_prev} = $self->{column};
8503          $self->{column}++;
8504          $self->{nc}
8505              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8506        } else {
8507          $self->{set_nc}->($self);
8508        }
8509      
8510              redo A;
8511            } else {
8512              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8513              $self->{state} = BOGUS_MD_STATE;
8514              ## Reconsume.
8515              redo A;
8516            }
8517          } elsif ($self->{nc} == 0x003E) { # >
8518            if ($self->{group_depth}) {
8519              $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed cm group'); ## TODO: type
8520              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8521            }
8522            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8523            
8524        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8525          $self->{line_prev} = $self->{line};
8526          $self->{column_prev} = $self->{column};
8527          $self->{column}++;
8528          $self->{nc}
8529              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8530        } else {
8531          $self->{set_nc}->($self);
8532        }
8533      
8534            return  ($self->{ct}); # ELEMENT
8535            redo A;
8536          } elsif ($self->{nc} == -1) {
8537            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8538            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
8539            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8540            
8541        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8542          $self->{line_prev} = $self->{line};
8543          $self->{column_prev} = $self->{column};
8544          $self->{column}++;
8545          $self->{nc}
8546              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8547        } else {
8548          $self->{set_nc}->($self);
8549        }
8550      
8551            return  ($self->{ct}); # ELEMENT
8552            redo A;
8553          } else {
8554            if ($self->{group_depth}) {
8555              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
8556            } else {
8557              $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8558              $self->{state} = BOGUS_MD_STATE;
8559            }
8560            ## Reconsume.
8561            redo A;
8562          }
8563        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
8564          if ($is_space->{$self->{nc}}) {
8565            ## Stay in the state.
8566            
8567        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8568          $self->{line_prev} = $self->{line};
8569          $self->{column_prev} = $self->{column};
8570          $self->{column}++;
8571          $self->{nc}
8572              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8573        } else {
8574          $self->{set_nc}->($self);
8575        }
8576      
8577            redo A;
8578          } elsif ($self->{nc} == 0x003E) { # >
8579            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8580            
8581        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8582          $self->{line_prev} = $self->{line};
8583          $self->{column_prev} = $self->{column};
8584          $self->{column}++;
8585          $self->{nc}
8586              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8587        } else {
8588          $self->{set_nc}->($self);
8589        }
8590      
8591            return  ($self->{ct}); # ENTITY/ELEMENT
8592            redo A;
8593          } elsif ($self->{nc} == -1) {
8594            $self->{parse_error}->(level => $self->{level}->{must}, type => 'unclosed md'); ## TODO: type
8595            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
8596            
8597        if ($self->{char_buffer_pos} < length $self->{char_buffer}) {
8598          $self->{line_prev} = $self->{line};
8599          $self->{column_prev} = $self->{column};
8600          $self->{column}++;
8601          $self->{nc}
8602              = ord substr ($self->{char_buffer}, $self->{char_buffer_pos}++, 1);
8603        } else {
8604          $self->{set_nc}->($self);
8605        }
8606      
8607            return  ($self->{ct}); # ENTITY/ELEMENT
8608            redo A;
8609          } else {
8610            $self->{parse_error}->(level => $self->{level}->{must}, type => 'string after md def'); ## TODO: type
8611          $self->{state} = BOGUS_MD_STATE;          $self->{state} = BOGUS_MD_STATE;
8612          ## Reconsume.          ## Reconsume.
8613          redo A;          redo A;
8614        }        }
   
   
8615      } elsif ($self->{state} == BOGUS_MD_STATE) {      } elsif ($self->{state} == BOGUS_MD_STATE) {
8616        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
8617          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;

Legend:
Removed from v.1.18  
changed lines
  Added in v.1.25

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24