showoff 0.3.4 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +24 -3
- data/Rakefile +0 -8
- data/bin/showoff +2 -8
- data/lib/showoff.rb +12 -9
- data/public/css/showoff.css +39 -24
- data/public/js/showoff.js +0 -2
- data/views/index.erb +5 -0
- data/views/onepage.erb +1 -3
- metadata +21 -7
data/README.rdoc
CHANGED
@@ -55,7 +55,7 @@ show an example presentation, so you can see what it's like.
|
|
55
55
|
You can break your slides up into sections of however many subdirectories deep
|
56
56
|
you need. ShowOff will recursively check all the directories mentioned in
|
57
57
|
your showoff.json file for any markdown files (.md). Each markdown file can
|
58
|
-
have any number of slides in it,
|
58
|
+
have any number of slides in it, separating each slide with the '!SLIDE'
|
59
59
|
keyword and optional slide styles.
|
60
60
|
|
61
61
|
For example, if you run 'showoff create my_new_pres' it will create a new
|
@@ -87,12 +87,18 @@ If you have multiple sections in your talk, you can make this json array
|
|
87
87
|
include all the sections you want to show in which order you want to show
|
88
88
|
them.
|
89
89
|
|
90
|
+
If you want to keep the ability to emit an HTML document from your
|
91
|
+
Markdown source file -- say, for a TextMate preview or a GitHub rendering
|
92
|
+
-- you can use angle brackets around the `!SLIDE` keyword and styles, e.g.
|
93
|
+
|
94
|
+
<!SLIDE bullets incremental transition=fade>
|
95
|
+
|
90
96
|
Some useful styles for each slide are:
|
91
97
|
|
92
98
|
* center - centers images on a slide
|
93
99
|
* full-page - allows an image to take up the whole slide
|
94
|
-
* bullets - sizes and
|
95
|
-
* smbullets - sizes and
|
100
|
+
* bullets - sizes and separates bullets properly (fits up to 5, generally)
|
101
|
+
* smbullets - sizes and separates more bullets (smaller, closer together)
|
96
102
|
* subsection - creates a different background for titles
|
97
103
|
* command - monospaces h1 title slides
|
98
104
|
* commandline - for pasted commandline sections (needs leading '$' for commands, then output on subsequent lines)
|
@@ -248,6 +254,17 @@ is your preference. An example of adding some styling is here.
|
|
248
254
|
Note that the example above uses CSS3 styling with ::+after+ and the +content+
|
249
255
|
-attribute to add an image to the slides.
|
250
256
|
|
257
|
+
= Language highlighting
|
258
|
+
|
259
|
+
Showoff uses {shjs}[http://shjs.sourceforge.net/] to highlight code blocks.
|
260
|
+
If you begin a code block with three @-signs followed by a
|
261
|
+
{programming language name}[http://shjs.sourceforge.net/doc/documentation.html],
|
262
|
+
that line will be stripped and the rest of the block will become sparkly
|
263
|
+
and colorful.
|
264
|
+
|
265
|
+
@@@ ruby
|
266
|
+
10.times { puts "Whee!" }
|
267
|
+
|
251
268
|
= Editor integration
|
252
269
|
|
253
270
|
The "add slide" feature can allow you to add the necessary boilerplate from your editor. If you are using vim, you can
|
@@ -346,6 +363,10 @@ These options are specified *after* the command.
|
|
346
363
|
|
347
364
|
Generate static version of presentation
|
348
365
|
|
366
|
+
=== PDF
|
367
|
+
Append a "/pdf" to the end of your presentation URL, and a PDF will be generated within the browser. For example,
|
368
|
+
http://localhost:9090/pdf
|
369
|
+
|
349
370
|
=== ZSH completion
|
350
371
|
You can complete commands and options in ZSH, by installing a script:
|
351
372
|
|
data/Rakefile
CHANGED
@@ -4,12 +4,4 @@ rescue LoadError
|
|
4
4
|
abort "Please `gem install mg`"
|
5
5
|
end
|
6
6
|
|
7
|
-
class MG
|
8
|
-
# Monkey patch until http://github.com/defunkt/mg/commit/no_safe_level
|
9
|
-
# is merged and released upstream.
|
10
|
-
def spec
|
11
|
-
@spec ||= eval(File.read(gemspec))
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
7
|
MG.new("showoff.gemspec")
|
data/bin/showoff
CHANGED
@@ -7,13 +7,7 @@ require 'gli'
|
|
7
7
|
|
8
8
|
include GLI
|
9
9
|
|
10
|
-
|
11
|
-
long_desc 'This command shows the currently installed version of ShowOff'
|
12
|
-
command [:version] do |c|
|
13
|
-
c.action do |global_options,options,args|
|
14
|
-
puts "ShowOff Version " + ShowOff::Version
|
15
|
-
end
|
16
|
-
end
|
10
|
+
version ShowOff::Version
|
17
11
|
|
18
12
|
desc 'Create new showoff presentation'
|
19
13
|
arg_name 'dir_name'
|
@@ -139,4 +133,4 @@ on_error do |exception|
|
|
139
133
|
true
|
140
134
|
end
|
141
135
|
|
142
|
-
GLI.run(ARGV)
|
136
|
+
exit GLI.run(ARGV)
|
data/lib/showoff.rb
CHANGED
@@ -2,33 +2,36 @@ require 'rubygems'
|
|
2
2
|
require 'sinatra/base'
|
3
3
|
require 'json'
|
4
4
|
require 'nokogiri'
|
5
|
-
require 'showoff_utils'
|
6
|
-
require 'princely'
|
7
5
|
require 'fileutils'
|
8
6
|
|
7
|
+
here = File.expand_path(File.dirname(__FILE__))
|
8
|
+
require "#{here}/showoff_utils"
|
9
|
+
require "#{here}/princely"
|
10
|
+
|
9
11
|
begin
|
10
12
|
require 'RMagick'
|
11
13
|
rescue LoadError
|
12
|
-
$stderr.puts 'image sizing disabled - install
|
14
|
+
$stderr.puts 'image sizing disabled - install rmagick'
|
13
15
|
end
|
14
16
|
|
15
17
|
begin
|
16
18
|
require 'pdfkit'
|
17
19
|
rescue LoadError
|
18
|
-
$stderr.puts 'pdf generation disabled - install
|
20
|
+
$stderr.puts 'pdf generation disabled - install pdfkit'
|
19
21
|
end
|
20
22
|
|
21
23
|
begin
|
22
24
|
require 'rdiscount'
|
23
25
|
rescue LoadError
|
24
26
|
require 'bluecloth'
|
27
|
+
Object.send(:remove_const,:Markdown)
|
25
28
|
Markdown = BlueCloth
|
26
29
|
end
|
27
30
|
require 'pp'
|
28
31
|
|
29
32
|
class ShowOff < Sinatra::Application
|
30
33
|
|
31
|
-
Version = VERSION = '0.
|
34
|
+
Version = VERSION = '0.4.1'
|
32
35
|
|
33
36
|
attr_reader :cached_image_size
|
34
37
|
|
@@ -72,7 +75,7 @@ class ShowOff < Sinatra::Application
|
|
72
75
|
end
|
73
76
|
|
74
77
|
def process_markdown(name, content, static=false)
|
75
|
-
slides = content.split(
|
78
|
+
slides = content.split(/^<?!SLIDE/)
|
76
79
|
slides.delete('')
|
77
80
|
final = ''
|
78
81
|
if slides.size > 1
|
@@ -82,7 +85,7 @@ class ShowOff < Sinatra::Application
|
|
82
85
|
md = ''
|
83
86
|
# extract content classes
|
84
87
|
lines = slide.split("\n")
|
85
|
-
content_classes = lines.shift.split rescue []
|
88
|
+
content_classes = lines.shift.strip.chomp('>').split rescue []
|
86
89
|
slide = lines.join("\n")
|
87
90
|
# add content class too
|
88
91
|
content_classes.unshift "content"
|
@@ -126,7 +129,7 @@ class ShowOff < Sinatra::Application
|
|
126
129
|
paths.pop
|
127
130
|
path = paths.join('/')
|
128
131
|
replacement_prefix = static ?
|
129
|
-
%(img src="
|
132
|
+
%(img src="file://#{options.pres_dir}/#{path}) :
|
130
133
|
%(img src="/image/#{path})
|
131
134
|
slide.gsub(/img src=\"(.*?)\"/) do |s|
|
132
135
|
img_path = File.join(path, $1)
|
@@ -322,7 +325,7 @@ class ShowOff < Sinatra::Application
|
|
322
325
|
path = showoff.instance_variable_get(:@root_path)
|
323
326
|
data = showoff.send(what, true)
|
324
327
|
if data.is_a?(File)
|
325
|
-
|
328
|
+
FileUtils.cp(data.path, "#{name}.pdf")
|
326
329
|
else
|
327
330
|
out = "#{path}/#{name}/static"
|
328
331
|
# First make a directory
|
data/public/css/showoff.css
CHANGED
@@ -1,24 +1,42 @@
|
|
1
1
|
@media screen {
|
2
2
|
body {
|
3
3
|
font-family: "Gill Sans", Helvetica, Arial, sans-serif;
|
4
|
+
background:#333;
|
5
|
+
overflow:hidden;
|
6
|
+
margin:0;
|
7
|
+
padding:0;
|
4
8
|
}
|
5
9
|
|
6
10
|
#preso, .slide {
|
7
11
|
background: #fff;
|
8
|
-
width:
|
9
|
-
height:
|
12
|
+
width: 1024px;
|
13
|
+
height: 768px;
|
10
14
|
margin-left:auto;
|
11
15
|
margin-right:auto;
|
12
16
|
overflow:hidden;
|
17
|
+
-webkit-box-shadow:0 0 25px rgba(0,0,0,0.35);
|
18
|
+
-moz-box-shadow:0 0 25px rgba(0,0,0,0.35);
|
19
|
+
box-shadow:0 0 25px rgba(0,0,0,0.35);
|
13
20
|
}
|
14
21
|
|
15
22
|
#footer {
|
16
|
-
background:
|
17
|
-
|
18
|
-
|
23
|
+
background: rgba(221,221,221,0.75);
|
24
|
+
color:#333;
|
25
|
+
padding: 2px 5px;
|
26
|
+
width: 1005px;
|
19
27
|
height: 20px;
|
20
|
-
|
21
|
-
|
28
|
+
line-height:20px;
|
29
|
+
font-size:14px;
|
30
|
+
position:relative;
|
31
|
+
top:-24px;
|
32
|
+
z-index: 16;
|
33
|
+
margin:0 auto;
|
34
|
+
-webkit-border-top-left-radius: 3px;
|
35
|
+
-webkit-border-top-right-radius: 3px;
|
36
|
+
-moz-border-radius-topleft: 3px;
|
37
|
+
-moz-border-radius-topright: 3px;
|
38
|
+
border-top-left-radius: 3px;
|
39
|
+
border-top-right-radius: 3px;
|
22
40
|
}
|
23
41
|
}
|
24
42
|
|
@@ -26,51 +44,47 @@
|
|
26
44
|
/* Portrait */
|
27
45
|
@media screen and (max-width: 320px)
|
28
46
|
{
|
29
|
-
#preso {
|
47
|
+
#preso {
|
30
48
|
margin: 0;
|
31
49
|
padding: 0;
|
32
50
|
width: 320px;
|
33
51
|
max-height: 356px;
|
34
|
-
margin-left:auto;
|
52
|
+
margin-left:auto;
|
35
53
|
margin-right:auto;
|
36
54
|
/* overflow:hidden;*/
|
37
55
|
}
|
38
|
-
#footer {
|
56
|
+
#footer {
|
39
57
|
background: #eee;
|
40
58
|
margin: 0;
|
41
59
|
padding: 2px;
|
42
60
|
width: 320px;
|
43
61
|
height: 20px;
|
44
|
-
margin-left:auto;
|
62
|
+
margin-left:auto;
|
45
63
|
margin-right:auto;
|
46
64
|
}
|
47
65
|
}
|
48
66
|
/* Landscape */
|
49
67
|
@media screen and (max-width: 480px)
|
50
68
|
{
|
51
|
-
#preso {
|
69
|
+
#preso {
|
52
70
|
margin: 0;
|
53
71
|
padding: 0;
|
54
72
|
/* min-height: 320px;*/
|
55
73
|
width: 480px;
|
56
|
-
margin-left:auto;
|
74
|
+
margin-left:auto;
|
57
75
|
margin-right:auto;
|
58
76
|
}
|
59
|
-
#footer {
|
77
|
+
#footer {
|
60
78
|
background: #eee;
|
61
79
|
margin: 0;
|
62
80
|
padding: 2px;
|
63
81
|
width: 480px;
|
64
82
|
height: 20px;
|
65
|
-
margin-left:auto;
|
83
|
+
margin-left:auto;
|
66
84
|
margin-right:auto;
|
67
85
|
}
|
68
86
|
}
|
69
87
|
|
70
|
-
.slide {
|
71
|
-
border: 1px solid #fff;
|
72
|
-
}
|
73
|
-
|
74
88
|
.center img {
|
75
89
|
display:block;
|
76
90
|
margin-left:auto;
|
@@ -149,6 +163,7 @@ pre { margin-left: 40px; font-size: 2.8em; }
|
|
149
163
|
|
150
164
|
.notes { display: none }
|
151
165
|
.hidden { position:absolute; top:0; left:-9999px; width:1px; height:1px; overflow:hidden; }
|
166
|
+
.buttonNav { display: none }
|
152
167
|
.offscreen { position:absolute; top:0; left:-9999px; overflow:hidden; }
|
153
168
|
#debugInfo { margin-left: 30px; }
|
154
169
|
#preshow { display: none; }
|
@@ -179,7 +194,7 @@ a.fg-button { float:left; }
|
|
179
194
|
|
180
195
|
.fg-button.ui-state-loading .ui-icon { background: url(spinner_bar.gif) no-repeat 0 0; }
|
181
196
|
|
182
|
-
#navmenu { position: absolute; top: 10px; left: 10px; width: 50px; }
|
197
|
+
#navmenu { position: absolute; top: 10px; left: 10px; width: 50px; z-index: 16; }
|
183
198
|
|
184
199
|
.code .c { color: #999988; font-style: italic } /* Comment */
|
185
200
|
.code .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
@@ -287,11 +302,11 @@ a.fg-button { float:left; }
|
|
287
302
|
body {
|
288
303
|
font-size: 70%;
|
289
304
|
}
|
290
|
-
|
305
|
+
|
291
306
|
#preso, .slide {
|
292
307
|
border: 1px solid #999;
|
293
308
|
}
|
294
|
-
|
309
|
+
|
295
310
|
.slide .center {
|
296
311
|
width: 600px;
|
297
312
|
height: 600px;
|
@@ -299,7 +314,7 @@ a.fg-button { float:left; }
|
|
299
314
|
text-align: center;
|
300
315
|
vertical-align: middle;
|
301
316
|
}
|
302
|
-
|
317
|
+
|
303
318
|
#preso, .slide {
|
304
319
|
background: #fff;
|
305
320
|
width: 600px;
|
@@ -317,7 +332,7 @@ a.fg-button { float:left; }
|
|
317
332
|
margin-left:auto;
|
318
333
|
margin-right:auto;
|
319
334
|
}
|
320
|
-
|
335
|
+
|
321
336
|
pre, code {
|
322
337
|
font-family: Monaco, monospace;
|
323
338
|
}
|
data/public/js/showoff.js
CHANGED
@@ -190,8 +190,6 @@ function showSlide(back_step) {
|
|
190
190
|
if (fullPage) {
|
191
191
|
$('#preso').css({'width' : '100%', 'overflow' : 'visible'});
|
192
192
|
currentSlide.css({'width' : '100%', 'text-align' : 'center', 'overflow' : 'visible'});
|
193
|
-
} else {
|
194
|
-
$('#preso').css({'width' : '1020px', 'overflow' : 'hidden'});
|
195
193
|
}
|
196
194
|
|
197
195
|
percent = getSlidePercent()
|
data/views/index.erb
CHANGED
@@ -61,6 +61,11 @@
|
|
61
61
|
</table>
|
62
62
|
</div>
|
63
63
|
|
64
|
+
<div class="buttonNav">
|
65
|
+
<input type="submit" onClick="prevStep();" value="prev"/>
|
66
|
+
<input type="submit" onClick="nextStep();" value="next"/>
|
67
|
+
</div>
|
68
|
+
|
64
69
|
<div id="preso">loading presentation...</div>
|
65
70
|
<div id="footer">
|
66
71
|
<span id="slideInfo"></span>
|
data/views/onepage.erb
CHANGED
@@ -12,9 +12,7 @@
|
|
12
12
|
<%= inline_css(['onepage.css'], 'public/css') %>
|
13
13
|
<% end %>
|
14
14
|
<%= inline_css(['reset.css', 'showoff.css', 'theme/ui.all.css', 'sh_style.css'], 'public/css') %>
|
15
|
-
|
16
|
-
<%= inline_css(css_file) %>
|
17
|
-
<% end %>
|
15
|
+
<%= inline_css(css_files) %>
|
18
16
|
|
19
17
|
<% if !@no_js %>
|
20
18
|
<%= inline_js(['jquery-1.4.2.min.js', 'jquery-print.js', 'showoff.js', 'onepage.js', 'sh_main.min.js', 'core.js', 'showoffcore.js'], 'public/js') %>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 3
|
9
8
|
- 4
|
10
|
-
|
9
|
+
- 1
|
10
|
+
version: 0.4.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Scott Chacon
|
@@ -82,14 +82,28 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - ">="
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
hash:
|
85
|
+
hash: 21
|
86
86
|
segments:
|
87
87
|
- 1
|
88
|
-
-
|
89
|
-
-
|
90
|
-
version: 1.
|
88
|
+
- 2
|
89
|
+
- 5
|
90
|
+
version: 1.2.5
|
91
91
|
type: :runtime
|
92
92
|
version_requirements: *id005
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: mg
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
type: :development
|
106
|
+
version_requirements: *id006
|
93
107
|
description: " ShowOff is a Sinatra web app that reads simple configuration files for a\n presentation. It is sort of like a Keynote web app engine. I am using it\n to do all my talks in 2010, because I have a deep hatred in my heart for\n Keynote and yet it is by far the best in the field.\n\n The idea is that you setup your slide files in section subdirectories and\n then startup the showoff server in that directory. It will read in your\n showoff.json file for which sections go in which order and then will give \n you a URL to present from.\n"
|
94
108
|
email: schacon@gmail.com
|
95
109
|
executables:
|