slideshow 0.7 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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