/[suikacvs]/markup/html/whatpm/Whatpm/ContentChecker/Atom.pm
Suika

Diff of /markup/html/whatpm/Whatpm/ContentChecker/Atom.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17 by wakaba, Thu Mar 20 10:58:17 2008 UTC revision 1.21 by wakaba, Sat Aug 30 10:26:39 2008 UTC
# Line 47  my $GetAtomAttrsChecker = sub { Line 47  my $GetAtomAttrsChecker = sub {
47        } elsif ($attr_ln eq '') {        } elsif ($attr_ln eq '') {
48          #          #
49        } else {        } else {
50          $self->{onerror}->(node => $attr, level => 'unsupported',          $self->{onerror}->(node => $attr,
51                             type => 'attribute');                             type => 'unknown attribute',
52                               level => $self->{level}->{uncertain});
53          ## ISSUE: No comformance createria for unknown attributes in the spec          ## ISSUE: No comformance createria for unknown attributes in the spec
54        }        }
55    
# Line 67  my $AtomLanguageTagAttrChecker = sub { Line 68  my $AtomLanguageTagAttrChecker = sub {
68    my $value = $attr->value;    my $value = $attr->value;
69    require Whatpm::LangTag;    require Whatpm::LangTag;
70    Whatpm::LangTag->check_rfc3066_language_tag ($value, sub {    Whatpm::LangTag->check_rfc3066_language_tag ($value, sub {
71      my %opt = @_;      $self->{onerror}->(@_, node => $attr);
72      my $type = 'LangTag:'.$opt{type};    }, $self->{level});
     $type .= ':' . $opt{subtag} if defined $opt{subtag};  
     $self->{onerror}->(node => $attr, type => $type, value => $opt{value},  
                        level => $opt{level});  
   });  
73    ## ISSUE: RFC 4646 (3066bis)?    ## ISSUE: RFC 4646 (3066bis)?
74  }; # $AtomLanguageTagAttrChecker  }; # $AtomLanguageTagAttrChecker
75    
# Line 97  my %AtomTextConstruct = ( Line 94  my %AtomTextConstruct = (
94          $element_state->{type} = $value;          $element_state->{type} = $value;
95        } else {        } else {
96          ## NOTE: IMT MUST NOT be used here.          ## NOTE: IMT MUST NOT be used here.
97          $self->{onerror}->(node => $attr, type => 'keyword:invalid');          $self->{onerror}->(node => $attr,
98                               type => 'invalid attribute value',
99                               level => $self->{level}->{must});
100        }        }
101      }, # checked in |checker|      }, # checked in |checker|
102    }, {    }, {
# Line 109  my %AtomTextConstruct = ( Line 108  my %AtomTextConstruct = (
108      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
109        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
110                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
111                           level => $self->{must_level});                           level => $self->{level}->{must});
112      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
113        #        #
114      } else {      } else {
# Line 117  my %AtomTextConstruct = ( Line 116  my %AtomTextConstruct = (
116            $element_state->{type} eq 'html') { # MUST NOT            $element_state->{type} eq 'html') { # MUST NOT
117          $self->{onerror}->(node => $child_el,          $self->{onerror}->(node => $child_el,
118                             type => 'element not allowed:atom|TextConstruct',                             type => 'element not allowed:atom|TextConstruct',
119                             level => $self->{must_level});                             level => $self->{level}->{must});
120        } elsif ($element_state->{type} eq 'xhtml') {        } elsif ($element_state->{type} eq 'xhtml') {
121          if ($child_nsuri eq q<http://www.w3.org/1999/xhtml> and          if ($child_nsuri eq q<http://www.w3.org/1999/xhtml> and
122              $child_ln eq 'div') { # MUST              $child_ln eq 'div') { # MUST
# Line 125  my %AtomTextConstruct = ( Line 124  my %AtomTextConstruct = (
124              $self->{onerror}              $self->{onerror}
125                  ->(node => $child_el,                  ->(node => $child_el,
126                     type => 'element not allowed:atom|TextConstruct',                     type => 'element not allowed:atom|TextConstruct',
127                     level => $self->{must_level});                     level => $self->{level}->{must});
128            } else {            } else {
129              $element_state->{has_div} = 1;              $element_state->{has_div} = 1;
130              ## TODO: SHOULD be suitable for handling as HTML [XHTML10]              ## TODO: SHOULD be suitable for handling as HTML [XHTML10]
# Line 133  my %AtomTextConstruct = ( Line 132  my %AtomTextConstruct = (
132          } else {          } else {
133            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
134                               type => 'element not allowed:atom|TextConstruct',                               type => 'element not allowed:atom|TextConstruct',
135                               level => $self->{must_level});                               level => $self->{level}->{must});
136          }          }
137        } else {        } else {
138          die "atom:TextConstruct type error: $element_state->{type}";          die "atom:TextConstruct type error: $element_state->{type}";
# Line 151  my %AtomTextConstruct = ( Line 150  my %AtomTextConstruct = (
150        if ($has_significant) {        if ($has_significant) {
151          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
152                             type => 'character not allowed:atom|TextConstruct',                             type => 'character not allowed:atom|TextConstruct',
153                             level => $self->{must_level});                             level => $self->{level}->{must});
154        }        }
155      } else {      } else {
156        die "atom:TextConstruct type error: $element_state->{type}";        die "atom:TextConstruct type error: $element_state->{type}";
# Line 162  my %AtomTextConstruct = ( Line 161  my %AtomTextConstruct = (
161      if ($element_state->{type} eq 'xhtml') {      if ($element_state->{type} eq 'xhtml') {
162        unless ($element_state->{has_div}) {        unless ($element_state->{has_div}) {
163          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
164                             type => 'element missing:div',                             type => 'child element missing',
165                             level => $self->{must_level});                             text => 'div',
166                               level => $self->{level}->{must});
167        }        }
168      } elsif ($element_state->{type} eq 'html') {      } elsif ($element_state->{type} eq 'html') {
169        ## TODO: SHOULD be suitable for handling as HTML [HTML4]        ## TODO: SHOULD be suitable for handling as HTML [HTML4]
# Line 187  my %AtomPersonConstruct = ( Line 187  my %AtomPersonConstruct = (
187      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
188        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
189                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
190                           level => $self->{must_level});                           level => $self->{level}->{must});
191      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
192        #        #
193      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 196  my %AtomPersonConstruct = ( Line 196  my %AtomPersonConstruct = (
196            $self->{onerror}            $self->{onerror}
197                ->(node => $child_el,                ->(node => $child_el,
198                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
199                   level => $self->{must_level});                   level => $self->{level}->{must});
200          } else {          } else {
201            $element_state->{has_name} = 1;            $element_state->{has_name} = 1;
202          }          }
# Line 205  my %AtomPersonConstruct = ( Line 205  my %AtomPersonConstruct = (
205            $self->{onerror}            $self->{onerror}
206                ->(node => $child_el,                ->(node => $child_el,
207                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
208                   level => $self->{must_level});                   level => $self->{level}->{must});
209          } else {          } else {
210            $element_state->{has_uri} = 1;            $element_state->{has_uri} = 1;
211          }          }
# Line 214  my %AtomPersonConstruct = ( Line 214  my %AtomPersonConstruct = (
214            $self->{onerror}            $self->{onerror}
215                ->(node => $child_el,                ->(node => $child_el,
216                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
217                   level => $self->{must_level});                   level => $self->{level}->{must});
218          } else {          } else {
219            $element_state->{has_email} = 1;            $element_state->{has_email} = 1;
220          }          }
# Line 222  my %AtomPersonConstruct = ( Line 222  my %AtomPersonConstruct = (
222          $self->{onerror}          $self->{onerror}
223              ->(node => $child_el,              ->(node => $child_el,
224                 type => 'element not allowed:atom|PersonConstruct',                 type => 'element not allowed:atom|PersonConstruct',
225                 level => $self->{must_level});                 level => $self->{level}->{must});
226        }        }
227      } else {      } else {
228        $self->{onerror}        $self->{onerror}
229            ->(node => $child_el,            ->(node => $child_el,
230               type => 'element not allowed:atom|PersonConstruct',               type => 'element not allowed:atom|PersonConstruct',
231               level => $self->{must_level});               level => $self->{level}->{must});
232      }      }
233      ## TODO: extension element      ## TODO: extension element
234    },    },
# Line 237  my %AtomPersonConstruct = ( Line 237  my %AtomPersonConstruct = (
237      if ($has_significant) {      if ($has_significant) {
238        $self->{onerror}->(node => $child_node,        $self->{onerror}->(node => $child_node,
239                           type => 'character not allowed:atom|PersonConstruct',                           type => 'character not allowed:atom|PersonConstruct',
240                           level => $self->{must_level});                           level => $self->{level}->{must});
241      }      }
242    },    },
243    check_end => sub {    check_end => sub {
# Line 245  my %AtomPersonConstruct = ( Line 245  my %AtomPersonConstruct = (
245    
246      unless ($element_state->{has_name}) {      unless ($element_state->{has_name}) {
247        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
248                           type => 'element missing:atom|name',                           type => 'child element missing:atom',
249                           level => $self->{must_level});                           text => 'name',
250                             level => $self->{level}->{must});
251      }      }
252    
253      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 290  $Element->{$ATOM_NS}->{uri} = { Line 291  $Element->{$ATOM_NS}->{uri} = {
291    
292      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
293      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
294        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
295        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
296    
297      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
298    },    },
# Line 314  $Element->{$ATOM_NS}->{email} = { Line 312  $Element->{$ATOM_NS}->{email} = {
312      ## TODO: addr-spec      ## TODO: addr-spec
313      $self->{onerror}->(node => $item->{node},      $self->{onerror}->(node => $item->{node},
314                         type => 'addr-spec not supported',                         type => 'addr-spec not supported',
315                         level => $self->{unsupported_level});                         level => $self->{level}->{uncertain});
316    
317      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
318    },    },
# Line 345  my %AtomDateConstruct = ( Line 343  my %AtomDateConstruct = (
343    
344        ## Check additional constraints described or referenced in        ## Check additional constraints described or referenced in
345        ## comments of ABNF rules for |date-time|.        ## comments of ABNF rules for |date-time|.
       my $level = $self->{must_level};  
346        if (0 < $M and $M < 13) {              if (0 < $M and $M < 13) {      
347          $self->{onerror}->(node => $node, type => 'datetime:bad day',          $self->{onerror}->(node => $node, type => 'datetime:bad day',
348                             level => $level)                             level => $self->{level}->{must})
349              if $d < 1 or              if $d < 1 or
350                  $d > [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]->[$M];                  $d > [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]->[$M];
351          $self->{onerror}->(node => $node, type => 'datetime:bad day',          $self->{onerror}->(node => $node, type => 'datetime:bad day',
352                             level => $level)                             level => $self->{level}->{must})
353              if $M == 2 and $d == 29 and              if $M == 2 and $d == 29 and
354                  not ($y % 400 == 0 or ($y % 4 == 0 and $y % 100 != 0));                  not ($y % 400 == 0 or ($y % 4 == 0 and $y % 100 != 0));
355        } else {        } else {
356          $self->{onerror}->(node => $node, type => 'datetime:bad month',          $self->{onerror}->(node => $node, type => 'datetime:bad month',
357                             level => $level);                             level => $self->{level}->{must});
358        }        }
359        $self->{onerror}->(node => $node, type => 'datetime:bad hour',        $self->{onerror}->(node => $node, type => 'datetime:bad hour',
360                           level => $level) if $h > 23;                           level => $self->{level}->{must}) if $h > 23;
361        $self->{onerror}->(node => $node, type => 'datetime:bad minute',        $self->{onerror}->(node => $node, type => 'datetime:bad minute',
362                           level => $level) if $m > 59;                           level => $self->{level}->{must}) if $m > 59;
363        $self->{onerror}->(node => $node, type => 'datetime:bad second',        $self->{onerror}->(node => $node, type => 'datetime:bad second',
364                           level => $level)                           level => $self->{level}->{must})
365            if $s > 60; ## NOTE: Validness of leap seconds are not checked.            if $s > 60; ## NOTE: Validness of leap seconds are not checked.
366        $self->{onerror}->(node => $node, type => 'datetime:bad timezone hour',        $self->{onerror}->(node => $node, type => 'datetime:bad timezone hour',
367                           level => $level) if $zh > 23;                           level => $self->{level}->{must}) if $zh > 23;
368        $self->{onerror}->(node => $node, type => 'datetime:bad timezone minute',        $self->{onerror}->(node => $node, type => 'datetime:bad timezone minute',
369                           level => $level) if $zm > 59;                           level => $self->{level}->{must}) if $zm > 59;
370      } else {      } else {
371        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
372                           type => 'datetime:syntax error',                           type => 'datetime:syntax error',
373                           level => $self->{must_level});                           level => $self->{level}->{must});
374      }      }
375      ## NOTE: SHOULD be accurate as possible (cannot be checked)      ## NOTE: SHOULD be accurate as possible (cannot be checked)
376    
# Line 393  $Element->{$ATOM_NS}->{entry} = { Line 390  $Element->{$ATOM_NS}->{entry} = {
390      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
391        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
392                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
393                           level => $self->{must_level});                           level => $self->{level}->{must});
394      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
395        #        #
396      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 445  $Element->{$ATOM_NS}->{entry} = { Line 442  $Element->{$ATOM_NS}->{entry} = {
442          $not_allowed = 1;          $not_allowed = 1;
443        }        }
444        if ($not_allowed) {        if ($not_allowed) {
445          $self->{onerror}->(node => $child_el, type => 'element not allowed');          $self->{onerror}->(node => $child_el, type => 'element not allowed',
446                               level => $self->{level}->{must});
447        }        }
448      } elsif ($child_nsuri eq $THR_NS and $child_ln eq 'in-reply-to') {      } elsif ($child_nsuri eq $THR_NS and $child_ln eq 'in-reply-to') {
449        ## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y        ## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y
# Line 455  $Element->{$ATOM_NS}->{entry} = { Line 453  $Element->{$ATOM_NS}->{entry} = {
453        #        #
454      } else {      } else {
455        ## TODO: extension element        ## TODO: extension element
456        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
457                             level => $self->{level}->{must});
458      }      }
459    },    },
460    check_child_text => sub {    check_child_text => sub {
461      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
462      if ($has_significant) {      if ($has_significant) {
463        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
464                           level => $self->{must_level});                           level => $self->{level}->{must});
465      }      }
466    },    },
467    check_end => sub {    check_end => sub {
# Line 493  $Element->{$ATOM_NS}->{entry} = { Line 492  $Element->{$ATOM_NS}->{entry} = {
492          }          }
493                    
494          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
495                             type => 'element missing:atom|author',                             type => 'child element missing:atom',
496                             level => $self->{must_level});                             text => 'author',
497                               level => $self->{level}->{must});
498        } # A        } # A
499      }      }
500    
# Line 506  $Element->{$ATOM_NS}->{entry} = { Line 506  $Element->{$ATOM_NS}->{entry} = {
506    
507      unless ($element_state->{has_element}->{id}) { # MUST      unless ($element_state->{has_element}->{id}) { # MUST
508        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
509                           type => 'element missing:atom|id');                           type => 'child element missing:atom',
510                             text => 'id',
511                             level => $self->{level}->{must});
512      }      }
513      unless ($element_state->{has_element}->{title}) { # MUST      unless ($element_state->{has_element}->{title}) { # MUST
514        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
515                           type => 'element missing:atom|title');                           type => 'child element missing:atom',
516                             text => 'title',
517                             level => $self->{level}->{must});
518      }      }
519      unless ($element_state->{has_element}->{updated}) { # MUST      unless ($element_state->{has_element}->{updated}) { # MUST
520        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
521                           type => 'element missing:atom|updated');                           type => 'child element missing:atom',
522                             text => 'updated',
523                             level => $self->{level}->{must});
524      }      }
525      if (not $element_state->{has_element}->{content} and      if (not $element_state->{has_element}->{content} and
526          not $element_state->{has_element}->{'link.alternate'}) {          not $element_state->{has_element}->{'link.alternate'}) {
527        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
528                           type => 'element missing:atom|link|alternate');                           type => 'child element missing:atom:link:alternate',
529                             level => $self->{level}->{must});
530      }      }
531    
532      if ($element_state->{require_summary} and      if ($element_state->{require_summary} and
533          not $element_state->{has_element}->{summary}) {          not $element_state->{has_element}->{summary}) {
534        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
535                           type => 'element missing:atom|summary',                           type => 'child element missing:atom',
536                           level => $self->{must_level});                           text => 'summary',
537                             level => $self->{level}->{must});
538      }      }
539    },    },
540  };  };
# Line 543  $Element->{$ATOM_NS}->{feed} = { Line 551  $Element->{$ATOM_NS}->{feed} = {
551      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
552        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
553                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
554                           level => $self->{must_level});                           level => $self->{level}->{must});
555      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
556        #        #
557      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 597  $Element->{$ATOM_NS}->{feed} = { Line 605  $Element->{$ATOM_NS}->{feed} = {
605        } else {        } else {
606          $not_allowed = 1;          $not_allowed = 1;
607        }        }
608        $self->{onerror}->(node => $child_el, type => 'element not allowed')        $self->{onerror}->(node => $child_el, type => 'element not allowed',
609                             level => $self->{level}->{must})
610            if $not_allowed;            if $not_allowed;
611      } else {      } else {
612        ## TODO: extension element        ## TODO: extension element
613        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
614                             level => $self->{level}->{must});
615      }      }
616    },    },
617    check_child_text => sub {    check_child_text => sub {
618      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
619      if ($has_significant) {      if ($has_significant) {
620        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
621                           level => $self->{must_level});                           level => $self->{level}->{must});
622      }      }
623    },    },
624    check_end => sub {    check_end => sub {
# Line 617  $Element->{$ATOM_NS}->{feed} = { Line 627  $Element->{$ATOM_NS}->{feed} = {
627      if ($element_state->{has_no_author_entry} and      if ($element_state->{has_no_author_entry} and
628          not $element_state->{has_element}->{author}) {          not $element_state->{has_element}->{author}) {
629        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
630                           type => 'element missing:atom|author',                           type => 'child element missing:atom',
631                           level => $self->{must_level});                           text => 'author',
632                             level => $self->{level}->{must});
633        ## ISSUE: If there is no |atom:entry| element,        ## ISSUE: If there is no |atom:entry| element,
634        ## there should be an |atom:author| element?        ## there should be an |atom:author| element?
635      }      }
# Line 627  $Element->{$ATOM_NS}->{feed} = { Line 638  $Element->{$ATOM_NS}->{feed} = {
638    
639      unless ($element_state->{has_element}->{id}) { # MUST      unless ($element_state->{has_element}->{id}) { # MUST
640        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
641                           type => 'element missing:atom|id');                           type => 'child element missing:atom',
642                             text => 'id',
643                             level => $self->{level}->{must});
644      }      }
645      unless ($element_state->{has_element}->{title}) { # MUST      unless ($element_state->{has_element}->{title}) { # MUST
646        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
647                           type => 'element missing:atom|title');                           type => 'child element missing:atom',
648                             text => 'title',
649                             level => $self->{level}->{must});
650      }      }
651      unless ($element_state->{has_element}->{updated}) { # MUST      unless ($element_state->{has_element}->{updated}) { # MUST
652        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
653                           type => 'element missing:atom|updated');                           type => 'element missing:atom',
654                             text => 'updated',
655                             level => $self->{level}->{must});
656      }      }
657      unless ($element_state->{has_element}->{'link.self'}) {      unless ($element_state->{has_element}->{'link.self'}) {
658        $self->{onerror}->(node => $item->{node}, level => 's',        $self->{onerror}->(node => $item->{node},
659                           type => 'element missing:atom|link|self');                           type => 'element missing:atom:link:self',
660                             level => $self->{level}->{should});
661      }      }
662    
663      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 662  $Element->{$ATOM_NS}->{content} = { Line 680  $Element->{$ATOM_NS}->{content} = {
680    
681        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
682        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
683          my %opt = @_;          $self->{onerror}->(@_, node => $item->{node});
684          $self->{onerror}->(node => $item->{node}, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
685      },      },
686      type => sub {      type => sub {
687        my ($self, $attr, $item, $element_state) = @_;        my ($self, $attr, $item, $element_state) = @_;
# Line 695  $Element->{$ATOM_NS}->{content} = { Line 710  $Element->{$ATOM_NS}->{content} = {
710              }              }
711            }            }
712            require Whatpm::IMTChecker;            require Whatpm::IMTChecker;
713            Whatpm::IMTChecker->check_imt (sub {            my $ic = Whatpm::IMTChecker->new;
714              my %opt = @_;            $ic->{level} = $self->{level};
715              $self->{onerror}->(node => $attr, level => $opt{level},            $ic->check_imt (sub {
716                                 type => 'IMT:'.$opt{type});              $self->{onerror}->(@_, node => $attr);
717            }, @type);            }, @type);
718          } else {          } else {
719            $self->{onerror}->(node => $attr, type => 'IMT:syntax error',            $self->{onerror}->(node => $attr, type => 'IMT:syntax error',
720                               level => $self->{must_level});                               level => $self->{level}->{must});
721          }          }
722        }        }
723    
# Line 716  $Element->{$ATOM_NS}->{content} = { Line 731  $Element->{$ATOM_NS}->{content} = {
731          $value = 'mime_text';          $value = 'mime_text';
732        } elsif ($value =~ m!^(?>message|multipart)/!i) {        } elsif ($value =~ m!^(?>message|multipart)/!i) {
733          $self->{onerror}->(node => $attr, type => 'IMT:composite',          $self->{onerror}->(node => $attr, type => 'IMT:composite',
734                             level => $self->{must_level});                             level => $self->{level}->{must});
735          $item->{parent_state}->{require_summary} = 1;          $item->{parent_state}->{require_summary} = 1;
736        } else {        } else {
737          $item->{parent_state}->{require_summary} = 1;          $item->{parent_state}->{require_summary} = 1;
# Line 735  $Element->{$ATOM_NS}->{content} = { Line 750  $Element->{$ATOM_NS}->{content} = {
750      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
751        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
752                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
753                           level => $self->{must_level});                           level => $self->{level}->{must});
754      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
755        #        #
756      } else {      } else {
# Line 745  $Element->{$ATOM_NS}->{content} = { Line 760  $Element->{$ATOM_NS}->{content} = {
760          # MUST NOT          # MUST NOT
761          $self->{onerror}->(node => $child_el,          $self->{onerror}->(node => $child_el,
762                             type => 'element not allowed:atom|content',                             type => 'element not allowed:atom|content',
763                             level => $self->{must_level});                             level => $self->{level}->{must});
764        } elsif ($element_state->{type} eq 'xhtml') {        } elsif ($element_state->{type} eq 'xhtml') {
765          if ($element_state->{has_div}) {          if ($element_state->{has_div}) {
766            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
767                               type => 'element not allowed:atom|content',                               type => 'element not allowed:atom|content',
768                               level => $self->{must_level});                               level => $self->{level}->{must});
769          } else {          } else {
770            ## TODO: SHOULD be suitable for handling as HTML [XHTML10]            ## TODO: SHOULD be suitable for handling as HTML [XHTML10]
771            $element_state->{has_div} = 1;            $element_state->{has_div} = 1;
# Line 760  $Element->{$ATOM_NS}->{content} = { Line 775  $Element->{$ATOM_NS}->{content} = {
775          if ($element_state->{has_src}) {          if ($element_state->{has_src}) {
776            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
777                               type => 'element not allowed:atom|content',                               type => 'element not allowed:atom|content',
778                               level => $self->{must_level});                               level => $self->{level}->{must});
779          }          }
780        } else {        } else {
781          ## NOTE: Elements are not explicitly disallowed.          ## NOTE: Elements are not explicitly disallowed.
# Line 777  $Element->{$ATOM_NS}->{content} = { Line 792  $Element->{$ATOM_NS}->{content} = {
792      if ($has_significant) {      if ($has_significant) {
793        if ($element_state->{has_src}) {        if ($element_state->{has_src}) {
794          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
795                             type => 'character not allowed',                             type => 'character not allowed:empty',
796                             level => $self->{must_level});                             level => $self->{level}->{must});
797        } elsif ($element_state->{type} eq 'xhtml' or        } elsif ($element_state->{type} eq 'xhtml' or
798                 $element_state->{type} eq 'xml') {                 $element_state->{type} eq 'xml') {
799          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
800                             type => 'character not allowed:atom|content',                             type => 'character not allowed:atom|content',
801                             level => $self->{must_level});                             level => $self->{level}->{must});
802        }        }
803      }      }
804    
# Line 798  $Element->{$ATOM_NS}->{content} = { Line 813  $Element->{$ATOM_NS}->{content} = {
813      if ($element_state->{has_src}) {      if ($element_state->{has_src}) {
814        if (not $element_state->{has_type}) {        if (not $element_state->{has_type}) {
815          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
816                             type => 'attribute missing:type',                             type => 'attribute missing',
817                             level => $self->{should_level});                             text => 'type',
818                               level => $self->{level}->{should});
819        } elsif ($element_state->{type} eq 'text' or        } elsif ($element_state->{type} eq 'text' or
820                 $element_state->{type} eq 'html' or                 $element_state->{type} eq 'html' or
821                 $element_state->{type} eq 'xhtml') {                 $element_state->{type} eq 'xhtml') {
822          $self->{onerror}          $self->{onerror}
823              ->(node => $item->{node}->get_attribute_node_ns (undef, 'type'),              ->(node => $item->{node}->get_attribute_node_ns (undef, 'type'),
824                 type => 'not IMT', level => $self->{must_level});                 type => 'not IMT', level => $self->{level}->{must});
825        }        }
826      }      }
827    
828      if ($element_state->{type} eq 'xhtml') {      if ($element_state->{type} eq 'xhtml') {
829        unless ($element_state->{has_div}) {        unless ($element_state->{has_div}) {
830          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
831                             type => 'element missing:div',                             type => 'child element missing',
832                             level => $self->{must_level});                             text => 'div',
833                               level => $self->{level}->{must});
834        }        }
835      } elsif ($element_state->{type} eq 'html') {      } elsif ($element_state->{type} eq 'html') {
836        ## TODO: SHOULD be suitable for handling as HTML [HTML4]        ## TODO: SHOULD be suitable for handling as HTML [HTML4]
# Line 828  $Element->{$ATOM_NS}->{content} = { Line 845  $Element->{$ATOM_NS}->{content} = {
845        ## If no @src, this would normally mean it contains a        ## If no @src, this would normally mean it contains a
846        ## single child element that would serve as the root element.        ## single child element that would serve as the root element.
847        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
                          level => $self->{unsupported_level},  
848                           type => 'atom|content not supported',                           type => 'atom|content not supported',
849                           value => $item->{node}->get_attribute_ns                           text => $item->{node}->get_attribute_ns
850                               (undef, 'type'));                               (undef, 'type'),
851                             level => $self->{level}->{uncertain});
852      } elsif ($element_state->{type} eq 'text' or      } elsif ($element_state->{type} eq 'text' or
853               $element_state->{type} eq 'mime-text') {               $element_state->{type} eq 'mime-text') {
854        #        #
# Line 842  $Element->{$ATOM_NS}->{content} = { Line 859  $Element->{$ATOM_NS}->{content} = {
859    
860        ## NOTE: SHOULD be suitable for the indicated media type.        ## NOTE: SHOULD be suitable for the indicated media type.
861        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
                          level => $self->{unsupported_level},  
862                           type => 'atom|content not supported',                           type => 'atom|content not supported',
863                           value => $item->{node}->get_attribute_ns                           text => $item->{node}->get_attribute_ns
864                               (undef, 'type'));                               (undef, 'type'),
865                             level => $self->{level}->{uncertain});
866      }      }
867    
868      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 863  $Element->{$ATOM_NS}->{category} = { Line 880  $Element->{$ATOM_NS}->{category} = {
880        my ($self, $attr) = @_;        my ($self, $attr) = @_;
881        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
882        Whatpm::URIChecker->check_iri ($attr->value, sub {        Whatpm::URIChecker->check_iri ($attr->value, sub {
883          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
884          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
885      },      },
886      term => sub {      term => sub {
887        my ($self, $attr, $item, $element_state) = @_;        my ($self, $attr, $item, $element_state) = @_;
# Line 885  $Element->{$ATOM_NS}->{category} = { Line 899  $Element->{$ATOM_NS}->{category} = {
899      my ($self, $item, $element_state) = @_;      my ($self, $item, $element_state) = @_;
900      unless ($element_state->{has_term}) {      unless ($element_state->{has_term}) {
901        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
902                           type => 'attribute missing:term');                           type => 'attribute missing',
903                             text => 'term',
904                             level => $self->{level}->{must});
905      }      }
906    
907      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 904  $Element->{$ATOM_NS}->{generator} = { Line 920  $Element->{$ATOM_NS}->{generator} = {
920        my ($self, $attr) = @_;        my ($self, $attr) = @_;
921        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
922        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
923          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
924          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
925        ## NOTE: Dereferencing SHOULD produce a representation        ## NOTE: Dereferencing SHOULD produce a representation
926        ## that is relevant to the agent.        ## that is relevant to the agent.
927      },      },
# Line 941  $Element->{$ATOM_NS}->{icon} = { Line 954  $Element->{$ATOM_NS}->{icon} = {
954      ## NOTE: No MUST.      ## NOTE: No MUST.
955      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
956      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
957        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
958        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
959    
960      ## NOTE: Image SHOULD be 1:1 and SHOULD be small      ## NOTE: Image SHOULD be 1:1 and SHOULD be small
961    
# Line 969  $Element->{$ATOM_NS}->{id} = { Line 979  $Element->{$ATOM_NS}->{id} = {
979    
980      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
981      Whatpm::URIChecker->check_iri ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri ($element_state->{value}, sub {
982        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
983        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
984      ## TODO: SHOULD be normalized      ## TODO: SHOULD be normalized
985    
986      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 1000  my $AtomIMTAttrChecker = sub { Line 1007  my $AtomIMTAttrChecker = sub {
1007            }            }
1008          }          }
1009          require Whatpm::IMTChecker;          require Whatpm::IMTChecker;
1010          Whatpm::IMTChecker->check_imt (sub {          my $ic = Whatpm::IMTChecker->new;
1011            my %opt = @_;          $ic->{level} = $self->{level};
1012            $self->{onerror}->(node => $attr, level => $opt{level},          $ic->check_imt (sub {
1013                               type => 'IMT:'.$opt{type});            $self->{onerror}->(@_, node => $attr);
1014          }, @type);          }, @type);
1015        } else {        } else {
1016          $self->{onerror}->(node => $attr, type => 'IMT:syntax error');          $self->{onerror}->(node => $attr, type => 'IMT:syntax error',
1017                               level => $self->{level}->{must});
1018        }        }
1019  }; # $AtomIMTAttrChecker  }; # $AtomIMTAttrChecker
1020    
# Line 1014  my $AtomIRIReferenceAttrChecker = sub { Line 1022  my $AtomIRIReferenceAttrChecker = sub {
1022    my ($self, $attr) = @_;    my ($self, $attr) = @_;
1023    ## NOTE: There MUST NOT be any white space.    ## NOTE: There MUST NOT be any white space.
1024    Whatpm::URIChecker->check_iri_reference ($attr->value, sub {    Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
1025      my %opt = @_;      $self->{onerror}->(@_, node => $attr);
1026      $self->{onerror}->(node => $attr, level => $opt{level},    }, $self->{level});
                        type => 'URI::'.$opt{type}.  
                        (defined $opt{position} ? ':'.$opt{position} : ''));  
   });  
1027  }; # $AtomIRIReferenceAttrChecker  }; # $AtomIRIReferenceAttrChecker
1028    
1029  $Element->{$ATOM_NS}->{link} = {  $Element->{$ATOM_NS}->{link} = {
# Line 1036  $Element->{$ATOM_NS}->{link} = { Line 1041  $Element->{$ATOM_NS}->{link} = {
1041    
1042        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
1043        Whatpm::URIChecker->check_iri ($value, sub {        Whatpm::URIChecker->check_iri ($value, sub {
1044          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
1045          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
1046    
1047        ## TODO: Warn if unregistered        ## TODO: Warn if unregistered
1048    
# Line 1069  $Element->{$ATOM_NS}->{link} = { Line 1071  $Element->{$ATOM_NS}->{link} = {
1071    
1072      unless ($item->{node}->has_attribute_ns (undef, 'href')) { # MUST      unless ($item->{node}->has_attribute_ns (undef, 'href')) { # MUST
1073        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1074                           type => 'attribute missing:href');                           type => 'attribute missing',
1075                             text => 'href',
1076                             level => $self->{level}->{must});
1077      }      }
1078    
1079      if ($item->{node}->rel eq $LINK_REL . 'enclosure' and      if ($item->{node}->rel eq $LINK_REL . 'enclosure' and
1080          not $item->{node}->has_attribute_ns (undef, 'length')) {          not $item->{node}->has_attribute_ns (undef, 'length')) {
1081        $self->{onerror}->(node => $item->{node}, level => 's',        $self->{onerror}->(node => $item->{node},
1082                           type => 'attribute missing:length');                           type => 'attribute missing',
1083                             text => 'length',
1084                             level => $self->{level}->{should});
1085      }      }
1086    },    },
1087  };  };
# Line 1097  $Element->{$ATOM_NS}->{logo} = { Line 1103  $Element->{$ATOM_NS}->{logo} = {
1103    
1104      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
1105      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
1106        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
1107        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
1108            
1109      ## NOTE: Image SHOULD be 2:1      ## NOTE: Image SHOULD be 2:1
1110    
# Line 1123  $Element->{$ATOM_NS}->{source} = { Line 1126  $Element->{$ATOM_NS}->{source} = {
1126      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
1127        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1128                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
1129                           level => $self->{must_level});                           level => $self->{level}->{must});
1130      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
1131        #        #
1132      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 1173  $Element->{$ATOM_NS}->{source} = { Line 1176  $Element->{$ATOM_NS}->{source} = {
1176          $not_allowed = 1;          $not_allowed = 1;
1177        }        }
1178        if ($not_allowed) {        if ($not_allowed) {
1179          $self->{onerror}->(node => $child_el, type => 'element not allowed');          $self->{onerror}->(node => $child_el, type => 'element not allowed',
1180                               level => $self->{level}->{must});
1181        }        }
1182      } else {      } else {
1183        ## TODO: extension element        ## TODO: extension element
1184        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
1185                             level => $self->{level}->{must});
1186      }      }
1187    },    },
1188    check_child_text => sub {    check_child_text => sub {
1189      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
1190      if ($has_significant) {      if ($has_significant) {
1191        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
1192                           level => $self->{must_level});                           level => $self->{level}->{must});
1193      }      }
1194    },    },
1195  };  };
# Line 1225  $Element->{$THR_NS}->{'in-reply-to'} = { Line 1230  $Element->{$THR_NS}->{'in-reply-to'} = {
1230        ## NOTE: Same as |atom:id|.        ## NOTE: Same as |atom:id|.
1231        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
1232        Whatpm::URIChecker->check_iri ($attr->value, sub {        Whatpm::URIChecker->check_iri ($attr->value, sub {
1233          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
1234          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
1235    
1236        ## TODO: Check against ID guideline...        ## TODO: Check against ID guideline...
1237      },      },
# Line 1249  $Element->{$THR_NS}->{'in-reply-to'} = { Line 1251  $Element->{$THR_NS}->{'in-reply-to'} = {
1251        
1252      unless ($element_state->{has_ref}) {      unless ($element_state->{has_ref}) {
1253        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1254                           type => 'attribute missing:ref',                           type => 'attribute missing',
1255                           level => $self->{must_level});                           text => 'ref',
1256                             level => $self->{level}->{must});
1257      }      }
1258    
1259      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 1271  $Element->{$THR_NS}->{total} = { Line 1274  $Element->{$THR_NS}->{total} = {
1274      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {
1275        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1276                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
1277                           level => $self->{must_level});                           level => $self->{level}->{must});
1278      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
1279        #        #
1280      } else {      } else {
1281        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1282                           type => 'element not allowed',                           type => 'element not allowed',
1283                           level => $self->{must_level});                           level => $self->{level}->{must});
1284      }      }
1285    },    },
1286    check_child_text => sub {    check_child_text => sub {
# Line 1290  $Element->{$THR_NS}->{total} = { Line 1293  $Element->{$THR_NS}->{total} = {
1293      ## NOTE: xsd:nonNegativeInteger      ## NOTE: xsd:nonNegativeInteger
1294      unless ($element_state->{value} =~ /\A(?>[0-9]+|-0+)\z/) {      unless ($element_state->{value} =~ /\A(?>[0-9]+|-0+)\z/) {
1295        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1296                           type => 'syntax error', ## TODO:                           type => 'invalid attribute value',
1297                           level => $self->{must_level});                           level => $self->{level}->{must});
1298      }      }
1299    
1300      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24