parade 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/LICENSE +21 -0
  2. data/README.md +542 -0
  3. data/Rakefile +15 -0
  4. data/bin/parade +138 -0
  5. data/lib/parade.rb +43 -0
  6. data/lib/parade/commands/commands.rb +84 -0
  7. data/lib/parade/commands/generate_outline.rb +34 -0
  8. data/lib/parade/commands/generate_presentation.rb +34 -0
  9. data/lib/parade/commands/generate_rackup.rb +32 -0
  10. data/lib/parade/commands/html_output.rb +47 -0
  11. data/lib/parade/commands/render_from_template.rb +50 -0
  12. data/lib/parade/commands/static_html.rb +38 -0
  13. data/lib/parade/commands/static_pdf.rb +39 -0
  14. data/lib/parade/commands/unknown.rb +23 -0
  15. data/lib/parade/features/live_ruby.rb +18 -0
  16. data/lib/parade/features/pdf_presentation.rb +24 -0
  17. data/lib/parade/features/preshow.rb +11 -0
  18. data/lib/parade/helpers/encode_image.rb +24 -0
  19. data/lib/parade/helpers/template_generator.rb +130 -0
  20. data/lib/parade/metadata.rb +73 -0
  21. data/lib/parade/metadata/assignment.rb +38 -0
  22. data/lib/parade/metadata/css_classes.rb +22 -0
  23. data/lib/parade/metadata/html_id.rb +35 -0
  24. data/lib/parade/metadata/template.rb +31 -0
  25. data/lib/parade/parsers/dsl.rb +138 -0
  26. data/lib/parade/parsers/dsl_file_parser.rb +17 -0
  27. data/lib/parade/parsers/json_file_parser.rb +67 -0
  28. data/lib/parade/parsers/markdown_image_paths.rb +44 -0
  29. data/lib/parade/parsers/markdown_slide_splitter.rb +63 -0
  30. data/lib/parade/parsers/presentation_directory_parser.rb +36 -0
  31. data/lib/parade/parsers/presentation_file_parser.rb +27 -0
  32. data/lib/parade/parsers/presentation_filepath_parser.rb +35 -0
  33. data/lib/parade/parsers/slides_file_content_parser.rb +27 -0
  34. data/lib/parade/renderers/columns_renderer.rb +68 -0
  35. data/lib/parade/renderers/command_line_renderer.rb +142 -0
  36. data/lib/parade/renderers/html_with_pygments.rb +42 -0
  37. data/lib/parade/renderers/inline_images.rb +31 -0
  38. data/lib/parade/renderers/special_paragraph_renderer.rb +23 -0
  39. data/lib/parade/renderers/update_image_paths.rb +75 -0
  40. data/lib/parade/section.rb +183 -0
  41. data/lib/parade/server.rb +139 -0
  42. data/lib/parade/slide.rb +128 -0
  43. data/lib/parade/version.rb +3 -0
  44. data/lib/public/css/960.css +653 -0
  45. data/lib/public/css/fg.menu.css +114 -0
  46. data/lib/public/css/ghf_marked.css +180 -0
  47. data/lib/public/css/jquery-terminal.css +73 -0
  48. data/lib/public/css/onepage.css +62 -0
  49. data/lib/public/css/parade.css +450 -0
  50. data/lib/public/css/pdf.css +13 -0
  51. data/lib/public/css/reset.css +53 -0
  52. data/lib/public/css/spinner_bar.gif +0 -0
  53. data/lib/public/css/theme/images/ui-bg_diagonals-small_100_f0efea_40x40.png +0 -0
  54. data/lib/public/css/theme/images/ui-bg_flat_35_f0f0f0_40x100.png +0 -0
  55. data/lib/public/css/theme/images/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
  56. data/lib/public/css/theme/images/ui-bg_glow-ball_25_2e2e28_600x600.png +0 -0
  57. data/lib/public/css/theme/images/ui-bg_highlight-soft_100_f0efea_1x100.png +0 -0
  58. data/lib/public/css/theme/images/ui-bg_highlight-soft_25_327E04_1x100.png +0 -0
  59. data/lib/public/css/theme/images/ui-bg_highlight-soft_25_5A9D1A_1x100.png +0 -0
  60. data/lib/public/css/theme/images/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
  61. data/lib/public/css/theme/images/ui-bg_inset-soft_22_3b3b35_1x100.png +0 -0
  62. data/lib/public/css/theme/images/ui-icons_808080_256x240.png +0 -0
  63. data/lib/public/css/theme/images/ui-icons_8DC262_256x240.png +0 -0
  64. data/lib/public/css/theme/images/ui-icons_cd0a0a_256x240.png +0 -0
  65. data/lib/public/css/theme/images/ui-icons_e7e6e4_256x240.png +0 -0
  66. data/lib/public/css/theme/images/ui-icons_eeeeee_256x240.png +0 -0
  67. data/lib/public/css/theme/images/ui-icons_ffffff_256x240.png +0 -0
  68. data/lib/public/css/theme/ui.accordion.css +9 -0
  69. data/lib/public/css/theme/ui.all.css +2 -0
  70. data/lib/public/css/theme/ui.base.css +9 -0
  71. data/lib/public/css/theme/ui.core.css +37 -0
  72. data/lib/public/css/theme/ui.datepicker.css +62 -0
  73. data/lib/public/css/theme/ui.dialog.css +13 -0
  74. data/lib/public/css/theme/ui.progressbar.css +4 -0
  75. data/lib/public/css/theme/ui.resizable.css +13 -0
  76. data/lib/public/css/theme/ui.slider.css +17 -0
  77. data/lib/public/css/theme/ui.tabs.css +9 -0
  78. data/lib/public/css/theme/ui.theme.css +245 -0
  79. data/lib/public/favicon.ico +0 -0
  80. data/lib/public/js/coffee-script.js +8 -0
  81. data/lib/public/js/fg.menu.js +645 -0
  82. data/lib/public/js/jTypeWriter.js +26 -0
  83. data/lib/public/js/jquery-1.4.2.js +6240 -0
  84. data/lib/public/js/jquery-print.js +109 -0
  85. data/lib/public/js/jquery-pubsub.js +27 -0
  86. data/lib/public/js/jquery-terminal.js +2712 -0
  87. data/lib/public/js/jquery.batchImageLoad.js +56 -0
  88. data/lib/public/js/jquery.cycle.all.js +1284 -0
  89. data/lib/public/js/keyboard.js +733 -0
  90. data/lib/public/js/parade-code-execution.js +122 -0
  91. data/lib/public/js/parade-command-input.js +16 -0
  92. data/lib/public/js/parade-command-visor.js +92 -0
  93. data/lib/public/js/parade-keyboard-input.js +54 -0
  94. data/lib/public/js/parade.js +675 -0
  95. data/lib/public/js/spine.js +904 -0
  96. data/lib/templates/config.ru.erb +4 -0
  97. data/lib/templates/showoff.erb +27 -0
  98. data/lib/templates/slides.md.erb +25 -0
  99. data/lib/views/header.erb +73 -0
  100. data/lib/views/index.erb +53 -0
  101. data/lib/views/inline_css.erb +3 -0
  102. data/lib/views/inline_js.erb +3 -0
  103. data/lib/views/onepage.erb +17 -0
  104. data/lib/views/pdf.erb +17 -0
  105. data/lib/views/slide.erb +5 -0
  106. metadata +317 -0
@@ -0,0 +1,183 @@
1
+ require_relative 'renderers/update_image_paths'
2
+
3
+ module Parade
4
+
5
+ #
6
+ # A Parade presentation is composed of a Section that may also be composed
7
+ # of many slides and sub-sections (child sections) of slides.
8
+ #
9
+ class Section
10
+
11
+ def initialize(params = {})
12
+ @description = ""
13
+ @post_renderers = []
14
+ @sections = []
15
+
16
+ @templates = {}
17
+ params.each {|k,v| send("#{k}=",v) if respond_to? "#{k}=" }
18
+ end
19
+
20
+ # @param [String] title the new title of the section
21
+ attr_writer :title
22
+
23
+ # @return [String] the title of the section
24
+ def title
25
+ @title ? @title : (section ? section.title : "Section")
26
+ end
27
+
28
+ # @return [String] the description of the section
29
+ attr_accessor :description
30
+
31
+ # @return [Array<#slides>] returns an array of a Section objects or array
32
+ # of Slide objects.
33
+ attr_reader :sections
34
+
35
+ # @return [Section] the parent section of this section. nil if this is a
36
+ # root section.
37
+ attr_accessor :section
38
+
39
+ #
40
+ # Append sections to this section.
41
+ #
42
+ # @param [Section,Array<Section>] content this any section that you want to
43
+ # add to this section.
44
+ #
45
+ def add_section(sub_sections)
46
+ sub_sections = Array(sub_sections).compact.flatten.map do |sub_section|
47
+ sub_section.section = self
48
+ sub_section
49
+ end
50
+ @sections = @sections + sub_sections
51
+ sub_sections
52
+ end
53
+
54
+ #
55
+ # Append slides to this setion.
56
+ #
57
+ # @param [Slide,Array<Slide>] content this any section that you want to
58
+ # add to this section.
59
+ #
60
+ def add_slides(slides)
61
+ sub_slides = Array(slides).compact.flatten.map do |slide|
62
+ slide.section = self
63
+ slide
64
+ end
65
+
66
+ @sections = @sections + sub_slides
67
+ sub_slides
68
+ end
69
+
70
+ #
71
+ # @example 'opening' would be the template name and 'custom_template.erb'
72
+ # would be the template filename.
73
+ #
74
+ # section "Introduction" do
75
+ # template "opening", "custom_template.erb"
76
+ # end
77
+ #
78
+ # @param [String] template_name the name of the template which it is
79
+ # referred to by the slides.
80
+ #
81
+ # @param [Types] template_filepath the filepath to the template to be loaded
82
+ #
83
+ def add_template(template_name,template_filepath)
84
+ @templates[template_name] = template_filepath
85
+ end
86
+
87
+ #
88
+ # @param [String] template_name the name of the template
89
+ # @param [Boolean] use_default_when_nil if while searching for the template
90
+ # it should use the parent section's default template. This usually wants
91
+ # to be false when looking for a specific template.
92
+ #
93
+ # @return [String] the filepath of the parent section template
94
+ def parent_section_template(template_name,use_default_when_nil=true)
95
+ section.template(template_name,use_default_when_nil) if section
96
+ end
97
+
98
+ #
99
+ # @return [String] the filepath of the default slide template.
100
+ def default_template
101
+ File.join(File.dirname(__FILE__), "..", "views", "slide.erb")
102
+ end
103
+
104
+ #
105
+ # Given the template name return the template file name associated with it.
106
+ # When a template is not found with the name within the section, the section
107
+ # traverses parent sections until it is found.
108
+ #
109
+ # A default template can be defined for a section which it will default
110
+ # to when no template name has been specified or the template name could
111
+ # not be found. Again the parent sections will be traversed if they have
112
+ # a default template.
113
+ #
114
+ # When there is no template specified or found within then it will default
115
+ # to the original slide template.
116
+ #
117
+ # @param [String] template_name the name of the template to retrieve.
118
+ #
119
+ # @return [String] the filepath to the template, given the template name.
120
+ #
121
+ def template(template_name,use_default_when_nil = true)
122
+ template_for_name = @templates[template_name] || parent_section_template(template_name,false)
123
+ template_for_name = (@templates['default'] || parent_section_template('default')) unless template_for_name and use_default_when_nil
124
+ template_for_name || default_template
125
+ end
126
+
127
+ attr_writer :pause_message
128
+
129
+ #
130
+ # @return [String] the pause message for the section, if none has been
131
+ # specified the default pause message is returned.
132
+ def pause_message
133
+ @pause_message || default_pause_message
134
+ end
135
+
136
+ def default_pause_message
137
+ ""
138
+ end
139
+
140
+ def resources
141
+ @resources || []
142
+ end
143
+
144
+ def add_resource(resource_filepath)
145
+ @resources ||= []
146
+ @resources << resource_filepath
147
+ end
148
+
149
+ # @return [Array<Slide>] the slides contained within this section and any
150
+ # sub-section.
151
+ def slides
152
+ sections_slides = sections.map do |section_or_slide|
153
+ section_or_slide.slides
154
+ end.flatten
155
+
156
+ # Update the sequence on all the slides for the entire section.
157
+ sections_slides.each_with_index {|slide,count| slide.sequence = (count + 1) }
158
+ end
159
+
160
+ # @return [Array<#render>] returns a list of Renderers that will perform
161
+ # their renderering on the slides after the slides have all habe been
162
+ # rendered.
163
+ attr_reader :post_renderers
164
+
165
+ #
166
+ # @param [#render] renderer add a renderer, any object responding to
167
+ # #render, that will process the slides HTML content.
168
+ #
169
+ def add_post_renderer(renderer)
170
+ @post_renderers << renderer
171
+ end
172
+
173
+ # @return [String] HTML representation of the section
174
+ def to_html
175
+ slides.map do |section_or_slide|
176
+ post_renderers.inject(section_or_slide.to_html) do |content,renderer|
177
+ renderer.render(content)
178
+ end
179
+ end.join("\n")
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,139 @@
1
+ require_relative "parsers/dsl"
2
+ require_relative 'renderers/update_image_paths'
3
+
4
+ require_relative 'features/live_ruby'
5
+ require_relative 'features/pdf_presentation'
6
+ require_relative 'features/preshow'
7
+
8
+ module Parade
9
+
10
+ class Server < Sinatra::Application
11
+
12
+ def initialize(app=nil)
13
+ super(app)
14
+ require_ruby_files
15
+ end
16
+
17
+ def require_ruby_files
18
+ Dir.glob("#{settings.presentation_directory}/*.rb").map { |path| require path }
19
+ end
20
+
21
+ set :views, File.dirname(__FILE__) + '/../views'
22
+ set :public_folder, File.dirname(__FILE__) + '/../public'
23
+
24
+ set :verbose, false
25
+
26
+ set :presentation_directory do
27
+ File.expand_path Dir.pwd
28
+ end
29
+
30
+ set :presentation_file, 'parade'
31
+
32
+ set :default_presentation_files, [ 'parade', 'parade.json' ]
33
+
34
+ def presentation_files
35
+ (Array(settings.presentation_file) + settings.default_presentation_files).compact.uniq
36
+ end
37
+
38
+ def load_presentation
39
+ root_node = Parsers::PresentationDirectoryParser.parse settings.presentation_directory,
40
+ :root_path => settings.presentation_directory, :parade_file => presentation_files
41
+
42
+ root_node.add_post_renderer Renderers::UpdateImagePaths.new :root_path => settings.presentation_directory
43
+ root_node
44
+ end
45
+
46
+ helpers do
47
+
48
+ #
49
+ # A shortcut to define a CSS resource file within a view template
50
+ #
51
+ def css(filepath)
52
+ %{<link rel="stylesheet" href="#{File.join "css", filepath}" type="text/css"/>}
53
+ end
54
+
55
+ #
56
+ # A shortcut to define a Javascript resource file within a view template
57
+ #
58
+ def js(filepath)
59
+ %{<script type="text/javascript" src="#{File.join "js", filepath}"></script>}
60
+ end
61
+
62
+ def custom_resource(resource_extension)
63
+ load_presentation.resources.map do |resource_path|
64
+ Dir.glob("#{resource_path}/*.#{resource_extension}").map do |path|
65
+ relative_path = path.sub(settings.presentation_directory,'')
66
+ yield relative_path if block_given?
67
+ end.join("\n")
68
+ end.join("\n")
69
+ end
70
+
71
+ #
72
+ # Create resources links to all the CSS files found at the root of
73
+ # presentation directory.
74
+ #
75
+ def custom_css_files
76
+ custom_resource "css" do |path|
77
+ css path
78
+ end
79
+ end
80
+
81
+ #
82
+ # Create resources links to all the Javascript files found at the root of
83
+ # presentation directory.
84
+ #
85
+ def custom_js_files
86
+ custom_resource "js" do |path|
87
+ js path
88
+ end
89
+ end
90
+
91
+ def presentation
92
+ load_presentation
93
+ end
94
+
95
+ def title
96
+ presentation.title
97
+ end
98
+
99
+ def slides
100
+ presentation.to_html
101
+ end
102
+
103
+ def pause_message
104
+ presentation.pause_message
105
+ end
106
+ end
107
+
108
+ #
109
+ # Path requests for files that match the prefix will be returned.
110
+ #
111
+ get %r{(?:image|file|js|css)/(.*)} do
112
+ path = params[:captures].first
113
+ full_path = File.join(settings.presentation_directory, path)
114
+ send_file full_path
115
+ end
116
+
117
+ #
118
+ # The request for slides is used by the client-side javascript presentation
119
+ # and returns all the slides HTML.
120
+ #
121
+ get "/slides" do
122
+ slides
123
+ end
124
+
125
+ get "/" do
126
+ erb :index
127
+ end
128
+
129
+ get "/onepage" do
130
+ erb :onepage
131
+ end
132
+
133
+ include LiveRuby
134
+ include PDFPresentation
135
+ include Preshow
136
+
137
+ end
138
+
139
+ end
@@ -0,0 +1,128 @@
1
+ require_relative 'metadata'
2
+ require_relative 'renderers/html_with_pygments'
3
+ require_relative 'renderers/command_line_renderer'
4
+ require_relative 'renderers/special_paragraph_renderer'
5
+ require_relative 'renderers/columns_renderer'
6
+
7
+ module Parade
8
+
9
+ #
10
+ # The Slide is the core class of the Presentation. The slide aggregates the
11
+ # markdown content, the slide metadata, and the slide template to create the
12
+ # HTML representation of the slide for Parade.
13
+ #
14
+ class Slide
15
+
16
+ # TODO: Previously this was #{name}#{sequence}, this is likely needing to be set
17
+ # by the slideshow itself to ensure that the content is unique and displayed
18
+ # in the correct order.
19
+ attr_accessor :sequence
20
+
21
+ attr_accessor :section
22
+
23
+ def title
24
+ section ? section.title : "Slide"
25
+ end
26
+
27
+ def reference
28
+ "#{section ? section.title : 'slide'}/#{sequence}"
29
+ end
30
+
31
+ #
32
+ # @param [Hash] params contains the parameters to help create the slide
33
+ # that is going to be displayed.
34
+ #
35
+ def initialize(params={})
36
+ @content = ""
37
+ @metadata = Metadata.new
38
+ params.each {|k,v| send("#{k}=",v) if respond_to? "#{k}=" }
39
+ end
40
+
41
+ # The raw, unformatted slide content.
42
+ attr_reader :content
43
+
44
+ #
45
+ # @param [String] value this is the new content initially is set or overrides
46
+ # the existing content within the slide
47
+ #
48
+ def content=(value)
49
+ @content = "#{value}\n"
50
+ end
51
+
52
+ #
53
+ # @param [String] append_raw_content this is additional raw content to add
54
+ # to the slide.
55
+ #
56
+ def <<(append_raw_content)
57
+ @content << "#{append_raw_content}\n"
58
+ end
59
+
60
+ #
61
+ # @return [Boolean] true if the slide has no content and false if the slide
62
+ # has content.
63
+ def empty?
64
+ @content.to_s.strip == ""
65
+ end
66
+
67
+ #
68
+ # A slide can contain various metadata to help define additional information
69
+ # about it.
70
+ #
71
+ # @param [Parade::Metadata] value metadata object which contains
72
+ # information for the slide
73
+ #
74
+ attr_accessor :metadata
75
+
76
+ # @return [String] the CSS classes for the slide
77
+ def slide_classes
78
+ title.downcase.gsub(' ','-')
79
+ end
80
+
81
+ # @return [String] the CSS classes for the content section of the slide
82
+ def content_classes
83
+ metadata.classes.join(" ")
84
+ end
85
+
86
+ # @return [String] the transition style for the slide
87
+ def transition
88
+ metadata.transition || "none"
89
+ end
90
+
91
+ # @return [String] an id for the slide
92
+ def id
93
+ metadata.id.to_s
94
+ end
95
+
96
+ def pre_renderers
97
+ [ Renderers::HTMLwithPygments ]
98
+ end
99
+
100
+ def post_renderers
101
+ [ Renderers::SpecialParagraphRenderer,
102
+ Renderers::CommandLineRenderer,
103
+ Renderers::ColumnsRenderer.new(:css_class => 'columns',:html_element => "h2",:segments => 12) ]
104
+ end
105
+
106
+ # @return [String] HTML rendering of the slide's raw contents.
107
+ def content_as_html
108
+ pre_renderers.inject(content) {|content,renderer| renderer.render(content) }
109
+ end
110
+
111
+ def slides
112
+ self
113
+ end
114
+
115
+ # @return [ERB] an ERB template that this slide will be rendered into
116
+ def template_file
117
+ erb_template_file = section.template metadata.template
118
+ ERB.new File.read(erb_template_file)
119
+ end
120
+
121
+ # @return [String] the HTML representation of the slide
122
+ def to_html
123
+ content = template_file.result(binding)
124
+ post_renderers.inject(content) {|content,renderer| renderer.render(content) }
125
+ end
126
+
127
+ end
128
+ end