slideshow 0.6.1 → 0.7

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