showoff 0.12.2 → 0.13.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.
- checksums.yaml +4 -4
- data/LICENSE +3 -1
- data/Rakefile +27 -2
- data/bin/showoff +22 -12
- data/lib/showoff.rb +21 -43
- data/lib/showoff/version.rb +1 -1
- data/lib/showoff_utils.rb +79 -14
- data/public/css/showoff.css +12 -1
- metadata +2 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c54ccde20fbe6df23ec6b8760dc4c379fdd5e510
|
4
|
+
data.tar.gz: 1da82fd0d90fbdeffee8da521ab4fba731046672
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d3d1f9f9e699646c389383282dabb862dd7c9ae0fe681a9a63f1efc158dea921847ba10a34b415352a47e74bed93a0a040fac600e416445d2f2545d14481087
|
7
|
+
data.tar.gz: 6c100036f06dd912ba08f8eeca4670807d342103e4e9db5946fafbee629e10f9765785ef074a8aa06006c231b107d136090745ef3ed74c1fa5b34e661242621d
|
data/LICENSE
CHANGED
data/Rakefile
CHANGED
@@ -1,8 +1,33 @@
|
|
1
|
-
task default
|
1
|
+
task :default do
|
2
|
+
system("rake -T")
|
3
|
+
end
|
2
4
|
|
3
5
|
desc "Build HTML documentation"
|
4
6
|
task :doc do
|
5
|
-
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
FileUtils.rm_rf('doc')
|
10
|
+
Dir.chdir('documentation') do
|
11
|
+
system("rdoc --main -HOME.rdoc /*.rdoc --op ../doc")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Update docs for webpage"
|
16
|
+
task 'doc:website' => [:doc] do
|
17
|
+
require 'fileutils'
|
18
|
+
|
19
|
+
if system('git checkout gh-pages')
|
20
|
+
FileUtils.rm_rf('documentation')
|
21
|
+
FileUtils.mv('doc', 'documentation')
|
22
|
+
system('git add documentation')
|
23
|
+
system('git commit -m "updating docs"')
|
24
|
+
system('git checkout -')
|
25
|
+
|
26
|
+
puts "Publish updates by pushing to Github:"
|
27
|
+
puts
|
28
|
+
puts " git push upstream gh-pages"
|
29
|
+
puts
|
30
|
+
end
|
6
31
|
end
|
7
32
|
|
8
33
|
desc "Run tests"
|
data/bin/showoff
CHANGED
@@ -21,10 +21,6 @@ A web based presentation engine with awesome interaction features.
|
|
21
21
|
that are served locally for presentation via web browser. Your audience can
|
22
22
|
view presentations directly as well, and interact with you in many ways.
|
23
23
|
|
24
|
-
ShowOff can optionally use the RMagick gem for automatic image resizing
|
25
|
-
functionality. If RMagick is available, images included in your presentation
|
26
|
-
will be resized down to meet size constraints of your presentation if needed.
|
27
|
-
|
28
24
|
Showoff can optionally use the PDFKit gem to autogenerate PDF files on demand.
|
29
25
|
Viewers can access the /pdf endpoint to download a generated PDF file. This
|
30
26
|
functionality is likely to be deprecated, since it is simpler and easier to
|
@@ -36,29 +32,31 @@ desc
|
|
36
32
|
|
37
33
|
|
38
34
|
desc 'Create new showoff presentation'
|
39
|
-
arg_name 'dir_name'
|
40
35
|
long_desc 'This command helps start a new showoff presentation by setting up the proper directory structure for you. It takes the directory name you would like showoff to create for you.'
|
41
36
|
command [:create,:init] do |c|
|
42
37
|
|
43
38
|
c.desc 'Don''t create sample slides'
|
44
39
|
c.switch [:n,:nosamples]
|
45
40
|
|
46
|
-
c.desc '
|
41
|
+
c.desc 'Comma separated list of initial slide directory name(s).'
|
47
42
|
c.default_value 'one'
|
48
43
|
c.flag [:d,:slidedir]
|
49
44
|
|
50
45
|
c.action do |global_options,options,args|
|
51
|
-
|
52
|
-
ShowOffUtils.create(
|
46
|
+
dir_name = args.first || '.'
|
47
|
+
ShowOffUtils.create(dir_name,!options[:n],options[:d])
|
53
48
|
if options[:n]
|
54
|
-
puts "Add slides and update #{
|
49
|
+
puts "Add slides and update #{dir_name}/#{ShowOffUtils.presentation_config_file}"
|
50
|
+
end
|
51
|
+
if args.empty?
|
52
|
+
puts "Run 'showoff serve' to see your new slideshow"
|
53
|
+
else
|
54
|
+
puts "Run 'showoff serve' in the #{dir_name} directory to see your new slideshow"
|
55
55
|
end
|
56
|
-
puts "Run 'showoff serve' in the #{args[0]} directory to see your new slideshow"
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
desc 'Build a showoff presentation from a showoff.json
|
61
|
-
arg_name 'dir_name'
|
59
|
+
desc 'Build a showoff presentation from a showoff.json outline'
|
62
60
|
long_desc 'This command helps start a new showoff presentation by creating each slide listing in the showoff.json file.'
|
63
61
|
command [:skeleton] do |c|
|
64
62
|
|
@@ -71,6 +69,18 @@ command [:skeleton] do |c|
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
72
|
+
desc 'Validate the consistency of your presentation.'
|
73
|
+
long_desc 'This ensures that each file listed in showoff.json exists and validates code blocks on each slide.'
|
74
|
+
command [:validate] do |c|
|
75
|
+
|
76
|
+
c.desc 'alternate json filename'
|
77
|
+
c.flag [:f,:file]
|
78
|
+
|
79
|
+
c.action do |global_options,options,args|
|
80
|
+
ShowOffUtils.validate(options[:f])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
74
84
|
desc 'Puts your showoff presentation into a gh-pages branch'
|
75
85
|
long_desc 'Generates a static version of your presentation into your gh-pages branch for publishing to GitHub Pages'
|
76
86
|
command :github do |c|
|
data/lib/showoff.rb
CHANGED
@@ -7,27 +7,13 @@ require 'pathname'
|
|
7
7
|
require 'logger'
|
8
8
|
require 'htmlentities'
|
9
9
|
require 'sinatra-websocket'
|
10
|
+
require 'tempfile'
|
10
11
|
|
11
12
|
here = File.expand_path(File.dirname(__FILE__))
|
12
13
|
require "#{here}/showoff_utils"
|
13
14
|
require "#{here}/commandline_parser"
|
14
15
|
require "#{here}/keymap"
|
15
16
|
|
16
|
-
begin
|
17
|
-
require 'rmagick'
|
18
|
-
puts "********************************************************************************"
|
19
|
-
puts " RMagick support has been deprecated."
|
20
|
-
puts
|
21
|
-
puts "CSS auto-scaling has improved greatly, and the image manipulation should no"
|
22
|
-
puts "longer be required. If you have images that don't scale properly, then you"
|
23
|
-
puts "should write custom styles to size them appropriately."
|
24
|
-
puts
|
25
|
-
puts " RMagic support will be removed completely in the next release."
|
26
|
-
puts "********************************************************************************"
|
27
|
-
rescue LoadError
|
28
|
-
# nop
|
29
|
-
end
|
30
|
-
|
31
17
|
begin
|
32
18
|
require 'pdfkit'
|
33
19
|
rescue LoadError
|
@@ -128,6 +114,14 @@ class ShowOff < Sinatra::Application
|
|
128
114
|
settings.showoff_config['locked'] ||= Array.new
|
129
115
|
end
|
130
116
|
|
117
|
+
# default code validators
|
118
|
+
settings.showoff_config['validators'] ||= {}
|
119
|
+
settings.showoff_config['validators']['perl'] ||= 'perl -cw'
|
120
|
+
settings.showoff_config['validators']['puppet'] ||= 'puppet parser validate'
|
121
|
+
settings.showoff_config['validators']['python'] ||= 'python -m py_compile'
|
122
|
+
settings.showoff_config['validators']['ruby'] ||= 'ruby -c'
|
123
|
+
settings.showoff_config['validators']['shell'] ||= 'sh -n'
|
124
|
+
|
131
125
|
# highlightjs syntax style
|
132
126
|
@highlightStyle = settings.showoff_config['highlight'] || 'default'
|
133
127
|
|
@@ -453,7 +447,7 @@ class ShowOff < Sinatra::Application
|
|
453
447
|
end
|
454
448
|
|
455
449
|
# Load and replace any file tags
|
456
|
-
content.scan(/(~~~FILE:([
|
450
|
+
content.scan(/(~~~FILE:([^:~]*):?(.*)?~~~)/).each do |match|
|
457
451
|
# make a list of code highlighting classes to include
|
458
452
|
css = match[2].split.collect {|i| "language-#{i.downcase}" }.join(' ')
|
459
453
|
|
@@ -809,35 +803,10 @@ class ShowOff < Sinatra::Application
|
|
809
803
|
img_path = Pathname.new(File.join(slide_dir, img[:src])).cleanpath.to_path
|
810
804
|
src = "#{replacement_prefix}/#{img_path}"
|
811
805
|
img[:src] = src
|
812
|
-
|
813
|
-
# TDOD: deprecated and to be removed
|
814
|
-
w, h = get_image_size(img_path)
|
815
|
-
if w && h
|
816
|
-
img[:width] = w
|
817
|
-
img[:height] = h
|
818
|
-
end
|
819
806
|
end
|
820
807
|
doc.to_html
|
821
808
|
end
|
822
809
|
|
823
|
-
if defined?(Magick)
|
824
|
-
def get_image_size(path)
|
825
|
-
if !cached_image_size.key?(path)
|
826
|
-
img = Magick::Image.ping(path).first
|
827
|
-
# don't set a size for svgs so they can expand to fit their container
|
828
|
-
if img.mime_type == 'image/svg+xml'
|
829
|
-
cached_image_size[path] = [nil, nil]
|
830
|
-
else
|
831
|
-
cached_image_size[path] = [img.columns, img.rows]
|
832
|
-
end
|
833
|
-
end
|
834
|
-
cached_image_size[path]
|
835
|
-
end
|
836
|
-
else
|
837
|
-
def get_image_size(path)
|
838
|
-
end
|
839
|
-
end
|
840
|
-
|
841
810
|
def update_commandline_code(slide)
|
842
811
|
html = Nokogiri::HTML::DocumentFragment.parse(slide)
|
843
812
|
parser = CommandlineParser.new
|
@@ -1208,7 +1177,7 @@ class ShowOff < Sinatra::Application
|
|
1208
1177
|
end
|
1209
1178
|
|
1210
1179
|
# Load a slide file from disk, parse it and return the text of a code block by index
|
1211
|
-
def get_code_from_slide(path, index)
|
1180
|
+
def get_code_from_slide(path, index, executable=true)
|
1212
1181
|
if path =~ /^(.*)(?::)(\d+)$/
|
1213
1182
|
path = $1
|
1214
1183
|
num = $2.to_i
|
@@ -1216,6 +1185,8 @@ class ShowOff < Sinatra::Application
|
|
1216
1185
|
num = 1
|
1217
1186
|
end
|
1218
1187
|
|
1188
|
+
classes = executable ? 'code.execute' : 'code'
|
1189
|
+
|
1219
1190
|
slide = "#{path}.md"
|
1220
1191
|
return unless File.exist? slide
|
1221
1192
|
|
@@ -1227,7 +1198,14 @@ class ShowOff < Sinatra::Application
|
|
1227
1198
|
html = process_markdown(slide, content, {})
|
1228
1199
|
doc = Nokogiri::HTML::DocumentFragment.parse(html)
|
1229
1200
|
|
1230
|
-
|
1201
|
+
if index == 'all'
|
1202
|
+
doc.css(classes).collect do |code|
|
1203
|
+
lang = code.attr('class') =~ /language-(\S*)/ ? $1 : nil
|
1204
|
+
[lang, code.text]
|
1205
|
+
end
|
1206
|
+
else
|
1207
|
+
doc.css(classes)[index.to_i].text rescue 'Invalid code block index'
|
1208
|
+
end
|
1231
1209
|
end
|
1232
1210
|
|
1233
1211
|
# Basic auth boilerplate
|
data/lib/showoff/version.rb
CHANGED
data/lib/showoff_utils.rb
CHANGED
@@ -31,19 +31,26 @@ class ShowOffUtils
|
|
31
31
|
@presentation_config_file = filename
|
32
32
|
end
|
33
33
|
|
34
|
-
def self.create(dirname,create_samples,
|
34
|
+
def self.create(dirname,create_samples,dirs='one')
|
35
35
|
FileUtils.mkdir_p(dirname)
|
36
36
|
Dir.chdir(dirname) do
|
37
|
-
|
38
|
-
# create section
|
39
|
-
FileUtils.mkdir_p(dir)
|
37
|
+
dirs = dirs.split(',')
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
if create_samples
|
40
|
+
dirs.each do |dir|
|
41
|
+
# create section
|
42
|
+
FileUtils.mkdir_p(dir)
|
43
|
+
|
44
|
+
# create markdown file
|
45
|
+
File.open("#{dir}/00_section.md", 'w+') do |f|
|
46
|
+
f.puts make_slide("Section Header", "center subsection")
|
47
|
+
end
|
48
|
+
File.open("#{dir}/01_slide.md", 'w+') do |f|
|
49
|
+
f.puts make_slide("My Presentation")
|
50
|
+
end
|
51
|
+
File.open("#{dir}/02_slide.md", 'w+') do |f|
|
52
|
+
f.puts make_slide("Bullet Points","bullets incremental",["first point","second point","third point"])
|
53
|
+
end
|
47
54
|
end
|
48
55
|
end
|
49
56
|
|
@@ -53,7 +60,8 @@ class ShowOffUtils
|
|
53
60
|
|
54
61
|
# create showoff.json
|
55
62
|
File.open(ShowOffUtils.presentation_config_file, 'w+') do |f|
|
56
|
-
|
63
|
+
sections = dirs.collect {|dir| {"section" => dir} }
|
64
|
+
f.puts JSON.pretty_generate({ "name" => "My Preso", "sections" => sections })
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
@@ -76,7 +84,12 @@ class ShowOffUtils
|
|
76
84
|
FileUtils.mkdir_p File.dirname(filename)
|
77
85
|
|
78
86
|
File.open(filename, 'w+') do |f|
|
79
|
-
|
87
|
+
if filename =~ /section/i
|
88
|
+
# kind of looks like a section slide
|
89
|
+
f.puts make_slide("#{filename.sub(/\.md$/, '')}", "center subsection")
|
90
|
+
else
|
91
|
+
f.puts make_slide("#{filename.sub(/\.md$/, '')}")
|
92
|
+
end
|
80
93
|
end
|
81
94
|
else
|
82
95
|
FileUtils.mkdir_p filename
|
@@ -84,6 +97,55 @@ class ShowOffUtils
|
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
100
|
+
def self.validate(config)
|
101
|
+
showoff = ShowOff.new!(:pres_file => config)
|
102
|
+
validators = showoff.settings.showoff_config['validators'] || {}
|
103
|
+
files = []
|
104
|
+
errors = []
|
105
|
+
|
106
|
+
# get a list of actual filenames
|
107
|
+
self.showoff_sections('.').each do |section|
|
108
|
+
if File.directory?(section)
|
109
|
+
files << showoff.load_section_files(section)
|
110
|
+
else
|
111
|
+
files << section
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
files.flatten!
|
116
|
+
files.each do |filename|
|
117
|
+
unless File.exist? filename
|
118
|
+
errors << "Missing path: #{filename}"
|
119
|
+
next
|
120
|
+
end
|
121
|
+
|
122
|
+
if filename.downcase.end_with? '.md'
|
123
|
+
print '.'
|
124
|
+
showoff.get_code_from_slide(filename.sub('.md',''), 'all', false).each_with_index do |block, index|
|
125
|
+
lang, code = block
|
126
|
+
validator = validators[lang]
|
127
|
+
if validator
|
128
|
+
# write out a tempfile because many validators require files to with
|
129
|
+
Tempfile.open('showoff-validation') do |f|
|
130
|
+
File.write(f.path, code)
|
131
|
+
unless system("#{validator} #{f.path}", :out => File::NULL, :err => File::NULL)
|
132
|
+
print 'F'
|
133
|
+
errors << "Invalid #{lang} code on #{filename} [#{index}]"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
puts
|
142
|
+
puts "Found #{errors.size} errors."
|
143
|
+
unless errors.empty?
|
144
|
+
errors.each { |err| puts " * #{err}" }
|
145
|
+
exit!
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
87
149
|
HEROKU_GEMS_FILE = '.gems'
|
88
150
|
HEROKU_BUNDLER_GEMS_FILE = 'Gemfile'
|
89
151
|
HEROKU_CONFIG_FILE = 'config.ru'
|
@@ -263,9 +325,12 @@ class ShowOffUtils
|
|
263
325
|
# name a slide as the last slide in the dir.
|
264
326
|
def self.find_next_number(slide_dir)
|
265
327
|
slide_dir ||= '.'
|
266
|
-
|
328
|
+
max = Dir.glob("#{slide_dir}/*.md").collect do |f|
|
329
|
+
next unless f =~ /^#{slide_dir}\/(\d+)/
|
330
|
+
$1.to_i
|
331
|
+
end.compact.max || 0
|
267
332
|
|
268
|
-
sprintf("%02d",
|
333
|
+
sprintf("%02d", max+1)
|
269
334
|
end
|
270
335
|
|
271
336
|
def self.determine_title(title,slide_name,code)
|
data/public/css/showoff.css
CHANGED
@@ -47,6 +47,10 @@ pre code {
|
|
47
47
|
overflow: hidden;
|
48
48
|
}
|
49
49
|
|
50
|
+
body#download {
|
51
|
+
overflow: auto;
|
52
|
+
}
|
53
|
+
|
50
54
|
#preso,
|
51
55
|
.slide {
|
52
56
|
background: #fff;
|
@@ -842,7 +846,8 @@ form .element {
|
|
842
846
|
.callout.warning,
|
843
847
|
.callout.question,
|
844
848
|
.callout.exercise,
|
845
|
-
.callout.stop
|
849
|
+
.callout.stop,
|
850
|
+
.callout.thumbsup {
|
846
851
|
padding-left: 3em;
|
847
852
|
}
|
848
853
|
|
@@ -851,6 +856,7 @@ form .element {
|
|
851
856
|
.callout.question:before { content: "\f059"; } /* fa-question-circle */
|
852
857
|
.callout.exercise:before { content: "\f41b"; } /* fa-pencil-square */
|
853
858
|
.callout.stop:before { content: "\f05e"; } /* fa-ban */
|
859
|
+
.callout.thumbsup:before { content: "\f164"; } /* fa-thumbs-up */
|
854
860
|
|
855
861
|
/**********************
|
856
862
|
*** end callouts ***
|
@@ -957,6 +963,11 @@ form .element {
|
|
957
963
|
border-top: 2px dashed #999;
|
958
964
|
}
|
959
965
|
|
966
|
+
.notes-section .callout {
|
967
|
+
margin-right: 1em;
|
968
|
+
margin-left: 1em;
|
969
|
+
}
|
970
|
+
|
960
971
|
.notes-section.notes .personal {
|
961
972
|
float: right;
|
962
973
|
border-left: 2px solid #999;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -353,10 +353,6 @@ post_install_message: |2+
|
|
353
353
|
means that if you've created your own custom styles, that you'll need to
|
354
354
|
refactor them. We do hope you find the new styles simpler and better looking.
|
355
355
|
|
356
|
-
RMagick will be completely removed in the next major release. Pleas migrate
|
357
|
-
away from it now. Browsers can autoscale images on demand pretty well now,
|
358
|
-
so you probably won't miss it much.
|
359
|
-
|
360
356
|
Showoff can optionally use the PDFKit gem to build PDF files using the
|
361
357
|
`showoff pdf` command. If you'd like your audience to download the PDF,
|
362
358
|
place it in `_files/share`.
|