Class: HtmlConditionalComment::Lexer
- Inherits:
-
Object
- Object
- HtmlConditionalComment::Lexer
- Defined in:
- lib/html-conditional-comment/lexer.rb
Overview
Converts string into array of tokens. Token is an array, first element is symbol representing the token, second element is string value.
Constant Summary collapse
- LESS_THAN =
/lt/i- LESS_THAN_EQUAL =
/lte/i- GREATER_THAN =
/gt/i- GREATER_THAN_EQUAL =
/gte/i- OPEN_PAREN =
/\(/- CLOSE_PAREN =
/\)/- NOT =
/\!/- OR =
/\|/- AND =
/\&/- TRUE =
/true/i- FALSE =
/false/i- IF_STATEMENT =
/if/i- ENDIF_STATEMENT =
/endif/i- OPEN =
Opening statement plus positive look ahead to avoid conflicts with other comments, could also have additional comments before “if”
/<!(\-\-)?[^>]*?\[(?=(end)?if)/- CLOSE =
Closing statement with additional comments after “endif”
/\].*?(\-\-)?>/- WHITE_SPACE =
/\s+/- FEATURE =
/[a-z]+/i- VERSION_VECTOR =
/\d+(\.[\d]+)?/- TOKENS =
[ [:if, IF_STATEMENT], [:endif, ENDIF_STATEMENT], [:paren_open, OPEN_PAREN], [:paren_close, CLOSE_PAREN], [:operator_less_than_equal, LESS_THAN_EQUAL], [:operator_less_than, LESS_THAN], [:operator_greater_than_equal, GREATER_THAN_EQUAL], [:operator_greater_than, GREATER_THAN], [:operator_not, NOT], [:operator_or, OR], [:operator_and, AND], [:boolean_true, TRUE], [:boolean_false, FALSE], [:feature, FEATURE], [:version_vector, VERSION_VECTOR] ]
Instance Method Summary collapse
-
#initialize(html_or_comment) ⇒ Lexer
constructor
A new instance of Lexer.
- #tokenize ⇒ Object
Constructor Details
#initialize(html_or_comment) ⇒ Lexer
Returns a new instance of Lexer.
57 58 59 |
# File 'lib/html-conditional-comment/lexer.rb', line 57 def initialize(html_or_comment) @scanner = StringScanner.new(html_or_comment) end |
Instance Method Details
#tokenize ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 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 105 106 |
# File 'lib/html-conditional-comment/lexer.rb', line 61 def tokenize() tokens = [] open = false #Run until nothing left in string until @scanner.eos?() #Split between if the conditional comment has been opened or not #State will help handle all the other HTML we don't care about if open @scanner.skip(WHITE_SPACE) if token = @scanner.scan(CLOSE) open = false tokens << [:close, token] else #Go through token specs and scan and stop on first one token = TOKENS.inject(nil) do |previous, spec| t = @scanner.scan(spec[1]) unless t.nil?() break [spec[0], t] end end if token tokens << token else raise TokenError.new(@scanner.rest()) end end #Closed (not opened) conditional comment else #Scan till we find an open token, if not done and use the rest if match = @scanner.scan_until(OPEN) open = true #TODO Gross way to get up till scan has succeeded match = match.slice(0..-(@scanner.matched.size() + 1)) tokens << [:html, match] unless match.empty?() tokens << [:open, @scanner.matched] else tokens << [:html, @scanner.rest()] if @scanner.rest?() break end end end @scanner.reset() tokens end |