Browse Source

Tons of documentation work

dev
Andy Meneely 12 years ago
parent
commit
d34e4729ce
  1. 6
      .yardopts
  2. 52
      API.md
  3. 81
      README.md
  4. 7
      Rakefile
  5. 12
      lib/squib/api/background.rb
  6. 8
      lib/squib/api/data.rb
  7. 17
      lib/squib/api/image.rb
  8. 11
      lib/squib/api/save.rb
  9. 8
      lib/squib/api/settings.rb
  10. 3
      lib/squib/api/shapes.rb
  11. 35
      lib/squib/api/text.rb
  12. 14
      lib/squib/api/units.rb
  13. 3
      lib/squib/constants.rb
  14. 27
      lib/squib/deck.rb
  15. 2
      lib/squib/graphics/text.rb
  16. 10
      lib/squib/input_helpers.rb
  17. 2
      samples/basic.rb
  18. 7
      samples/hello-world.rb
  19. 15
      samples/ranges.rb
  20. 14
      samples/units.rb
  21. 2
      squib.gemspec

6
.yardopts

@ -0,0 +1,6 @@
--markup markdown
--api public
-
API.md
LICENSE.txt
samples/**/*.rb

52
API.md

@ -0,0 +1,52 @@
# @markup markdown
# Squib API
# Squib::Deck and Squib::Card
Squib essentially has two main classes: `Deck` and `Card`. `Deck` is the front-end, and `Card` is the back-end. The contract of `Deck` is to do the various manipulations of options and then delegate the operation to `Card` to do the low-level graphical operations.
For most users, I recommending solely using `Deck` methods. If you want to roll up your sleeves and get your hands messy, you can access the Cairo or Pango contexts the directly via the `Card` class.
# Specifying Parameters
Squib makes extensive use of [Ruby 2.0's named parameters](http://www.ruby-doc.org/core-2.0.0/doc/syntax/calling_methods_rdoc.html#label-Keyword+Arguments). This means you can specify your parameters in any order you please. In fact, with named parameters you *must* specify which argument ties to which parameter. If you get an error like this:
```cmd
C:/Ruby200/lib/ruby/gems/2.0.0/gems/squib-0.0.2/lib/squib/api/text.rb:17:in `text': wrong number of arguments (1 for 0)
(ArgumentError)
from hello-world.rb:5:in `block in <main>'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/squib-0.0.2/lib/squib/deck.rb:21:in `instance_eval'
from C:/Ruby200/lib/ruby/gems/2.0.0/gems/squib-0.0.2/lib/squib/deck.rb:21:in `initialize'
from hello-world.rb:4:in `new'
from hello-world.rb:4:in `<main>'
```
...then you're not specifying the parameters explicitly (e.g. the above example was with `text 'X'` instead of `text str: 'X'`)
All parameters are optional. For example `x` and `y` default to 0 (i.e. the upper-left corner of the card).
Any parameter that is specified in the command overrides any Squib defaults, `config.yml` settings, or layout rules.
# Specifying Ranges
All public `Deck` methods allow a range to be specified as a first parameter. This parameter is used to access an internal `Array` of `Squib::Cards`. This can be an actual Ruby range, or anything that implements `#each` (thus can be an `Enumerable`). Integers are also supported for changing one card only. Negatives work from the back of the deck. Here are some examples from `samples/ranges.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/ranges.rb)
{include:file:samples/ranges.rb}
Many more examples can be found in `ranges.rb` in the [samples]() folder . In particular, take a look at some idioms that uses hashes to denote things like card "types", or future-proofing against creating and deleting cards with an ID column.
# Pixels and Other Units
By default, Squib thinks in pixels. This decision was made so that we can have pixel-perfect layouts without automatically scaling everything, even though working in units is sometimes easier. To convert, we provide the `Deck#inch` method, as shown in
`samples/units.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/units.rb)
# Specifying Colors
Squib uses the `rcairo` [color parser](https://github.com/rcairo/rcairo/blob/master/lib/cairo/color.rb) to accepts a variety of color specifications, along with over [300 pre-defined constants](https://github.com/rcairo/rcairo/blob/master/lib/cairo/colors.rb). Here are some examples from `samples/colors.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/colors.rb)
{include:file:samples/colors.rb}
# Specifying Files
All files opened for reading (e.g. for `png` and `xlsx`) are opened relative to the current directory.

81
README.md

@ -1,24 +1,20 @@
# 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)
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 complex text rendering, reading PNGs and SVGs, reading from ExcelX files, and shape drawing. Plus, you have the full power of Ruby behind you.
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:
Check it out!
* 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
* Plus the full power of Ruby!
```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
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
Squib::Deck.new do
text str: 'Hello, World!'
save_png
end
```
@ -36,18 +32,65 @@ Or install it yourself as:
$ gem install squib
Note: Squib has some native dependencies, such as [Cairo](https://github.com/rcairo/rcairo) and [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 *highly* recommend using [http://rubyinstaller.org/].
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/
## Development
## Getting Started
After installing Squib, you can create a project and run your first build like this:
```sh
$ squib new my-cool-game
$ cd my-cool-game
$ ruby deck.rb
```
Squib is currently in pre-release alpha, so the API is still maturing. If you are using Squib, however, I'd love to hear about it! Feel free to [file a bug](https://github.com/andymeneely/squib/issues) if you find any.
The `squib new` command will generate files and folders like this:
```
_output
gitkeep.txt
.gitignore
ABOUT.md
config.yml
deck.rb
Gemfile
layout.yml
PNP NOTES.md
```
## API
The central file here is `deck.rb`. Here's a more complex example of a deck to work from:
API docs to be written. The `samples` directory for in-depth examples.
```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
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
* The `samples` directory in the [source repository](https://github.com/andymeneely/squib) has lots of examples
* The [API.md]() walks through the various methods and options
* [API Documentation](http://rubydoc.info/gems/squib/) is also kept up-to-date.
## Development
Squib is currently in pre-release alpha, so the API is still maturing. If you are using Squib, however, I'd love to hear about it! Feel free to [file a bug or feature request](https://github.com/andymeneely/squib/issues).
## Contributing
Squib is an open source tool, and I would love participation. If you want your code integrated:
1. Fork it ( https://github.com/[my-github-username]/squib/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)

7
Rakefile

@ -1,6 +1,11 @@
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'yard'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec
task :default => :spec
YARD::Rake::YardocTask.new(:doc) do |t|
t.files = ['lib/**/*.rb', 'samples/**/*.rb'] # optional
#t.options = ['--any', '--extra', '--opts'] # optional
end

12
lib/squib/api/background.rb

@ -1,13 +1,11 @@
module Squib
class Deck
#module API
def background(range: :all, color: :black)
range = rangeify(range)
color = colorify(color)
range.each { |i| @cards[i].background(color) }
end
def background(range: :all, color: :black)
range = rangeify(range)
color = colorify(color)
range.each { |i| @cards[i].background(color) }
end
#end
end
end

8
lib/squib/api/data.rb

@ -3,10 +3,18 @@ require 'roo'
module Squib
class Deck
#@api private todo
def csv(file: 'deck.csv', header: true)
raise 'Not implemented!'
end
# Convenience method for pulling Excel data from `.xlsx` files
# Pulls the data into a Hash of arrays based on the columns. First row is assumed to be the header row.
# See the example at {file:samples/excel.rb samples/excel.rb}. The accompanying Excel file is in the [source repository](https://github.com/andymeneely/squib/tree/master/samples)
#
# @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)
s = Roo::Excelx.new(file)
s.default_sheet = s.sheets[sheet]

17
lib/squib/api/image.rb

@ -1,12 +1,29 @@
module Squib
class Deck
# Renders a png file at the given location.
# See {file:samples/image.rb samples/image.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
# Note: scaling not currently supported.
#
# @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 x: the x-coordinate to place
# @param y: the y-coordinate to place
# @param alpha: the alpha-transparency percentage used to blend this image
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) }
end
# Renders an entire svg file at the given location. Uses the SVG-specified units and DPI to determine the pixel width and height.
# See {file:samples/image.rb samples/image.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
# Note: scaling not currently supported.
#
# @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 x: the x-coordinate to place
# @param y: the y-coordinate to place
def svg(range: :all, file: nil, x: 0, y: 0)
range = rangeify(range)
file = fileify(file)

11
lib/squib/api/save.rb

@ -1,12 +1,23 @@
module Squib
class Deck
# Saves the range of cards to either PNG or PDF
#
# @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges}
# @param dir: the directory for the output to be sent to. Will be created if it doesn't exist
# @param format: the format that this will be rendered too. Options `:pdf, :png`. Array of both is allowed: `[:pdf, :png]`
# @param prefix: the prefix of the file name to be printed
def save(range: :all, dir: "_output", format: :png, prefix: "card_")
format = [format].flatten
save_png(range: range, dir: dir, prefix: prefix) if format.include? :png
save_pdf if format.include? :pdf
end
# Saves the range of cards to PNG
#
# @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges}
# @param dir: the directory for the output to be sent to. Will be created if it doesn't exist
# @param prefix: the prefix of the file name to be printed
def save_png(range: :all, dir: "_output", prefix: 'card_')
range = rangeify(range); dir = dirify(dir, allow_create: true)
range.each { |i| @cards[i].save_png(i, dir, prefix) }

8
lib/squib/api/settings.rb

@ -1,7 +1,15 @@
module Squib
class Deck
# Toggle hints globally.
# Text hints are rectangles around where the text will be laid out. They are intended to be temporary.
# Setting a hint to nil or to :off will disable hints. @see samples/text.rb
#
# @param [Color] text the color of the text hint. To turn off use nil or :off. @see API.md
# @return nil
# @api public
def hint(text: nil)
text = nil if text == :off
@text_hint = colorify(text, nillable: true)
end

3
lib/squib/api/shapes.rb

@ -2,9 +2,10 @@ module Squib
class Deck
def rect(range: :all, x: 0, y: 0, width: 825, height: 1125, \
x_radius: 0, y_radius: 0, color: :black)
radius: 0, x_radius: 0, y_radius: 0, color: :black)
range = rangeify(range)
color = colorify(color)
x_radius,y_radius = radiusify(radius, x_radius, y_radius)
range.each do |i|
@cards[i].draw_rectangle(x, y, width, height, x_radius, y_radius, color)
end

35
lib/squib/api/text.rb

@ -1,25 +1,48 @@
module Squib
class Deck
# @api private todo
def font(type: 'Arial', size: 12, **options)
raise 'Not implemented!'
end
# @api private todo
def set_font(type: 'Arial', size: 12, **options)
raise 'Not implemented!'
end
#
# font: description string, including family, styles, and size.
# Renders a string at a given location, width, alignment, font, etc.
# Unix-like newlines are interpreted even on Windows. See the {file:samples/text-options.rb samples/text.rb} for a lengthy example.
#
# => e.g. 'Arial bold italic 12'
# For the official documentation the string, see the [Pango docs](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3AFontDescription#style).
# This [description](http://www.pygtk.org/pygtk2reference/class-pangofontdescription.html) is also quite good.
# @param range: the range of cards over which this will be rendered. See {file:API.md#label-Specifying+Ranges Specifying Ranges}
# @param str: the string to be rendered. Must support `#to_s`.
# @param font: the Font description string, including family, styles, and size.
# (e.g. `'Arial bold italic 12'`)
# For the official documentation, see the [Pango docs](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3AFontDescription#style).
# This [description](http://www.pygtk.org/pygtk2reference/class-pangofontdescription.html) is also quite good.
# See the {file:samples/text-options.rb samples/text.rb} as well.
# @param x: the x-coordinate to place
# @param y: the y-coordinate to place
# @param color: (default: :black) the color the font will render to. See {file:API.md#label-Specifying+Colors Specifying Colors}
# @param markup: [Boolean] (default: false) Enable markup parsing of `str` using the HTML-like Pango Markup syntax, defined [here](http://ruby-gnome2.sourceforge.jp/hiki.cgi?pango-markup) and [here](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html).
# @param width: the width of the box the string will be placed in. Stretches to the content by default.
# @param height: the height of the box the string will be placed in. Stretches to the content by default.
# @param wrap: When height is set, determines the behavior of how the string wraps. The `:word_char` option will break at words, but then fall back to characters when the word cannot fit. #
# Options are `:none, :word, :char, :word_char`. Also: `true` is the same as `:word_char`, `false` is the same as `:none`. Default `:word_char`
# @param fitxy: sets the text `width` and `height` to be equal to `width - x` and `height - y` for easy centering
# @param align: options `:left, :right, and :center`. Default `:left`
# @param justify: [Boolean] toggles whether or not the text is justified or not. Default `false`
# @param valign: When width and height are set, align text vertically according to the logical extents of the text. Options are `:top, :middle, :bottom`. Default `:top`
# @param ellipsize: When width and height are set, determines the behavior of overflowing text. Options are `:none, :start, :middle, :end`. Also: `true` maps to `:end` and `false` maps to `:none`. Default `:end`
# @param hint: show a text hint with the given color. Overrides global hints (see {Deck#hint}).
#
# @api public
def text(range: :all, str: '', font: :use_set, x: 0, y: 0, **options)
range = rangeify(range)
str = [str] * @cards.size unless str.respond_to? :each
font = fontify(font)
color = colorify(options[:color], nillable: false)
options['hint'] = colorify(options['hint']) unless options['hint'].nil?
options[:hint] = colorify(options[:hint]) unless options[:hint].nil?
range.each do |i|
cards[i].text(str[i], font, x, y, color, options)
end

14
lib/squib/api/units.rb

@ -0,0 +1,14 @@
module Squib
class Deck
# Given inches, returns the number of pixels according to the deck's DPI.
#
# @param [Decimal] n, the number of inches
# @return [Decimal] the number of pixels, according to the deck's DPI
# @api public
def inches(n)
@dpi * n
end
end
end

3
lib/squib/constants.rb

@ -1,7 +1,8 @@
module Squib
module Constants
DEFAULT_FONT = 'Arial 36'
#@api public
DEFAULT_FONT = 'Arial 36 B'
end
end

27
lib/squib/deck.rb

@ -3,7 +3,15 @@ require 'squib/card'
require 'squib/input_helpers'
require 'squib/constants'
# The project module
#
# @api public
module Squib
# The main interface to Squib. Provides a front-end porcelain whereas the Card class interacts with the graphics plumbing.
#
# @api public
class Deck
include Enumerable
include Squib::InputHelpers
@ -12,9 +20,12 @@ module Squib
attr_reader :cards
attr_reader :text_hint
def initialize(width: 825, height: 1125, cards: 1, config: 'config.yml', &block)
# Squib's constructor that sets the immutable properties.
#
# @api public
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', &block)
@width=width; @height=height
@dpi = 300
@dpi = dpi
@font = 'Sans 36'
@cards = []
cards.times{ @cards << Squib::Card.new(self, width, height) }
@ -24,20 +35,21 @@ module Squib
end
end
# API: Accesses the array of cards in the deck
# Directly accesses the array of cards in the deck
#
# @api public
def [](key)
@cards[key]
end
# Public: Accesses each card of the array in the deck
# @api
# Iterates over each card in the deck
#
# @api public
def each(&block)
@cards.each { |card| block.call(card) }
end
# Internal: Load the configuration file, if exists,
# overriding hardcoded defaults
# Load the configuration file, if exists, overriding hardcoded defaults
# @api private
def load_config(file)
if File.exists? file
@ -57,6 +69,7 @@ module Squib
require 'squib/api/settings'
require 'squib/api/shapes'
require 'squib/api/text'
require 'squib/api/units'
end
end

2
lib/squib/graphics/text.rb

@ -34,6 +34,8 @@ module Squib
:char => Pango::Layout::WRAP_CHAR,
:word_char => Pango::Layout::WRAP_WORD_CHAR,
true => Pango::Layout::WRAP_WORD_CHAR,
false => nil,
:none => nil
}
layout.wrap = h[options[:wrap]]
end

10
lib/squib/input_helpers.rb

@ -49,6 +49,16 @@ module Squib
end
module_function :fontify
def radiusify(radius, x_radius, y_radius)
unless radius.nil?
ret_x = radius
ret_y = radius
end
ret_x = x_radius unless x_radius.nil?
rex_y = y_radius unless y_radius.nil?
return ret_x,ret_y
end
def xyify
#TODO: Allow negative numbers that subtract from the card width & height
end

2
samples/basic.rb

@ -16,7 +16,7 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
png range: [0,2], file: 'shiny-purse.png', x: 620, y: 75
svg range: 1..2, file: 'spanner.svg', x: 620, y: 218
save format: :png
save prefix: 'basic_', format: :png
end
puts "Done!"

7
samples/hello-world.rb

@ -0,0 +1,7 @@
#!/usr/bin/env ruby
require 'squib'
Squib::Deck.new do
text str: 'Hello, World!'
save_png
end

15
samples/ranges.rb

@ -12,15 +12,24 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
text str: data['level'], x: 65, y: 40, font: 'Arial 72'
# Could be explicit about using :all, too
text range: :all, str: data['type'], x: 50, y: 128, font: 'Arial 18'
text range: :all,
str: data['type'], x: 40, y: 128, font: 'Arial 18',
width: 100, align: :center
# Ranges are inclusive
# Ranges are inclusive, zero-based
text range: 0..1, str: "Thief and Grifter only!!", x: 25, y:200
# Integers are also allowed
text range: 0, str: "Thief only!", x: 25, y: 250
# Negatives go from the back of the deck
text range: -1, str: "Mastermind only!", x: 25, y: 250
text range: -2..-1, str: "Grifter and Mastermind only!", x: 25, y: 650
# We can use Arrays too!
text range: [0,2], str: "Thief and Mastermind only!!", x: 25, y:300
# Useful idiom: construct a hash from card names back to id,
# Useful idiom: construct a hash from card names back to its index (ID),
# then use a range. No need to memorize IDs, and you can add cards easily
id = {} ; data['name'].each_with_index{ |name,i| id[name] = i}
text range: id['Thief']..id['Grifter'],

14
samples/units.rb

@ -0,0 +1,14 @@
require 'squib'
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
background color: :white
bleed = inches(0.125)
cut_width = inches(2.5)
cut_height = inches(3.5)
rect x: bleed, y: bleed, width: cut_width, height: cut_height, radius: 25
save prefix: 'units_', format: :png
end
puts "Done!"

2
squib.gemspec

@ -36,4 +36,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "yard"
end

Loading…
Cancel
Save