slide-em-up 0.1.8 → 0.2.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.
- data/README.md +105 -3
- data/bin/slide-em-up +3 -1
- data/lib/slide-em-up/presentation.rb +1 -1
- data/lib/slide-em-up/remote_api.rb +52 -0
- data/lib/slide-em-up/routes.rb +20 -0
- data/lib/slide-em-up/version.rb +1 -1
- data/lib/slide-em-up.rb +5 -3
- data/themes/3d_slideshow/js/slideshow.js +28 -1
- data/themes/html5rocks/js/slides.js +21 -0
- data/themes/shower/js/script.js +42 -0
- metadata +17 -15
data/README.md
CHANGED
@@ -6,13 +6,114 @@ a style and it displays it in HTML5. With a browser in full-screen, you can
|
|
6
6
|
make amazing presentations!
|
7
7
|
|
8
8
|
|
9
|
+
How to do your first presentation with Slide'em up?
|
10
|
+
---------------------------------------------------
|
11
|
+
|
12
|
+
1. Install slide-em-up: `gem install slide-em-up`
|
13
|
+
2. Create a directory for your presentation: `mkdir foobar && cd foobar`
|
14
|
+
3. Create a section for your slides: `mkdir main_section`
|
15
|
+
4. Write some slides: `vim main_section/slides.md`
|
16
|
+
|
17
|
+
!SLIDE
|
18
|
+
# My First slide #
|
19
|
+
It's awesome
|
20
|
+
|
21
|
+
!SLIDE
|
22
|
+
# My second slide #
|
23
|
+
This rocks too!
|
24
|
+
|
25
|
+
5. Write the `presentation.json` file with the metadata:
|
26
|
+
|
27
|
+
{
|
28
|
+
"title": "My first presentation",
|
29
|
+
"theme": "shower",
|
30
|
+
"sections": ["main_section"]
|
31
|
+
}
|
32
|
+
|
33
|
+
6. Launch the tool: `slide-em-up`
|
34
|
+
7. Open your browser on http://localhost:9000/
|
35
|
+
8. Use the arrows keys to navigate between the slides
|
36
|
+
|
37
|
+
|
38
|
+
Markup for the slides
|
39
|
+
---------------------
|
40
|
+
|
41
|
+
This slides are writen in [Markdown](http://daringfireball.net/projects/markdown/syntax)
|
42
|
+
and `!SLIDE` is the indicator for a new slide.
|
43
|
+
|
44
|
+
Example:
|
45
|
+
|
46
|
+
!SLIDE
|
47
|
+
# Title of the first slide #
|
48
|
+
## A subtitle ##
|
49
|
+
And some text...
|
50
|
+
|
51
|
+
!SLIDE
|
52
|
+
# Another slide #
|
53
|
+
|
54
|
+
* a
|
55
|
+
* bullet
|
56
|
+
* list
|
57
|
+
|
58
|
+
!SLIDE
|
59
|
+
# Third slide #
|
60
|
+
|
61
|
+
1. **bold**
|
62
|
+
2. _italics_
|
63
|
+
3. https://github.com/
|
64
|
+
|
65
|
+
|
66
|
+
Syntax Highlighting
|
67
|
+
-------------------
|
68
|
+
|
69
|
+
To highlight some code in your slides, you have to install
|
70
|
+
[pygments](http://pygments.org/). Then, surround your code with backticks
|
71
|
+
like this:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class Foobar
|
75
|
+
def baz
|
76
|
+
puts "Foobar says baz"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
|
82
|
+
Themes
|
83
|
+
------
|
84
|
+
|
85
|
+
Several themes are available: shower, 3d_slideshow and html5rocks.
|
86
|
+
To choose the theme for your presentation, edit the `presentation.json`
|
87
|
+
file and change the `"theme"` element.
|
88
|
+
|
89
|
+
|
90
|
+
Remote Control
|
91
|
+
--------------
|
92
|
+
|
93
|
+
When your start slide-em-up in console, a message says something like:
|
94
|
+
|
95
|
+
> Your remote key is 652df
|
96
|
+
|
97
|
+
This remote key can be used to send actions to browsers that display the
|
98
|
+
presentation. For example, this command goes to the next line:
|
99
|
+
|
100
|
+
curl http://localhost:9000/remote/652df/next
|
101
|
+
|
102
|
+
The last part of the URL is the action and can be `next`, `prev`, `up` or
|
103
|
+
`down`.
|
104
|
+
|
105
|
+
It's also possible to force slide-em-up to use a specific remote key by
|
106
|
+
setting the `APIKEY` environment variable:
|
107
|
+
|
108
|
+
APIKEY=foobar slide-em-up
|
109
|
+
|
110
|
+
|
9
111
|
TODO
|
10
112
|
----
|
11
113
|
|
12
|
-
* Explain how to install and use it in README
|
13
114
|
* Same command line stuff than showoff
|
14
|
-
*
|
15
|
-
*
|
115
|
+
* Add a showoff theme for compatibility
|
116
|
+
* Many more themes and features
|
16
117
|
|
17
118
|
|
18
119
|
Issues or Suggestions
|
@@ -33,6 +134,7 @@ Scott Chacon is the guy who made [ShowOff](https://github.com/schacon/showoff).
|
|
33
134
|
Slide'em up is only a copy of ShowOff, where sinatra was replaced by Goliath.
|
34
135
|
|
35
136
|
Themes were picked from the internet. Thanks to:
|
137
|
+
|
36
138
|
- Hakim El Hattab for 3d_slideshow
|
37
139
|
- Google for html5rocks
|
38
140
|
- Vadim Makeev for shower
|
data/bin/slide-em-up
CHANGED
@@ -5,7 +5,9 @@ require "goliath/runner"
|
|
5
5
|
|
6
6
|
|
7
7
|
presentation = SlideEmUp::Presentation.new(Dir.pwd)
|
8
|
+
key = ENV['APIKEY'] || rand(1_000_000).to_s(16)
|
9
|
+
puts "Your remote key is #{key}"
|
8
10
|
|
9
11
|
runner = Goliath::Runner.new(ARGV, nil)
|
10
|
-
runner.app = SlideEmUp::
|
12
|
+
runner.app = SlideEmUp::Routes.run(presentation, :remote_key => key)
|
11
13
|
runner.run
|
@@ -16,7 +16,7 @@ module SlideEmUp
|
|
16
16
|
|
17
17
|
def initialize(dir)
|
18
18
|
infos = extract_normal_infos(dir) || extract_infos_from_showoff(dir) || {}
|
19
|
-
infos = { "title" => "No title", "theme" => "
|
19
|
+
infos = { "title" => "No title", "theme" => "shower" }.merge(infos)
|
20
20
|
@meta = build_meta(infos["title"], dir)
|
21
21
|
@theme = build_theme(infos["theme"])
|
22
22
|
@common = build_theme("common")
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "goliath/api"
|
2
|
+
|
3
|
+
module SlideEmUp
|
4
|
+
class RemoteAPI < Goliath::API
|
5
|
+
def initialize(key)
|
6
|
+
# Secret token...
|
7
|
+
@key = key
|
8
|
+
|
9
|
+
# Share channel between connections
|
10
|
+
@chan = ::EM::Channel.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def response(env)
|
14
|
+
path_info = Rack::Utils.unescape(env['PATH_INFO'])
|
15
|
+
slash, key, action = path_info.split('/', 3)
|
16
|
+
|
17
|
+
# Events are public
|
18
|
+
return stream_events(env) if 'events' == action
|
19
|
+
|
20
|
+
# Sending events is restricted
|
21
|
+
return forbidden unless key == @key
|
22
|
+
|
23
|
+
@chan.push(action)
|
24
|
+
[200, {
|
25
|
+
"Content-Type" => "text/plain; charset=utf-8",
|
26
|
+
"Content-Length" => Rack::Utils.bytesize(action).to_s
|
27
|
+
}, [action]]
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_close(env)
|
31
|
+
return unless env['subscription']
|
32
|
+
env.logger.info "Stream connection closed."
|
33
|
+
@chan.unsubscribe(env['subscription'])
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def stream_events(env)
|
39
|
+
env['subscription'] = @chan.subscribe do |msg|
|
40
|
+
env.stream_send("data: #{msg}\n\n")
|
41
|
+
end
|
42
|
+
streaming_response(200, {"Content-Type" => "text/event-stream"})
|
43
|
+
end
|
44
|
+
|
45
|
+
def forbidden
|
46
|
+
[403, {
|
47
|
+
"Content-Type" => "text/plain",
|
48
|
+
"Content-Length" => "10"
|
49
|
+
}, ["Forbidden\n"]]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rack/builder"
|
2
|
+
|
3
|
+
|
4
|
+
module SlideEmUp
|
5
|
+
class Routes
|
6
|
+
|
7
|
+
def self.run(presentation, opts = {})
|
8
|
+
Rack::Builder.new do
|
9
|
+
map '/remote' do
|
10
|
+
run SlideEmUp::RemoteAPI.new(opts[:remote_key])
|
11
|
+
end
|
12
|
+
|
13
|
+
map '/' do
|
14
|
+
run SlideEmUp::SlidesAPI.new(presentation)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/slide-em-up/version.rb
CHANGED
data/lib/slide-em-up.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module SlideEmUp
|
2
|
-
autoload :Presentation,
|
3
|
-
autoload :SlidesAPI,
|
4
|
-
autoload :
|
2
|
+
autoload :Presentation, "slide-em-up/presentation"
|
3
|
+
autoload :SlidesAPI, "slide-em-up/slides_api"
|
4
|
+
autoload :RemoteAPI, "slide-em-up/remote_api"
|
5
|
+
autoload :Routes, "slide-em-up/routes"
|
6
|
+
autoload :VERSION, "slide-em-up/version"
|
5
7
|
end
|
@@ -42,11 +42,38 @@ var Slideshow = (function(){
|
|
42
42
|
document.addEventListener('keydown', onDocumentKeyDown, false);
|
43
43
|
document.addEventListener('touchstart', onDocumentTouchStart, false);
|
44
44
|
window.addEventListener('hashchange', onWindowHashChange, false);
|
45
|
+
|
46
|
+
startEventSourceHandler('/remote/sub/events');
|
45
47
|
|
46
48
|
// Read the initial state of the URL (hash)
|
47
49
|
readURL();
|
48
50
|
}
|
49
|
-
|
51
|
+
|
52
|
+
function startEventSourceHandler (uri) {
|
53
|
+
if (window['EventSource'] == undefined) return ;
|
54
|
+
|
55
|
+
var source = new EventSource(uri);
|
56
|
+
|
57
|
+
source.onmessage = function(e) {
|
58
|
+
switch(e.data){
|
59
|
+
case 'next':
|
60
|
+
Slideshow.navigateRight();
|
61
|
+
break;
|
62
|
+
case 'prev':
|
63
|
+
Slideshow.navigateLeft();
|
64
|
+
break;
|
65
|
+
case 'up':
|
66
|
+
Slideshow.navigateUp();
|
67
|
+
break;
|
68
|
+
case 'down':
|
69
|
+
Slideshow.navigateDown();
|
70
|
+
break;
|
71
|
+
default:
|
72
|
+
console.log(e);
|
73
|
+
};
|
74
|
+
};
|
75
|
+
}
|
76
|
+
|
50
77
|
/**
|
51
78
|
* Handler for the document level 'keydown' event.
|
52
79
|
*
|
@@ -304,6 +304,7 @@
|
|
304
304
|
function(e) { if (e.state) { _t.go(e.state); } }, false);
|
305
305
|
query('#left-init-key').addEventListener('click',
|
306
306
|
function() { _t.next(); }, false);
|
307
|
+
this._startEventSource('/remote/sub/events');
|
307
308
|
this._update();
|
308
309
|
};
|
309
310
|
|
@@ -320,6 +321,26 @@
|
|
320
321
|
});
|
321
322
|
return slideCount + 1;
|
322
323
|
},
|
324
|
+
_startEventSource: function(uri) {
|
325
|
+
if (window['EventSource'] == undefined) return ;
|
326
|
+
|
327
|
+
var source = new EventSource(uri);
|
328
|
+
var _t = this;
|
329
|
+
source.onmessage = function(e) {
|
330
|
+
switch(e.data){
|
331
|
+
case 'next':
|
332
|
+
_t.next(); break;
|
333
|
+
case 'prev':
|
334
|
+
_t.prev(); break;
|
335
|
+
case 'up':
|
336
|
+
_t.showNotes(); break;
|
337
|
+
case 'down':
|
338
|
+
_t.switch3D(); break;
|
339
|
+
default:
|
340
|
+
console.log(e);
|
341
|
+
};
|
342
|
+
};
|
343
|
+
},
|
323
344
|
_update: function(dontPush) {
|
324
345
|
// in order to delay the time where the counter shows the slide number we check if
|
325
346
|
// the slides are already loaded (so we show the loading... instead)
|
data/themes/shower/js/script.js
CHANGED
@@ -81,6 +81,47 @@
|
|
81
81
|
}
|
82
82
|
}
|
83
83
|
|
84
|
+
function startEventSourceHandler (uri) {
|
85
|
+
if (window['EventSource'] == undefined) return ;
|
86
|
+
|
87
|
+
var source = new EventSource(uri);
|
88
|
+
var current_slide_number = getCurrentSlideNumber();
|
89
|
+
|
90
|
+
source.onmessage = function(e) {
|
91
|
+
switch(e.data){
|
92
|
+
case 'next':
|
93
|
+
current_slide_number++;
|
94
|
+
goToSlide(current_slide_number);
|
95
|
+
break;
|
96
|
+
case 'prev':
|
97
|
+
current_slide_number--;
|
98
|
+
goToSlide(current_slide_number);
|
99
|
+
break;
|
100
|
+
case 'up':
|
101
|
+
if (!isSlideListMode()) {
|
102
|
+
e.preventDefault();
|
103
|
+
|
104
|
+
history.pushState(null, null, url.pathname + getSlideHashByNumber(current_slide_number));
|
105
|
+
enterSlideListMode();
|
106
|
+
scrollToCurrentSlide();
|
107
|
+
}
|
108
|
+
break;
|
109
|
+
case 'down':
|
110
|
+
if (isSlideListMode()) {
|
111
|
+
e.preventDefault();
|
112
|
+
|
113
|
+
history.pushState(null, null, url.pathname + '?full' + getSlideHashByNumber(current_slide_number));
|
114
|
+
enterSingleSlideMode();
|
115
|
+
|
116
|
+
updateProgress(current_slide_number);
|
117
|
+
}
|
118
|
+
break;
|
119
|
+
default:
|
120
|
+
console.log(e);
|
121
|
+
};
|
122
|
+
};
|
123
|
+
}
|
124
|
+
|
84
125
|
window.addEventListener('DOMContentLoaded', function () {
|
85
126
|
if (!isSlideListMode()) {
|
86
127
|
// "?full" is present without slide hash so we should display first
|
@@ -210,4 +251,5 @@
|
|
210
251
|
}
|
211
252
|
}, false);
|
212
253
|
|
254
|
+
startEventSourceHandler('/remote/sub/events');
|
213
255
|
}());
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slide-em-up
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-09-13 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: goliath
|
16
|
-
requirement: &
|
16
|
+
requirement: &79848310 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.9'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *79848310
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redcarpet
|
27
|
-
requirement: &
|
27
|
+
requirement: &79852140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '1.17'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *79852140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: erubis
|
38
|
-
requirement: &
|
38
|
+
requirement: &79874950 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '2.7'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *79874950
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: yajl-ruby
|
49
|
-
requirement: &
|
49
|
+
requirement: &81723610 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0.8'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *81723610
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: albino
|
60
|
-
requirement: &
|
60
|
+
requirement: &82417980 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '1.3'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *82417980
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
|
-
requirement: &
|
71
|
+
requirement: &83019290 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '2.3'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *83019290
|
80
80
|
description: Slide'em up is a presentation tool that displays markdown-formatted slides
|
81
81
|
email: bruno.michel@af83.com
|
82
82
|
executables:
|
@@ -91,6 +91,8 @@ files:
|
|
91
91
|
- bin/slide-em-up
|
92
92
|
- lib/slide-em-up.rb
|
93
93
|
- lib/slide-em-up/slides_api.rb
|
94
|
+
- lib/slide-em-up/remote_api.rb
|
95
|
+
- lib/slide-em-up/routes.rb
|
94
96
|
- lib/slide-em-up/presentation.rb
|
95
97
|
- lib/slide-em-up/version.rb
|
96
98
|
- themes/shower/index.erb
|
@@ -143,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
145
|
version: '0'
|
144
146
|
requirements: []
|
145
147
|
rubyforge_project:
|
146
|
-
rubygems_version: 1.8.
|
148
|
+
rubygems_version: 1.8.10
|
147
149
|
signing_key:
|
148
150
|
specification_version: 3
|
149
151
|
summary: Slide'em up is a presentation tool that displays markdown-formatted slides
|