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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b8bc22bca10cb765cb6f12290bdf44b2ba0c17f
4
- data.tar.gz: 73e786933d4992b577a70cc4ad469d9da9ddb749
3
+ metadata.gz: 5049af41567ade99af8a0949da8f756bdbe4eaad
4
+ data.tar.gz: 09b6a2ba7fadc69530ac3465a1a5497576fc5319
5
5
  SHA512:
6
- metadata.gz: bf8d8dd4ab0851ceab926316dbcf25da51c7037a87b0a5401dcdacec770602d6395be99fb83954fc79e6d41f4bf184a0707768a489d5139d667840eee6e73093
7
- data.tar.gz: 3e0e1fb262a34f67d885e145283179e29e4199c9bc8e59c11f80a95f67c8c294e9d2f652ac549520aea8d303066f452de208c860095dca5049de8f015e6800b4
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
- # clean up the path and remove some of the relative nonsense
1040
- img_path = Pathname.new(File.join(slide_dir, img[:src])).cleanpath.to_path
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.warn "Cached presentations: #{@@cache.keys}"
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.warn "Generating locale: #{@locale}"
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
@@ -1,3 +1,3 @@
1
1
  # No namespace here since ShowOff is a class and I'd have to inherit from
2
2
  # Sinatra::Application (which we don't want to load here)
3
- SHOWOFF_VERSION = '0.18.1'
3
+ SHOWOFF_VERSION = '0.18.2'
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
@@ -28,6 +28,7 @@ de:
28
28
  navigation:
29
29
  next: Nächste Folie
30
30
  previous: Vorherige Folie
31
+ sync: Synchronisieren der Präsentation
31
32
  loading: laden der Präsentation...
32
33
  activity_complete: Aktivität vollständig
33
34
  follow:
data/locales/en.yml CHANGED
@@ -28,6 +28,7 @@ en:
28
28
  navigation:
29
29
  next: Next
30
30
  previous: Previous
31
+ sync: Sync Presentation
31
32
  loading: loading presentation...
32
33
  activity_complete: Activity complete
33
34
  follow:
data/locales/es.yml CHANGED
@@ -28,6 +28,7 @@ es:
28
28
  navigation:
29
29
  next: Siguiente
30
30
  previous: Anterior
31
+ sync: Sincronizar presentación
31
32
  loading: cargando presentación...
32
33
  activity_complete: Actividad completa
33
34
  follow:
data/locales/fr.yml CHANGED
@@ -28,6 +28,7 @@ fr:
28
28
  navigation:
29
29
  next: Prochain
30
30
  previous: Précédent
31
+ sync: Synchroniser la présentation
31
32
  loading: Chargement de la présentation...
32
33
  activity_complete: Activité terminée
33
34
  follow:
data/locales/ja.yml CHANGED
@@ -28,6 +28,7 @@ ja:
28
28
  navigation:
29
29
  next: 次へ
30
30
  previous: 前へ
31
+ sync: プレゼンテーションの同期
31
32
  loading: プレゼンテーション?ロード中...
32
33
  activity_complete: アクティビティ完了
33
34
  follow:
data/locales/nl.yml CHANGED
@@ -28,6 +28,7 @@ nl:
28
28
  navigation:
29
29
  next: Volgende
30
30
  previous: Vorige
31
+ sync: Presentatie synchroniseren
31
32
  loading: Laden van presentatie...
32
33
  activity_complete: Activiteiten voltooid
33
34
  follow:
data/locales/pt.yml CHANGED
@@ -28,6 +28,7 @@ pt:
28
28
  navigation:
29
29
  next: Próximo
30
30
  previous: Anterior
31
+ sync: Sincronizar Apresentação
31
32
  loading: carregando apresentação...
32
33
  activity_complete: Atividade completada
33
34
  follow:
@@ -293,7 +293,7 @@
293
293
  min-width: 210px;
294
294
  min-height: 210px;
295
295
  height: 210px;
296
- border-top: 1px solid #ccc;
296
+ border-top: 3px solid #ccc;
297
297
  overflow: auto;
298
298
  }
299
299
 
@@ -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. */
@@ -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(reconnectControlChannel(), 5000);
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
- if (mode.follow && ! activityIncomplete) {
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.1
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-05-23 00:00:00.000000000 Z
12
+ date: 2017-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra