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.
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.
22 23 24 25 26 27 28 29 |
# File 'lib/crass/scanner.rb', line 22 def initialize(input) string = input.is_a?(IO) ? input.read : input.to_s @chars = string.chars.to_a @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 |
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 38 39 40 |
# File 'lib/crass/scanner.rb', line 33 def consume if @pos == @len '' else @pos += 1 @current = @scanner.getch 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.
45 46 47 48 |
# File 'lib/crass/scanner.rb', line 45 def consume_rest @pos = @len @scanner.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 - @marker] 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 |
# File 'lib/crass/scanner.rb', line 75 def peek(length = 1) @scanner.peek(length) end |
#reconsume ⇒ Object
82 83 84 85 |
# File 'lib/crass/scanner.rb', line 82 def reconsume @scanner.unscan @pos -= 1 if @pos > 0 end |
#reset ⇒ Object
Resets the pointer to the beginning of the string.
88 89 90 91 92 93 |
# File 'lib/crass/scanner.rb', line 88 def reset @current = nil @len = @chars.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.
98 99 100 101 102 103 104 105 |
# File 'lib/crass/scanner.rb', line 98 def scan(pattern) if match = @scanner.scan(pattern) @pos += match.size @current = @chars[@pos - 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.
110 111 112 113 114 115 116 117 |
# File 'lib/crass/scanner.rb', line 110 def scan_until(pattern) if match = @scanner.scan_until(pattern) @pos += match.size @current = @chars[@pos - 1] end match end |