Permalink
Browse files

Added Rocco docs

  • Loading branch information...
1 parent 4dd60e2 commit 8befd3e92dc9378f1c61f88bb40dc2c5b3ae20c4 @ddemaree committed Mar 11, 2012
Showing with 186 additions and 41 deletions.
  1. +1 −1 .gitignore
  2. +103 −0 README.md
  3. +2 −0 Rakefile
  4. +41 −40 lib/soundwave.rb
  5. +37 −0 lib/soundwave/page.rb
  6. +2 −0 soundwave.gemspec
View
@@ -7,7 +7,7 @@ Gemfile.lock
InstalledFiles
_yardoc
coverage
-doc/
+docs/
lib/bundler/man
pkg
rdoc
View
@@ -0,0 +1,103 @@
+**Soundwave** is a tool for generating static web pages with structured data,
+with [Mustache][mo] or [Tilt][tilt] templates, and data files formatted as
+YAML or JSON. I use it to rapidly prototype blog themes, and other kinds of
+highly structured websites.
+
+[mo]:http://mustache.github.com/
+[tilt]:http://github.com/rtomayko/tilt
+
+Soundwave projects consist entirely of text files (plus images or other static assets);
+there's (currently) no plugin API or Ruby configuration interface. So long as your content
+is in the right place and formatted properly, Soundwave should just work.
+
+### Installation and usage
+
+Install Soundwave with Rubygems:
+
+ gem install soundwave
+
+Once installed, you can use Soundwave in several ways:
+
+#### From the command line
+
+Use the `soundwave` command to generate a whole site:
+
+ soundwave ./my_site ./my_site/public
+
+You can also generate a single page, and write its contents to `STDOUT`:
+
+ soundwave ./my_site/index.mustache
+
+
+#### As a Rake task
+
+Add the following to your `Rakefile`:
+
+ require 'soundwave/rake'
+ Soundwave::RakeTask.new(:pages, "./", "./public")
+
+Then you can invoke this task like so:
+
+ rake pages
+
+#### As a Rack app
+
+_This feature is still in development, and will change a lot._
+
+The `Soundwave::Server` Rack app generates a dynamic preview of your site, for easy rapid design or development. To use it, first add a `config.ru` file to your project with the following code:
+
+ require 'soundwave/server'
+ site = Soundwave::Site.new
+ run Soundwave::Server.new(site)
+
+Then you can start the server with `rackup`:
+
+ rackup
+
+Voila! Your site is now online at `http://localhost:9292`.
+
+### A Soundwave site
+
+A Soundwave site folder looks something like
+this:
+
+ my_site/
+ _data/
+ index.yml
+ about/
+ index.json
+ includes/
+ _head.mustache
+ css/
+ styles.css.scss
+ bootstrap.min.css
+ about/
+ index.mustache
+ index.mustache
+
+Files ending in `.mustache` are **page templates** written in [Mustache][mo]
+syntax. At render time, these are converted into static web pages at the
+same logical path relative to the site root: `index.mustache` becomes
+`_site/index.html`. Tilt templates (ERb, Liquid, Haml) are also supported,
+however the Mustache syntax is strongly preferred for regular web pages.
+
+**Tilt templates** are also supported (as of version 0.4.0), using the same
+`name.format.engine` naming convention followed by Ruby on Rails. In this
+example project, the file `css/styles.css.scss` is a Sass stylesheet. At render
+time, it is parsed and written to `_site/css/styles.css`. You can use any template
+engine or library supported by Tilt, including Less or CoffeeScript.
+
+Each template is (optionally) paired with a **data file**. `index.mustache`
+is rendered using the data in `_data/index.yml`, which is parsed into a simple
+locals hash that's in turn passed into `Mustache.render`. Data files can be
+written in YAML or JSON.
+
+You can also include **static files**, such as the vanilla CSS stylesheet at
+`css/bootstrap.css`. Any file whose extension isn't `.mustache` or any of the ones
+supported by Tilt (`.scss`, `.erb`, etc.) is assumed to be a static file and simply
+copied into the output directory at the same logical path.
+
+Mustache templates can include **partials**. To distinguish partials from regular
+templates (and prevent them from being rendered and copied along with everything else),
+in Soundwave, partials' filenames always begin with an underscore.
+
View
@@ -2,9 +2,11 @@
require "bundler/gem_tasks"
require 'rspec/core/rake_task'
require 'annotations/rake_task'
+require 'rocco/tasks'
RSpec::Core::RakeTask.new(:spec)
Annotations::RakeTask.new(:notes)
+Rocco::make 'docs/'
task :default => [:spec, :notes]
View
@@ -1,65 +1,66 @@
-require 'hike'
-require 'mustache'
-require 'multi_json'
+# **Soundwave** is a tool for generating static web pages with structured data,
+# with [Mustache][mo] or [Tilt][tilt] templates, and data files formatted as
+# YAML or JSON. I use it to rapidly prototype blog themes, and other kinds of
+# highly structured websites.
+#
+# Information on installing and using Soundwave can be found in the README.
+#
+# Before I forget: Soundwave is ©2012— [David Demaree](http://demaree.me),
+# released as open source software under the MIT license.
+#
+#### Prerequisites
-module Soundwave
- class Mustache < ::Mustache
- attr_reader :page
-
- def initialize(page=nil)
- @page = page
- end
+# [Hike](http://github.com/sstephenson/hike) is used to set up and query load paths.
+# We'll be using it to find partials, data files, and (in `Soundwave::Server`) templates.
+require 'hike'
- def site
- @page.site
- end
+# [MultiJson](http://github.com/intridea/multi_json) is a universal Ruby wrapper around
+# several popular JSON parsing and decoding libraries.
+require 'multi_json'
- def template
- @page.path.read
- end
+#### Public Interface
- def partial_path(name)
- name = name.to_s
- dirname = File.dirname(name)
- basename = File.basename(name)
- partialname = "_#{basename}"
- File.join(dirname, partialname)
- end
+module Soundwave
+ VERSION = '0.4.0'
- def partial(name)
- @paths ||= [@page.path.dirname, site.source.join("includes"), Dir.pwd].map(&:to_s).uniq
- @trail ||= Hike::Trail.new(@page.site.source).tap do |t|
- t.append_extension ".mustache"
- @paths.each { |p| t.append_path(p) }
- end
-
- if path = (@trail.find(partial_path(name)) || @trail.find(name.to_s))
- File.read(path)
- end
- end
- end
+ # Most major stuff in Soundwave revolves around the `Site` class. Sites are
+ # collections of templates and other files stored in a directory in the filesystem.
class Site
- attr_accessor :source, :destination
- def initialize(source="./", destination="./_site")
+ attr_accessor :source, :data_dir
+
+ # `Soundwave::Site.new` takes an optional `source` path, defaults to the current directory.
+ def initialize(source="./")
@source = Pathname(source).expand_path
+ # `data_dir` defaults to the `_data` directory under `source`.
+ @data_dir = source.join("_data")
end
+ # The aptly named `generate` takes a `destination` path for the generated web pages.
def generate(destination)
destination = Pathname(destination)
+ # TODO: Expand to handle all files, not just Mustache.
+ #
+ # First, we find all of the `.mustache` files in the project and iterate over that list.
+ # Files whose basenames start with an underscore (_) are skipped.
+ #
+ # Next, we create a [Page](./soundwave/page.html) object for each file and write it to
+ # the destination path.
Dir[source.join("**","*.mustache")].each do |path|
next if File.basename(path).to_s =~ /^_/
+
page = Page.new(self, path)
page.write(destination.join(page.output_path))
end
end
+ private
+
def data_trail
- @_data_path ||= Hike::Trail.new(source.join("_data")).tap do |t|
+ @_data_path ||= Hike::Trail.new(data_dir).tap do |t|
t.append_path "."
- t.append_extension ".json"
- t.append_extension ".yml", ".yaml"
+ t.extensions.replace([".json", ".yml", ".yaml"])
end
end
end
View
@@ -1,7 +1,44 @@
require 'soundwave'
require 'tilt'
+require 'mustache'
module Soundwave
+ class Mustache < ::Mustache
+ attr_reader :page
+
+ def initialize(page=nil)
+ @page = page
+ end
+
+ def site
+ @page.site
+ end
+
+ def template
+ @page.path.read
+ end
+
+ def partial_path(name)
+ name = name.to_s
+ dirname = File.dirname(name)
+ basename = File.basename(name)
+ partialname = "_#{basename}"
+ File.join(dirname, partialname)
+ end
+
+ def partial(name)
+ @paths ||= [@page.path.dirname, site.source.join("includes"), Dir.pwd].map(&:to_s).uniq
+ @trail ||= Hike::Trail.new(@page.site.source).tap do |t|
+ t.append_extension ".mustache"
+ @paths.each { |p| t.append_path(p) }
+ end
+
+ if path = (@trail.find(partial_path(name)) || @trail.find(name.to_s))
+ File.read(path)
+ end
+ end
+ end
+
class Page
attr_reader :site, :path
attr_accessor :data
View
@@ -22,6 +22,8 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency "hike"
gem.add_runtime_dependency "tilt"
+ gem.add_development_dependency "rocco"
+ gem.add_development_dependency "redcarpet", "~> 1.7.0"
gem.add_development_dependency "rack"
gem.add_development_dependency "annotations"
gem.add_development_dependency "bundler"

0 comments on commit 8befd3e

Please sign in to comment.