Class: SilkLayout::CSS::PageRule

Inherits:
Object
  • Object
show all
Defined in:
lib/silk_layout/css/page_rule.rb

Constant Summary collapse

CSS_PX_PER_IN =
96.0
MM_PER_IN =
25.4
A4 =
[(210.0 / MM_PER_IN) * CSS_PX_PER_IN, (297.0 / MM_PER_IN) * CSS_PX_PER_IN].freeze
NAMED_SIZES =
{
  "a4" => A4
}.freeze
ORIENTATIONS =
%w[
  landscape
  portrait
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(selector:, declarations:, order:) ⇒ PageRule

Returns a new instance of PageRule.



76
77
78
79
80
# File 'lib/silk_layout/css/page_rule.rb', line 76

def initialize(selector:, declarations:, order:)
  @selector = selector
  @declarations = declarations
  @order = order
end

Instance Attribute Details

#declarationsObject (readonly)

Returns the value of attribute declarations.



17
18
19
# File 'lib/silk_layout/css/page_rule.rb', line 17

def declarations
  @declarations
end

#orderObject (readonly)

Returns the value of attribute order.



17
18
19
# File 'lib/silk_layout/css/page_rule.rb', line 17

def order
  @order
end

#selectorObject (readonly)

Returns the value of attribute selector.



17
18
19
# File 'lib/silk_layout/css/page_rule.rb', line 17

def selector
  @selector
end

Class Method Details

.length_dimensions(tokens) ⇒ Object



46
47
48
49
50
51
52
53
# File 'lib/silk_layout/css/page_rule.rb', line 46

def self.length_dimensions(tokens)
  return nil unless tokens.length.between?(1, 2)

  lengths = tokens.map { |token| length_to_px(token) }
  return nil if lengths.any?(&:nil?)

  [lengths[0], lengths[1] || lengths[0]]
end

.length_to_px(token) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/silk_layout/css/page_rule.rb', line 55

def self.length_to_px(token)
  match = token.to_s.match(/\A([-+]?\d*\.?\d+)(px|in)\z/i)
  return nil unless match

  value = match[1].to_f
  return nil unless value.positive?

  (match[2].downcase == "in") ? value * CSS_PX_PER_IN : value
end

.named_dimensions(tokens) ⇒ Object



39
40
41
42
43
44
# File 'lib/silk_layout/css/page_rule.rb', line 39

def self.named_dimensions(tokens)
  return nil unless tokens.length == 1

  named = NAMED_SIZES[tokens[0].downcase]
  named&.dup
end

.orient(dimensions, orientation) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/silk_layout/css/page_rule.rb', line 65

def self.orient(dimensions, orientation)
  case orientation
  when "landscape"
    (dimensions[0] > dimensions[1]) ? dimensions : dimensions.reverse
  when "portrait"
    (dimensions[0] < dimensions[1]) ? dimensions : dimensions.reverse
  else
    dimensions
  end
end

.parse_size(value) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/silk_layout/css/page_rule.rb', line 27

def self.parse_size(value)
  tokens = value.to_s.strip.split(/\s+/)
  return nil if tokens.empty?

  orientation = tokens.find { |token| ORIENTATIONS.include?(token.downcase) }&.downcase
  size_tokens = tokens.reject { |token| ORIENTATIONS.include?(token.downcase) }
  dimensions = named_dimensions(size_tokens) || length_dimensions(size_tokens)
  return nil unless dimensions

  orient(dimensions, orientation)
end

.resolve_page_size(page_rules) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/silk_layout/css/page_rule.rb', line 19

def self.resolve_page_size(page_rules)
  page_rules
    .select { |rule| rule.selector.to_s.empty? }
    .sort_by(&:order)
    .filter_map(&:size)
    .last
end

Instance Method Details

#sizeObject



82
83
84
85
86
87
# File 'lib/silk_layout/css/page_rule.rb', line 82

def size
  declaration = last_declaration_named("size")
  return nil unless declaration

  self.class.parse_size(declaration[1].value)
end