require 'rubygems'
require 'sinatra/base'
require 'json'
require 'nokogiri'
require 'showoff_utils'
begin
require 'rdiscount'
rescue LoadError
require 'bluecloth'
Markdown = BlueCloth
end
require 'pp'
class ShowOff < Sinatra::Application
set :views, File.dirname(__FILE__) + '/../views'
set :public, File.dirname(__FILE__) + '/../public'
set :pres_dir, 'example'
def initialize(app=nil)
super(app)
puts dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
if Dir.pwd == dir
options.pres_dir = dir + '/example'
else
options.pres_dir = Dir.pwd
end
puts options.pres_dir
end
helpers do
def load_section_files(section)
section = File.join(options.pres_dir, section)
files = Dir.glob("#{section}/**/*").sort
pp files
files
end
def css_files
Dir.glob("#{options.pres_dir}/*.css").map { |path| File.basename(path) }
end
def js_files
Dir.glob("#{options.pres_dir}/*.js").map { |path| File.basename(path) }
end
def process_markdown(name, content)
slides = content.split(/^!SLIDE/)
slides.delete('')
final = ''
if slides.size > 1
seq = 1
end
slides.each do |slide|
md = ''
lines = slide.split("\n")
classes = lines.shift
slide = lines.join("\n")
if seq
md += "
\n"
seq += 1
else
md += "
\n"
end
sl = Markdown.new(slide).to_html
sl = update_image_paths(name, sl)
md += sl
md += "
\n"
final += update_commandline_code(md)
end
final
end
def update_image_paths(path, slide)
paths = path.split('/')
paths.pop
path = paths.join('/')
slide.gsub(/img src=\"(.*?)\"/, 'img src="/image/' + path + '/\1"')
end
def update_commandline_code(slide)
html = Nokogiri::XML.parse(slide)
html.css('pre').each do |pre|
pre.css('code').each do |code|
out = code.text
lines = out.split("\n")
if lines.first[0, 3] == '@@@'
lang = lines.shift.gsub('@@@', '').strip
pre.set_attribute('class', 'sh_' + lang)
code.content = lines.join("\n")
end
end
end
html.css('.commandline > pre > code').each do |code|
out = code.text
lines = out.split(/^\$(.*?)$/)
lines.delete('')
code.content = ''
while(lines.size > 0) do
command = lines.shift
result = lines.shift
c = Nokogiri::XML::Node.new('code', html)
c.set_attribute('class', 'command')
c.content = '$' + command
code << c
c = Nokogiri::XML::Node.new('code', html)
c.set_attribute('class', 'result')
c.content = result
code << c
end
end
html.root.to_s
end
end
get '/' do
erb :index
end
get %r{(?:image|file)/(.*)} do
path = params[:captures].first
full_path = File.join(options.pres_dir, path)
send_file full_path
end
get '/slides' do
index = File.join(options.pres_dir, 'showoff.json')
files = []
if File.exists?(index)
order = JSON.parse(File.read(index))
order = order.map { |s| s['section'] }
order.each do |section|
files << load_section_files(section)
end
files = files.flatten
files = files.select { |f| f =~ /.md/ }
data = ''
files.each do |f|
fname = f.gsub(options.pres_dir + '/', '').gsub('.md', '')
data += process_markdown(fname, File.read(f))
end
end
data
end
end