Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tag: v0.1
Fetching contributors…

Cannot retrieve contributors at this time

executable file 243 lines (213 sloc) 7.983 kB
#!/usr/bin/env ruby
# The MIT License
#
# Copyright (c) 2011 Ryan Funduk, David Francisco
#
# 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.
#
# First install the dependencies (it may take some minutes):
# gem install watchr
# gem install thin
# Then execute the following command:
# ./watch [options]
# (if don't have execute permission, try "ruby watch")
#
require 'rubygems'
require 'optparse'
require 'watchr'
require 'thin'
require 'erb'
require 'rake'
# Default options
$settings = {
:source => 'slideshow',
:master => 'master.html',
:live => true,
:output => 'slideshow.html',
:multiple => false,
:port => 7000,
:binding => "0.0.0.0"
}
$partials = 0
module Builder
# This module is based on a blog post by Ryan Funduk
# To see the original source visit http://ryanfunduk.com/simple-partials/
def self.write_output(filename, result)
if $settings[:output] && !$settings[:multiple]
filename = $settings[:output]
else
# If there are N .html files in the source folder (excluding the partials), the result will be N html files
ext = filename.split('.').last
filename = filename.split '/'
filename.delete $settings[:source]
filename.insert -2, ext unless ext == 'html'
filename = filename.join '/'
result.gsub! /V%/, '<%'
result.gsub! /%V/, '%>'
end
f = File.open(filename, 'wb')
f.write(result)
f.close
puts "wrote : #{filename}"
end
def self.partial(name)
filename = "#{$settings[:source]}/#{name}.partial"
if File.exists? filename
$partials += 1
puts "loaded : #{name}.partial"
f = File.open(filename, 'rb')
# _partial_ is the var where the result is stored, since we're inside a ERB.new already!
# The rand() was added in case partials contain partials themselves too
page = ERB.new(f.read, nil, nil, "_partial_#{rand(2010)}") # TODO add collision detection
f.close
result = page.result
else
# puts "error : #{filename}"
result = ""
end
result
rescue
puts "error : #{filename}"
""
end
# Build the compiled html file that includes the layout and all partials
def self.build
$partials = 0
if !$settings[:multiple]
# If the result should be only one html file, then only one .html should exist
sources = ["#{$settings[:source]}/#{$settings[:master]}"]
else
sources = FileList["#{$settings[:source]}/*.*"].exclude("#{$settings[:source]}/*.partial")
end
puts "\n"
sources.each do |source|
puts "compiling : #{source}"
f = File.open(source, 'rb')
page = ERB.new(f.read)
f.close
write_output source, page.result
end
puts "done : Compiled #{sources.size} sources w/ #{$partials} partials."
rescue
puts "error : Compiling master file."
end
end
module Options
$optparse
# Check if the specified options are valid
def self.valid_options?
dir_exists = File.directory? $settings[:source]
if !dir_exists && $settings[:custom_source]
puts "Invalid directory specified with the --source option."
elsif !dir_exists
puts "Could not find the slideshow folder." \
"Please use the --source option if you want to use a custom value (default is '#{$settings[:source]}')."
end
master_exists = File.exists? "#{$settings[:source]}/#{$settings[:master]}"
if !master_exists && $settings[:custom_master] && !$settings[:multiple]
puts "Invalid file name for the master slide specified with the --input option."
elsif !master_exists && !$settings[:multiple]
puts "Could not find the master slide file. " \
"Please use the --input option if you want to use a custom value (default is '#{$settings[:master]}')."
else
master_exists = true # It doesn't really exist, but we'll handle several master slides
end
dir_exists && master_exists
end
def self.init
$optparse = OptionParser.new do |opts|
# Slideshow folder
opts.on( '-s', '--source DIR', "Creates a slideshow using the files on the specified folder " \
"(default is '#{$settings[:source]}')" ) do |dir|
$settings[:source] = dir
$settings[:custom_source] = true # This var is only used to print a better error message
end
# Name of the resulting html file
opts.on( '-o', '--output FILENAME', "Name of the resulting html file " \
"(default is '#{$settings[:output]}')" ) do |filename|
$settings[:output] = filename
end
# Name of the master slide html file
opts.on( '-i', '--input FILENAME', "Name of the master slide file " \
"(default is '#{$settings[:master]}')" ) do |filename|
$settings[:master] = filename
$settings[:custom_master] = true # This var is only used to print a better error message
end
# Allow several slideshows inside the source folder
opts.on( '-m', '--multiple', 'Allows several slideshows inside the source folder' ) do
$settings[:multiple] = true
end
# Excluding live.js
opts.on( '-n', '--nolivejs', "Excludes the live.js library " \
"(live.js should only be used while developing)" ) do
$settings[:live] = false
end
# Port number
opts.on( '-p', '--port PORT', "Runs on the specified port " \
"(default is #{$settings[:port]})" ) do |port|
$settings[:port] = port
end
# Binding address
opts.on( '-b', '--binding IP', "Binds to the specified ip " \
"(default is #{$settings[:binding]})" ) do |binding|
$settings[:binding] = binding
end
# Help
opts.on( '-h', '--help', 'Shows this help message' ) do
puts opts
exit
end
end
end
# Parse the given command line parameters
def self.parse!
init unless $optparse
$optparse.parse!
end
end
# Parse the given command line parameters
Options::parse!
# Merge some required defaults
$settings.merge!({
:root => Dir.pwd,
:watched_files => "#{$settings[:source]}/.*",
})
@root = $settings[:source]
@live = $settings[:live]
# Simpler way of calling the "partial" method from views
def partial(name) Builder::partial(name) end
# Check if the specified options are valid
exit unless Options::valid_options?
puts ">>> Watching #{$settings[:root]}/#{$settings[:watched_files]}"
puts ">>> Check your slideshow at http://#{$settings[:binding]}:#{$settings[:port]}/index.html"
puts ">>> Your slideshow will be built and refreshed automagically\n"
# Launch the watcher
Thread.new do
script = Watchr::Script.new
Builder::build
script.watch $settings[:watched_files] do
Builder::build
end
controller = Watchr::Controller.new(script, Watchr.handler.new)
controller.run
end
# Run the thin server
Thin::Server.start($settings[:binding], $settings[:port]) do
run Rack::Directory.new("#{$settings[:root]}")
end
Jump to Line
Something went wrong with that request. Please try again.