parade 0.9.0 → 0.9.1

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.
data/README.md CHANGED
@@ -25,8 +25,8 @@ Parade has over presentational software:
25
25
 
26
26
  * Code Execution
27
27
 
28
- > Slides are able to provide execution and show results for javascript,
29
- Coffeescript, and Ruby live within the browser. Allowing for live
28
+ > Slides are able to provide execution and show results for JavaScript,
29
+ and Coffeescript live within the browser. Allowing for live
30
30
  demonstrations of code.
31
31
 
32
32
  * Web
@@ -301,7 +301,7 @@ Parade defines a number of special CSS classes:
301
301
  > make all slide text 70%
302
302
  >
303
303
  > ### execute
304
- > on Javascript, Coffeescript and Ruby highlighted code slides, you can
304
+ > on Javascript and Coffeescript highlighted code slides, you can
305
305
  > click on the code to execute it and display the results on the slide
306
306
 
307
307
 
@@ -513,6 +513,27 @@ Serves the parade presentation in the current directory
513
513
  >
514
514
  > parade serve
515
515
 
516
+ ## parade static html [path/to/parade/file]
517
+
518
+ Generates a static html representation of the presentation.
519
+
520
+ > ### Options
521
+ >
522
+ > These options are specified *after* the command.
523
+ >
524
+ > *-o, --output=file* Presentation output file
525
+
526
+ ## parade static pdf [path/to/parade/file]
527
+
528
+ Generates a pdf representation of the presentation.
529
+
530
+ > ### Options
531
+ >
532
+ > These options are specified *after* the command.
533
+ >
534
+ > *-o, --output=file* Presentation output file
535
+
536
+
516
537
  # Future Plans
517
538
 
518
539
  I really want this to evolve into a dynamic presentation software server,
data/bin/parade CHANGED
@@ -54,7 +54,7 @@ command [:s,:serve,:server] do |c|
54
54
  puts "
55
55
  -------------------------
56
56
 
57
- Your Parade presentation is now starting up.
57
+ yourr Parade presentation is now starting up.
58
58
 
59
59
  To view it plainly, visit [ #{url} ]
60
60
 
@@ -86,6 +86,9 @@ command [:static] do |c|
86
86
  c.desc "Force creation of the asset, even if one already exists with a similar name"
87
87
  c.switch [:f, :force]
88
88
 
89
+ c.desc 'Output file'
90
+ c.flag [:o,:output]
91
+
89
92
  c.action do |global,local,args|
90
93
 
91
94
  format_type = args.shift
@@ -5,9 +5,9 @@ module Parade
5
5
 
6
6
  #
7
7
  # Saves an html representation of the presentation to a single HTML file.
8
- #
8
+ #
9
9
  # @see HtmlOutput
10
- #
10
+ #
11
11
  class StaticHtml
12
12
  include RenderFromTemplate
13
13
 
@@ -5,7 +5,7 @@ module Parade
5
5
 
6
6
  #
7
7
  # Saves a PDF version of the presentation that is from the HtmlOutput
8
- #
8
+ #
9
9
  class StaticPdf
10
10
 
11
11
  def description
data/lib/parade/server.rb CHANGED
@@ -2,10 +2,6 @@ require_relative 'section'
2
2
  require_relative "parsers/dsl"
3
3
  require_relative 'renderers/update_image_paths'
4
4
 
5
- require_relative 'features/live_ruby'
6
- require_relative 'features/pdf_presentation'
7
- require_relative 'features/preshow'
8
-
9
5
  require_relative 'slide_post_renderers'
10
6
  require_relative 'slide_pre_renderers'
11
7
 
@@ -13,18 +9,17 @@ module Parade
13
9
 
14
10
  class Server < Sinatra::Application
15
11
 
16
- def initialize(app=nil)
17
- super(app)
18
- require_ruby_files
19
- end
20
12
 
21
- def require_ruby_files
22
- Dir.glob("#{settings.presentation_directory}/*.rb").map { |path| require path }
13
+ def self.views_path
14
+ File.dirname(__FILE__) + '/../views'
23
15
  end
24
16
 
25
- set :views, File.dirname(__FILE__) + '/../views'
26
- set :public_folder, File.dirname(__FILE__) + '/../public'
17
+ def self.public_path
18
+ File.dirname(__FILE__) + '/../public'
19
+ end
27
20
 
21
+ set :views, views_path
22
+ set :public_folder, public_path
28
23
  set :verbose, false
29
24
 
30
25
  set :presentation_directory do
@@ -32,9 +27,56 @@ module Parade
32
27
  end
33
28
 
34
29
  set :presentation_file, 'parade'
35
-
36
30
  set :default_presentation_files, [ 'parade', 'parade.json' ]
37
31
 
32
+
33
+ #
34
+ # Includes the specified module into the server to grant the server additional
35
+ # functionality.
36
+ #
37
+ def self.register(server_module)
38
+ include server_module
39
+ end
40
+
41
+ #
42
+ # Register a javascript file that will be loaded after the code javscript
43
+ #
44
+ def self.register_javascript(js_file)
45
+ plugin_javascript_files.push js_file
46
+ end
47
+
48
+ #
49
+ # @return the javascript files that have been registered by plugins
50
+ #
51
+ def self.plugin_javascript_files
52
+ @javscript_files ||= []
53
+ end
54
+
55
+ def self.register_stylesheet(css_file)
56
+ plugin_stylesheet_files.push css_file
57
+ end
58
+
59
+ def self.plugin_stylesheet_files
60
+ @css_files ||= []
61
+ end
62
+
63
+ def self.register_command(input,description)
64
+ plugin_commands.push OpenStruct.new(:input => input,:description => description)
65
+ end
66
+
67
+ def self.plugin_commands
68
+ @plugin_commands ||= []
69
+ end
70
+
71
+ def initialize(app=nil)
72
+ super(app)
73
+ require_ruby_files
74
+ end
75
+
76
+ def require_ruby_files
77
+ Dir.glob("#{settings.presentation_directory}/*.rb").map { |path| require path }
78
+ end
79
+
38
80
  def presentation_files
39
81
  (Array(settings.presentation_file) + settings.default_presentation_files).compact.uniq
40
82
  end
@@ -82,6 +124,18 @@ module Parade
82
124
  end
83
125
  end
84
126
 
127
+ def plugin_css_files
128
+ self.class.plugin_stylesheet_files.map do |path|
129
+ "<style>\n#{File.read(path)}\n</style>"
130
+ end.join("\n")
131
+ end
132
+
133
+ def plugin_js_files
134
+ self.class.plugin_javascript_files.map do |path|
135
+ "<script type='text/javascript'>#{File.read(path)}</script>"
136
+ end.join("\n")
137
+ end
138
+
85
139
  #
86
140
  # Create resources links to all the Javascript files found at the root of
87
141
  # presentation directory.
@@ -92,6 +146,10 @@ module Parade
92
146
  end
93
147
  end
94
148
 
149
+ def plugin_commands
150
+ self.class.plugin_commands
151
+ end
152
+
95
153
  def presentation
96
154
  load_presentation
97
155
  end
@@ -134,10 +192,6 @@ module Parade
134
192
  erb :onepage
135
193
  end
136
194
 
137
- include LiveRuby
138
- include PDFPresentation
139
- include Preshow
140
-
141
195
  end
142
196
 
143
- end
197
+ end
@@ -1,3 +1,3 @@
1
1
  module Parade
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  end
@@ -270,7 +270,6 @@ pre { margin: 1em 40px; padding: .25em; }
270
270
  .offscreen { position:absolute; top:0; left:-9999px; overflow:hidden; }
271
271
  #debugInfo { margin-left: 30px; }
272
272
  #notesInfo { margin-left: 30px; display: none }
273
- #preshow { display: none; }
274
273
 
275
274
  #help {
276
275
  background: #9f9;
@@ -389,7 +388,7 @@ a.fg-button { float:left; }
389
388
  cursor: pointer;
390
389
  }
391
390
 
392
- #tips, #preshow_timer {
391
+ #tips {
393
392
  display:inline;
394
393
  background-color:#000;
395
394
  color:#fff;
@@ -407,10 +406,6 @@ a.fg-button { float:left; }
407
406
  text-align:right;
408
407
  }
409
408
 
410
- #preshow_timer {
411
- bottom: 0px;
412
- }
413
-
414
409
  /** Print **/
415
410
  @media print {
416
411
  body {
@@ -1,5 +1,8 @@
1
1
  window.CodeExecutor = Spine.Class.create({
2
2
  init: function() {
3
+ this.visibleCodeBlocks = {};
4
+ this.executeCodeFor = {}
5
+
3
6
  $.subscribe("code:execute",$.proxy(function(e,code) {
4
7
  this.executeCode(code);
5
8
  },this));
@@ -7,10 +10,9 @@ window.CodeExecutor = Spine.Class.create({
7
10
  this.executeVisibleCode();
8
11
  },this));
9
12
  },
10
- visibleCodeBlocks: function() {
11
- return { ruby : $('.execute .ruby pre:visible'),
12
- js : $('.execute .javascript pre:visible'),
13
- coffee : $('.execute .coffeescript pre:visible') }
13
+ registerVisibleCodeBlock: function(language,elements,execution) {
14
+ this.visibleCodeBlocks[language] = elements;
15
+ this.executeCodeFor[language] = execution;
14
16
  },
15
17
  executeVisibleCode: function() {
16
18
 
@@ -32,35 +34,7 @@ window.CodeExecutor = Spine.Class.create({
32
34
  codeExecutor(code['code']);
33
35
  },
34
36
  executorForLanguage: function(language) {
35
- return this.supportedLanguages()[language];
36
- },
37
- supportedLanguages: function() {
38
- return { ruby : this.executeRuby,
39
- js : this.executeJavaScript,
40
- coffee : this.executeCoffee };
41
- },
42
- executeJavaScript: function(code) {
43
- var result = eval(code);
44
- setTimeout(function() { $.publish('code:execution:finished'); }, 250 );
45
- if (result != null) { $.publish('code:execution:results',result); }
46
- },
47
- executeRuby: function(code) {
48
- $.get('/eval_ruby', { code: code }, function(result) {
49
- if (result != null) { $.publish('code:execution:results',result); }
50
- $.publish('code:execution:finished');
51
- });
52
- },
53
- executeCoffee: function(code) {
54
- // When Coffeescript completes it's work the final result is encapsulated
55
- // within it. To get around it, the result of the last evaluation needs to
56
- // be assigned to the window, which we can then use for the purposes of
57
- // displaying the results.
58
-
59
- var codeWithAssignmentToResults = code + ';window.result=result;'
60
- eval(CoffeeScript.compile(codeWithAssignmentToResults));
61
-
62
- setTimeout(function() { $.publish('code:execution:finished'); }, 250 );
63
- if (result != null) { $.publish('code:execution:results',result); }
37
+ return this.executeCodeFor[language];
64
38
  }
65
39
  });
66
40
 
@@ -104,14 +78,28 @@ $(document).ready(function() {
104
78
  codeExecutor = new CodeExecutor;
105
79
  codeViewer = new CodeViewer;
106
80
 
81
+ codeExecutor.registerVisibleCodeBlock('js',$('.execute .javascript pre:visible'),function(code) {
82
+ var result = eval(code);
83
+ setTimeout(function() { $.publish('code:execution:finished'); }, 250 );
84
+ if (result != null) { $.publish('code:execution:results',result); }
85
+ });
86
+
107
87
  $('.execute pre.javascript').live("click", function() {
108
88
  var code = $(this).text();
109
89
  $.publish('code:execute',{ lang: 'js', code: code, elem: $(this) });
110
90
  });
111
91
 
112
- $('.execute pre.ruby').live("click", function() {
113
- var code = $(this).text();
114
- $.publish('code:execute',{ lang: 'ruby', code: code, elem: $(this) });
92
+ codeExecutor.registerVisibleCodeBlock('coffee',$('.execute .coffeescript pre:visible'), function(code) {
93
+ // When Coffeescript completes it's work the final result is encapsulated
94
+ // within it. To get around it, the result of the last evaluation needs to
95
+ // be assigned to the window, which we can then use for the purposes of
96
+ // displaying the results.
97
+
98
+ var codeWithAssignmentToResults = code + ';window.result=result;'
99
+ eval(CoffeeScript.compile(codeWithAssignmentToResults));
100
+
101
+ setTimeout(function() { $.publish('code:execution:finished'); }, 250 );
102
+ if (result != null) { $.publish('code:execution:results',result); }
115
103
  });
116
104
 
117
105
  $('.execute pre.coffeescript').live("click", function() {
@@ -42,10 +42,6 @@ $(document).ready(function() {
42
42
  $.publish("presentation:pause:toggle");
43
43
  });
44
44
 
45
- MainKeyboard.on('p', function(){
46
- $.publish("presentation:preshow:toggle");
47
- });
48
-
49
45
  MainKeyboard.on('enter', function(){
50
46
  $.publish("code:execute:visible")
51
47
  });
@@ -1,153 +1,5 @@
1
1
  $(document).ready(function() {
2
2
 
3
- window.Preshow = Spine.Class.create({
4
- init: function() {
5
- this.element = $(arguments[0]);
6
- this.secondsToRun = parseFloat(arguments[1] * 60);
7
-
8
- $.subscribe("presentation:preshow:toggle",$.proxy(function() {
9
- this.toggle();
10
- },this));
11
-
12
- },
13
- preshowRunning: false,
14
- start: function() {
15
-
16
- if (this.preshowIntervalReference) {
17
- return;
18
- }
19
-
20
- this.preservePresentationSpace();
21
-
22
- this.load();
23
-
24
- this.images = this.element.children("img");
25
-
26
- this.currentImageIndex = 0;
27
- this.totalImages = this.images.size();
28
-
29
-
30
- this.preshowRunning = true;
31
-
32
- $.publish("presentation:preshow:start");
33
-
34
- this.currentRunTime = 0;
35
- this.currentRemainingTime = this.secondsToRun;
36
-
37
- this.nextImage();
38
- this.preshowIntervalReference = setInterval($.proxy(this.perform,this),1000);
39
-
40
- },
41
- preservePresentationSpace: function() {
42
- this.storedPresentationSpace = this.element.html();
43
- },
44
- restorePresentationSpace: function() {
45
- this.element.empty();
46
- this.element.html(this.storedPresentationSpace);
47
- },
48
- displayImagesInterval: 5,
49
- perform: function() {
50
- this.currentRunTime ++;
51
- this.currentRemainingTime --;
52
-
53
- time = this.secondsToTime(this.currentRemainingTime);
54
-
55
- $('#preshow_timer').text(time + ' to go-time')
56
- var description = this.preshowDescription && this.preshowDescription[tmpImg.attr("ref")]
57
-
58
- if(description) {
59
- $('#tips').show();
60
- $('#tips').text(description);
61
- } else {
62
- $('#tips').hide();
63
- }
64
-
65
- if ((this.currentRunTime % this.displayImagesInterval) == 0) {
66
- this.nextImage();
67
- }
68
-
69
- this.preshowTip();
70
-
71
- if (this.currentRemainingTime <= 0) {
72
- this.stop();
73
- }
74
-
75
- },
76
- stop: function() {
77
-
78
- if (!this.preshowIntervalReference) {
79
- return;
80
- }
81
-
82
- this.preshowRunning = false;
83
- window.clearInterval(this.preshowIntervalReference);
84
- this.preshowIntervalReference = undefined;
85
-
86
- $('#preshow').remove();
87
- $('#tips').remove();
88
- $('#preshow_timer').remove();
89
-
90
- this.restorePresentationSpace();
91
-
92
- $.publish("presentation:preshow:stop");
93
-
94
- },
95
- toggle: function() {
96
-
97
- if (this.preshowIntervalReference) {
98
- this.stop();
99
- } else {
100
- this.start();
101
- }
102
-
103
- },
104
- preshowPath: "preshow",
105
- load: function() {
106
-
107
- $.getJSON(this.preshowPath, false, $.proxy(function(data) {
108
-
109
- this.element.after("<div id='preshow'></div><div id='tips'></div><div id='preshow_timer'></div>")
110
-
111
- $.each(data, $.proxy(function(i, n) {
112
- if(n == "preshow.json") {
113
- // has a descriptions file
114
- $.getJSON("/file/preshow/preshow.json", false, function(data) {
115
- this.preshowDescription = data;
116
- })
117
- } else {
118
- $('#preshow').append('<img ref="' + n + '" src="/file/preshow/' + n + '"/>');
119
- this.images = $("#preshow > img");
120
- this.totalImages = this.images.size();
121
- }
122
- },this));
123
-
124
- },this));
125
-
126
- },
127
- nextImage: function() {
128
- this.currentImageIndex ++;
129
- if((this.currentImageIndex + 1) > this.totalImages) {
130
- this.currentImageIndex = 0;
131
- }
132
-
133
- this.element.empty();
134
- tmpImg = this.images.eq(this.currentImageIndex).clone();
135
- $(tmpImg).attr('width', '1020');
136
- this.element.html(tmpImg);
137
- },
138
- preshowTip: function() {
139
-
140
- },
141
- secondsToTime: function(seconds) {
142
- minutes = Math.floor(seconds / 60)
143
- seconds = seconds - (minutes * 60)
144
- if(seconds < 10) {
145
- seconds = "0" + seconds
146
- }
147
- return minutes + ":" + seconds
148
- }
149
- });
150
-
151
3
  window.ToggleView = Spine.Class.create({
152
4
  init: function () {
153
5
 
@@ -513,23 +365,6 @@ $(document).ready(function() {
513
365
  this.showSlide()
514
366
  },this));
515
367
 
516
- $.subscribe("presentation:preshow:start",$.proxy(function() {
517
- this.footer.hide();
518
- },this));
519
-
520
- $.subscribe("presentation:preshow:stop",$.proxy(function() {
521
- this.footer.show();
522
-
523
- // Returning from a presentation requires the presentation frame to
524
- // be rebuilt.
525
-
526
- this.presentationFrame.cycle({
527
- timeout: 0
528
- });
529
- this.showSlide();
530
-
531
- },this));
532
-
533
368
  },
534
369
  centerSlides: function() {
535
370
  var presentation = this;
@@ -718,8 +553,6 @@ $(document).ready(function() {
718
553
  var locationWatcher = new LocationWatcher();
719
554
  locationWatcher.start();
720
555
 
721
- preshow = new Preshow("#preso",0.25);
722
-
723
556
  // bind event handlers
724
557
  /* window.onresize = resized; */
725
558
  /* window.onscroll = scrolled; */
data/lib/views/header.erb CHANGED
@@ -71,5 +71,8 @@
71
71
 
72
72
  <%= css 'default.css' %>
73
73
 
74
+ <%= plugin_css_files %>
74
75
  <%= custom_css_files %>
75
- <%= custom_js_files %>
76
+
77
+ <%= plugin_js_files %>
78
+ <%= custom_js_files %>
data/lib/views/index.erb CHANGED
@@ -23,7 +23,11 @@
23
23
  <tr><td class="key">f</td><td>toggle footer</td></tr>
24
24
  <tr><td class="key">r</td><td>reload slides</td></tr>
25
25
  <tr><td class="key">n</td><td>toggle notes</td></tr>
26
- <tr><td class="key">p</td><td>run preshow</td></tr>
26
+
27
+ <% plugin_commands.each do |command| %>
28
+ <tr><td class="key"><%= command.input %></td><td><%= command.description %></td></tr>
29
+ <% end %>
30
+
27
31
  </table>
28
32
  </div>
29
33
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parade
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -198,9 +198,6 @@ files:
198
198
  - lib/parade/commands/static_html.rb
199
199
  - lib/parade/commands/static_pdf.rb
200
200
  - lib/parade/commands/unknown.rb
201
- - lib/parade/features/live_ruby.rb
202
- - lib/parade/features/pdf_presentation.rb
203
- - lib/parade/features/preshow.rb
204
201
  - lib/parade/helpers/encode_image.rb
205
202
  - lib/parade/helpers/template_generator.rb
206
203
  - lib/parade/metadata/assignment.rb
@@ -231,7 +228,6 @@ files:
231
228
  - lib/parade/version.rb
232
229
  - lib/parade.rb
233
230
  - lib/public/css/960.css
234
- - lib/public/css/default.css
235
231
  - lib/public/css/fg.menu.css
236
232
  - lib/public/css/ghf_marked.css
237
233
  - lib/public/css/jquery-terminal.css
@@ -1,18 +0,0 @@
1
- module Parade
2
-
3
- module LiveRuby
4
-
5
- def self.included(server)
6
- server.get '/eval_ruby' do
7
- eval_ruby(params[:code])
8
- end
9
- end
10
-
11
- def eval_ruby(code)
12
- eval(code).to_s
13
- rescue => exception
14
- exception.message
15
- end
16
- end
17
-
18
- end
@@ -1,24 +0,0 @@
1
- module Parade
2
- module PDFPresentation
3
- def self.included(server)
4
-
5
- server.get '/pdf' do
6
-
7
- # TODO: Find the presentation file and/or regenerate it every time
8
-
9
- template_options = { 'erb_template_file' => File.join(File.dirname(__FILE__), "..", "..", "views", "pdf.erb"),
10
- 'custom_asset_path' => settings.presentation_directory,
11
- 'slides' => slides }
12
-
13
- html_content = TemplateGenerator.new(template_options).render
14
-
15
- # TODO the image references here are not full filepaths. creating issues
16
-
17
- kit = PDFKit.new(html_content,:page_size => 'Letter', :orientation => 'Landscape')
18
-
19
- send_file kit.to_file('presentation.pdf')
20
- end
21
-
22
- end
23
- end
24
- end
@@ -1,11 +0,0 @@
1
- module Parade
2
- module Preshow
3
- def self.included(server)
4
-
5
- server.get "/preshow" do
6
- Dir.glob("#{settings.presentation_directory}/preshow/*").map { |path| File.basename(path) }.to_json
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,3 +0,0 @@
1
- @media screen {
2
-
3
- }