Class: Himl::Parser::Document
- Inherits:
-
Nokogiri::XML::SAX::Document
- Object
- Nokogiri::XML::SAX::Document
- Himl::Parser::Document
- Defined in:
- lib/himl/parser.rb
Defined Under Namespace
Classes: Tag
Constant Summary collapse
- ErbEndMarker =
Class.new(Tag)
- ErbBlockStartMarker =
Class.new(Tag)
- ROOT_NODE =
'THE_HIML_ROOT_NODE'
- ERB_TAG =
'HIML_ERB_TAG'
- ERB_TAG_REGEXP =
/<%(?:=|==|-|#|%)?(.*?)(?:[-=])?%>/
- BLOCK_REGEXP =
/\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
- VOID_TAGS =
%w(area base br col command embed hr img input keygen link meta param source track wbr).freeze
- MID_BLOCK_KEYWORDS =
Copied from Haml
%w[else elsif rescue ensure end when]
- START_BLOCK_KEYWORDS =
%w[if begin case unless]
- START_BLOCK_KEYWORD_REGEX =
/(?:\w+(?:,\s*\w+)*\s*=\s*)?(#{START_BLOCK_KEYWORDS.join('|')})/
- BLOCK_KEYWORD_REGEX =
/^-?\s*(?:(#{MID_BLOCK_KEYWORDS.join('|')})|#{START_BLOCK_KEYWORD_REGEX.source})\b/
Instance Attribute Summary collapse
-
#context ⇒ Object
Returns the value of attribute context.
Instance Method Summary collapse
- #characters(string) ⇒ Object
- #close_document! ⇒ Object
- #end_element(name) ⇒ Object
- #erb_template ⇒ Object
-
#initialize(template) ⇒ Document
constructor
A new instance of Document.
- #start_element(name) ⇒ Object
- #template ⇒ Object
Constructor Details
#initialize(template) ⇒ Document
Returns a new instance of Document.
52 53 54 55 56 |
# File 'lib/himl/parser.rb', line 52 def initialize(template) @original_template, @tags, @end_tags = template, [], [] template = template.gsub(ERB_TAG_REGEXP, "<#{ERB_TAG}>\\1</#{ERB_TAG}>") @lines = "<#{ROOT_NODE}>\n#{template}</#{ROOT_NODE}>\n".lines end |
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
50 51 52 |
# File 'lib/himl/parser.rb', line 50 def context @context end |
Instance Method Details
#characters(string) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/himl/parser.rb', line 106 def characters(string) if (last_tag = @tags.last).erb_tag? case string.strip when 'end', '}' @tags.pop @tags << ErbEndMarker.new(nil, last_tag.indentation, last_tag.line) when BLOCK_KEYWORD_REGEX @tags.pop @tags.pop if (ErbBlockStartMarker === @tags.last) && (@tags.last.indentation == last_tag.indentation) @tags << ErbBlockStartMarker.new(nil, last_tag.indentation, last_tag.line, 'end') end end erb_tag = @tags.reverse_each.detect(&:erb_tag?) if erb_tag && (match = BLOCK_REGEXP.match(string)) erb_tag.block_start = match[1].strip end end |
#close_document! ⇒ Object
125 126 127 128 129 130 |
# File 'lib/himl/parser.rb', line 125 def close_document! @current_tag = nil raise SyntaxError, "Unclosed tag: #{@tags.last}" if @tags.last.name != ROOT_NODE end |
#end_element(name) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/himl/parser.rb', line 80 def end_element(name) last_tag = @tags.last return if last_tag.name == ROOT_NODE if (name == ERB_TAG) && last_tag.is_a?(ErbEndMarker) raise SyntaxError, "end of block indentation mismatch at line: #{current_line}, column: #{current_indentation}" if last_tag.indentation != @tags[-2].indentation @tags.pop if (ErbBlockStartMarker === @tags.last) && (@tags.last.indentation == last_tag.indentation) @tags.pop else raise SyntaxError, "end of block mismatch at line: #{current_line}, column: #{current_indentation}" unless (ErbBlockStartMarker === @tags.last) && (@tags.last.indentation == last_tag.indentation) end end if name == last_tag.name if ((last_tag.indentation == current_indentation) || (last_tag.line == current_line)) @tags.pop else raise SyntaxError, "end tag indentation mismatch for <#{name}> at line: #{current_line}, column: #{current_indentation}" end end @tags << ErbBlockStartMarker.new(nil, last_tag.indentation, last_tag.line, last_tag.block_end) if (last_tag.name == ERB_TAG) && last_tag.has_block? end |
#erb_template ⇒ Object
62 63 64 65 66 67 68 69 70 |
# File 'lib/himl/parser.rb', line 62 def erb_template lines = @original_template.lines @end_tags.reverse_each do |index, tag| lines.insert index - 1, tag end lines.join end |
#start_element(name) ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/himl/parser.rb', line 72 def start_element(name, *) @current_tag = name unless name == ROOT_NODE @tags << Tag.new(name, current_indentation, current_line) unless VOID_TAGS.include? name.downcase end |
#template ⇒ Object
58 59 60 |
# File 'lib/himl/parser.rb', line 58 def template @lines.join end |