diff --git a/.gitmodules b/.gitmodules
index 277540d..1900a30 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -12,3 +12,6 @@
[submodule "samples/autoscale_font"]
path = samples/autoscale_font
url = https://gist.github.com/andymeneely/a4536fff0f3dc5d59c66
+[submodule "samples/build_groups"]
+ path = samples/build_groups
+ url = git@gist.github.com:bda48487e3b8c9d15edb.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6cfca2e..bce08fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,8 +3,12 @@ Squib follows [semantic versioning](http://semver.org).
## v0.10.0 / Unreleased
+Features:
+* Build groups! Simplify the process of building your deck different ways (e.g. one for color, one for PNP). Can be enabled explicitly or via command line. [See our shiny new docs for how these work](http://squib.readthedocs.org).
+
Chores:
* Switched to `require_relative` internally throughout the codebase to be more pry-friendly (#130)
+* Rewrote the entire API doc and placed it on [squib.readthedocs.org](http://squib.readthedocs.org)
## v0.9.0 / 2016-01-10
diff --git a/docs/build_groups.rst b/docs/build_groups.rst
new file mode 100644
index 0000000..5f06b19
--- /dev/null
+++ b/docs/build_groups.rst
@@ -0,0 +1,47 @@
+Use Groups for Custom Builds
+============================
+
+Often in the prototyping process you'll find yourself cycling between running your overall build and building a single card. You'll probably be commenting out code in the process.
+
+And even after your code is stable, you'll probably want to build your deck multiple ways: maybe a printer-friendly black-and-white version for print-and-play and then a full color version.
+
+Squib's Build Groups help you with these situations. By grouping your Squib code into different groups, you can run parts of it at a time without having to go back and commenting out code.
+
+Here's a basic example:
+
+.. raw:: html
+
+
+
+
+
+Only one group is enabled by default: ``:all``. All other groups are disabled by default. To see which groups are enabled currently, the :doc:`/dsl/groups` returns the set.
+
+Groups can be enabled and disabled in several ways:
+
+ * The :doc:`/dsl/enable_group` and :doc:`/dsl/disable_group` DSL methods can explicitly enable/disable a group. Again, you're back to commenting out the *enable_group* call, but that's easier than remembering what lines to comment out each time.
+ * When a ``Squib::Deck`` is initialized, the `environment variable `_ ``SQUIB_BUILD`` is consulted for a comma-separated string. These are converted to Ruby symbols and the corresponding groups are enabled.
+
+Note that the environment variables are intended to change from run to run, from the command line (see above gist for examples in various OS's).
+
+.. note::
+
+ There should be no need to set the SQUIB_BUILD variable globally on your system.
+
+Don't like how Windows specifies environment variables? One adaptation of this is to do the environment setting in a ``Rakefile``. Rake is the build utility that comes with Ruby, and it allows us to set different tasks exactly in this way. This Rakefile works nicely with our above code example:
+
+
+.. raw:: html
+
+
+
+
+
+
+Thus, you can just run this code with commands like these::
+
+ $ rake
+ $ rake pnp
+ $ rake color
+ $ rake test
+ $ rake both
diff --git a/docs/dsl/disable_group.rst b/docs/dsl/disable_group.rst
new file mode 100644
index 0000000..fe2897e
--- /dev/null
+++ b/docs/dsl/disable_group.rst
@@ -0,0 +1,16 @@
+disable_group
+=============
+
+Disable the given build group for the rest of the build. Thus, code within the corresponding :doc:`/dsl/group` block will not be executed. See :doc:`/build_groups` for ways to use this effectively.
+
+
+Required Arguments
+------------------
+
+group
+ the name of the group to disable. Convention is to use a Ruby symbol.
+
+
+
+Examples
+--------
diff --git a/docs/dsl/enable_group.rst b/docs/dsl/enable_group.rst
new file mode 100644
index 0000000..afef78d
--- /dev/null
+++ b/docs/dsl/enable_group.rst
@@ -0,0 +1,16 @@
+enable_group
+=============
+
+Enable the given build group for the rest of the build. Thus, code within the corresponding :doc:`/dsl/group` block will be executed. See :doc:`/build_groups` for ways to use this effectively.
+
+
+Required Arguments
+------------------
+
+group
+ the name of the group to enable. Convention is to use a Ruby symbol.
+
+
+
+Examples
+--------
diff --git a/docs/dsl/group.rst b/docs/dsl/group.rst
new file mode 100644
index 0000000..baa3971
--- /dev/null
+++ b/docs/dsl/group.rst
@@ -0,0 +1,28 @@
+group
+=====
+
+Establish a set of commands that can be enabled/disabled together to allow for customized builds. See :doc:`/build_groups` for ways to use this effectively.
+
+Required Arguments
+------------------
+
+group
+ default: ``:all``
+
+ The name of the group. Convention is to use a Ruby symbol.
+
+
+&block
+ When this group is enabled (and only ``:all`` is enabled by default), then this block is executed. Otherwise, the block is ignored.
+
+
+Examples
+--------
+
+Use group to organize your Squib code into build groups::
+
+ Squib::Deck.new do
+ group :pnp do
+ save_pdf
+ end
+ end
diff --git a/docs/dsl/groups.rst b/docs/dsl/groups.rst
new file mode 100644
index 0000000..a84861f
--- /dev/null
+++ b/docs/dsl/groups.rst
@@ -0,0 +1,23 @@
+groups
+======
+
+Returns the set of group names that have been enabled. See :doc:`/build_groups` for ways to use this effectively.
+
+Arguments
+---------
+
+(none)
+
+
+Examples
+--------
+
+Use group to organize your Squib code into build groups::
+
+ Squib::Deck.new do
+ enable_group :pnp
+ group :pnp do
+ save_pdf
+ end
+ puts groups # outputs :all and :pnp
+ end
diff --git a/docs/index.rst b/docs/index.rst
index 80115a7..70f3aa9 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -20,6 +20,7 @@ Contents:
bleed
config
backends
+ build_groups
help
dsl/index.rst
diff --git a/docs/server.bat b/docs/server.bat
new file mode 100644
index 0000000..a8ddf46
--- /dev/null
+++ b/docs/server.bat
@@ -0,0 +1 @@
+sphinx-autobuild . _build/html
diff --git a/lib/squib/api/groups.rb b/lib/squib/api/groups.rb
new file mode 100644
index 0000000..58326ef
--- /dev/null
+++ b/lib/squib/api/groups.rb
@@ -0,0 +1,47 @@
+require 'set'
+
+module Squib
+
+ # An idea for later...
+ # def enable_group_env group
+ # ENV['SQUIB_BUILD'] ||= ''
+ # ENV['SQUIB_BUILD'] += ','
+ # ENV['SQUIB_BUILD'] += group
+ # end
+ # module_function :enable_group_env
+
+ class Deck
+
+ # See official API docs
+ def group grp = :all, &block
+ raise 'Please provide a block' unless block_given?
+ block.yield if groups.include? grp
+ end
+
+ # See official API docs
+ def enable_group grp
+ groups # make sure it's initialized
+ @build_groups << grp
+ end
+
+ # See official API docs
+ def disable_group grp
+ groups # make sure it's initialized
+ @build_groups.delete grp
+ end
+
+ # See official API docs
+ def groups
+ @build_groups ||= Set.new.add(:all)
+ end
+
+ # See official API docs
+ def enable_groups_from_env!
+ return if ENV['SQUIB_BUILD'].nil?
+ ENV['SQUIB_BUILD'].split(',').each do |grp|
+ enable_group grp.strip.to_sym
+ end
+ end
+
+ end
+end
diff --git a/lib/squib/deck.rb b/lib/squib/deck.rb
index 2f83528..af6b0a0 100644
--- a/lib/squib/deck.rb
+++ b/lib/squib/deck.rb
@@ -69,6 +69,7 @@ module Squib
@height = Args::UnitConversion.parse height, dpi
cards.times{ |i| @cards << Squib::Card.new(self, @width, @height, i) }
@layout = LayoutParser.load_layout(layout)
+ enable_groups_from_env!
if block_given?
instance_eval(&block) # here we go. wheeeee!
end
@@ -102,6 +103,7 @@ module Squib
##################
require_relative 'api/background'
require_relative 'api/data'
+ require_relative 'api/groups'
require_relative 'api/image'
require_relative 'api/save'
require_relative 'api/settings'
diff --git a/samples/build_groups b/samples/build_groups
new file mode 160000
index 0000000..064cd9e
--- /dev/null
+++ b/samples/build_groups
@@ -0,0 +1 @@
+Subproject commit 064cd9e28d522e9253df8f946755d9d2556ef56b