From 6c60476e429b6ee44ad2856bc733c25cbf7cc24d Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Fri, 25 Jul 2014 01:01:41 -0400 Subject: [PATCH] Starting work on the new options --- .yardopts | 1 + API.md | 1 - README.md | 30 ++++--------- lib/squib/api/background.rb | 13 +++--- lib/squib/api/data.rb | 3 +- lib/squib/api/image.rb | 22 +++++----- lib/squib/constants.rb | 16 ++++--- lib/squib/input_helpers.rb | 84 ++++++++++++++++++++++++------------- samples/basic.rb | 2 +- 9 files changed, 97 insertions(+), 75 deletions(-) diff --git a/.yardopts b/.yardopts index 6c4981c..804b7bf 100644 --- a/.yardopts +++ b/.yardopts @@ -1,3 +1,4 @@ +--readme README.md --markup markdown --api public - diff --git a/API.md b/API.md index 0b9c2e7..2c2c7a7 100644 --- a/API.md +++ b/API.md @@ -1,4 +1,3 @@ -# @markup markdown # Squib API # Squib::Deck and Squib::Card diff --git a/README.md b/README.md index 3beaec3..feff74b 100644 --- a/README.md +++ b/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 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/) * Reading PNGs and SVGs using [Cairo](http://cairographics.org/) * Reading `.xlsx` files * Basic shape drawing -* Saving to PNGs and PDFs +* Rendering to PNGs and PDFs * Plus the full power of Ruby! +Check this out. + ```ruby require 'squib' @@ -17,6 +19,8 @@ Squib::Deck.new do end ``` +That script just created 3 PNG images at 825x1125 with the string "Hello, World" in the upper-left corner. + ## Installation Install it yourself with: @@ -31,7 +35,7 @@ And then execute: $ 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 @@ -57,25 +61,9 @@ layout.yml PNP NOTES.md ``` -The central file here is `deck.rb`. Here's a more complex 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' +The central file here is `deck.rb`. Here's a basic example of a deck to work from: - rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50 - - 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 -``` +{include:file:samples/basic.rb} ## Learning Squib's API diff --git a/lib/squib/api/background.rb b/lib/squib/api/background.rb index d7e0df3..11b3191 100644 --- a/lib/squib/api/background.rb +++ b/lib/squib/api/background.rb @@ -2,13 +2,14 @@ module Squib class Deck # 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} - # @param color: the color the font will render to. See {file:API.md#label-Specifying+Colors Specifying Colors} + # @params opts: the parameter hash. + # @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 - def background(range: :all, color: :white) - range = rangeify(range) - color = colorify(color) - range.each { |i| @cards[i].background(color) } + def background(opts = {}) + opts = needs(opts,[:range, :color]) + opts[:range].each { |i| @cards[i].background(opts[:color]) } end end diff --git a/lib/squib/api/data.rb b/lib/squib/api/data.rb index 140b24b..66a6d36 100644 --- a/lib/squib/api/data.rb +++ b/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 sheet: [Integer] The zero-based index of the sheet from which to read. # @api public - def xlsx(file: 'deck.xlsx', sheet: 0) + def xlsx(opts = {}) + needs(opts, [:file, :sheet]) s = Roo::Excelx.new(file) s.default_sheet = s.sheets[sheet] data = {} diff --git a/lib/squib/api/image.rb b/lib/squib/api/image.rb index 3892589..d81ba48 100644 --- a/lib/squib/api/image.rb +++ b/lib/squib/api/image.rb @@ -6,15 +6,17 @@ module Squib # 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 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 y: the y-coordinate to place # @param alpha: the alpha-transparency percentage used to blend this image + # @return [nil] intended to be void # @api public - def png(range: :all, file: nil, x: 0, y: 0, alpha: 1.0) - range = rangeify(range) - file = fileify(file) - range.each{ |i| @cards[i].png(file, x, y, alpha) } + def png(opts = {}) + opts = needs(opts, [:range, :files, :x, :y, :alpha]) + opts[:range].each do |i| + @cards[i].png(opts[:file][i], opts[:x], opts[:y], opts:[alpha]) + 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. @@ -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. # @return [nil] essentially a void method # @api public - def svg(range: :all, file: nil, id: nil, x: 0, y: 0, width: :native, height: :native) - range = rangeify(range) - file = fileify(file) - id = idify(id) - range.each{ |i| @cards[i].svg(file, id, x, y, width, height) } + def svg(opts = {}) + p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height]) + p[:range].each do |i| + @cards[i].svg(p[:file], p[:id], p[:x], p[:y], p[:width], p[:height]) + end end end diff --git a/lib/squib/constants.rb b/lib/squib/constants.rb index d19b562..34af675 100644 --- a/lib/squib/constants.rb +++ b/lib/squib/constants.rb @@ -1,8 +1,14 @@ 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 \ No newline at end of file diff --git a/lib/squib/input_helpers.rb b/lib/squib/input_helpers.rb index 9a88cd7..b83cfca 100644 --- a/lib/squib/input_helpers.rb +++ b/lib/squib/input_helpers.rb @@ -1,73 +1,97 @@ +require 'squib/constants' + module Squib 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? range = 0..(@cards.size-1) if range == :all range = range..range if range.is_a? Integer if range.max > (@cards.size-1) raise "#{range} is outside of deck range of 0..#{@cards.size-1}" end - return range + opts[:range] = range + opts end module_function :rangeify - def fileify(file) - raise "File #{File.expand_path(file)} does not exist!" unless File.exists? file - file + def fileify(opts, expand_singletons=false) + opts[:file] = [opts[:file]] * @cards.size if expand_singletons + 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 module_function :fileify - def dirify(dir, allow_create: false) - return dir if Dir.exists? dir + def dirify(opts, allow_create=false) + return opts if Dir.exists? opts[:dir] if allow_create - Squib.logger.warn "PDF output dir #{dir} does not exist... attempting to create it" - Dir.mkdir dir - return dir + Squib.logger.warn "Dir #{opts[:dir]} does not exist, creating it." + Dir.mkdir opts[:dir] + return opts else - raise "#{dir} does not exist!" + raise "#{opts[:dir]} does not exist!" end end module_function :dirify - def colorify(color, nillable: false) + def colorify(opts, nillable=false) 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 - color ||= :black - color = Cairo::Color.parse(color) + opts[:color] = Cairo::Color.parse(opts[:color]) end - color + opts end module_function :colorify - def fontify (font) - font = @font if font==:use_set - font = Squib::DEFAULT_FONT if font==:default - font + def fontify (opts) + opts[:font] = @font if opts[:font]==:use_set + opts[:font] = Squib::SYSTEM_DEFAULTS[:font] if opts[:font] ==:default + opts end module_function :fontify - def radiusify(radius, x_radius, y_radius) - if radius.nil? - return x_radius, y_radius - else - return radius,radius + def radiusify(opts) + unless opts[:radius].nil? + opts[:x_radius] = opts[:radius] + opts[:y_radius] = opts[:radius] end + opts end module_function :radiusify - def idify(svgid) - unless svgid.nil? - svgid = '#' << svgid unless svgid.start_with? '#' + def svgidify(opts) + unless opts[:id].nil? + opts[:id] = '#' << opts[:id] unless svgid.start_with? '#' end - svgid + opts end module_function :idify 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 diff --git a/samples/basic.rb b/samples/basic.rb index f316dfb..f7e641d 100644 --- a/samples/basic.rb +++ b/samples/basic.rb @@ -5,7 +5,7 @@ data = {'name' => ['Thief', 'Grifter', 'Mastermind'], 'level' => [1,2,3]} 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: 75, y: 75, width: 128, height: 128, radius: 25