#!/usr/bin/env ruby -w require 'camping' require 'yaml' require 'redcloth' require 'vendor/dcss/lib/dcss' Camping.goes :Presenter module Presenter PATH = File.dirname(__FILE__) end module Presenter::Controllers #s5 user interface components class Ui < R '(.*)/ui/(.+)' #hacky check MIME_TYPES = { '.css' => 'text/css', '.js' => 'text/javascript', '.jpg' => 'image/jpeg', '.gif' => 'image/gif', '.png' => 'image/png', '.html' => 'text/html' } def get(pres, path) @headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain" @headers['X-Sendfile'] = "#{PATH}/s5/ui/#{path}" end end class Index < R '/' def get @presentations = Dir.glob("#{PATH}/*.pres").map { |pres| pres.split('/').last[0...-5] } render :index end end class Show < R '/(\w+)' def get(pres) @title = pres @slides = File.read("#{PATH}/#{pres}.pres/slides").split("\n---") @meta = YAML.load(@slides.delete_at(0)) @slides = @slides.map do |slide| slide_class, body = slide.match(%r{ ( \( [^\)]+ \)\n ){0,1} (.*) }mx).to_a[1..2] body, notes = body.split("\n--notes--\n") slide_class = slide_class[1..-3] unless slide_class.nil? body = RedCloth.new(body, [:no_span_caps]).to_html notes = RedCloth.new(notes, [:no_span_caps]).to_html if notes { :class => slide_class, :body => body, :notes => notes } end @styles = DuckCSS::CSSParser.new(File.read("#{PATH}/#{pres}.pres/styles.dcss")).to_css render :s5 end end end module Presenter::Views def index html { title { "Presenter (in Camping)" } body { ul { @presentations.each { |pres| li { a pres, :href => "#{pres}/" } } } } } end # underscore denotes partial, which means the layout is not used def s5 xhtml_transitional { head { title { @title } # metadata meta :name => 'generator', :content => 'S5 (goes Camping)' meta :name => 'version', :content => "S5 1.2a2" @meta.each { |k,v| meta :name => k, :content => v } # config parameters meta :name => "defaultView", :content => "slideshow" meta :name => "controlVis", :content => "hidden" link :rel => "stylesheet", :href => "/ui/default/slides.css", :type => "text/css", :media => "projection", :id => "slideProj" link :rel => "stylesheet", :href => "/ui/default/outline.css", :type => "text/css", :media => "screen", :id => "outlineStyle" link :rel => "stylesheet", :href => "/ui/default/print.css", :type => "text/css", :media => "print", :id => "slidePrint" link :rel => "stylesheet", :href => "/ui/default/opera.css", :type => "text/css", :media => "projection", :id => "operaFix" script :src => "/ui/default/slides.js", :type => "text/javascript" style(:type => 'text/css') { @styles } } body { div.layout { div.controls! { } div.currentSlide! { } div.header! { } div.footer! { } } div.presentation { @slides.each_with_index do |slide, index| div(:class => "slide #{slide[:class]}", :id => "slide#{index+1}") { slide[:body] + "
#{slide[:notes]}
" } end } } } end end