diff options
Diffstat (limited to 'jni/ruby/lib/rexml/dtd')
-rw-r--r-- | jni/ruby/lib/rexml/dtd/attlistdecl.rb | 10 | ||||
-rw-r--r-- | jni/ruby/lib/rexml/dtd/dtd.rb | 46 | ||||
-rw-r--r-- | jni/ruby/lib/rexml/dtd/elementdecl.rb | 17 | ||||
-rw-r--r-- | jni/ruby/lib/rexml/dtd/entitydecl.rb | 56 | ||||
-rw-r--r-- | jni/ruby/lib/rexml/dtd/notationdecl.rb | 39 |
5 files changed, 168 insertions, 0 deletions
diff --git a/jni/ruby/lib/rexml/dtd/attlistdecl.rb b/jni/ruby/lib/rexml/dtd/attlistdecl.rb new file mode 100644 index 0000000..25955ee --- /dev/null +++ b/jni/ruby/lib/rexml/dtd/attlistdecl.rb @@ -0,0 +1,10 @@ +require "rexml/child" +module REXML + module DTD + class AttlistDecl < Child + START = "<!ATTLIST" + START_RE = /^\s*#{START}/um + PATTERN_RE = /\s*(#{START}.*?>)/um + end + end +end diff --git a/jni/ruby/lib/rexml/dtd/dtd.rb b/jni/ruby/lib/rexml/dtd/dtd.rb new file mode 100644 index 0000000..62317ba --- /dev/null +++ b/jni/ruby/lib/rexml/dtd/dtd.rb @@ -0,0 +1,46 @@ +require "rexml/dtd/elementdecl" +require "rexml/dtd/entitydecl" +require "rexml/comment" +require "rexml/dtd/notationdecl" +require "rexml/dtd/attlistdecl" +require "rexml/parent" + +module REXML + module DTD + class Parser + def Parser.parse( input ) + case input + when String + parse_helper input + when File + parse_helper input.read + end + end + + # Takes a String and parses it out + def Parser.parse_helper( input ) + contents = Parent.new + while input.size > 0 + case input + when ElementDecl.PATTERN_RE + match = $& + contents << ElementDecl.new( match ) + when AttlistDecl.PATTERN_RE + matchdata = $~ + contents << AttlistDecl.new( matchdata ) + when EntityDecl.PATTERN_RE + matchdata = $~ + contents << EntityDecl.new( matchdata ) + when Comment.PATTERN_RE + matchdata = $~ + contents << Comment.new( matchdata ) + when NotationDecl.PATTERN_RE + matchdata = $~ + contents << NotationDecl.new( matchdata ) + end + end + contents + end + end + end +end diff --git a/jni/ruby/lib/rexml/dtd/elementdecl.rb b/jni/ruby/lib/rexml/dtd/elementdecl.rb new file mode 100644 index 0000000..f90b27d --- /dev/null +++ b/jni/ruby/lib/rexml/dtd/elementdecl.rb @@ -0,0 +1,17 @@ +require "rexml/child" +module REXML + module DTD + class ElementDecl < Child + START = "<!ELEMENT" + START_RE = /^\s*#{START}/um + # PATTERN_RE = /^\s*(#{START}.*?)>/um + PATTERN_RE = /^\s*#{START}\s+((?:[:\w][-\.\w]*:)?[-!\*\.\w]*)(.*?)>/ + #\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true) + + def initialize match + @name = match[1] + @rest = match[2] + end + end + end +end diff --git a/jni/ruby/lib/rexml/dtd/entitydecl.rb b/jni/ruby/lib/rexml/dtd/entitydecl.rb new file mode 100644 index 0000000..a9286b2 --- /dev/null +++ b/jni/ruby/lib/rexml/dtd/entitydecl.rb @@ -0,0 +1,56 @@ +require "rexml/child" +module REXML + module DTD + class EntityDecl < Child + START = "<!ENTITY" + START_RE = /^\s*#{START}/um + PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um + SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um + PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um + PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um + # <!ENTITY name SYSTEM "..."> + # <!ENTITY name "..."> + def initialize src + super() + md = nil + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + @middle = "PUBLIC" + @content = "#{md[2]} #{md[4]}" + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + @middle = "SYSTEM" + @content = md[2] + elsif src.match( PLAIN ) + md = src.match( PLAIN, true ) + @middle = "" + @content = md[2] + elsif src.match( PERCENT ) + md = src.match( PERCENT, true ) + @middle = "" + @content = md[2] + end + raise ParseException.new("failed Entity match", src) if md.nil? + @name = md[1] + end + + def to_s + rv = "<!ENTITY #@name " + rv << "#@middle " if @middle.size > 0 + rv << @content + rv + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def EntityDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end diff --git a/jni/ruby/lib/rexml/dtd/notationdecl.rb b/jni/ruby/lib/rexml/dtd/notationdecl.rb new file mode 100644 index 0000000..17d1b9e --- /dev/null +++ b/jni/ruby/lib/rexml/dtd/notationdecl.rb @@ -0,0 +1,39 @@ +require "rexml/child" +module REXML + module DTD + class NotationDecl < Child + START = "<!NOTATION" + START_RE = /^\s*#{START}/um + PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um + SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um + def initialize src + super() + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + else + raise ParseException.new( "error parsing notation: no matching pattern", src ) + end + @name = md[1] + @middle = md[2] + @rest = md[3] + end + + def to_s + "<!NOTATION #@name #@middle #@rest>" + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def NotationDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end |