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
nil
if 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
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
true
if the end of the string has been reached,false
otherwise. -
#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.
25 26 27 28 29 30 |
# File 'lib/crass/scanner.rb', line 25 def initialize(input) @string = input.is_a?(IO) ? input.read : input.to_s @scanner = StringScanner.new(@string) 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.
11 12 13 |
# File 'lib/crass/scanner.rb', line 11 def current @current end |
#marker ⇒ Object
15 16 17 |
# File 'lib/crass/scanner.rb', line 15 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.
19 20 21 |
# File 'lib/crass/scanner.rb', line 19 def pos @pos end |
#string ⇒ Object (readonly)
String being scanned.
22 23 24 |
# File 'lib/crass/scanner.rb', line 22 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.
34 35 36 37 38 39 40 41 |
# File 'lib/crass/scanner.rb', line 34 def consume if @pos < @len @pos += 1 @current = @scanner.getch else '' end 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.
46 47 48 49 50 51 52 53 |
# File 'lib/crass/scanner.rb', line 46 def consume_rest result = @scanner.rest @current = result[-1] @pos = @len result end |
#eos? ⇒ Boolean
Returns true
if the end of the string has been reached, false
otherwise.
57 58 59 |
# File 'lib/crass/scanner.rb', line 57 def eos? @pos == @len end |
#mark ⇒ Object
Sets the marker to the position of the next character that will be consumed.
63 64 65 |
# File 'lib/crass/scanner.rb', line 63 def mark @marker = @pos end |
#marked ⇒ Object
69 70 71 72 73 74 75 |
# File 'lib/crass/scanner.rb', line 69 def marked if result = @string[@marker, @pos - @marker] result 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.
80 81 82 |
# File 'lib/crass/scanner.rb', line 80 def peek(length = 1) @string[pos, length] end |
#reconsume ⇒ Object
87 88 89 90 |
# File 'lib/crass/scanner.rb', line 87 def reconsume @scanner.unscan @pos -= 1 if @pos > 0 end |
#reset ⇒ Object
Resets the pointer to the beginning of the string.
93 94 95 96 97 98 |
# File 'lib/crass/scanner.rb', line 93 def reset @current = nil @len = @string.size @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.
103 104 105 106 107 108 109 110 |
# File 'lib/crass/scanner.rb', line 103 def scan(pattern) if match = @scanner.scan(pattern) @pos += match.size @current = match[-1] end match 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.
115 116 117 118 119 120 121 122 |
# File 'lib/crass/scanner.rb', line 115 def scan_until(pattern) if match = @scanner.scan_until(pattern) @pos += match.size @current = match[-1] end match end |