showoff 0.18.1 → 0.18.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/showoff +15 -0
- data/lib/showoff.rb +11 -4
- data/lib/showoff/version.rb +1 -1
- data/lib/showoff_utils.rb +48 -0
- data/locales/de.yml +1 -0
- data/locales/en.yml +1 -0
- data/locales/es.yml +1 -0
- data/locales/fr.yml +1 -0
- data/locales/ja.yml +1 -0
- data/locales/nl.yml +1 -0
- data/locales/pt.yml +1 -0
- data/public/css/presenter.css +1 -1
- data/public/css/showoff.css +8 -0
- data/public/js/presenter.js +7 -1
- data/public/js/showoff.js +29 -6
- data/views/index.erb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5049af41567ade99af8a0949da8f756bdbe4eaad
|
4
|
+
data.tar.gz: 09b6a2ba7fadc69530ac3465a1a5497576fc5319
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4332919c9668a1549a91512a74b0b91ec86b8f930a29779dc10c5b0858e4d418cf3a9efe7dddf6977b890e8a16ed13a0e4a8a5ce2a1293040ee59501d954c410
|
7
|
+
data.tar.gz: 720a04998515eba5fa39ff989e18b6a351d69bbcd56a2e55bb435f5b596987e5ffb930d07fa7f4c337060de5f5c7624a02aa5a6f899e9ca1aea1c648c66ade89
|
data/bin/showoff
CHANGED
@@ -68,6 +68,21 @@ module Wrapper
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
desc 'Display information about a Showoff presentation'
|
72
|
+
long_desc 'This command compiles the presentation, then lists out all Markdown files, images, stylesheets, and javascripts included.'
|
73
|
+
command [:info] do |c|
|
74
|
+
|
75
|
+
c.desc 'alternate json filename'
|
76
|
+
c.flag [:f,:file]
|
77
|
+
|
78
|
+
c.desc 'render output as json'
|
79
|
+
c.switch [:j,:json]
|
80
|
+
|
81
|
+
c.action do |global_options,options,args|
|
82
|
+
ShowOffUtils.info(options[:f], options[:j])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
71
86
|
desc 'Validate the consistency of your presentation.'
|
72
87
|
long_desc 'This ensures that each file listed in showoff.json exists and validates code blocks on each slide.'
|
73
88
|
command [:validate] do |c|
|
data/lib/showoff.rb
CHANGED
@@ -1036,10 +1036,17 @@ class ShowOff < Sinatra::Application
|
|
1036
1036
|
end
|
1037
1037
|
|
1038
1038
|
doc.css('img').each do |img|
|
1039
|
-
|
1040
|
-
|
1039
|
+
|
1040
|
+
# does the image path start from the preso root?
|
1041
|
+
if img[:src].start_with? '/'
|
1042
|
+
img_path = img[:src]
|
1043
|
+
else
|
1044
|
+
# clean up the path and remove some of the relative nonsense
|
1045
|
+
img_path = Pathname.new(File.join(slide_dir, img[:src])).cleanpath.to_path
|
1046
|
+
end
|
1041
1047
|
src = "#{replacement_prefix}/#{img_path}"
|
1042
1048
|
img[:src] = src
|
1049
|
+
|
1043
1050
|
end
|
1044
1051
|
doc.to_html
|
1045
1052
|
end
|
@@ -1251,12 +1258,12 @@ class ShowOff < Sinatra::Application
|
|
1251
1258
|
end
|
1252
1259
|
|
1253
1260
|
def slides(static=false)
|
1254
|
-
@logger.
|
1261
|
+
@logger.info "Cached presentations: #{@@cache.keys}"
|
1255
1262
|
|
1256
1263
|
# if we have a cache and we're not asking to invalidate it
|
1257
1264
|
return @@cache[@locale] if (@@cache[@locale] and params['cache'] != 'clear')
|
1258
1265
|
|
1259
|
-
@logger.
|
1266
|
+
@logger.info "Generating locale: #{@locale}"
|
1260
1267
|
|
1261
1268
|
# If we're displaying from a repository, let's update it
|
1262
1269
|
ShowOffUtils.update(settings.verbose) if settings.url
|
data/lib/showoff/version.rb
CHANGED
data/lib/showoff_utils.rb
CHANGED
@@ -97,6 +97,37 @@ class ShowOffUtils
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
+
def self.info(config, json = false)
|
101
|
+
ShowOffUtils.presentation_config_file = config
|
102
|
+
showoff = ShowOff.new!
|
103
|
+
content = showoff.slides
|
104
|
+
dom = Nokogiri::HTML(content)
|
105
|
+
|
106
|
+
data = {}
|
107
|
+
data['files'] = self.showoff_slide_files('.')
|
108
|
+
data['images'] = dom.css('img').map {|img| img[:src].sub(/.\/image\/+/,'') }
|
109
|
+
data['styles'] = Dir.glob('*.css')
|
110
|
+
data['scripts'] = Dir.glob('*.js')
|
111
|
+
|
112
|
+
# now grep through the styles and identify referenced images
|
113
|
+
data['styles'].each do |style|
|
114
|
+
File.readlines(style).each do |line|
|
115
|
+
next unless line =~ /url\(\'(\S+)\'\)/
|
116
|
+
data['images'] << $1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
if json
|
121
|
+
puts JSON.pretty_generate(data)
|
122
|
+
else
|
123
|
+
data.each do |key, list|
|
124
|
+
puts "#{key.capitalize}:"
|
125
|
+
list.each {|file| puts " * #{file}" }
|
126
|
+
puts
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
100
131
|
def self.validate(config)
|
101
132
|
showoff = ShowOff.new!(:pres_file => config)
|
102
133
|
validators = showoff.settings.showoff_config['validators'] || {}
|
@@ -449,6 +480,9 @@ class ShowOffUtils
|
|
449
480
|
# - { "section": [ "array.md, "of.md, "files.md"] }
|
450
481
|
# - { "include": "sections.json" }
|
451
482
|
sections = {}
|
483
|
+
counters = {}
|
484
|
+
lastpath = nil
|
485
|
+
|
452
486
|
data.map do |entry|
|
453
487
|
next entry if entry.is_a? String
|
454
488
|
next nil unless entry.is_a? Hash
|
@@ -489,6 +523,20 @@ class ShowOffUtils
|
|
489
523
|
end
|
490
524
|
else
|
491
525
|
path = File.dirname(entry)
|
526
|
+
|
527
|
+
# this lastpath business allows us to reference files in a directory that aren't
|
528
|
+
# necessarily contiguous.
|
529
|
+
if path != lastpath
|
530
|
+
counters[path] ||= 0
|
531
|
+
counters[path] += 1
|
532
|
+
end
|
533
|
+
|
534
|
+
# now record the last path we've seen
|
535
|
+
lastpath = path
|
536
|
+
|
537
|
+
# and if there are more than one disparate occurences of path, add a counter to this string
|
538
|
+
path = "#{path} (#{counters[path]})" unless counters[path] == 1
|
539
|
+
|
492
540
|
sections[path] ||= []
|
493
541
|
sections[path] << filename
|
494
542
|
end
|
data/locales/de.yml
CHANGED
data/locales/en.yml
CHANGED
data/locales/es.yml
CHANGED
data/locales/fr.yml
CHANGED
data/locales/ja.yml
CHANGED
data/locales/nl.yml
CHANGED
data/locales/pt.yml
CHANGED
data/public/css/presenter.css
CHANGED
data/public/css/showoff.css
CHANGED
@@ -1199,6 +1199,14 @@ a.term:after {
|
|
1199
1199
|
right: 1em;
|
1200
1200
|
}
|
1201
1201
|
|
1202
|
+
#synchronize {
|
1203
|
+
display: none;
|
1204
|
+
position: absolute;
|
1205
|
+
bottom: 1em;
|
1206
|
+
left: 1em;
|
1207
|
+
font-size: 0.8em;
|
1208
|
+
}
|
1209
|
+
|
1202
1210
|
/* Render hidden headlines so that when we print with wkhtmltopdf, we can use section
|
1203
1211
|
titles for page headers. it would make sense to put this in the print section, but
|
1204
1212
|
then you get a weird double headline when previewing a print in the browser. */
|
data/public/js/presenter.js
CHANGED
@@ -293,6 +293,10 @@ function openSlave()
|
|
293
293
|
// Add a class to differentiate from the audience view
|
294
294
|
slaveWindow.document.getElementById("preso").className = 'display';
|
295
295
|
|
296
|
+
// remove some display view chrome
|
297
|
+
$('.slide.activity', slaveWindow.document).removeClass('activity').children('.activityToggle').remove();
|
298
|
+
$('#synchronize', slaveWindow.document).remove();
|
299
|
+
|
296
300
|
// call back and update the parent presenter if the window is closed
|
297
301
|
slaveWindow.onunload = function(e) {
|
298
302
|
slaveWindow.opener.closeSlave(true);
|
@@ -630,7 +634,9 @@ reconnectControlChannel = function() {
|
|
630
634
|
},
|
631
635
|
error: function() {
|
632
636
|
console.log("Showoff server unavailable");
|
633
|
-
setTimeout(
|
637
|
+
setTimeout( function() {
|
638
|
+
reconnectControlChannel();
|
639
|
+
}, 5000);
|
634
640
|
},
|
635
641
|
});
|
636
642
|
}
|
data/public/js/showoff.js
CHANGED
@@ -4,6 +4,7 @@ var ShowOff = {};
|
|
4
4
|
|
5
5
|
var preso_started = false
|
6
6
|
var slidenum = 0
|
7
|
+
var presenterSlideNum = 0
|
7
8
|
var slideTotal = 0
|
8
9
|
var slides
|
9
10
|
var currentSlide
|
@@ -117,6 +118,11 @@ function setupPreso(load_slides, prefix) {
|
|
117
118
|
buttons: buttons
|
118
119
|
});
|
119
120
|
|
121
|
+
$("#synchronize").button();
|
122
|
+
$("#synchronize").click(function() {
|
123
|
+
synchronize();
|
124
|
+
});
|
125
|
+
|
120
126
|
// wait until the presentation is loaded to hook up the previews.
|
121
127
|
$("body").bind("showoff:loaded", function (event) {
|
122
128
|
var target = $('#navigationHover');
|
@@ -249,10 +255,6 @@ function initializePresentation(prefix) {
|
|
249
255
|
}
|
250
256
|
});
|
251
257
|
|
252
|
-
// The display window doesn't need the extra chrome
|
253
|
-
if(typeof(presenterView) != 'undefined') {
|
254
|
-
$('.slide.activity').removeClass('activity').children('.activityToggle').remove();
|
255
|
-
}
|
256
258
|
$('.slide.activity .activityToggle input.activity').checkboxradio();
|
257
259
|
$('.slide.activity .activityToggle input.activity').change(toggleComplete);
|
258
260
|
|
@@ -772,6 +774,9 @@ function showSlide(back_step, updatepv) {
|
|
772
774
|
activityIncomplete = false;
|
773
775
|
}
|
774
776
|
|
777
|
+
// show the sync button if we're not on the same slide as the presenter
|
778
|
+
checkSyncState();
|
779
|
+
|
775
780
|
// make all bigly text tremendous
|
776
781
|
currentSlide.children('.content.bigtext').bigtext();
|
777
782
|
|
@@ -1278,8 +1283,10 @@ function editSlide() {
|
|
1278
1283
|
window.open(link);
|
1279
1284
|
}
|
1280
1285
|
|
1281
|
-
function follow(slide, newIncrement) {
|
1282
|
-
|
1286
|
+
function follow(slide, newIncrement, force) {
|
1287
|
+
presenterSlideNum = slide;
|
1288
|
+
|
1289
|
+
if ((mode.follow && ! activityIncomplete) || force) {
|
1283
1290
|
var lastSlide = slidenum;
|
1284
1291
|
console.log("New slide: " + slide);
|
1285
1292
|
gotoSlide(slide);
|
@@ -1302,6 +1309,22 @@ function follow(slide, newIncrement) {
|
|
1302
1309
|
|
1303
1310
|
}
|
1304
1311
|
}
|
1312
|
+
|
1313
|
+
// show the sync button if we're not on the same slide as the presenter
|
1314
|
+
checkSyncState();
|
1315
|
+
}
|
1316
|
+
|
1317
|
+
function checkSyncState() {
|
1318
|
+
if (presenterSlideNum != slidenum && presenterSlideNum != null) {
|
1319
|
+
$("#synchronize").show();
|
1320
|
+
}
|
1321
|
+
else {
|
1322
|
+
$("#synchronize").hide();
|
1323
|
+
}
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
function synchronize() {
|
1327
|
+
follow(presenterSlideNum, 0, true);
|
1305
1328
|
}
|
1306
1329
|
|
1307
1330
|
function getPosition() {
|
data/views/index.erb
CHANGED
@@ -95,7 +95,7 @@
|
|
95
95
|
<%= erb :help %>
|
96
96
|
|
97
97
|
<div id="preso"><center><%= I18n.t('loading') %></center></div>
|
98
|
-
|
98
|
+
<a id="synchronize"><i class="fa fa-link" aria-hidden="true" href="#"></i> <%= I18n.t('navigation.sync') %></a>
|
99
99
|
<div id="notes"></div>
|
100
100
|
|
101
101
|
<footer id="footer">
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.
|
4
|
+
version: 0.18.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|