slideshow 0.7 → 0.7.1

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.
Files changed (3) hide show
  1. data/lib/slideshow.rb +4 -3
  2. metadata +1 -2
  3. data/lib/slideshow.v6.rb +0 -599
data/lib/slideshow.rb CHANGED
@@ -12,7 +12,7 @@ require 'pp'
12
12
 
13
13
  module Slideshow
14
14
 
15
- VERSION = '0.7'
15
+ VERSION = '0.7.1'
16
16
 
17
17
  class Params
18
18
 
@@ -220,8 +220,8 @@ class Gen
220
220
  when /^\s*#.*$/
221
221
  # skip comment lines
222
222
  else
223
- logger.debug "line #{i+1}: #{line}"
224
- values = line.split( /[ <,+\n]+/ )
223
+ logger.debug "line #{i+1}: #{line.strip}"
224
+ values = line.strip.split( /[ <,+]+/ )
225
225
 
226
226
  # add source for shortcuts (assumes relative path; if not issue warning/error)
227
227
  values << values[0] if values.size == 1
@@ -229,6 +229,7 @@ class Gen
229
229
  # normalize all source paths (1..-1) /make full path/add template dir
230
230
  (1..values.size-1).each do |i|
231
231
  values[i] = "#{templatesdir}/#{values[i]}"
232
+ logger.debug " path[#{i}]=>#{values[i]}<"
232
233
  end
233
234
 
234
235
  manifest << values
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slideshow
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.7"
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -62,7 +62,6 @@ extra_rdoc_files: []
62
62
 
63
63
  files:
64
64
  - lib/slideshow.rb
65
- - lib/slideshow.v6.rb
66
65
  - lib/templates
67
66
  - lib/templates/footer.html.erb
68
67
  - lib/templates/fullerscreen.txt
data/lib/slideshow.v6.rb DELETED
@@ -1,599 +0,0 @@
1
- require 'optparse'
2
- require 'erb'
3
- require 'redcloth'
4
- require 'maruku'
5
- require 'logger'
6
- require 'fileutils'
7
- require 'ftools'
8
- require 'hpricot'
9
- require 'uv'
10
- require 'pp'
11
-
12
-
13
- module Slideshow
14
-
15
- VERSION = '0.7'
16
-
17
- class Params
18
-
19
- def initialize( name, headers )
20
- @svgname = "#{name}.svg"
21
- @cssname = "#{name}.css"
22
- @headers = headers
23
- end
24
-
25
- def params_binding
26
- binding
27
- end
28
-
29
- end
30
-
31
- # todo: split (command line) options and headers?
32
- # e.g. share (command line) options between slide shows (but not headers?)
33
-
34
- class Opts
35
-
36
- def initialize
37
- @hash = {}
38
- end
39
-
40
- def put( key, value )
41
- key = normalize_key( key )
42
- setter = "#{key}=".to_sym
43
-
44
- if respond_to? setter
45
- send setter, value
46
- else
47
- @hash[ key ] = value
48
- end
49
- end
50
-
51
- def code_theme=( value )
52
- @hash[ :code_theme ] = value.tr( '-', '_' )
53
- end
54
-
55
- def gradient=( value )
56
- put_gradient( value, :theme, :color1, :color2 )
57
- end
58
-
59
- def gradient_colors=( value )
60
- put_gradient( value, :color1, :color2 )
61
- end
62
-
63
- def gradient_color=( value )
64
- put_gradient( value, :color1 )
65
- end
66
-
67
- def gradient_theme=( value )
68
- put_gradient( value, :theme )
69
- end
70
-
71
- def []( key )
72
- value = @hash[ normalize_key( key ) ]
73
- if value.nil?
74
- puts "** Warning: header '#{key}' undefined"
75
- "- #{key} not found -"
76
- else
77
- value
78
- end
79
- end
80
-
81
- def generate?
82
- get_boolean( 'generate', false )
83
- end
84
-
85
- def has_includes?
86
- @hash[ :include ]
87
- end
88
-
89
- def includes
90
- # fix: use os-agnostic delimiter (use : for Mac/Unix?)
91
- has_includes? ? @hash[ :include ].split( ';' ) : []
92
- end
93
-
94
- def s5?
95
- get_boolean( 's5', false )
96
- end
97
-
98
- def fullerscreen?
99
- get_boolean( 'fuller', false ) || get_boolean( 'fullerscreen', false )
100
- end
101
-
102
- def code_theme
103
- get( 'code-theme', DEFAULTS[ :code_theme ] )
104
- end
105
-
106
- def code_line_numbers?
107
- get_boolean( 'code-line-numbers', DEFAULTS[ :code_line_numbers ] )
108
- end
109
-
110
- def template
111
- # todo: change to manifest??
112
- # todo: use DEFAULTS??
113
- get( 'template', 's6.txt' )
114
- end
115
-
116
- DEFAULTS =
117
- {
118
- :title => 'Untitled Slide Show',
119
- :footer => '',
120
- :subfooter => '',
121
- :gradient_theme => 'dark',
122
- :gradient_color1 => 'red',
123
- :gradient_color2 => 'black',
124
- :code_theme => 'amy',
125
- :code_line_numbers => 'true'
126
- }
127
-
128
- def set_defaults
129
- DEFAULTS.each_pair do | key, value |
130
- @hash[ key ] = value if @hash[ key ].nil?
131
- end
132
- end
133
-
134
- private
135
-
136
- def normalize_key( key )
137
- key.to_s.downcase.tr('-', '_').to_sym
138
- end
139
-
140
- # Assigns the given gradient-* keys to the values in the given string.
141
- def put_gradient( string, *keys )
142
- values = string.split( ' ' )
143
-
144
- values.zip(keys).each do |v, k|
145
- @hash[ normalize_key( "gradient-#{k}" ) ] = v.tr( '-', '_' )
146
- end
147
- end
148
-
149
- def get( key, default )
150
- @hash.fetch( normalize_key(key), default )
151
- end
152
-
153
- def get_boolean( key, default )
154
- value = @hash[ normalize_key( key ) ]
155
- if value.nil?
156
- default
157
- else
158
- (value == true || value =~ /true|yes|on/i) ? true : false
159
- end
160
- end
161
-
162
- end # class Opts
163
-
164
-
165
- class Gen
166
-
167
- KNOWN_TEXTILE_EXTNAMES = [ '.textile', '.t' ]
168
- KNOWN_MARKDOWN_EXTNAMES = [ '.markdown', '.mark', '.m', '.txt', '.text' ]
169
-
170
- def initialize
171
- @logger = Logger.new(STDOUT)
172
- @logger.level = Logger::INFO
173
- @opts = Opts.new
174
- end
175
-
176
- def logger
177
- @logger
178
- end
179
-
180
- def opts
181
- @opts
182
- end
183
-
184
- def cache_dir
185
- PLATFORM =~ /win32/ ? win32_cache_dir : File.join(File.expand_path("~"), ".slideshow")
186
- end
187
-
188
- def win32_cache_dir
189
- unless File.exists?(home = ENV['HOMEDRIVE'] + ENV['HOMEPATH'])
190
- puts "No HOMEDRIVE or HOMEPATH environment variable. Set one to save a" +
191
- "local cache of stylesheets for syntax highlighting and more."
192
- return false
193
- else
194
- return File.join(home, 'slideshow')
195
- end
196
- end
197
-
198
- def load_manifest( name )
199
- # todo: check if file exists (if yes use custom template package!) - allows you to override builtin package with same name
200
- if ['fullerscreen.txt','s5.txt','s6.txt'].include? name
201
- templatesdir = "#{File.dirname(__FILE__)}/templates"
202
- logger.debug "use builtin template package"
203
- logger.debug "templatesdir=#{templatesdir}"
204
- filename = "#{templatesdir}/#{name}"
205
- else
206
- templatesdir = File.dirname( name )
207
- logger.debug "use custom template package"
208
- logger.debug "templatesdir=#{templatesdir}"
209
- filename = name
210
- end
211
-
212
- manifest = []
213
- puts " Loading template manifest #{filename}..."
214
-
215
- File.open( filename ).readlines.each_with_index do |line,i|
216
- case line
217
- when /^\s*$/
218
- # skip empty lines
219
- when /^\s*#.*$/
220
- # skip comment lines
221
- else
222
- puts "line #{i+1}: #{line}"
223
- values = line.split( /[ <,+\n]+/ )
224
- manifest << values
225
- end
226
- end
227
-
228
- manifest
229
- end
230
-
231
- def load_template( name, builtin )
232
-
233
- if opts.has_includes?
234
- opts.includes.each do |path|
235
- logger.debug "File.exists? #{path}/#{name}"
236
-
237
- if File.exists?( "#{path}/#{name}" ) then
238
- puts "Loading custom template #{path}/#{name}..."
239
- return File.read( "#{path}/#{name}" )
240
- end
241
- end
242
- end
243
-
244
- # fallback load builtin template packaged with gem
245
- load_builtin_template( builtin )
246
- end
247
-
248
- def load_builtin_template( name )
249
- templatesdir = "#{File.dirname(__FILE__)}/templates"
250
- logger.debug "templatesdir=#{templatesdir}"
251
-
252
- File.read( "#{templatesdir}/#{name}" )
253
- end
254
-
255
- def render_template( content, b=TOPLEVEL_BINDING )
256
- ERB.new( content ).result( b )
257
- end
258
-
259
-
260
- def create_slideshow_templates
261
-
262
- files =
263
- case
264
- when opts.s5?
265
- [[ 's5/header.html.erb', 'header.html.erb' ],
266
- [ 's5/footer.html.erb', 'footer.html.erb' ],
267
- [ 's5/style.css.erb', 'style.css.erb' ]]
268
- when opts.fullerscreen? # use fullerscreen templates
269
- [[ 'header.html.erb', 'header.html.erb' ],
270
- [ 'footer.html.erb', 'footer.html.erb' ],
271
- [ 'style.css.erb', 'style.css.erb' ]]
272
- else # use default s6 templates
273
- [[ 's6/header.html.erb', 'header.html.erb' ],
274
- [ 's6/footer.html.erb', 'footer.html.erb' ],
275
- [ 's6/style.css.erb', 'style.css.erb' ]]
276
- end
277
-
278
- # background theming shared between s5/s6/fullerscreen
279
- files << [ 'gradient.svg.erb', 'gradient.svg.erb' ]
280
-
281
- files.each do |file|
282
- source = "#{File.dirname(__FILE__)}/templates/#{file[0]}"
283
- dest = "#{file[1]}"
284
-
285
- puts "Copying '#{source}' to '#{dest}'"
286
- File.copy( source, dest )
287
- end
288
-
289
- puts "Done."
290
- end
291
-
292
- def create_slideshow( fn )
293
-
294
- manifest_name = opts.template
295
- puts "manifest_name=#{manifest_name}"
296
- manifest = load_manifest( manifest_name )
297
- pp manifest
298
- return
299
-
300
- if opts.s5?
301
- headerdoc = load_template( 'header.html.erb', 's5/header.html.erb' )
302
- footerdoc = load_template( 'footer.html.erb', 's5/footer.html.erb' )
303
- styledoc = load_template( 'style.css.erb', 's5/style.css.erb' )
304
- elsif opts.fullerscreen? # use fullerscreen templates
305
- headerdoc = load_template( 'header.html.erb', 'header.html.erb' )
306
- footerdoc = load_template( 'footer.html.erb', 'footer.html.erb' )
307
- styledoc = load_template( 'style.css.erb', 'style.css.erb' )
308
- else # use default s6 templates
309
- headerdoc = load_template( 'header.html.erb', 's6/header.html.erb' )
310
- footerdoc = load_template( 'footer.html.erb', 's6/footer.html.erb' )
311
- styledoc = load_template( 'style.css.erb', 's6/style.css.erb' )
312
- end
313
-
314
- # background theming shared between s5/s6/fullerscreen
315
- gradientdoc = load_template( 'gradient.svg.erb', 'gradient.svg.erb' )
316
-
317
- basename = File.basename( fn, '.*' )
318
- extname = File.extname( fn )
319
-
320
- known_extnames = KNOWN_TEXTILE_EXTNAMES + KNOWN_MARKDOWN_EXTNAMES
321
-
322
- if extname.empty? then
323
- extname = ".textile" # default to .textile
324
-
325
- known_extnames.each do |e|
326
- logger.debug "File.exists? #{basename}#{e}"
327
- if File.exists?( "#{basename}#{e}" ) then
328
- extname = e
329
- logger.debug "extname=#{extname}"
330
- break
331
- end
332
- end
333
- end
334
-
335
- inname = "#{basename}#{extname}"
336
- outname = "#{basename}.html"
337
- svgname = "#{basename}.svg"
338
- cssname = "#{basename}.css"
339
-
340
- logger.debug "inname=#{inname}"
341
-
342
- content = File.read( inname )
343
-
344
- # todo: read headers before command line options (lets you override options using commandline switch)
345
-
346
- # read source document
347
- # strip leading optional headers (key/value pairs) including optional empty lines
348
-
349
- read_headers = true
350
- content = ""
351
-
352
- File.open( inname ).readlines.each do |line|
353
- if read_headers && line =~ /^\s*(\w[\w-]*)[ \t]*:[ \t]*(.*)/
354
- key = $1.downcase
355
- value = $2.strip
356
-
357
- logger.debug " adding option: key=>#{key}< value=>#{value}<"
358
- opts.put( key, value )
359
- elsif line =~ /^\s*$/
360
- content << line unless read_headers
361
- else
362
- read_headers = false
363
- content << line
364
- end
365
- end
366
-
367
- # run pre-filters (built-in macros)
368
- # o replace {{{ w/ <pre class='code'>
369
- # o replace }}} w/ </pre>
370
- content.gsub!( "{{{{{{", "<pre class='code'>_S9BEGIN_" )
371
- content.gsub!( "}}}}}}", "_S9END_</pre>" )
372
- content.gsub!( "{{{", "<pre class='code'>" )
373
- content.gsub!( "}}}", "</pre>" )
374
- # restore escaped {{{}}} I'm sure there's a better way! Rubyize this! Anyone?
375
- content.gsub!( "_S9BEGIN_", "{{{" )
376
- content.gsub!( "_S9END_", "}}}" )
377
-
378
- opts.set_defaults
379
-
380
- params = Params.new( basename, opts )
381
-
382
- puts "Preparing slideshow theme '#{svgname}'..."
383
-
384
- out = File.new( svgname, "w+" )
385
- out << render_template( gradientdoc, params.params_binding )
386
- out.flush
387
- out.close
388
-
389
- puts "Preparing slideshow '#{outname}'..."
390
-
391
- # convert light-weight markup to hypertext
392
-
393
- if KNOWN_MARKDOWN_EXTNAMES.include?( extname )
394
- content = Maruku.new( content, {:on_error => :raise} ).to_html
395
- # old code: content = BlueCloth.new( content ).to_html
396
- else
397
- # turn off hard line breaks
398
- # turn off span caps (see http://rubybook.ca/2008/08/16/redcloth)
399
- red = RedCloth.new( content, [:no_span_caps] )
400
- red.hard_breaks = false
401
- content = red.to_html
402
- end
403
-
404
-
405
- # post-processing
406
-
407
- slide_counter = 0
408
- content2 = ''
409
-
410
- # wrap h1's in slide divs; note use just <h1 since some processors add ids e.g. <h1 id='x'>
411
- content.each_line do |line|
412
- if line.include?( '<h1' ) then
413
- content2 << "\n\n</div>" if slide_counter > 0
414
- content2 << "<div class='slide'>\n\n"
415
- slide_counter += 1
416
- end
417
- content2 << line
418
- end
419
- content2 << "\n\n</div>" if slide_counter > 0
420
-
421
- ## todo: run syntax highlighting before markup/textilize? lets us add textile to highlighted code?
422
- ## avoid undoing escaped entities?
423
-
424
- include_code_stylesheet = false
425
- # syntax highlight code
426
- # todo: can the code handle escaped entities? e.g. &gt;
427
- doc = Hpricot(content2)
428
- doc.search("pre.code, pre > code").each do |e|
429
- if e.inner_html =~ /^\s*#!(\w+)/
430
- lang = $1.downcase
431
- if e.inner_html =~ /^\{\{\{/ # {{{ assumes escape/literal #!lang
432
- # do nothing; next
433
- logger.debug " skipping syntax highlighting using lang=#{lang}; assumimg escaped literal"
434
- else
435
- logger.debug " syntax highlighting using lang=#{lang}"
436
- if Uv.syntaxes.include?(lang)
437
- code = e.inner_html.sub(/^\s*#!\w+/, '').strip
438
-
439
- code.gsub!( "&lt;", "<" )
440
- code.gsub!( "&gt;", ">" )
441
- code.gsub!( "&amp;", "&" )
442
- # todo: missing any other entities? use CGI::unescapeHTML?
443
- logger.debug "code=>#{code}<"
444
-
445
- code_highlighted = Uv.parse( code, "xhtml", lang, opts.code_line_numbers?, opts.code_theme )
446
- # old code: e.inner_html = code_highlighted
447
- # todo: is it ok to replace the pre.code enclosing element to avoid duplicates?
448
- e.swap( code_highlighted )
449
- include_code_stylesheet = true
450
- end
451
- end
452
- end
453
- end
454
-
455
- content2 = doc.to_s
456
-
457
-
458
- out = File.new( outname, "w+" )
459
- out << render_template( headerdoc, params.params_binding )
460
- out << content2
461
- out << render_template( footerdoc, params.params_binding )
462
- out.flush
463
- out.close
464
-
465
- puts "Preparing slideshow stylesheet '#{cssname}'..."
466
-
467
- out = File.new( cssname, "w+" )
468
- out << render_template( styledoc, params.params_binding )
469
-
470
- if include_code_stylesheet
471
- logger.debug "cache_dir=#{cache_dir}"
472
-
473
- FileUtils.mkdir(cache_dir) unless File.exists?(cache_dir) if cache_dir
474
- Uv.copy_files "xhtml", cache_dir
475
-
476
- theme = opts.code_theme
477
-
478
- theme_content = File.read( "#{cache_dir}/css/#{theme}.css" )
479
-
480
- out << "/* styles for code syntax highlighting theme '#{theme}' */\n"
481
- out << "\n"
482
- out << theme_content
483
- end
484
-
485
- out.flush
486
- out.close
487
-
488
-
489
- if opts.s5?
490
- # copy s5 machinery to s5 folder
491
- # todo/fix: is there a better way to check if the dir exists?
492
- Dir.mkdir( 's5' ) unless File.directory?( 's5' )
493
-
494
- [ 'opera.css', 'outline.css', 'print.css', 's5-core.css', 'slides.js' ].each do |name|
495
-
496
- source = "#{File.dirname(__FILE__)}/templates/s5/#{name}"
497
- dest = "s5/#{name}"
498
-
499
- logger.debug "copying '#{source} ' to '#{dest}'"
500
- File.copy( source, dest )
501
- end
502
- elsif opts.fullerscreen?
503
- # do nothing; slideshow machinery built into plugin (requires install!)
504
- else
505
- # copy s6 machinery to s6 folder
506
- Dir.mkdir( 's6' ) unless File.directory?( 's6' )
507
-
508
- [ 'outline.css', 'print.css', 'slides.css', 'slides.js', 'jquery.js' ].each do |name|
509
-
510
- source = "#{File.dirname(__FILE__)}/templates/s6/#{name}"
511
- dest = "s6/#{name}"
512
-
513
- logger.debug "copying '#{source} ' to '#{dest}'"
514
- File.copy( source, dest )
515
- end
516
- end
517
-
518
- puts "Done."
519
- end
520
-
521
-
522
- def run( args )
523
-
524
- opt=OptionParser.new do |cmd|
525
-
526
- cmd.banner = "Usage: slideshow [options] name"
527
-
528
- #todo/fix: use -s5 option without optional hack? possible with OptionParser package/lib?
529
- # use -5 switch instead?
530
- # todo: set template (manifest) to s5
531
- cmd.on( '-s[OPTIONAL]', '--s5', 'S5 Compatible Slide Show' ) { opts.put( 's5', true ) }
532
- # todo: set template (manifest) to fullerscreen
533
- cmd.on( '-f[OPTIONAL]', '--fullerscreen', 'FullerScreen Compatible Slide Show' ) { opts.put( 'fuller', true ) }
534
- # opts.on( "-s", "--style STYLE", "Select Stylesheet" ) { |s| $options[:style]=s }
535
- # opts.on( "-v", "--version", "Show version" ) {}
536
-
537
- cmd.on( '-g', '--generate', 'Generate Slide Show Templates' ) { opts.put( 'generate', true ) }
538
- # use -d or -o to select output directory for slideshow or slideshow templates?
539
- # cmd.on( '-d', '--directory DIRECTORY', 'Output Directory' ) { |s| opts.put( 'directory', s ) }
540
- cmd.on( '-i', '--include PATH', 'Load Path' ) { |s| opts.put( 'include', s ) }
541
-
542
- # todo: find different letter for debug trace switch (use v for version?)
543
- cmd.on( "-v", "--verbose", "Show debug trace" ) {
544
- logger.datetime_format = "%H:%H:%S"
545
- logger.level = Logger::DEBUG
546
- }
547
-
548
- cmd.on( "-t", "--template TEMPLATE", "Template Manifest" ) do |t|
549
- # todo: do some checks on passed in template argument
550
- puts "Using template #{t}"
551
- opts.put( 'template', t )
552
- end
553
-
554
- cmd.on_tail( "-h", "--help", "Show this message" ) {
555
- puts
556
- puts "Slide Show (S9) is a free web alternative to PowerPoint or KeyNote in Ruby"
557
- puts
558
- puts cmd.help
559
- puts
560
- puts "Examples:"
561
- puts " slideshow microformats"
562
- puts " slideshow microformats.textile"
563
- puts " slideshow -s5 microformats # S5 compatible"
564
- puts " slideshow -f microformats # FullerScreen compatible"
565
- puts
566
- puts "More examles:"
567
- puts " slideshow -g # Generate slide show templates"
568
- puts " slideshow -g -s5 # Generate S5 compatible slide show templates"
569
- puts " slideshow -g -f # Generate FullerScreen compatible slide show templates"
570
- puts
571
- puts " slideshow -i . microformats # Use slide show templates in path ."
572
- puts " slideshow -i . -s5 microformats # Use S5 compatible slide show templates in path ."
573
- puts
574
- puts "Further information:"
575
- puts " http://slideshow.rubyforge.org"
576
- exit
577
- }
578
- end
579
-
580
- opt.parse!( args )
581
-
582
- puts "Slide Show (S9) Version: #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
583
-
584
- if opts.generate?
585
- create_slideshow_templates
586
- else
587
- args.each { |fn| create_slideshow( fn ) }
588
- end
589
- end
590
-
591
- end # class Gen
592
-
593
- def Slideshow.main
594
- Gen.new.run(ARGV)
595
- end
596
-
597
- end # module Slideshow
598
-
599
- Slideshow.main if __FILE__ == $0