Relax parsing of XML doctypes

This allows the parser to parse doctypes that contain a mixture of
names, public IDs, inline rules, etc.

Fixes #159
This commit is contained in:
Yorick Peterse 2016-09-06 22:25:22 +02:00
parent e58a41f711
commit 68f1f9f660
No known key found for this signature in database
GPG Key ID: EDD30D2BEB691AC9
2 changed files with 37 additions and 22 deletions

View File

@ -60,35 +60,20 @@ expression
# <!DOCTYPE html [ ... ]>
doctype
= T_DOCTYPE_START T_DOCTYPE_NAME doctype_follow
= T_DOCTYPE_START T_DOCTYPE_NAME T_DOCTYPE_TYPE? string? string? doctype_inline T_DOCTYPE_END
{
name = val[1]
follow = val[2]
on_doctype(
:name => name,
:type => follow[0],
:public_id => follow[1],
:system_id => follow[2],
:inline_rules => follow[3]
:name => val[1],
:type => val[2],
:public_id => val[3],
:system_id => val[4],
:inline_rules => val[5]
)
}
;
# Returns: [T_DOCTYPE_TYPE, string, string, doctype_inline]
doctype_follow
= T_DOCTYPE_END { [] }
| T_DOCTYPE_TYPE doctype_types { [val[0], *val[1]] }
| doctype_inline T_DOCTYPE_END { [nil, nil, nil, val[0]] }
;
doctype_inline
= T_DOCTYPE_INLINE+ { val[0].inject(:+) }
;
doctype_types
= string string? T_DOCTYPE_END { [val[0], val[1]] }
| T_DOCTYPE_END { nil }
= T_DOCTYPE_INLINE* { val[0].inject(:+) }
;
# CDATA tags

View File

@ -104,4 +104,34 @@ describe Oga::XML::Parser do
@document.doctype.inline_rules.should == "\nfoo"
end
end
describe 'doctypes with a type, public ID, system ID, and inline rules' do
before :all do
@document = parse('<!DOCTYPE svg PUBLIC "foo" "bar" [rule1]>')
end
it 'returns a Doctype instance' do
@document.doctype.should be_an_instance_of(Oga::XML::Doctype)
end
it 'sets the name of the doctype' do
@document.doctype.name.should == 'svg'
end
it 'sets the type of the doctype' do
@document.doctype.type.should == 'PUBLIC'
end
it 'sets the public ID of the doctype' do
@document.doctype.public_id.should == 'foo'
end
it 'sets the system ID of the doctype' do
@document.doctype.system_id.should == 'bar'
end
it 'sets the inline rules of the doctype' do
@document.doctype.inline_rules.should == 'rule1'
end
end
end