commit 2c93887e5fd35daf3ad3a97afae862817e1badd5 Author: John Bintz Date: Wed Oct 9 22:51:03 2013 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d87d4be --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c212bba --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in nandeck-ruby.gemspec +gemspec diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..8ad8cf3 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013 John Bintz + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a5f8f4 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# Build nanDECK directive files in Ruby + +[nanDECK](http://www.nand.it/nandeck/) is a tool used by game designers to build +decks of cards quickly using a series of drawing directives. There's some abiliity +for iterating over data and using variables, but not with the same flexibility +that a full-blown scripting language like Ruby can offer. `nandeck-ruby` provides +a series of primitives, composite objects, and boilerplate classes that let you +quickly build nanDECK files from a set of data from, say, a Google Drive +spreadsheet. + +## Usage + +``` ruby +require 'nandeck' + +class Card + def self.width + 2.5 + end + + def self.height + 3.5 + end + + def self.border + 0.125 + end + + def self.real_border + border * 2 + end + + def self.pixel + 0.03 + end +end + +output = [] +output += Nandeck::CardSize.new(300, Card.width, Card.height).to_a +output += Nandeck::PageSize.new(8.5, 11, :portrait).to_a +output += Nandeck::Margins.new(0.5, 0.25).to_a +output << "OVERSAMPLE = 2" +output << "IMAGEFILTER = Lanczos" + +output << Nandeck::Rectangle.new(1, 0, 0, Card.width, Card.height, '#000000', '#ffffff', Card.border) +output << Nandeck::Image.new(1, "images/background.png", 0, 0, Card.width, Card.height, flag: 'P', alpha_channel: "10@270") + +area = Nandeck::Geometry.new(Card.border + 0.05, Card.real_border + 0.05, 0.688, 0.640) +output << Nandeck::Image.new(1, "images/balloon.png", *balloon.to_a) + +Nandeck::Font.for(typeface: "Tahoma", flag: 'T') do |font| + height = 0.41 + + font.for(size: inches_to_points(height), color: "#000000") do |balloon_font| + x, y = balloon.center.to_a + + output << balloon_font.text(1, "5", x - height / 2 - 0.10, y - height / 2 - 0.10, height + 0.20, height) + end +end + +line_height = 14 + +Nandeck::Font.for typeface: "Tahoma", size: line_height, flag: "TB", color: '#000000' do |font| + font.for color: '#ffffff' do |outline| + output << Nandeck::TextBlock.new(1, outline, "name", 16, 0.90, Card.real_border + 0.1, Card.width - Card.real_border - 1.00, 0.38, outline: Card.pixel * 2) + end + + output << Nandeck::TextBlock.new(1, font, "name", 16, 0.90, Card.real_border + 0.1, Card.width - Card.real_border - 1.00, 0.38) +end + +File.open("output.txt", "w") do |fh| + fh.print output.collect(&:to_s).join("\n") +end +``` + diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..2995527 --- /dev/null +++ b/Rakefile @@ -0,0 +1 @@ +require "bundler/gem_tasks" diff --git a/lib/nandeck.rb b/lib/nandeck.rb new file mode 100644 index 0000000..80f950f --- /dev/null +++ b/lib/nandeck.rb @@ -0,0 +1,18 @@ +require "nandeck/version" +require 'nandeck/conversions' +require 'nandeck/primitive' + +require 'nandeck/definitions/card_size' +require 'nandeck/definitions/geometry' +require 'nandeck/definitions/margins' +require 'nandeck/definitions/page_size' + +require 'nandeck/primitives/font' +require 'nandeck/primitives/image' +require 'nandeck/primitives/line' +require 'nandeck/primitives/rectangle' +require 'nandeck/primitives/text_block' + +module Nandeck + # Your code goes here... +end diff --git a/lib/nandeck/conversions.rb b/lib/nandeck/conversions.rb new file mode 100644 index 0000000..559751f --- /dev/null +++ b/lib/nandeck/conversions.rb @@ -0,0 +1,19 @@ +module Nandeck + module Conversions + def point_to_pixel(point) + point * 300.0 / 72.0 + end + + def pixel_to_point(pixel) + pixel * 72.0 / 300.0 + end + + def inches_to_points(inch) + inch * 72.0 + end + + def points_to_inches(point) + point / 72.0 + end + end +end diff --git a/lib/nandeck/definitions/card_size.rb b/lib/nandeck/definitions/card_size.rb new file mode 100644 index 0000000..7cd2462 --- /dev/null +++ b/lib/nandeck/definitions/card_size.rb @@ -0,0 +1,17 @@ +module Nandeck + class CardSize + def initialize(dpi, width, height) + @dpi, @width, @height = dpi, width, height + end + + def to_a + output = [] + output << "UNIT = INCH" + output << "CARDSIZE = #{@width}, #{@height}" + output << "BORDER = NONE" + output << "DPI = #{@dpi}" + output + end + end +end + diff --git a/lib/nandeck/definitions/geometry.rb b/lib/nandeck/definitions/geometry.rb new file mode 100644 index 0000000..6d4ae97 --- /dev/null +++ b/lib/nandeck/definitions/geometry.rb @@ -0,0 +1,16 @@ +module Nandeck + class Geometry + def initialize(x, y, width, height) + @x, @y, @width, @height = x, y, width, height + end + + def to_a + [ @x, @y, @width, @height ] + end + + def center + [ @x + @width / 2, @y + @height / 2 ] + end + end +end + diff --git a/lib/nandeck/definitions/margins.rb b/lib/nandeck/definitions/margins.rb new file mode 100644 index 0000000..ef0c265 --- /dev/null +++ b/lib/nandeck/definitions/margins.rb @@ -0,0 +1,14 @@ +module Nandeck + class Margins + def initialize(left_right, top_bottom) + @left_right, @top_bottom = left_right, top_bottom + end + + def to_a + output = [] + output << "MARGINS = #{@left_right}, #{@left_right}, #{@top_bottom}, #{@top_bottom}" + output + end + end +end + diff --git a/lib/nandeck/definitions/page_size.rb b/lib/nandeck/definitions/page_size.rb new file mode 100644 index 0000000..e0b29cf --- /dev/null +++ b/lib/nandeck/definitions/page_size.rb @@ -0,0 +1,14 @@ +module Nandeck + class PageSize + def initialize(width, height, orientation) + @width, @height, @orientation = width, height, orientation + end + + def to_a + output = [] + output << "PAGE = #{@width}, #{@height}, #{@orientation}" + output + end + end +end + diff --git a/lib/nandeck/primitive.rb b/lib/nandeck/primitive.rb new file mode 100644 index 0000000..f6d4f16 --- /dev/null +++ b/lib/nandeck/primitive.rb @@ -0,0 +1,34 @@ +module Nandeck + class Primitive + include Conversions + + def initializs(card_index) + @card_index = card_index + end + + def card_indexes + return @card_indexes if @card_indexes + + @card_indexes = [] + + @card_index.split(',').collect(&:strip).each do |part| + if part['-'] + + else + @card_indexes << part + end + end + + @card_indexes + end + + def to_s + raise "Override me" + end + + def geometry + "#{@x}, #{@y}, #{@width}, #{@height}" + end + end +end + diff --git a/lib/nandeck/primitives/font.rb b/lib/nandeck/primitives/font.rb new file mode 100644 index 0000000..5c8953a --- /dev/null +++ b/lib/nandeck/primitives/font.rb @@ -0,0 +1,55 @@ +module Nandeck + class Font + def self.for(settings) + yield new(settings) + end + + def initialize(settings) + @settings = settings + end + + def for(settings) + yield self.class.new(@settings.merge(settings)) + end + + def size + @settings[:size] + end + + def write + @writing = true + @given_font_definition = false + + yield + + @writing = false + end + + def text(card_index, text, x, y, width, height, options = {}) + options = { + horizontal: :center, + vertical: :wwcenter, + angle: 0, + alpha: 100, + outline: nil + }.merge(options) + + text = %{TEXT = #{card_index}, "#{text}", #{x}, #{y}, #{width}, #{height}, #{options[:horizontal]}, #{options[:vertical]}, #{options[:angle]}, #{options[:alpha]}} + if options[:outline] + text << %{, #{options[:outline]}} + end + + output = '' + + if !@writing || !@given_font_definition + output << %{FONT = #{@settings[:typeface]}, #{@settings[:size]}, #{@settings[:flag]}, #{@settings[:color]}\n} + @given_font_definition = true + end + + output << text + + output + end + end +end + diff --git a/lib/nandeck/primitives/image.rb b/lib/nandeck/primitives/image.rb new file mode 100644 index 0000000..8269b81 --- /dev/null +++ b/lib/nandeck/primitives/image.rb @@ -0,0 +1,20 @@ +module Nandeck + class Image < Primitive + attr_reader :card_index, :filename, :x, :y, :width, :height, :options + + def initialize(card_index, filename, x, y, width, height, options = {}) + options = { + angle: 0, + flag: "PN", + alpha_channel: 100 + }.merge(options) + + @card_index, @filename, @x, @y, @width, @height, @options = card_index, filename, x, y, width, height, options + end + + def to_s + %{IMAGE = #{@card_index}, "#{@filename}", #{geometry}, #{@options[:angle]}, #{@options[:flag]}, #{@options[:alpha_channel]}} + end + end +end + diff --git a/lib/nandeck/primitives/line.rb b/lib/nandeck/primitives/line.rb new file mode 100644 index 0000000..6f43c1b --- /dev/null +++ b/lib/nandeck/primitives/line.rb @@ -0,0 +1,12 @@ +module Nandeck + class Line < Primitive + def initialize(card_index, x, y, width, height, color, thickness) + @card_index, @x, @y, @width, @height, @color, @thickness = card_index, x, y, width, height, color, thickness + end + + def to_s + %{LINE = #{@card_index}, #{geometry}, #{@color}, #{@thickness}} + end + end +end + diff --git a/lib/nandeck/primitives/rectangle.rb b/lib/nandeck/primitives/rectangle.rb new file mode 100644 index 0000000..00ef56b --- /dev/null +++ b/lib/nandeck/primitives/rectangle.rb @@ -0,0 +1,12 @@ +module Nandeck + class Rectangle < Primitive + def initialize(card_index, x, y, width, height, border_color, fill_color = "EMPTY", border_width = "0") + @card_index, @x, @y, @width, @height, @border_color, @fill_color, @border_width = card_index, x, y, width, height, border_color, fill_color, border_width + end + + def to_s + %{RECTANGLE = #{@card_index}, #{geometry}, #{@border_color}, #{@fill_color}, #{@border_width}} + end + end +end + diff --git a/lib/nandeck/primitives/text_block.rb b/lib/nandeck/primitives/text_block.rb new file mode 100644 index 0000000..9244e7d --- /dev/null +++ b/lib/nandeck/primitives/text_block.rb @@ -0,0 +1,63 @@ +module Nandeck + class TextBlock < Primitive + def initialize(card_index, font, text, character_break, x, y, width, height, options = {}) + @card_index, @font, @text, @character_break, @x, @y, @width, @height = card_index, font, text, character_break, x, y, width, height + + @options = { + line_height: font.size, + line_height_adjustment: 0, + outline: nil + }.merge(options) + end + + def line_height + @options[:line_height] + end + + def line_height_adjustment + @options[:line_height_adjustment] + end + + def line_height_inches + points_to_inches(line_height) + end + + def to_s + sy = (@height - (lines.length * line_height_inches) / 2) - line_height_inches + y = 0 + + output = [] + + @font.write do + lines.each do |line| + if line.length != 0 + output << @font.text(@card_index, line.join(' '), @x, @y + sy + y, @width, points_to_inches(line_height) * 2, { vertical: :top }.merge(@options) ) + end + + y += points_to_inches(line_height + line_height_adjustment) + end + end + + output.join("\n") + "\n" + end + + def lines + return @lines if @lines + + words = @text.to_s.split(' ') + + @lines = [ [] ] + + while !words.empty? + if @lines.last.join(' ').length + words.first.length > @character_break + @lines << [] + end + + @lines.last << words.shift + end + + @lines + end + end +end + diff --git a/lib/nandeck/version.rb b/lib/nandeck/version.rb new file mode 100644 index 0000000..ff79dda --- /dev/null +++ b/lib/nandeck/version.rb @@ -0,0 +1,3 @@ +module Nandeck + VERSION = "0.0.1" +end diff --git a/nandeck.gemspec b/nandeck.gemspec new file mode 100644 index 0000000..36a99a3 --- /dev/null +++ b/nandeck.gemspec @@ -0,0 +1,19 @@ +# -*- encoding: utf-8 -*- +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'nandeck/version' + +Gem::Specification.new do |gem| + gem.name = "nandeck" + gem.version = Nandeck::VERSION + gem.authors = ["John Bintz"] + gem.email = ["john@coswellproductions.com"] + gem.description = %q{Ruby classes to make nanDECK directive file seasier to generate.} + gem.summary = %q{Ruby classes to make nanDECK directive file seasier to generate.} + gem.homepage = "" + + gem.files = `git ls-files`.split($/) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.require_paths = ["lib"] +end