From 45d8c2cad930a9ef48d5de2323df9312851ff40d Mon Sep 17 00:00:00 2001 From: Alex Chaffee Date: Fri, 20 Jan 2012 09:56:59 -0800 Subject: [PATCH] accepts a showoff.json file, which can include literal markdown as a section entry --- bin/deck | 1 - deck.gemspec | 1 + lib/deck/rack_app.rb | 46 +++++++++++++++++++++---- lib/deck/slide.rb | 11 ++++-- spec/rack_app_spec.rb | 80 ++++++++++++++++++++++++++++++++++++++++++- spec/slide_spec.rb | 19 ++++++++++ 6 files changed, 147 insertions(+), 11 deletions(-) diff --git a/bin/deck b/bin/deck index 309b481..e5e11c0 100755 --- a/bin/deck +++ b/bin/deck @@ -35,7 +35,6 @@ when 'run' # Fix Rack bug https://github.com/rack/rack/issues/301 require 'deck/rack_static_patch' - port = 4333 # todo: option slide_files = ARGV Rack::Handler.default.run Deck::RackApp.build(slide_files), :Port => port diff --git a/deck.gemspec b/deck.gemspec index a437bba..ff38ca4 100644 --- a/deck.gemspec +++ b/deck.gemspec @@ -23,6 +23,7 @@ deck.js (http://imakewebthings.github.com/deck.js) is a JavaScript library for b s.add_dependency "rack" s.add_dependency "nokogiri" s.add_dependency "coderay" + s.add_dependency "json" s.add_dependency 'rack-codehighlighter' end diff --git a/lib/deck/rack_app.rb b/lib/deck/rack_app.rb index 85d93c4..1111b7e 100644 --- a/lib/deck/rack_app.rb +++ b/lib/deck/rack_app.rb @@ -1,5 +1,6 @@ here = File.expand_path File.dirname(__FILE__) +require 'json' require 'coderay' require 'rack/codehighlighter' @@ -30,23 +31,38 @@ def self.build slide_files end def initialize slide_files - @slide_files = [slide_files].flatten + @slide_files = [slide_files].flatten.map do |slide_file| + case slide_file + when /\/?showoff.json$/ + puts "matched" + json_file_dir = File.expand_path(File.dirname(slide_file)) + json_file = slide_file + config = JSON.parse(File.read(json_file)) + config['sections'].map do |markdown_file| + if markdown_file =~ /^# / # you can use literal markdown instead of a file name + s = Slide.split(markdown_file) + s + else + File.new(json_file_dir + '/' + markdown_file) + end + end + else + File.new(slide_file) + end + end.flatten @file_servers = [Rack::File.new("#{::Deck::RackApp.app_root}/public")] + @slide_files.map do |slide_file| - Rack::File.new(File.dirname slide_file) + File.expand_path File.dirname(slide_file) if slide_file.is_a? File + end.compact.uniq.map do |slide_file_dir| + Rack::File.new(slide_file_dir) end end def call env request = Rack::Request.new(env) if request.path == "/" - slides = [] - @slide_files.each do |file| - slides += Slide.from_file file - end - deck = SlideDeck.new :slides => slides [200, {'Content-Type' => 'text/html'}, [deck.to_pretty]] else result = [404, {}, []] @@ -57,5 +73,21 @@ def call env result end end + + def deck + SlideDeck.new :slides => slides + end + + def slides + out = [] + @slide_files.each do |file| + out += if file.is_a? Slide + [file] + else + Slide.from_file file + end + end + out + end end end diff --git a/lib/deck/slide.rb b/lib/deck/slide.rb index adbdc02..7651ffa 100644 --- a/lib/deck/slide.rb +++ b/lib/deck/slide.rb @@ -13,6 +13,7 @@ def self.from_file markdown_file end # given a chunk of Markdown text, splits it into an array of Slide objects + # todo: move into SlideDeck? def self.split content unless content =~ /^\ nil, :markdown_text => nil, :slide_id => nil - + needs :classes => nil, :slide_id => nil + needs :markdown_text => nil def initialize options = {} super options @@ -57,6 +58,12 @@ def initialize options = {} @markdown_text = "" end + def ==(other) + Slide === other and + @classes == other.classes and + @markdown_text == other.markdown_text + end + def process_classes ["slide"] + case @classes when NilClass diff --git a/spec/rack_app_spec.rb b/spec/rack_app_spec.rb index 75f9f3a..a92e3e3 100644 --- a/spec/rack_app_spec.rb +++ b/spec/rack_app_spec.rb @@ -5,9 +5,14 @@ require "rack/test" -describe Deck::RackApp do +module Deck + describe RackApp do include Rack::Test::Methods + def here + File.expand_path File.dirname(__FILE__) + end + describe "app with middleware" do def app @app ||= Deck::RackApp.build [] @@ -173,5 +178,78 @@ def assert_code_is_highlighted end end + describe '#slides' do + it "builds a bunch of slide objects from the slide_files property" do + slide_file = nil + @dir = Files do + slide_file = file "foo.md", "# hello" + end + app = RackApp.new [slide_file] + assert { app.slides == Slide.from_file(slide_file) } + end + + it "reads a showoff.json file" do + foo_file, bar_file, showoff_file = nil,nil,nil + @dir = Files do + foo_file = file "foo.md", "# hello" + bar_file = file "bar.md", "# hello" + showoff_file = file "showoff.json", <<-JSON + { + "name": "Ruby For Programmers", + "description": "an introduction to the Ruby programming language", + "sections": [ + "foo.md", + "bar.md" + ] + } + JSON + end + app = RackApp.new [showoff_file] + assert { app.slides == Slide.from_file(foo_file) + Slide.from_file(bar_file) } + end + + it "reads a showoff.json file including literal markdown as a section" do + foo_file, bar_file, showoff_file = nil,nil,nil + @dir = Files do + foo_file = file "foo.md", "# hello" + bar_file = file "bar.md", "# goodbye" + showoff_file = file "showoff.json", <<-JSON + { + "name": "Ruby For Programmers", + "description": "an introduction to the Ruby programming language", + "sections": [ + "foo.md", + "# literal markdown", + "bar.md" + ] + } + JSON + end + app = RackApp.new [showoff_file] + assert { + app.slides.size == 3 + } + assert { + app.slides[1].markdown_text == "# literal markdown\n" + } + assert { app.slides[0].slide_id == "hello" } + assert { app.slides[1].slide_id == "literal_markdown" } + assert { app.slides[2].slide_id == "goodbye" } + # assert { + # app.slides == + # Slide.from_file(foo_file) + + # [Slide.new(:markdown_text => "# literal markdown")] + + # Slide.from_file(bar_file) + # } + assert { + app.deck.to_html.include?("

literal markdown

") + } + end + + it "if no slides are specified, it globs all markdown files under ." + + end + end + end end diff --git a/spec/slide_spec.rb b/spec/slide_spec.rb index c7e39a9..8ccba87 100644 --- a/spec/slide_spec.rb +++ b/spec/slide_spec.rb @@ -284,5 +284,24 @@ def slide_from markdown_text assert { html == expected_html } end end + + describe "==" do + it "a slide is equal to itself" do + s = slide_from("# hello") + assert { s == s } + end + + it "a slide is equal to a clone of itself" do + s1 = slide_from("# hello") + s2 = slide_from("# hello") + assert { s1 == s2 } + end + + it "a slide is not equal to a different slide" do + s1 = slide_from("# hello") + s2 = slide_from("# goodbye") + deny { s1 == s2 } + end + end end end