Module: Arrolio::LayoutSpec::Loader
- Defined in:
- lib/arrolio/layout_spec/loader.rb
Overview
Loads a LayoutSpec from YAML. Lengths accept mm/cm/in/pt/px.
Constant Summary collapse
- MM_TO_PT =
2.83464567- CM_TO_PT =
28.3464567- IN_TO_PT =
72.0- PT_TO_PT =
1.0- PX_TO_PT =
0.75
Class Method Summary collapse
- .build_from_hash(hash) ⇒ Object
- .build_margins(attrs) ⇒ Object
- .build_region_extents(hash) ⇒ Object
- .build_template(name, attrs) ⇒ Object
- .build_templates(hash) ⇒ Object
- .load(source) ⇒ Object
- .parse_length(value) ⇒ Object
- .read_yaml(source) ⇒ Object
Class Method Details
.build_from_hash(hash) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/arrolio/layout_spec/loader.rb', line 40 def build_from_hash(hash) templates = build_templates(hash.fetch('page_templates', {})) default = hash.fetch('default_page_template') do templates.keys.first or raise LayoutSpecError, 'no page templates in layout spec', spec_field: :page_templates end styles = Style::Registry.new(hash.fetch('styles', {})) flows = hash.fetch('flows', {}).transform_values do |f| f = { 'region' => f } unless f.is_a?(Hash) Flow.new( name: f['name'], region: f['region']&.to_sym, source: f['source'], default_style_id: f['default_style_id']&.to_sym ) end LayoutSpec.new( page_templates: templates, default_page_template: default, styles: styles, flows: flows, font_paths: hash.fetch('font_paths', {}), header_footer: hash.fetch('header_footer', {}), cover_logo: hash.fetch('cover_logo', {}), font_manifest: hash.fetch('font_manifest', {}) ) end |
.build_margins(attrs) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/arrolio/layout_spec/loader.rb', line 84 def build_margins(attrs) margins = attrs['margins'] return PageTemplate::LETTER.first if margins.nil? case margins when Numeric, String then { all: parse_length(margins) } when Hash margins.to_h { |k, v| [k.to_sym, parse_length(v)] } else raise LayoutSpecError, 'margins must be number/string/hash', spec_field: :margins end end |
.build_region_extents(hash) ⇒ Object
97 98 99 |
# File 'lib/arrolio/layout_spec/loader.rb', line 97 def build_region_extents(hash) hash.to_h { |k, v| [k.to_sym, parse_length(v)] } end |
.build_template(name, attrs) ⇒ Object
75 76 77 78 79 80 81 82 |
# File 'lib/arrolio/layout_spec/loader.rb', line 75 def build_template(name, attrs) PageTemplate.new( name: name, page_size: attrs['page_size'] || PageTemplate::LETTER, margins: build_margins(attrs), region_extents: build_region_extents(attrs.fetch('region_extents', {})) ) end |
.build_templates(hash) ⇒ Object
68 69 70 71 72 73 |
# File 'lib/arrolio/layout_spec/loader.rb', line 68 def build_templates(hash) hash.to_h do |name, attrs| attrs = {} unless attrs.is_a?(Hash) [name, build_template(name, attrs)] end end |
.load(source) ⇒ Object
17 18 19 |
# File 'lib/arrolio/layout_spec/loader.rb', line 17 def load(source) build_from_hash(read_yaml(source)) end |
.parse_length(value) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/arrolio/layout_spec/loader.rb', line 101 def parse_length(value) return value.to_f if value.is_a?(Numeric) case value.to_s when /\A([\d.]+)mm\z/ then Regexp.last_match(1).to_f * MM_TO_PT when /\A([\d.]+)cm\z/ then Regexp.last_match(1).to_f * CM_TO_PT when /\A([\d.]+)in\z/ then Regexp.last_match(1).to_f * IN_TO_PT when /\A([\d.]+)px\z/ then Regexp.last_match(1).to_f * PX_TO_PT when /\A([\d.]+)pt\z/ then Regexp.last_match(1).to_f * PT_TO_PT when /\A[\d.]+\z/ then value.to_f else raise LayoutSpecError, "cannot parse length #{value.inspect}", spec_field: :length end end |
.read_yaml(source) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/arrolio/layout_spec/loader.rb', line 21 def read_yaml(source) case source when Hash then source when String if File.exist?(source) result = YAML.safe_load_file(source, aliases: true) result.is_a?(Hash) ? result : {} else result = YAML.safe_load(source, aliases: true) result.is_a?(Hash) ? result : {} end when IO, StringIO result = YAML.safe_load(source.read, aliases: true) result.is_a?(Hash) ? result : {} else raise ArgumentError, "Loader needs Hash/String/IO; got #{source.class}" end end |