Module: CSS::Urange
Overview
Parser for CSS <urange> tokens, e.g. ‘U+0-7F`, `U+26`, `U+10??`. drafts.csswg.org/css-syntax/#urange-syntax
Operates on the source string rather than a token stream because the tokenizer destructively normalizes shapes like ‘U+0` (the `+` is absorbed into a number-token whose sign is lost on serialization). Sticking with the source preserves the exact form.
Constant Summary collapse
- URANGE_RE =
/\Au\+([0-9a-f?]{1,6})(?:-([0-9a-f]{1,6}))?\z/i.freeze
- WILDCARD_RE =
/\A[0-9a-f]*\?+\z/i.freeze
- MAX_CODEPOINT =
0x10FFFF
Instance Method Summary collapse
Instance Method Details
#parse(input) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/css/urange.rb', line 17 def parse(input) s = input.to_s.strip m = URANGE_RE.match(s) raise ParseError, "invalid urange: #{input.inspect}" unless m start_str, end_str = m[1], m[2] first, last = if end_str raise ParseError, 'wildcards are not allowed in range form' if start_str.include?('?') [start_str.to_i(16), end_str.to_i(16)] elsif start_str.include?('?') raise ParseError, 'wildcards must be trailing' unless start_str.match?(WILDCARD_RE) [start_str.tr('?', '0').to_i(16), start_str.tr('?', 'f').to_i(16)] else n = start_str.to_i(16) [n, n] end raise ParseError, "codepoint out of range: U+#{format('%X', last)}" if last > MAX_CODEPOINT raise ParseError, "urange start must be <= end (U+#{format('%X', first)} > U+#{format('%X', last)})" if first > last Nodes::UnicodeRange.new(first:, last:) end |