Class: Plist::StreamParser

Inherits:
Object
  • Object
show all
Defined in:
lib/plist/parser.rb

Constant Summary

TEXT =
/([^<]+)/
XMLDECL_PATTERN =
/<\?xml\s+(.*?)\?>*/um
DOCTYPE_PATTERN =
/\s*<!DOCTYPE\s+(.*?)(\[|>)/um
COMMENT_START =
/\A<!--/u
COMMENT_END =
/.*?-->/um

Instance Method Summary (collapse)

Constructor Details

- (StreamParser) initialize(plist_data_or_file, listener)



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/plist/parser.rb', line 63

def initialize( plist_data_or_file, listener )
  if plist_data_or_file.respond_to? :read
    @xml = plist_data_or_file.read
  elsif File.exists? plist_data_or_file
    @xml = File.read( plist_data_or_file )
  else
    @xml = plist_data_or_file
  end

  @listener = listener
end

Instance Method Details

- (Object) parse



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/plist/parser.rb', line 82

def parse
  plist_tags = PTag::mappings.keys.join('|')
  start_tag  = /<(#{plist_tags})([^>]*)>/i
  end_tag    = /<\/(#{plist_tags})[^>]*>/i

  require 'strscan'

  @scanner = StringScanner.new( @xml )
  until @scanner.eos?
    if @scanner.scan(COMMENT_START)
      @scanner.scan(COMMENT_END)
    elsif @scanner.scan(XMLDECL_PATTERN)
    elsif @scanner.scan(DOCTYPE_PATTERN)
    elsif @scanner.scan(start_tag)
      @listener.tag_start(@scanner[1], nil)
      if (@scanner[2] =~ /\/$/)
        @listener.tag_end(@scanner[1])
      end
    elsif @scanner.scan(TEXT)
      @listener.text(@scanner[1])
    elsif @scanner.scan(end_tag)
      @listener.tag_end(@scanner[1])
    else
      raise "Unimplemented element"
    end
  end
end