deckrb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/README.md +63 -0
  2. data/bin/deck +59 -0
  3. data/deck/GPL-license.txt +278 -0
  4. data/deck/MIT-license.txt +21 -0
  5. data/deck/README.md +57 -0
  6. data/deck/core/deck.core.css +404 -0
  7. data/deck/core/deck.core.html +39 -0
  8. data/deck/core/deck.core.js +498 -0
  9. data/deck/core/deck.core.scss +447 -0
  10. data/deck/extensions/goto/deck.goto.css +41 -0
  11. data/deck/extensions/goto/deck.goto.html +7 -0
  12. data/deck/extensions/goto/deck.goto.js +134 -0
  13. data/deck/extensions/goto/deck.goto.scss +46 -0
  14. data/deck/extensions/hash/deck.hash.css +13 -0
  15. data/deck/extensions/hash/deck.hash.html +2 -0
  16. data/deck/extensions/hash/deck.hash.js +129 -0
  17. data/deck/extensions/hash/deck.hash.scss +15 -0
  18. data/deck/extensions/menu/deck.menu.css +47 -0
  19. data/deck/extensions/menu/deck.menu.js +187 -0
  20. data/deck/extensions/menu/deck.menu.scss +58 -0
  21. data/deck/extensions/navigation/deck.navigation.css +43 -0
  22. data/deck/extensions/navigation/deck.navigation.html +3 -0
  23. data/deck/extensions/navigation/deck.navigation.js +91 -0
  24. data/deck/extensions/navigation/deck.navigation.scss +56 -0
  25. data/deck/extensions/scale/deck.scale.css +16 -0
  26. data/deck/extensions/scale/deck.scale.js +155 -0
  27. data/deck/extensions/scale/deck.scale.scss +17 -0
  28. data/deck/extensions/status/deck.status.css +18 -0
  29. data/deck/extensions/status/deck.status.html +6 -0
  30. data/deck/extensions/status/deck.status.js +95 -0
  31. data/deck/extensions/status/deck.status.scss +22 -0
  32. data/deck/extensions/theme-picker/deck.theme-picker.css +55 -0
  33. data/deck/extensions/theme-picker/deck.theme-picker.js +13 -0
  34. data/deck/introduction/index.html +221 -0
  35. data/deck/introduction/index.rb +101 -0
  36. data/deck/jquery-1.7.min.js +4 -0
  37. data/deck/modernizr.custom.js +4 -0
  38. data/deck/test/fixtures/complex.html +24 -0
  39. data/deck/test/fixtures/empty.html +19 -0
  40. data/deck/test/fixtures/iframe_simple.html +10 -0
  41. data/deck/test/fixtures/iframes.html +32 -0
  42. data/deck/test/fixtures/nesteds.html +36 -0
  43. data/deck/test/fixtures/standard.html +42 -0
  44. data/deck/test/index.html +39 -0
  45. data/deck/test/lib/jasmine-html.js +190 -0
  46. data/deck/test/lib/jasmine-jquery.js +288 -0
  47. data/deck/test/lib/jasmine.css +166 -0
  48. data/deck/test/lib/jasmine.js +2477 -0
  49. data/deck/test/settings.js +3 -0
  50. data/deck/test/spec.core.js +434 -0
  51. data/deck/test/spec.goto.js +119 -0
  52. data/deck/test/spec.hash.js +81 -0
  53. data/deck/test/spec.menu.js +66 -0
  54. data/deck/test/spec.navigation.js +51 -0
  55. data/deck/test/spec.scale.js +57 -0
  56. data/deck/test/spec.status.js +58 -0
  57. data/deck/themes/style/neon.css +114 -0
  58. data/deck/themes/style/neon.scss +139 -0
  59. data/deck/themes/style/swiss.css +75 -0
  60. data/deck/themes/style/swiss.scss +91 -0
  61. data/deck/themes/style/web-2.0.css +205 -0
  62. data/deck/themes/style/web-2.0.scss +236 -0
  63. data/deck/themes/transition/fade.css +44 -0
  64. data/deck/themes/transition/fade.scss +70 -0
  65. data/deck/themes/transition/horizontal-slide.css +79 -0
  66. data/deck/themes/transition/horizontal-slide.scss +94 -0
  67. data/deck/themes/transition/vertical-slide.css +97 -0
  68. data/deck/themes/transition/vertical-slide.scss +116 -0
  69. data/lib/deck.rb +7 -0
  70. data/lib/deck/app.rb +16 -0
  71. data/lib/deck/deck.rb +166 -0
  72. data/lib/deck/rack_static_patch.rb +13 -0
  73. data/lib/deck/slide.rb +120 -0
  74. data/lib/deck/version.rb +3 -0
  75. data/spec/deck_spec.rb +98 -0
  76. data/spec/javascripts/support/jasmine_config.rb +23 -0
  77. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  78. data/spec/slide_spec.rb +285 -0
  79. data/spec/spec_helper.rb +7 -0
  80. metadata +172 -0
data/lib/deck.rb ADDED
@@ -0,0 +1,7 @@
1
+ here = File.expand_path(File.dirname(__FILE__))
2
+
3
+ module Deck
4
+ end
5
+
6
+ require "deck/deck"
7
+ require "deck/slide"
data/lib/deck/app.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Deck
2
+ class App
3
+ def initialize root, files
4
+ @root, @files = root, files
5
+ end
6
+
7
+ def call env
8
+ slides = []
9
+ @files.each do |file|
10
+ slides += Slide.from_file "#{@root}/#{file}"
11
+ end
12
+ deck = Deck.new :slides => slides
13
+ [200, {}, deck.to_pretty]
14
+ end
15
+ end
16
+ end
data/lib/deck/deck.rb ADDED
@@ -0,0 +1,166 @@
1
+ require 'erector'
2
+ require 'redcarpet'
3
+
4
+ require "deck/slide"
5
+
6
+ module Deck
7
+ class Deck < Erector::Widgets::Page
8
+ needs :title => "deck.rb presentation",
9
+ :description => nil,
10
+ :author => nil
11
+
12
+ needs :slides => nil
13
+
14
+ def page_title
15
+ @title
16
+ end
17
+
18
+ # todo: promote into Text
19
+ # todo: support numbers a la '&#1234;'
20
+ def entity entity_id
21
+ raw("&#{entity_id};")
22
+ end
23
+
24
+ # left over from deck.js' introduction/index.html
25
+
26
+ # <!DOCTYPE html>
27
+ # <!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
28
+ # <!--[if IE 7]> <html class="no-js ie7" lang="en"> <![endif]-->
29
+ # <!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
30
+ # <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
31
+
32
+ # todo: promote into Page
33
+ def stylesheet src, attributes = {}
34
+ link({:rel => "stylesheet", :href => src}.merge(attributes))
35
+ end
36
+
37
+ def head_content
38
+ super
39
+ meta 'charset' => 'utf-8'
40
+ meta 'http-equiv'=>"X-UA-Compatible", 'content'=>"IE=edge,chrome=1"
41
+ meta :name=>"viewport", :content=>"width=1024, user-scalable=no"
42
+ meta :name => "description", :content=> @description if @description
43
+ meta :name => "author", :content=> @author if @author
44
+
45
+ # <!-- Core and extension CSS files -->
46
+ stylesheet "deck/core/deck.core.css"
47
+
48
+ stylesheet "deck/extensions/goto/deck.goto.css"
49
+ stylesheet "deck/extensions/menu/deck.menu.css"
50
+ stylesheet "deck/extensions/navigation/deck.navigation.css"
51
+ stylesheet "deck/extensions/status/deck.status.css"
52
+ stylesheet "deck/extensions/hash/deck.hash.css"
53
+ stylesheet "deck/extensions/scale/deck.scale.css"
54
+
55
+ stylesheet "deck/extensions/theme-picker/deck.theme-picker.css"
56
+
57
+ # <!-- Theme CSS files (menu swaps these out) -->
58
+ stylesheet "deck/themes/style/web-2.0.css", :id=>"style-theme-link"
59
+ stylesheet "deck/themes/transition/horizontal-slide.css", :id => "transition-theme-link"
60
+
61
+ script :src=>"deck/modernizr.custom.js"
62
+ end
63
+
64
+ def scripts
65
+ # comment 'Grab CDN jQuery, with a protocol relative URL; fall back to local if offline'
66
+ # script :src => '//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js'
67
+ script :src => './deck/jquery-1.7.min.js'
68
+
69
+ comment 'Deck Core and extensions'
70
+ script :type => "text/javascript", :src => 'deck/core/deck.core.js'
71
+
72
+ script :type => "text/javascript", :src => 'deck/extensions/hash/deck.hash.js'
73
+ script :type => "text/javascript", :src => 'deck/extensions/menu/deck.menu.js'
74
+ script :type => "text/javascript", :src => 'deck/extensions/goto/deck.goto.js'
75
+ script :type => "text/javascript", :src => 'deck/extensions/status/deck.status.js'
76
+ script :type => "text/javascript", :src => 'deck/extensions/navigation/deck.navigation.js'
77
+ script :type => "text/javascript", :src => 'deck/extensions/scale/deck.scale.js'
78
+
79
+
80
+ # fire up deck.js
81
+ script "$(function(){$.deck('.slide');});"
82
+
83
+ script :type => "text/javascript", :src => 'deck/extensions/theme-picker/deck.theme-picker.js'
84
+
85
+ end
86
+
87
+ def body_attributes
88
+ {:class=>"deck-container"}
89
+ end
90
+
91
+ def body_content
92
+ slides
93
+ slide_navigation
94
+ deck_status
95
+ goto_slide
96
+ permalink
97
+ scripts
98
+ end
99
+
100
+ def slide slide_id
101
+ # todo: use Slide object, but without markdown
102
+ # slide = Slide.new(:slide_id => slide_id)
103
+ section.slide :id => slide_id do
104
+ yield
105
+ end
106
+ end
107
+
108
+ def slides
109
+ if @slides
110
+ @slides.each do |slide|
111
+ widget slide
112
+ end
113
+ else
114
+ default_slide
115
+ end
116
+ end
117
+
118
+ def default_slide
119
+ slide 'readme' do
120
+ h2 "deck.rb"
121
+ ul {
122
+ li "based on deck.js"
123
+ li "create a subclass of Deck (see introduction.rb)"
124
+ li "run erector to build it"
125
+ }
126
+ pre "erector --to-html ./deck.rb # generates deck.html"
127
+ end
128
+ end
129
+
130
+ def slide_navigation
131
+ a :href => '#', :class => 'deck-prev-link', :title => 'Previous' do
132
+ character 8592
133
+ end
134
+ a :href => '#', :class => 'deck-next-link', :title => 'Next' do
135
+ character 8594
136
+ end
137
+ end
138
+
139
+ def deck_status
140
+ p :class => 'deck-status' do
141
+ span :class => 'deck-status-current' do
142
+ end
143
+ text '/'
144
+ span :class => 'deck-status-total' do
145
+ end
146
+ end
147
+ end
148
+
149
+ def goto_slide
150
+ form :action => '.', :method => 'get', :class => 'goto-form' do
151
+ label :for => 'goto-slide' do
152
+ text 'Go to slide:'
153
+ end
154
+ input :type => 'text', :name => 'slidenum', :id => 'goto-slide', :list => 'goto-datalist'
155
+ datalist :id => 'goto-datalist' do
156
+ end
157
+ input :type => 'submit', :value => 'Go'
158
+ end
159
+ end
160
+
161
+ def permalink
162
+ a "#", :href => '.', :title => 'Permalink to this slide', :class => 'deck-permalink'
163
+ end
164
+
165
+ end
166
+ end
@@ -0,0 +1,13 @@
1
+ # Fix Rack bug https://github.com/rack/rack/issues/301
2
+ module Rack
3
+ class Static
4
+ def initialize(app, options={})
5
+ @app = app
6
+ @urls = options[:urls] || ["/favicon.ico"]
7
+ @index = options[:index]
8
+ root = options[:root] || Dir.pwd
9
+ cache_control = options[:cache_control]
10
+ @file_server = Rack::File.new(root, cache_control)
11
+ end
12
+ end
13
+ end
data/lib/deck/slide.rb ADDED
@@ -0,0 +1,120 @@
1
+ # based on work by Alex and others in Showoff
2
+ require 'redcarpet'
3
+
4
+
5
+ module Deck
6
+ class Slide < Erector::Widget
7
+
8
+ # todo: test this method
9
+ def self.from_file markdown_file
10
+ split File.read(markdown_file)
11
+ end
12
+
13
+ # given a chunk of Markdown text, splits it into an array of Slide objects
14
+ def self.split content
15
+ unless content =~ /^\<?!SLIDE/m
16
+ content = content.gsub(/^# /m, "<!SLIDE>\n# ")
17
+ end
18
+
19
+ lines = content.split("\n")
20
+ slides = []
21
+ slides << (slide = Slide.new)
22
+ until lines.empty?
23
+ line = lines.shift
24
+ if line =~ /^<?!SLIDE(.*)>?/
25
+ slides << (slide = Slide.new(:classes => $1))
26
+
27
+ elsif line =~ /^# / and !slide.empty?
28
+ # every H1 defines a new slide, unless there's a !SLIDE before it
29
+ slides << (slide = Slide.new)
30
+ slide << line
31
+
32
+ else
33
+ slide << line
34
+ end
35
+ end
36
+
37
+ slides.delete_if {|slide| slide.empty? }
38
+
39
+ slides
40
+ end
41
+
42
+ ####
43
+
44
+ attr_reader :classes, :markdown_text
45
+
46
+ needs :classes => nil, :markdown_text => nil, :slide_id => nil
47
+
48
+
49
+ def initialize options = {}
50
+ super options
51
+
52
+ @classes = process_classes
53
+ @markdown_text = ""
54
+ end
55
+
56
+ def process_classes
57
+ ["slide"] + case @classes
58
+ when NilClass
59
+ []
60
+ when String
61
+ @classes.strip.chomp('>').split
62
+ when Array
63
+ @classes
64
+ else
65
+ raise "can't deal with :classes => #{@classes.inspect}"
66
+ end
67
+ end
68
+
69
+ def markdown
70
+ @@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
71
+ :no_intra_emphasis => true,
72
+ :tables => true,
73
+ :fenced_code_blocks => true,
74
+ :no_intra_emphasis => true,
75
+ :autolink => true,
76
+ :strikethrough => true,
77
+ :lax_html_blocks => false,
78
+ :space_after_headers => true,
79
+ :superscript => false
80
+ )
81
+ end
82
+
83
+ def <<(s)
84
+ @markdown_text << s
85
+ @markdown_text << "\n"
86
+ end
87
+
88
+ def empty?
89
+ @markdown_text.strip == ""
90
+ end
91
+
92
+ def slide_id
93
+ @slide_id ||= begin
94
+ lines = @markdown_text.split("\n")
95
+ raise "an empty slide has no id" if lines.empty?
96
+ lines.first.gsub(/^#*/, '').strip.downcase.gsub(/[^\w\s]/, '').gsub(/\s/, '_')
97
+ end
98
+ end
99
+
100
+ def header_only?
101
+ markdown_text.strip =~ /^# / and markdown_text.strip.split("\n").size == 1
102
+ end
103
+
104
+ def massaged_markdown_text
105
+ unless header_only?
106
+ "##{markdown_text.strip}"
107
+ else
108
+ markdown_text
109
+ end
110
+ end
111
+
112
+ def content
113
+ section :class => @classes, :id => slide_id do
114
+ text "\n" # markdown HTML should be left-aligned, in case of PRE blocks and other quirks
115
+ html = markdown.render(massaged_markdown_text)
116
+ rawtext html
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,3 @@
1
+ module Deck
2
+ VERSION = "0.1.0"
3
+ end
data/spec/deck_spec.rb ADDED
@@ -0,0 +1,98 @@
1
+ here = File.expand_path File.dirname(__FILE__)
2
+ require "#{here}/spec_helper"
3
+
4
+ require "deck/deck"
5
+
6
+ module Deck
7
+ describe Deck do
8
+ def temp_dir options = {:remove => true}
9
+ @temp_dir ||= begin
10
+ require 'tmpdir'
11
+ require 'fileutils'
12
+ called_from = File.basename caller.first.split(':').first, ".rb"
13
+ path = File.join(Dir::tmpdir, "#{called_from}_#{Time.now.to_i}_#{rand(1000)}")
14
+ Dir.mkdir(path)
15
+ at_exit {FileUtils.rm_rf(path) if File.exists?(path)} if options[:remove]
16
+ path
17
+ end
18
+ end
19
+
20
+ def to_html nokogiri_node
21
+ nokogiri_node.serialize(:save_with => 0).chomp
22
+ end
23
+
24
+ def as_html_page snippet
25
+ snippet =~ /<html/ ? snippet : "<html>#{snippet}</html>"
26
+ end
27
+
28
+ def deck_widget options = {}
29
+ @deck_widget ||= Deck.new options
30
+ end
31
+
32
+ def doc
33
+ @doc ||= begin
34
+ @html = deck_widget.to_html
35
+ Nokogiri.parse(as_html_page(@html))
36
+ end
37
+ end
38
+
39
+ def write name, contents = "contents of #{name}"
40
+ path = "#{temp_dir}/#{name}"
41
+ File.open(path, "w") do |f|
42
+ f.write contents
43
+ end
44
+ File.new path
45
+ end
46
+
47
+ describe "#write" do
48
+ before do
49
+ @hello = write "hello.txt"
50
+ @goodbye = write "goodbye.txt", "farewell"
51
+ end
52
+
53
+ it "uses temp_dir" do
54
+ File.dirname(@hello).should == temp_dir
55
+ File.dirname(@goodbye).should == temp_dir
56
+ end
57
+
58
+ it "writes a default value" do
59
+ File.read(@hello).should == "contents of hello.txt"
60
+ end
61
+
62
+ it "writes a given value" do
63
+ # since write returns a File instance, we can call read on it
64
+ @goodbye.read.should == "farewell"
65
+ end
66
+
67
+ it "writes a file" do
68
+ file = write("hello.md", "# hello")
69
+ assert { File.read(file) == "# hello" }
70
+ end
71
+
72
+ end
73
+
74
+
75
+ it "renders a basic deck.js HTML page" do
76
+ assert { doc }
77
+ assert { @html.include? '<link href="deck/core/deck.core.css" rel="stylesheet" />' }
78
+ end
79
+
80
+ it "contains a single dummy slide" do
81
+ assert { doc.css('section.slide').size == 1 }
82
+ end
83
+
84
+ it "renders a markdown file with one slide" do
85
+ file = write("hello.md", "# hello")
86
+
87
+ deck_widget :slides => Slide.split(File.read file)
88
+ assert { doc.css('section.slide').size == 1 }
89
+ slide = doc.css('section.slide').first
90
+ assert { slide["id"] == "hello" }
91
+ assert { to_html(slide) == "<section class=\"slide\" id=\"hello\">" +
92
+ "<h1>hello</h1>\n" +
93
+ "</section>"
94
+ }
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,23 @@
1
+ module Jasmine
2
+ class Config
3
+
4
+ # Add your overrides or custom config code here
5
+
6
+ end
7
+ end
8
+
9
+
10
+ # Note - this is necessary for rspec2, which has removed the backtrace
11
+ module Jasmine
12
+ class SpecBuilder
13
+ def declare_spec(parent, spec)
14
+ me = self
15
+ example_name = spec["name"]
16
+ @spec_ids << spec["id"]
17
+ backtrace = @example_locations[parent.description + " " + example_name]
18
+ parent.it example_name, {} do
19
+ me.report_spec(spec["id"])
20
+ end
21
+ end
22
+ end
23
+ end