Class: Polites::Parser

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

Overview

The parser takes XML content from a Polites file and parses it into our own abstract syntax tree built from Node elements. This can then be modified and formatted into the desired output.

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



18
19
20
# File 'lib/polites/parser.rb', line 18

def initialize
  reset
end

Instance Method Details

#parse(source) ⇒ Node+

Parse a unit into our AST. This will deal with anything passed in, but to parse multiple nodes successfully or to parse and entire sheet, see #parse_fragment and #parse_sheet.

Parameters:

  • source (Nokogiri::Node, String)

Returns:

Raises:

  • (ParseError)

    when given a source we cannot deal with.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/polites/parser.rb', line 79

def parse(source)
  case source
  when Nokogiri::XML::Element
    parse_element(source)
  when Nokogiri::XML::NodeSet
    source.map { |s| parse(s) }.compact
  when Nokogiri::XML::Text
    Text.new(source.text)
  when String
    doc = Nokogiri(source)
    if doc.children.any?
      parse(doc.children)
    else
      Text.new(source)
    end
  else
    raise ParseError, "unexpected #{source.inspect}"
  end
end

#parse_fragment(source) ⇒ Array<Node>

Parse a content fragment, which consists of multiple source elements but not necessarily an entire sheet.

Parameters:

  • source (String)

Returns:



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/polites/parser.rb', line 60

def parse_fragment(source)
  element = case source
            when Nokogiri::XML::Element
              source
            when String
              Nokogiri(source)
            end
  element.xpath('string/p').map do |el|
    parse(el)
  end
end

#parse_markup(element) ⇒ Markup

Parse just the markup section of a sheet into a Markup container.

Parameters:

  • element (Nokogiri::Node)

Returns:



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/polites/parser.rb', line 43

def parse_markup(element)
  markup = element.xpath('markup').first
  tags = markup.xpath('tag').map do |e|
    if e[:pattern]
      SimpleTag.new(e[:definition], e[:pattern])
    elsif e[:startPattern] && e[:endPattern]
      RangeTag.new(e[:definition], e[:startPattern], e[:endPattern])
    end
  end
  Markup.new(markup[:version], markup[:identifier], markup[:displayName], tags)
end

#parse_sheet(source) ⇒ Sheet

Parse an entire sheet of content, including all its structural elements.

Parameters:

  • source (String)

Returns:



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/polites/parser.rb', line 26

def parse_sheet(source)
  sheet = Nokogiri(source).xpath('/sheet').first
  Sheet.new(
    version: sheet[:version],
    app_version: sheet[:app_version],
    markup: parse_markup(sheet),
    content: parse_fragment(sheet),
    keywords: parse_keywords(sheet),
    files: parse_files(sheet),
    notes: parse_notes(sheet)
  )
end