showoff 0.12.2 → 0.13.0

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: ec76aa0788c47474cae17e4e7fd001f5f59528fb
4
- data.tar.gz: 672f97f4f81b725f1f0d68418b5a292f3061d58d
3
+ metadata.gz: c54ccde20fbe6df23ec6b8760dc4c379fdd5e510
4
+ data.tar.gz: 1da82fd0d90fbdeffee8da521ab4fba731046672
5
5
  SHA512:
6
- metadata.gz: 46464828f157e75fd4783ef28628ff404573f57f69d3fa87da500a5cf4be46ce62a9e9639e695cf3f451eca27ec423ab9be48137ffc75fb45317b104c2218204
7
- data.tar.gz: 6e3c5444159ce33d30e273de6de19da2357bec6b1aa82da65a7d7b4d5cad118bd472fba0289109c5a70eb0efd2184f080e64ec443aa0823f048445351acca284
6
+ metadata.gz: 8d3d1f9f9e699646c389383282dabb862dd7c9ae0fe681a9a63f1efc158dea921847ba10a34b415352a47e74bed93a0a040fac600e416445d2f2545d14481087
7
+ data.tar.gz: 6c100036f06dd912ba08f8eeca4670807d342103e4e9db5946fafbee629e10f9765785ef074a8aa06006c231b107d136090745ef3ed74c1fa5b34e661242621d
data/LICENSE CHANGED
@@ -1,4 +1,6 @@
1
- Copyright (c) 2009 Scott Chacon
1
+ MIT License (MIT)
2
+
3
+ Copyright (c) 2009-2016 Scott Chacon; Ben Ford; Puppet, Inc.
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,8 +1,33 @@
1
- task default: :test
1
+ task :default do
2
+ system("rake -T")
3
+ end
2
4
 
3
5
  desc "Build HTML documentation"
4
6
  task :doc do
5
- system("rdoc --main README.rdoc README.rdoc documentation/*.rdoc")
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 'sample slide directory name'
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
- raise "dir_name is required" if args.empty?
52
- ShowOffUtils.create(args[0],!options[:n],options[:d])
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 #{args[0]}/#{ShowOffUtils.presentation_config_file}"
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 outling'
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:([^:]*):?(.*)?~~~)/).each do |match|
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
- return doc.css('code.execute')[index.to_i].text rescue 'Invalid code block index'
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
@@ -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.12.2'
3
+ SHOWOFF_VERSION = '0.13.0'
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,dir='one')
34
+ def self.create(dirname,create_samples,dirs='one')
35
35
  FileUtils.mkdir_p(dirname)
36
36
  Dir.chdir(dirname) do
37
- if create_samples
38
- # create section
39
- FileUtils.mkdir_p(dir)
37
+ dirs = dirs.split(',')
40
38
 
41
- # create markdown file
42
- File.open("#{dir}/01_slide.md", 'w+') do |f|
43
- f.puts make_slide("My Presentation")
44
- end
45
- File.open("#{dir}/02_slide.md", 'w+') do |f|
46
- f.puts make_slide("Bullet Points","bullets incremental",["first point","second point","third point"])
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
- f.puts JSON.pretty_generate({ "name" => "My Preso", "sections" => [ { "section" => dir } ]})
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
- f.puts make_slide("#{filename.sub(/\.md$/, '')}")
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
- next_num = Dir.glob("#{slide_dir}/*.md").size + 1
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", next_num)
333
+ sprintf("%02d", max+1)
269
334
  end
270
335
 
271
336
  def self.determine_title(title,slide_name,code)
@@ -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.12.2
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-12 00:00:00.000000000 Z
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`.