Class: Crass::Scanner
- Inherits:
-
Object
- Object
- Crass::Scanner
- Defined in:
- lib/crass/scanner.rb
Overview
Similar to a StringScanner, but with extra functionality needed to tokenize CSS while preserving the original text.
Instance Attribute Summary collapse
-
#current ⇒ Object
readonly
Current character, or
nilif the scanner hasn't yet consumed a character, or is at the end of the string. -
#marker ⇒ Object
Current marker position.
-
#pos ⇒ Object
Position of the next character that will be consumed.
-
#string ⇒ Object
readonly
The string being scanned.
Instance Method Summary collapse
-
#consume ⇒ Object
Consumes the next character and returns it, advancing the pointer, or an empty string if the end of the string has been reached.
-
#consume_rest ⇒ Object
Consumes the rest of the string and returns it, advancing the pointer to the end of the string.
-
#eos? ⇒ Boolean
Returns
trueif the end of the string has been reached,falseotherwise. -
#initialize(input) ⇒ Scanner
constructor
Creates a Scanner instance for the given input string or IO instance.
-
#mark ⇒ Object
Sets the marker to the position of the next character that will be consumed.
- #marked ⇒ Object
-
#peek(length = 1) ⇒ Object
Returns up to length characters starting at the current position, but doesn't consume them.
-
#reconsume ⇒ Object
Moves the pointer back one character without changing the value of #current.
-
#reset ⇒ Object
Resets the pointer to the beginning of the string.
-
#scan(pattern) ⇒ Object
Tries to match pattern at the current position.
-
#scan_until(pattern) ⇒ Object
Scans the string until the pattern is matched.
Constructor Details
#initialize(input) ⇒ Scanner
Creates a Scanner instance for the given input string or IO instance.
24 25 26 27 28 29 |
# File 'lib/crass/scanner.rb', line 24 def initialize(input) @string = input.is_a?(IO) ? input.read : input.to_s @chars = @string.chars.to_a reset end |
Instance Attribute Details
#current ⇒ Object (readonly)
Current character, or nil if the scanner hasn't yet consumed a
character, or is at the end of the string.
10 11 12 |
# File 'lib/crass/scanner.rb', line 10 def current @current end |
#marker ⇒ Object
14 15 16 |
# File 'lib/crass/scanner.rb', line 14 def marker @marker end |
#pos ⇒ Object
Position of the next character that will be consumed. This is a character position, not a byte position, so it accounts for multi-byte characters.
18 19 20 |
# File 'lib/crass/scanner.rb', line 18 def pos @pos end |
#string ⇒ Object (readonly)
The string being scanned.
21 22 23 |
# File 'lib/crass/scanner.rb', line 21 def string @string end |
Instance Method Details
#consume ⇒ Object
Consumes the next character and returns it, advancing the pointer, or an empty string if the end of the string has been reached.
33 34 35 36 37 |
# File 'lib/crass/scanner.rb', line 33 def consume @current = @chars[@pos] || '' @pos += 1 if @current @current end |
#consume_rest ⇒ Object
Consumes the rest of the string and returns it, advancing the pointer to the end of the string. Returns an empty string is the end of the string has already been reached.
42 43 44 45 46 47 48 |
# File 'lib/crass/scanner.rb', line 42 def consume_rest rest = @string[@pos..@len] || '' @current = rest[-1] || '' @pos = @len rest end |
#eos? ⇒ Boolean
Returns true if the end of the string has been reached, false
otherwise.
52 53 54 |
# File 'lib/crass/scanner.rb', line 52 def eos? @pos == @len end |
#mark ⇒ Object
Sets the marker to the position of the next character that will be consumed.
58 59 60 |
# File 'lib/crass/scanner.rb', line 58 def mark @marker = @pos end |
#marked ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/crass/scanner.rb', line 64 def marked if result = @chars[@marker...@pos] result.join('') else '' end end |
#peek(length = 1) ⇒ Object
Returns up to length characters starting at the current position, but doesn't consume them. The number of characters returned may be less than length if the end of the string is reached.
75 76 77 78 79 80 81 |
# File 'lib/crass/scanner.rb', line 75 def peek(length = 1) if result = @chars[@pos, length] result.join('') else '' end end |
#reconsume ⇒ Object
86 87 88 |
# File 'lib/crass/scanner.rb', line 86 def reconsume @pos -= 1 if @pos > 0 end |
#reset ⇒ Object
Resets the pointer to the beginning of the string.
91 92 93 94 95 96 |
# File 'lib/crass/scanner.rb', line 91 def reset @current = nil @len = @string.length @marker = 0 @pos = 0 end |
#scan(pattern) ⇒ Object
Tries to match pattern at the current position. If it matches, the
matched substring will be returned and the pointer will be advanced.
Otherwise, nil will be returned.
101 102 103 104 105 106 107 108 109 |
# File 'lib/crass/scanner.rb', line 101 def scan(pattern) match = pattern.match(@string, @pos) return nil if match.nil? || match.begin(0) != @pos @pos = match.end(0) @current = @chars[@pos - 1] match[0] end |
#scan_until(pattern) ⇒ Object
Scans the string until the pattern is matched. Returns the substring up
to and including the end of the match, and advances the pointer. If there
is no match, nil is returned and the pointer is not advanced.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/crass/scanner.rb', line 114 def scan_until(pattern) start = @pos match = pattern.match(@string, @pos) return nil if match.nil? @pos = match.end(0) @current = @chars[@pos - 1] @string[start...@pos] end |