slideshow 0.6.1 → 0.7

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.
@@ -7,17 +7,17 @@ require 'fileutils'
7
7
  require 'ftools'
8
8
  require 'hpricot'
9
9
  require 'uv'
10
+ require 'pp'
10
11
 
11
12
 
12
13
  module Slideshow
13
14
 
14
- VERSION = '0.6.1'
15
+ VERSION = '0.7'
15
16
 
16
17
  class Params
17
18
 
18
19
  def initialize( name, headers )
19
- @svgname = "#{name}.svg"
20
- @cssname = "#{name}.css"
20
+ @name = name
21
21
  @headers = headers
22
22
  end
23
23
 
@@ -104,7 +104,11 @@ class Opts
104
104
 
105
105
  def code_line_numbers?
106
106
  get_boolean( 'code-line-numbers', DEFAULTS[ :code_line_numbers ] )
107
- end
107
+ end
108
+
109
+ def manifest
110
+ get( 'manifest', 's6.txt' )
111
+ end
108
112
 
109
113
  DEFAULTS =
110
114
  {
@@ -159,7 +163,10 @@ class Gen
159
163
 
160
164
  KNOWN_TEXTILE_EXTNAMES = [ '.textile', '.t' ]
161
165
  KNOWN_MARKDOWN_EXTNAMES = [ '.markdown', '.mark', '.m', '.txt', '.text' ]
162
-
166
+ BUILTIN_MANIFESTS = [ 'fullerscreen.txt', 'fullerscreen.txt.gen',
167
+ 's5.txt','s5.txt.gen',
168
+ 's6.txt','s6.txt.gen' ]
169
+
163
170
  def initialize
164
171
  @logger = Logger.new(STDOUT)
165
172
  @logger.level = Logger::INFO
@@ -188,7 +195,59 @@ class Gen
188
195
  end
189
196
  end
190
197
 
191
- def load_template( name, builtin )
198
+ def load_manifest( path )
199
+
200
+ # check if file exists (if yes use custom template package!) - allows you to override builtin package with same name
201
+ if BUILTIN_MANIFESTS.include?( path ) && !File.exists?( path )
202
+ templatesdir = "#{File.dirname(__FILE__)}/templates"
203
+ logger.debug "use builtin template package"
204
+ logger.debug "templatesdir=#{templatesdir}"
205
+ filename = "#{templatesdir}/#{path}"
206
+ else
207
+ templatesdir = File.dirname( path )
208
+ logger.debug "use custom template package"
209
+ logger.debug "templatesdir=#{templatesdir}"
210
+ filename = path
211
+ end
212
+
213
+ manifest = []
214
+ puts " Loading template manifest #{filename}..."
215
+
216
+ File.open( filename ).readlines.each_with_index do |line,i|
217
+ case line
218
+ when /^\s*$/
219
+ # skip empty lines
220
+ when /^\s*#.*$/
221
+ # skip comment lines
222
+ else
223
+ logger.debug "line #{i+1}: #{line}"
224
+ values = line.split( /[ <,+\n]+/ )
225
+
226
+ # add source for shortcuts (assumes relative path; if not issue warning/error)
227
+ values << values[0] if values.size == 1
228
+
229
+ # normalize all source paths (1..-1) /make full path/add template dir
230
+ (1..values.size-1).each do |i|
231
+ values[i] = "#{templatesdir}/#{values[i]}"
232
+ end
233
+
234
+ manifest << values
235
+ end
236
+ end
237
+
238
+ manifest
239
+ end
240
+
241
+ def load_template( path )
242
+ puts " Loading template #{path}..."
243
+ return File.read( path )
244
+ end
245
+
246
+ def render_template( content, b=TOPLEVEL_BINDING )
247
+ ERB.new( content ).result( b )
248
+ end
249
+
250
+ def load_template_old_delete( name, builtin )
192
251
 
193
252
  if opts.has_includes?
194
253
  opts.includes.each do |path|
@@ -205,71 +264,41 @@ class Gen
205
264
  load_builtin_template( builtin )
206
265
  end
207
266
 
208
- def load_builtin_template( name )
267
+ def load_builtin_template_old_delete( name )
209
268
  templatesdir = "#{File.dirname(__FILE__)}/templates"
210
269
  logger.debug "templatesdir=#{templatesdir}"
211
270
 
212
271
  File.read( "#{templatesdir}/#{name}" )
213
272
  end
214
-
215
- def render_template( content, b=TOPLEVEL_BINDING )
216
- ERB.new( content ).result( b )
217
- end
218
-
273
+
219
274
 
220
275
  def create_slideshow_templates
221
-
222
- files =
223
- case
224
- when opts.s5?
225
- [[ 's5/header.html.erb', 'header.html.erb' ],
226
- [ 's5/footer.html.erb', 'footer.html.erb' ],
227
- [ 's5/style.css.erb', 'style.css.erb' ]]
228
- when opts.fullerscreen? # use fullerscreen templates
229
- [[ 'header.html.erb', 'header.html.erb' ],
230
- [ 'footer.html.erb', 'footer.html.erb' ],
231
- [ 'style.css.erb', 'style.css.erb' ]]
232
- else # use default s6 templates
233
- [[ 's6/header.html.erb', 'header.html.erb' ],
234
- [ 's6/footer.html.erb', 'footer.html.erb' ],
235
- [ 's6/style.css.erb', 'style.css.erb' ]]
236
- end
237
-
238
- # background theming shared between s5/s6/fullerscreen
239
- files << [ 'gradient.svg.erb', 'gradient.svg.erb' ]
240
-
241
- files.each do |file|
242
- source = "#{File.dirname(__FILE__)}/templates/#{file[0]}"
243
- dest = "#{file[1]}"
244
-
245
- puts "Copying '#{source}' to '#{dest}'"
276
+ logger.debug "manifest=#{opts.manifest}.gen"
277
+ manifest = load_manifest( opts.manifest+".gen" )
278
+
279
+ manifest.each do |entry|
280
+ dest = entry[0]
281
+ source = entry[1]
282
+
283
+ # make sure dirs exist
284
+ logger.debug "makedirs( #{File.dirname(dest)} )"
285
+ File.makedirs( File.dirname(dest) )
286
+
287
+ puts "Copying to #{dest} from #{source}..."
246
288
  File.copy( source, dest )
247
289
  end
248
290
 
249
- puts "Done."
291
+ puts "Done."
250
292
  end
251
293
 
252
294
  def create_slideshow( fn )
253
295
 
254
- if opts.s5?
255
- headerdoc = load_template( 'header.html.erb', 's5/header.html.erb' )
256
- footerdoc = load_template( 'footer.html.erb', 's5/footer.html.erb' )
257
- styledoc = load_template( 'style.css.erb', 's5/style.css.erb' )
258
- elsif opts.fullerscreen? # use fullerscreen templates
259
- headerdoc = load_template( 'header.html.erb', 'header.html.erb' )
260
- footerdoc = load_template( 'footer.html.erb', 'footer.html.erb' )
261
- styledoc = load_template( 'style.css.erb', 'style.css.erb' )
262
- else # use default s6 templates
263
- headerdoc = load_template( 'header.html.erb', 's6/header.html.erb' )
264
- footerdoc = load_template( 'footer.html.erb', 's6/footer.html.erb' )
265
- styledoc = load_template( 'style.css.erb', 's6/style.css.erb' )
266
- end
267
-
268
- # background theming shared between s5/s6/fullerscreen
269
- gradientdoc = load_template( 'gradient.svg.erb', 'gradient.svg.erb' )
296
+ logger.debug "manifest=#{opts.manifest}"
297
+ manifest = load_manifest( opts.manifest )
298
+ # pp manifest
270
299
 
271
- basename = File.basename( fn, '.*' )
272
- extname = File.extname( fn )
300
+ basename = File.basename( fn, '.*' )
301
+ extname = File.extname( fn )
273
302
 
274
303
  known_extnames = KNOWN_TEXTILE_EXTNAMES + KNOWN_MARKDOWN_EXTNAMES
275
304
 
@@ -287,14 +316,13 @@ class Gen
287
316
  end
288
317
 
289
318
  inname = "#{basename}#{extname}"
290
- outname = "#{basename}.html"
291
- svgname = "#{basename}.svg"
292
- cssname = "#{basename}.css"
293
319
 
294
320
  logger.debug "inname=#{inname}"
295
321
 
296
322
  content = File.read( inname )
297
323
 
324
+ # todo: read headers before command line options (lets you override options using commandline switch)
325
+
298
326
  # read source document
299
327
  # strip leading optional headers (key/value pairs) including optional empty lines
300
328
 
@@ -330,15 +358,8 @@ class Gen
330
358
  opts.set_defaults
331
359
 
332
360
  params = Params.new( basename, opts )
333
-
334
- puts "Preparing slideshow theme '#{svgname}'..."
335
361
 
336
- out = File.new( svgname, "w+" )
337
- out << render_template( gradientdoc, params.params_binding )
338
- out.flush
339
- out.close
340
-
341
- puts "Preparing slideshow '#{outname}'..."
362
+ puts "Preparing slideshow '#{basename}'..."
342
363
 
343
364
  # convert light-weight markup to hypertext
344
365
 
@@ -370,6 +391,7 @@ class Gen
370
391
  end
371
392
  content2 << "\n\n</div>" if slide_counter > 0
372
393
 
394
+ =begin
373
395
  ## todo: run syntax highlighting before markup/textilize? lets us add textile to highlighted code?
374
396
  ## avoid undoing escaped entities?
375
397
 
@@ -405,20 +427,42 @@ class Gen
405
427
  end
406
428
 
407
429
  content2 = doc.to_s
430
+ =end
431
+
432
+
433
+ manifest.each do |entry|
434
+ outname = entry[0]
435
+ if outname.include? '__file__' # process
436
+ outname = outname.gsub( '__file__', basename )
437
+ puts "Preparing #{outname}..."
438
+
439
+ out = File.new( outname, "w+" )
440
+
441
+ out << render_template( load_template( entry[1] ), params.params_binding )
442
+
443
+ if entry.size > 2 # more than one source file? assume header and footer with content added inbetween
444
+ out << content2
445
+ out << render_template( load_template( entry[2] ), params.params_binding )
446
+ end
408
447
 
448
+ out.flush
449
+ out.close
450
+
451
+ else # just copy verbatim if target/dest has no __file__ in name
452
+ dest = entry[0]
453
+ source = entry[1]
454
+
455
+ # make sure dirs exist
456
+ logger.debug "makedirs( #{File.dirname(dest)} )"
457
+ File.makedirs( File.dirname(dest) )
458
+
459
+ puts "Copying to #{dest} from #{source}..."
460
+ File.copy( source, dest )
461
+ end
462
+ end
409
463
 
410
- out = File.new( outname, "w+" )
411
- out << render_template( headerdoc, params.params_binding )
412
- out << content2
413
- out << render_template( footerdoc, params.params_binding )
414
- out.flush
415
- out.close
416
-
417
- puts "Preparing slideshow stylesheet '#{cssname}'..."
418
-
419
- out = File.new( cssname, "w+" )
420
- out << render_template( styledoc, params.params_binding )
421
-
464
+
465
+ =begin
422
466
  if include_code_stylesheet
423
467
  logger.debug "cache_dir=#{cache_dir}"
424
468
 
@@ -433,39 +477,7 @@ class Gen
433
477
  out << "\n"
434
478
  out << theme_content
435
479
  end
436
-
437
- out.flush
438
- out.close
439
-
440
-
441
- if opts.s5?
442
- # copy s5 machinery to s5 folder
443
- # todo/fix: is there a better way to check if the dir exists?
444
- Dir.mkdir( 's5' ) unless File.directory?( 's5' )
445
-
446
- [ 'opera.css', 'outline.css', 'print.css', 's5-core.css', 'slides.js' ].each do |name|
447
-
448
- source = "#{File.dirname(__FILE__)}/templates/s5/#{name}"
449
- dest = "s5/#{name}"
450
-
451
- logger.debug "copying '#{source} ' to '#{dest}'"
452
- File.copy( source, dest )
453
- end
454
- elsif opts.fullerscreen?
455
- # do nothing; slideshow machinery built into plugin (requires install!)
456
- else
457
- # copy s6 machinery to s6 folder
458
- Dir.mkdir( 's6' ) unless File.directory?( 's6' )
459
-
460
- [ 'outline.css', 'print.css', 'slides.css', 'slides.js', 'jquery.js' ].each do |name|
461
-
462
- source = "#{File.dirname(__FILE__)}/templates/s6/#{name}"
463
- dest = "s6/#{name}"
464
-
465
- logger.debug "copying '#{source} ' to '#{dest}'"
466
- File.copy( source, dest )
467
- end
468
- end
480
+ =end
469
481
 
470
482
  puts "Done."
471
483
  end
@@ -479,21 +491,28 @@ def run( args )
479
491
 
480
492
  #todo/fix: use -s5 option without optional hack? possible with OptionParser package/lib?
481
493
  # use -5 switch instead?
482
- cmd.on( '-s[OPTIONAL]', '--s5', 'S5 Compatible Slide Show' ) { opts.put( 's5', true ) }
483
- cmd.on( '-f[OPTIONAL]', '--fullerscreen', 'FullerScreen Compatible Slide Show' ) { opts.put( 'fuller', true ) }
494
+ cmd.on( '-s[OPTIONAL]', '--s5', 'S5 Compatible Slide Show' ) { opts.put( 's5', true ); opts.put( 'manifest', 's5.txt' ) }
495
+ cmd.on( '-f[OPTIONAL]', '--fullerscreen', 'FullerScreen Compatible Slide Show' ) { opts.put( 'fuller', true ); opts.put( 'manifest', 'fullerscreen.txt' ) }
484
496
  # opts.on( "-s", "--style STYLE", "Select Stylesheet" ) { |s| $options[:style]=s }
485
497
  # opts.on( "-v", "--version", "Show version" ) {}
486
498
 
487
499
  cmd.on( '-g', '--generate', 'Generate Slide Show Templates' ) { opts.put( 'generate', true ) }
488
500
  # use -d or -o to select output directory for slideshow or slideshow templates?
489
501
  # cmd.on( '-d', '--directory DIRECTORY', 'Output Directory' ) { |s| opts.put( 'directory', s ) }
490
- cmd.on( '-i', '--include PATH', 'Load Path' ) { |s| opts.put( 'include', s ) }
491
-
492
- cmd.on( "-t", "--trace", "Show debug trace" ) {
502
+ # cmd.on( '-i', '--include PATH', 'Load Path' ) { |s| opts.put( 'include', s ) }
503
+
504
+ # todo: find different letter for debug trace switch (use v for version?)
505
+ cmd.on( "-v", "--verbose", "Show debug trace" ) do
493
506
  logger.datetime_format = "%H:%H:%S"
494
- logger.level = Logger::DEBUG
495
- }
496
- cmd.on_tail( "-h", "--help", "Show this message" ) {
507
+ logger.level = Logger::DEBUG
508
+ end
509
+
510
+ cmd.on( "-t", "--template TEMPLATE", "Template Manifest" ) do |t|
511
+ # todo: do some checks on passed in template argument
512
+ opts.put( 'manifest', t )
513
+ end
514
+
515
+ cmd.on_tail( "-h", "--help", "Show this message" ) do
497
516
  puts
498
517
  puts "Slide Show (S9) is a free web alternative to PowerPoint or KeyNote in Ruby"
499
518
  puts
@@ -510,13 +529,12 @@ def run( args )
510
529
  puts " slideshow -g -s5 # Generate S5 compatible slide show templates"
511
530
  puts " slideshow -g -f # Generate FullerScreen compatible slide show templates"
512
531
  puts
513
- puts " slideshow -i . microformats # Use slide show templates in path ."
514
- puts " slideshow -i . -s5 microformats # Use S5 compatible slide show templates in path ."
532
+ puts " slideshow -t s3.txt microformats # Use custom slide show templates"
515
533
  puts
516
534
  puts "Further information:"
517
535
  puts " http://slideshow.rubyforge.org"
518
536
  exit
519
- }
537
+ end
520
538
  end
521
539
 
522
540
  opt.parse!( args )
@@ -0,0 +1,599 @@
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
@@ -0,0 +1,5 @@
1
+ # builtin FullerScreen template package manifest
2
+
3
+ __file__.html header.html.erb + footer.html.erb
4
+ __file__.svg gradient.svg.erb
5
+ __file__.css style.css.erb
@@ -0,0 +1,7 @@
1
+ # FullerScreen manifest to generate sample template package from builtin templates
2
+
3
+ fullerscreen.txt fullerscreen.txt.sample
4
+ header.html.erb
5
+ footer.html.erb
6
+ gradient.svg.erb
7
+ style.css.erb
@@ -0,0 +1,11 @@
1
+ # FullerScreen template package manifest sample
2
+ # Change as desired/needed
3
+ #
4
+ # Questions? Comments?
5
+ # Send them along to the Free Web Slide Show Alternatives (S5, S6, S9 And Friends) Forum/Mailing List.
6
+ # http://groups.google.com/group/webslideshow
7
+
8
+ __file__.html header.html.erb + footer.html.erb
9
+ __file__.svg gradient.svg.erb
10
+ __file__.css style.css.erb
11
+
@@ -7,14 +7,14 @@
7
7
 
8
8
  <title><%= @headers['title'] %></title>
9
9
 
10
- <link title="Style" href="<%= @cssname %>" type="text/css" rel="STYLESHEET">
10
+ <link title="Style" href="<%= "#{@name}.css" %>" type="text/css" rel="STYLESHEET">
11
11
 
12
12
  </head>
13
13
  <body>
14
14
 
15
15
  <div class="layout">
16
16
  <div class="background">
17
- <object data="<%= @svgname %>" width="100%" height="100%"></object>
17
+ <object data="<%= "#{@name}.svg" %>" width="100%" height="100%"></object>
18
18
  </div>
19
19
  </div>
20
20
 
@@ -0,0 +1,10 @@
1
+ # builtin S5 template package manifest
2
+
3
+ __file__.svg gradient.svg.erb
4
+ __file__.html s5/header.html.erb + s5/footer.html.erb
5
+ __file__.css s5/style.css.erb
6
+ s5/opera.css
7
+ s5/outline.css
8
+ s5/print.css
9
+ s5/s5-core.css
10
+ s5/slides.js
@@ -0,0 +1,12 @@
1
+ # S5 manifest to generate sample template package from builtin templates
2
+
3
+ s5.txt s5.txt.sample
4
+ gradient.svg.erb
5
+ header.html.erb s5/header.html.erb
6
+ footer.html.erb s5/footer.html.erb
7
+ style.html.erb s5/style.css.erb
8
+ s5/opera.css
9
+ s5/outline.css
10
+ s5/print.css
11
+ s5/s5-core.css
12
+ s5/slides.js
@@ -0,0 +1,15 @@
1
+ # S5 template package manifest sample
2
+ # Change as desired/needed
3
+ #
4
+ # Questions? Comments?
5
+ # Send them along to the Free Web Slide Show Alternatives (S5, S6, S9 And Friends) Forum/Mailing List.
6
+ # http://groups.google.com/group/webslideshow
7
+
8
+ __file__.svg gradient.svg.erb
9
+ __file__.html header.html.erb + footer.html.erb
10
+ __file__.css style.css.erb
11
+ s5/opera.css
12
+ s5/outline.css
13
+ s5/print.css
14
+ s5/s5-core.css
15
+ s5/slides.js
@@ -8,7 +8,7 @@
8
8
  <meta name="defaultView" content="slideshow" />
9
9
  <meta name="controlVis" content="hidden" />
10
10
  <!-- style sheet links -->
11
- <link rel="stylesheet" href="<%= @cssname %>" type="text/css" media="projection" id="slideProj" />
11
+ <link rel="stylesheet" href="<%= "#{@name}.css" %>" type="text/css" media="projection" id="slideProj" />
12
12
  <link rel="stylesheet" href="s5/outline.css" type="text/css" media="screen" id="outlineStyle" />
13
13
  <link rel="stylesheet" href="s5/print.css" type="text/css" media="print" id="slidePrint" />
14
14
  <link rel="stylesheet" href="s5/opera.css" type="text/css" media="projection" id="operaFix" />
@@ -23,7 +23,7 @@
23
23
  <div class="layout">
24
24
 
25
25
  <div class="background">
26
- <object data="<%= @svgname %>" width="100%" height="100%"></object>
26
+ <object data="<%= "#{@name}.svg" %>" width="100%" height="100%"></object>
27
27
  </div>
28
28
 
29
29
  <div id="controls"><!-- DO NOT EDIT --></div>
@@ -0,0 +1,10 @@
1
+ # builtin S6 template package manifest
2
+
3
+ __file__.svg gradient.svg.erb
4
+ __file__.html s6/header.html.erb + s6/footer.html.erb
5
+ __file__.css s6/style.css.erb
6
+ s6/jquery.js
7
+ s6/outline.css
8
+ s6/print.css
9
+ s6/slides.css
10
+ s6/slides.js
@@ -0,0 +1,12 @@
1
+ # S6 manifest to generate sample template package from builtin templates
2
+
3
+ s6.txt s6.txt.sample
4
+ gradient.svg.erb
5
+ header.html.erb s6/header.html.erb
6
+ footer.html.erb s6/footer.html.erb
7
+ style.css.erb s6/style.css.erb
8
+ s6/jquery.js
9
+ s6/outline.css
10
+ s6/print.css
11
+ s6/slides.css
12
+ s6/slides.js
@@ -0,0 +1,15 @@
1
+ # S6 template package manifest sample
2
+ # Change as desired/needed
3
+ #
4
+ # Questions? Comments?
5
+ # Send them along to the Free Web Slide Show Alternatives (S5, S6, S9 And Friends) Forum/Mailing List.
6
+ # http://groups.google.com/group/webslideshow
7
+
8
+ __file__.svg gradient.svg.erb
9
+ __file__.html header.html.erb + footer.html.erb
10
+ __file__.css style.css.erb
11
+ s6/jquery.js
12
+ s6/outline.css
13
+ s6/print.css
14
+ s6/slides.css
15
+ s6/slides.js
@@ -7,7 +7,7 @@
7
7
  <!-- configuration parameters -->
8
8
  <meta name="defaultView" content="slideshow" />
9
9
  <!-- style sheet links -->
10
- <link rel="stylesheet" href="<%= @cssname %>" type="text/css" media="projection" id="slideProj" />
10
+ <link rel="stylesheet" href="<%= "#{@name}.css" %>" type="text/css" media="projection" id="slideProj" />
11
11
  <link rel="stylesheet" href="s6/outline.css" type="text/css" media="screen" id="outlineStyle" />
12
12
  <link rel="stylesheet" href="s6/print.css" type="text/css" media="print" id="slidePrint" />
13
13
 
@@ -22,7 +22,7 @@
22
22
  <div class="layout">
23
23
 
24
24
  <div class="background">
25
- <object data="<%= @svgname %>" width="100%" height="100%">
25
+ <object data="<%= "#{@name}.svg" %>" width="100%" height="100%">
26
26
  </object>
27
27
  </div>
28
28
 
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.6.1
4
+ version: "0.7"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -9,11 +9,12 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-30 00:00:00 -07:00
12
+ date: 2009-01-26 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: RedCloth
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
@@ -23,6 +24,7 @@ dependencies:
23
24
  version:
24
25
  - !ruby/object:Gem::Dependency
25
26
  name: maruku
27
+ type: :runtime
26
28
  version_requirement:
27
29
  version_requirements: !ruby/object:Gem::Requirement
28
30
  requirements:
@@ -32,6 +34,7 @@ dependencies:
32
34
  version:
33
35
  - !ruby/object:Gem::Dependency
34
36
  name: hpricot
37
+ type: :runtime
35
38
  version_requirement:
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
@@ -41,6 +44,7 @@ dependencies:
41
44
  version:
42
45
  - !ruby/object:Gem::Dependency
43
46
  name: ultraviolet
47
+ type: :runtime
44
48
  version_requirement:
45
49
  version_requirements: !ruby/object:Gem::Requirement
46
50
  requirements:
@@ -58,8 +62,12 @@ extra_rdoc_files: []
58
62
 
59
63
  files:
60
64
  - lib/slideshow.rb
65
+ - lib/slideshow.v6.rb
61
66
  - lib/templates
62
67
  - lib/templates/footer.html.erb
68
+ - lib/templates/fullerscreen.txt
69
+ - lib/templates/fullerscreen.txt.gen
70
+ - lib/templates/fullerscreen.txt.sample
63
71
  - lib/templates/gradient.svg.erb
64
72
  - lib/templates/header.html.erb
65
73
  - lib/templates/s5
@@ -71,6 +79,9 @@ files:
71
79
  - lib/templates/s5/s5-core.css
72
80
  - lib/templates/s5/slides.js
73
81
  - lib/templates/s5/style.css.erb
82
+ - lib/templates/s5.txt
83
+ - lib/templates/s5.txt.gen
84
+ - lib/templates/s5.txt.sample
74
85
  - lib/templates/s6
75
86
  - lib/templates/s6/footer.html.erb
76
87
  - lib/templates/s6/header.html.erb
@@ -80,6 +91,9 @@ files:
80
91
  - lib/templates/s6/slides.css
81
92
  - lib/templates/s6/slides.js
82
93
  - lib/templates/s6/style.css.erb
94
+ - lib/templates/s6.txt
95
+ - lib/templates/s6.txt.gen
96
+ - lib/templates/s6.txt.sample
83
97
  - lib/templates/style.css.erb
84
98
  - bin/slideshow
85
99
  has_rdoc: false
@@ -104,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
118
  requirements: []
105
119
 
106
120
  rubyforge_project: slideshow
107
- rubygems_version: 1.1.1
121
+ rubygems_version: 1.3.1
108
122
  signing_key:
109
123
  specification_version: 2
110
124
  summary: Slide Show (S9) - A Free Web Alternative to PowerPoint and KeyNote in Ruby