Module: CSS::Escape

Extended by:
CodePoints, Escape
Included in:
Escape
Defined in:
lib/css/escape.rb

Overview

CSS Syntax §9.3 escape primitives — ‘serialize an identifier`, `serialize a name`, and `serialize a string`. Reused by both the main serializer and the selector serializer.

Constant Summary

Constants included from CodePoints

CodePoints::DIGIT_TABLE, CodePoints::HEX_DIGIT_TABLE, CodePoints::IDENT_CP_TABLE, CodePoints::IDENT_START_TABLE, CodePoints::REPLACEMENT

Instance Method Summary collapse

Methods included from CodePoints

build_table, digit?, hex_digit?, ident_code_point?, ident_start_code_point?

Instance Method Details

#control_or_nul(cp) ⇒ Object

NUL collapses to U+FFFD; controls (0x01..0x1F, 0x7F) get hex escapes. Returns nil for non-control code points.



75
76
77
78
79
80
# File 'lib/css/escape.rb', line 75

def control_or_nul(cp)
  return CodePoints::REPLACEMENT if cp.zero?
  return format('\\%x ', cp)     if (0x01..0x1F).cover?(cp) || cp == 0x7F

  nil
end

#ident(ident) ⇒ Object

§9.3.1.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/css/escape.rb', line 10

def ident(ident)
  buf       = +''
  lone_dash = ident.length == 1 && ident == '-'
  hyphen0   = ident.start_with?('-')

  ident.each_char.with_index {|c, i|
    cp = c.ord

    if (esc = control_or_nul(cp))
      buf << esc
    elsif i.zero? && lone_dash
      buf << '\\-'
    elsif (i.zero? && digit?(c)) || (i == 1 && hyphen0 && digit?(c))
      buf << format('\\%x ', cp)
    elsif ident_code_point?(c)
      buf << c
    else
      buf << "\\#{c}"
    end
  }

  buf
end

#name(name) ⇒ Object

§9.3 “Serialize a name”. Like an ident but allows leading digits and hyphens — used for unrestricted hash tokens.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/css/escape.rb', line 36

def name(name)
  buf = +''

  name.each_char {|c|
    cp = c.ord

    if (esc = control_or_nul(cp))
      buf << esc
    elsif ident_code_point?(c)
      buf << c
    else
      buf << "\\#{c}"
    end
  }

  buf
end

#string(s) ⇒ Object

§9.3.2. Always uses double quotes.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/css/escape.rb', line 55

def string(s)
  buf = +'"'

  s.each_char {|c|
    cp = c.ord

    if (esc = control_or_nul(cp))
      buf << esc
    elsif c == '"' || c == '\\'
      buf << "\\#{c}"
    else
      buf << c
    end
  }

  buf << '"'
end