Browse Source

Added support for merging multiple layout files

dev
Andy Meneely 11 years ago
parent
commit
75ab0b565f
  1. 3
      CHANGELOG.md
  2. 43
      README.md
  3. 12
      lib/squib/deck.rb
  4. 1
      samples/custom-layout.yml
  5. 15
      samples/custom-layout2.yml
  6. 7
      samples/layouts.rb
  7. 4
      spec/data/multifile-a.yml
  8. 4
      spec/data/multifile-b.yml
  9. 8
      spec/data/multifile-extends-a.yml
  10. 9
      spec/data/multifile-extends-b.yml
  11. 24
      spec/deck_spec.rb

3
CHANGELOG.md

@ -1,6 +1,7 @@
# Squib CHANGELOG
## Samples show you can use text instead of symbols
# Custom layouts now support loading & merging multiple files, see README and updated sample
# Samples now show that you can use text instead of symbols
## v0.0.5
* Image rotation for png and svg via `angle`

43
README.md

@ -169,6 +169,12 @@ Layouts will override Squib's defaults, but are overriden by anything specified
* If anything was not yet specified, use what was given in a layout (if a layout was specified in the command and the file was given to the Deck)
* If still anything was not yet specified, use what was given in Squib's defaults.
Layouts also allow merging, extending, and combining layouts. The sample demonstrates this, but they are also explained below. See the `layouts.rb` sample found [here](https://github.com/andymeneely/squib/tree/master/samples/)
{include:file:samples/layouts.rb}
### Merge Keys and `extends`
Since Layouts are in Yaml, we have the full power of that data format. One particular feature you should look into are ["merge keys"](http://www.yaml.org/YAML_for_ruby.html#merge_key). With merge keys, you can define base styles in one entry, then include those keys elsewhere. For example:
```yaml
@ -193,9 +199,42 @@ yang:
x: += 50
```
See the `use_layout` sample found [here](https://github.com/andymeneely/squib/tree/master/samples/)
### Multiple layout files
Squib also supports the combination of multiple layout files. As shown in the above example, if you provide an `Array` of files then Squib will merge them sequentially. Colliding keys will be completely re-defined by the later file. Extends is processed after _each_ file. YAML merge keys are NOT supported across multiple files (use extends instead). Here's a demonstrative example:
```yaml
# load order: a.yml, b.yml
##############
# file a.yml #
##############
grandparent:
x: 100
parent_a:
extends: grandparent
x: += 10 # evaluates to 110
parent_b:
extends: grandparent
x: += 20 # evaluates to 120
##############
# file b.yml #
##############
child_a:
extends: parent_a
x: += 3 # evaluates to 113
parent_b: # redefined
extends: grandparent
x: += 30 # evaluates to 130
child_b:
extends: parent_b
x: += 3 # evaluates to 133
```
{include:file:samples/use_layout.rb}
This can hopefully be helpful for:
* Creating a base layout for structure, and one for color (for easier color/black-and-white switching)
* Sharing base layouts with other designers
## Configuration File

12
lib/squib/deck.rb

@ -50,6 +50,7 @@ module Squib
# @param cards [Integer] the number of cards in the deck
# @param dpi [Integer] the pixels per inch when rendering out to PDF or calculating using inches.
# @param config [String] the file used for global settings of this deck
# @param layout [String, Array] load a YML file of custom layouts. Multiple files are merged sequentially, redefining collisons. See README and sample for details.
# @param block [Block] the main body of the script.
# @api public
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
@ -105,12 +106,13 @@ module Squib
# Load the layout configuration file, if exists
# @api private
def load_layout(file)
return if file.nil?
def load_layout(files)
@layout = {}
yml = YAML.load_file(file)
yml.each do |key, value|
@layout[key] = recurse_extends(yml, key, {})
Array(files).each do |file|
yml = @layout.merge(YAML.load_file(file))
yml.each do |key, value|
@layout[key] = recurse_extends(yml, key, {})
end
end
end

1
samples/custom-layout.yml

@ -1,3 +1,4 @@
# Used in the layouts.rb sample in conjunction with custom-layout2.yml
frame:
x: 38
y: 38

15
samples/custom-layout2.yml

@ -0,0 +1,15 @@
# Used in the layouts.rb sample in conjunction with custom-layout.yml
#
# When used with custom-layout.yml loaded first, this layout overrides subtitle
subtitle:
x: 150
y: 150
width: 575
height: 60
align: left
valign: middle
font_size: 25
# This one is completely new
description:
extends: subtitle
y: += 350

7
samples/layouts.rb

@ -32,3 +32,10 @@ Squib::Deck.new(layout: 'custom-layout.yml') do
save_png prefix: 'layout_'
end
Squib::Deck.new(layout:['custom-layout.yml', 'custom-layout2.yml']) do
text str: 'The Title', layout: :title # from custom-layout.yml
text str: 'The Subtitle', layout: :subtitle # redefined in custom-layout2.yml
text str: 'The Description', layout: :description # from custom-layout2.yml
save_png prefix: 'layout2_'
end

4
spec/data/multifile-a.yml

@ -0,0 +1,4 @@
title:
x: 100
subtitle:
x: 200

4
spec/data/multifile-b.yml

@ -0,0 +1,4 @@
title: # redefined
x: 300
desc:
x: 400

8
spec/data/multifile-extends-a.yml

@ -0,0 +1,8 @@
grandparent:
x: 100
parent_a:
extends: grandparent
x: += 10 # evaluates to 110
parent_b:
extends: grandparent
x: += 20 # evaluates to 120, for now...

9
spec/data/multifile-extends-b.yml

@ -0,0 +1,9 @@
child_a:
extends: parent_a
x: += 3 # evaluates to 113
parent_b: # redefined
extends: grandparent
x: += 30 # evaluates to 130
child_b:
extends: parent_b
x: += 3 # evaluates to 133

24
spec/deck_spec.rb

@ -183,6 +183,30 @@ describe Squib::Deck do
raise_error(RuntimeError, 'Invalid layout: circular extends with \'a\'')
end
it 'redefines keys on multiple layouts' do
a = test_file('multifile-a.yml')
b = test_file('multifile-b.yml')
d = Squib::Deck.new(layout: [a, b])
expect(d.layout).to eq({
'title' => { 'x' => 300 },
'subtitle' => { 'x' => 200 },
'desc' => { 'x' => 400 }
})
end
it 'evaluates extends on each file first' do
a = test_file('multifile-extends-a.yml')
b = test_file('multifile-extends-b.yml')
d = Squib::Deck.new(layout: [a, b])
expect(d.layout).to eq({
'grandparent' => { 'x' => 100 },
'parent_a' => { 'x' => 110, 'extends' => 'grandparent' },
'parent_b' => { 'x' => 130, 'extends' => 'grandparent' },
'child_a' => { 'x' => 113, 'extends' => 'parent_a' },
'child_b' => { 'x' => 133, 'extends' => 'parent_b' }
})
end
end
end

Loading…
Cancel
Save