Browse Source

Starting work on the new options

dev
Andy Meneely 12 years ago
parent
commit
6c60476e42
  1. 1
      .yardopts
  2. 1
      API.md
  3. 30
      README.md
  4. 13
      lib/squib/api/background.rb
  5. 3
      lib/squib/api/data.rb
  6. 22
      lib/squib/api/image.rb
  7. 16
      lib/squib/constants.rb
  8. 84
      lib/squib/input_helpers.rb
  9. 2
      samples/basic.rb

1
.yardopts

@ -1,3 +1,4 @@
--readme README.md
--markup markdown --markup markdown
--api public --api public
- -

1
API.md

@ -1,4 +1,3 @@
# @markup markdown
# Squib API # Squib API
# Squib::Deck and Squib::Card # Squib::Deck and Squib::Card

30
README.md

@ -1,13 +1,15 @@
# Squib [![Gem Version](https://badge.fury.io/rb/squib.svg)](https://rubygems.org/gems/squib) [![Build Status](https://secure.travis-ci.org/andymeneely/squib.svg?branch=master)](https://travis-ci.org/andymeneely/squib) [![Dependency Status](https://gemnasium.com/andymeneely/squib.svg)](https://gemnasium.com/andymeneely/squib) [![Coverage Status](https://img.shields.io/coveralls/andymeneely/squib.svg)](https://coveralls.io/r/andymeneely/squib) [![Inline docs](http://inch-ci.org/github/andymeneely/squib.png?branch=master)](http://inch-ci.org/github/andymeneely/squib) # Squib [![Gem Version](https://badge.fury.io/rb/squib.svg)](https://rubygems.org/gems/squib) [![Build Status](https://secure.travis-ci.org/andymeneely/squib.svg?branch=master)](https://travis-ci.org/andymeneely/squib) [![Dependency Status](https://gemnasium.com/andymeneely/squib.svg)](https://gemnasium.com/andymeneely/squib) [![Coverage Status](https://img.shields.io/coveralls/andymeneely/squib.svg)](https://coveralls.io/r/andymeneely/squib) [![Inline docs](http://inch-ci.org/github/andymeneely/squib.png?branch=master)](http://inch-ci.org/github/andymeneely/squib)
Squib is a Ruby DSL for prototyping card and board games. Think of it like [nanDeck](http://www.nand.it/nandeck/) done "the Ruby way". Start with some basic commands and generate print-ready PNGs and PDFs. Squib supports: Squib is a Ruby [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for prototyping card and board games. Think of it like [nanDeck](http://www.nand.it/nandeck/) done "the Ruby way". Squib supports:
* Complex text rendering using [Pango](http://www.pango.org/) * Complex text rendering using [Pango](http://www.pango.org/)
* Reading PNGs and SVGs using [Cairo](http://cairographics.org/) * Reading PNGs and SVGs using [Cairo](http://cairographics.org/)
* Reading `.xlsx` files * Reading `.xlsx` files
* Basic shape drawing * Basic shape drawing
* Saving to PNGs and PDFs * Rendering to PNGs and PDFs
* Plus the full power of Ruby! * Plus the full power of Ruby!
Check this out.
```ruby ```ruby
require 'squib' require 'squib'
@ -17,6 +19,8 @@ Squib::Deck.new do
end end
``` ```
That script just created 3 PNG images at 825x1125 with the string "Hello, World" in the upper-left corner.
## Installation ## Installation
Install it yourself with: Install it yourself with:
@ -31,7 +35,7 @@ And then execute:
$ bundle $ bundle
Note: Squib has some native dependencies, such as [Cairo](https://github.com/rcairo/rcairo), [Pango](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3ALayout), and [Nokogiri](http://nokogiri.org/), which all require DevKit to compile C code. This is usually not painful, but on some setups can cause headaches. For Windows users, I *strongly* recommend using the *non-*64 bit RubyInstaller at http://rubyinstaller.org. For Mac, I recommend using [rvm](https://rvm.io). Note: Squib has some native dependencies, such as [Cairo](https://github.com/rcairo/rcairo), [Pango](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3ALayout), and [Nokogiri](http://nokogiri.org/), which all require DevKit to compile C code. This is usually not painful, but can cause headaches on some setups. For Windows users, I *strongly* recommend using the *non-64 bit* RubyInstaller at http://rubyinstaller.org. For Mac, I recommend using [rvm](https://rvm.io). Squib requires Ruby 2.0 or later.
## Getting Started ## Getting Started
@ -57,25 +61,9 @@ layout.yml
PNP NOTES.md PNP NOTES.md
``` ```
The central file here is `deck.rb`. Here's a more complex example of a deck to work from: The central file here is `deck.rb`. Here's a basic example of a deck to work from:
```ruby
require 'squib'
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
background color: :white
data = xlsx file: 'sample.xlsx'
rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50 {include:file:samples/basic.rb}
text str: data['name'], x: 250, y: 55, font: 'Arial 54'
text str: data['level'], x: 65, y: 40, font: 'Arial 72'
png file: 'icon.png', x: 665, y: 30
save format: :png
end
```
## Learning Squib's API ## Learning Squib's API

13
lib/squib/api/background.rb

@ -2,13 +2,14 @@ module Squib
class Deck class Deck
# Fills the background with the given color # Fills the background with the given color
# #
# @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges} # @params opts: the parameter hash.
# @param color: the color the font will render to. See {file:API.md#label-Specifying+Colors Specifying Colors} # @option range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges}
# @option color: the color the font will render to. See {file:API.md#label-Specifying+Colors Specifying Colors}
# @return [nil]
# @api public # @api public
def background(range: :all, color: :white) def background(opts = {})
range = rangeify(range) opts = needs(opts,[:range, :color])
color = colorify(color) opts[:range].each { |i| @cards[i].background(opts[:color]) }
range.each { |i| @cards[i].background(color) }
end end
end end

3
lib/squib/api/data.rb

@ -15,7 +15,8 @@ module Squib
# @param file: [String] the file to open. Must end in `.xlsx`. Opens relative to the current directory. # @param file: [String] the file to open. Must end in `.xlsx`. Opens relative to the current directory.
# @param sheet: [Integer] The zero-based index of the sheet from which to read. # @param sheet: [Integer] The zero-based index of the sheet from which to read.
# @api public # @api public
def xlsx(file: 'deck.xlsx', sheet: 0) def xlsx(opts = {})
needs(opts, [:file, :sheet])
s = Roo::Excelx.new(file) s = Roo::Excelx.new(file)
s.default_sheet = s.sheets[sheet] s.default_sheet = s.sheets[sheet]
data = {} data = {}

22
lib/squib/api/image.rb

@ -6,15 +6,17 @@ module Squib
# Note: scaling not currently supported for PNGs. # Note: scaling not currently supported for PNGs.
# #
# @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges} # @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges}
# @param file: the . See {file:API.md#Specifying+Files Specifying Files} # @param file: file(s) to read in. If it's a single file, then it's use for every card. If the parameter is an Array of files, then each file is looked up for each card. See {file:API.md#Specifying+Files Specifying Files}
# @param x: the x-coordinate to place # @param x: the x-coordinate to place
# @param y: the y-coordinate to place # @param y: the y-coordinate to place
# @param alpha: the alpha-transparency percentage used to blend this image # @param alpha: the alpha-transparency percentage used to blend this image
# @return [nil] intended to be void
# @api public # @api public
def png(range: :all, file: nil, x: 0, y: 0, alpha: 1.0) def png(opts = {})
range = rangeify(range) opts = needs(opts, [:range, :files, :x, :y, :alpha])
file = fileify(file) opts[:range].each do |i|
range.each{ |i| @cards[i].png(file, x, y, alpha) } @cards[i].png(opts[:file][i], opts[:x], opts[:y], opts:[alpha])
end
end end
# Renders an entire svg file at the given location. Uses the SVG-specified units and DPI to determine the pixel width and height. # Renders an entire svg file at the given location. Uses the SVG-specified units and DPI to determine the pixel width and height.
@ -32,11 +34,11 @@ module Squib
# @param height: the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. # @param height: the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document.
# @return [nil] essentially a void method # @return [nil] essentially a void method
# @api public # @api public
def svg(range: :all, file: nil, id: nil, x: 0, y: 0, width: :native, height: :native) def svg(opts = {})
range = rangeify(range) p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height])
file = fileify(file) p[:range].each do |i|
id = idify(id) @cards[i].svg(p[:file], p[:id], p[:x], p[:y], p[:width], p[:height])
range.each{ |i| @cards[i].svg(file, id, x, y, width, height) } end
end end
end end

16
lib/squib/constants.rb

@ -1,8 +1,14 @@
module Squib module Squib
module Constants
#@api public
DEFAULT_FONT = 'Arial 36 B'
end #@api public
SYSTEM_DEFAULTS = {
:range => :all,
:color => :white,
:font => 'Arial, Sans 36',
:sheet => 0,
:x => 0,
:y => 0,
:alpha => 1.0
}
end end

84
lib/squib/input_helpers.rb

@ -1,73 +1,97 @@
require 'squib/constants'
module Squib module Squib
module InputHelpers module InputHelpers
def rangeify (range) def needs(opts, params)
opts = Squib::SYSTEM_DEFAULTS.merge(opts)
opts = rangeify(opts) if params.include? :range
opts = fileify(opts) if params.include? :file
opts = fileify(opts, true) if params.include? :files
opts = colorify(opts) if params.include? :color
opts = colorify(opts, true) if params.include? :nillable_color
opts = dirify(opts) if params.include? :dir
opts = dirify(opts, true) if params.include? :creatable_dir
opts = fontify(opts) if params.include? :font
opts = radiusify(opts) if params.include? :radius
opts = svgidify(opts) if params.include? :svgid
end
module_function :needs
def rangeify (opts)
range = opts[:range]
raise 'Range cannot be nil' if range.nil? raise 'Range cannot be nil' if range.nil?
range = 0..(@cards.size-1) if range == :all range = 0..(@cards.size-1) if range == :all
range = range..range if range.is_a? Integer range = range..range if range.is_a? Integer
if range.max > (@cards.size-1) if range.max > (@cards.size-1)
raise "#{range} is outside of deck range of 0..#{@cards.size-1}" raise "#{range} is outside of deck range of 0..#{@cards.size-1}"
end end
return range opts[:range] = range
opts
end end
module_function :rangeify module_function :rangeify
def fileify(file) def fileify(opts, expand_singletons=false)
raise "File #{File.expand_path(file)} does not exist!" unless File.exists? file opts[:file] = [opts[:file]] * @cards.size if expand_singletons
file files = [opts[:file]].flatten
files.each do |file|
unless File.exists? file
raise "File #{File.expand_path(file)} does not exist!"
end
end
opts
end end
module_function :fileify module_function :fileify
def dirify(dir, allow_create: false) def dirify(opts, allow_create=false)
return dir if Dir.exists? dir return opts if Dir.exists? opts[:dir]
if allow_create if allow_create
Squib.logger.warn "PDF output dir #{dir} does not exist... attempting to create it" Squib.logger.warn "Dir #{opts[:dir]} does not exist, creating it."
Dir.mkdir dir Dir.mkdir opts[:dir]
return dir return opts
else else
raise "#{dir} does not exist!" raise "#{opts[:dir]} does not exist!"
end end
end end
module_function :dirify module_function :dirify
def colorify(color, nillable: false) def colorify(opts, nillable=false)
if nillable # for optional color arguments like text hints if nillable # for optional color arguments like text hints
color = Cairo::Color.parse(color) unless color.nil? opts[:color] = Cairo::Color.parse(opts[:color]) unless opts[:color].nil?
else else
color ||= :black opts[:color] = Cairo::Color.parse(opts[:color])
color = Cairo::Color.parse(color)
end end
color opts
end end
module_function :colorify module_function :colorify
def fontify (font) def fontify (opts)
font = @font if font==:use_set opts[:font] = @font if opts[:font]==:use_set
font = Squib::DEFAULT_FONT if font==:default opts[:font] = Squib::SYSTEM_DEFAULTS[:font] if opts[:font] ==:default
font opts
end end
module_function :fontify module_function :fontify
def radiusify(radius, x_radius, y_radius) def radiusify(opts)
if radius.nil? unless opts[:radius].nil?
return x_radius, y_radius opts[:x_radius] = opts[:radius]
else opts[:y_radius] = opts[:radius]
return radius,radius
end end
opts
end end
module_function :radiusify module_function :radiusify
def idify(svgid) def svgidify(opts)
unless svgid.nil? unless opts[:id].nil?
svgid = '#' << svgid unless svgid.start_with? '#' opts[:id] = '#' << opts[:id] unless svgid.start_with? '#'
end end
svgid opts
end end
module_function :idify module_function :idify
def xyify def xyify
#TODO: Allow negative numbers that subtract from the card width & height #TODO: Allow negative numbers that subtract from the card width & height.
end end
end end

2
samples/basic.rb

@ -5,7 +5,7 @@ data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
'level' => [1,2,3]} 'level' => [1,2,3]}
Squib::Deck.new(width: 825, height: 1125, cards: 3) do Squib::Deck.new(width: 825, height: 1125, cards: 3) do
background color: :white puts background color: :white
rect x: 38, y: 38, width: 750, height: 1050, radius: 38 rect x: 38, y: 38, width: 750, height: 1050, radius: 38
rect x: 75, y: 75, width: 128, height: 128, radius: 25 rect x: 75, y: 75, width: 128, height: 128, radius: 25

Loading…
Cancel
Save