slideshow 1.1.0.beta7 → 1.1.0.beta8
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.
- data/Manifest.txt +5 -2
- data/lib/slideshow.rb +7 -3
- data/lib/slideshow/{fetch.rb → commands/fetch.rb} +23 -12
- data/lib/slideshow/{gen.rb → commands/gen.rb} +334 -507
- data/lib/slideshow/commands/gen_templates.rb +66 -0
- data/lib/slideshow/commands/list.rb +32 -0
- data/lib/slideshow/config.rb +31 -2
- data/lib/slideshow/helpers/syntax/uv_helper.rb +4 -4
- data/lib/slideshow/manifest.rb +3 -7
- data/lib/slideshow/runner.rb +130 -0
- data/lib/slideshow/version.rb +1 -1
- metadata +9 -6
data/Manifest.txt
CHANGED
@@ -6,13 +6,15 @@ bin/slideshow
|
|
6
6
|
config/slideshow.builtin.yml
|
7
7
|
config/slideshow.yml
|
8
8
|
lib/slideshow.rb
|
9
|
+
lib/slideshow/commands/fetch.rb
|
10
|
+
lib/slideshow/commands/gen.rb
|
11
|
+
lib/slideshow/commands/gen_templates.rb
|
12
|
+
lib/slideshow/commands/list.rb
|
9
13
|
lib/slideshow/config.rb
|
10
|
-
lib/slideshow/fetch.rb
|
11
14
|
lib/slideshow/filters/debug_filter.rb
|
12
15
|
lib/slideshow/filters/headers_filter.rb
|
13
16
|
lib/slideshow/filters/slide_filter.rb
|
14
17
|
lib/slideshow/filters/text_filter.rb
|
15
|
-
lib/slideshow/gen.rb
|
16
18
|
lib/slideshow/headers.rb
|
17
19
|
lib/slideshow/helpers/analytics_helper.rb
|
18
20
|
lib/slideshow/helpers/background_helper.rb
|
@@ -31,6 +33,7 @@ lib/slideshow/markup/markdown.rb
|
|
31
33
|
lib/slideshow/markup/rest.rb
|
32
34
|
lib/slideshow/markup/textile.rb
|
33
35
|
lib/slideshow/opts.rb
|
36
|
+
lib/slideshow/runner.rb
|
34
37
|
lib/slideshow/slide.rb
|
35
38
|
lib/slideshow/version.rb
|
36
39
|
templates/s6.txt
|
data/lib/slideshow.rb
CHANGED
@@ -42,10 +42,14 @@ require 'slideshow/version'
|
|
42
42
|
require 'slideshow/opts'
|
43
43
|
require 'slideshow/headers'
|
44
44
|
require 'slideshow/config'
|
45
|
-
require 'slideshow/gen'
|
46
45
|
require 'slideshow/manifest'
|
47
|
-
require 'slideshow/fetch'
|
48
46
|
require 'slideshow/slide'
|
47
|
+
require 'slideshow/runner'
|
48
|
+
|
49
|
+
require 'slideshow/commands/fetch'
|
50
|
+
require 'slideshow/commands/gen'
|
51
|
+
require 'slideshow/commands/gen_templates'
|
52
|
+
require 'slideshow/commands/list'
|
49
53
|
|
50
54
|
require 'slideshow/markup/textile'
|
51
55
|
require 'slideshow/markup/markdown'
|
@@ -92,7 +96,7 @@ module Slideshow
|
|
92
96
|
args += slideshowopt.split if slideshowopt
|
93
97
|
args += ARGV.dup
|
94
98
|
|
95
|
-
|
99
|
+
Runner.new.run(args)
|
96
100
|
end
|
97
101
|
|
98
102
|
end # module Slideshow
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module Slideshow
|
2
|
-
|
2
|
+
|
3
|
+
class Fetch
|
4
|
+
|
5
|
+
include Manifest # gets us methods like installed_template_manifests, etc.
|
6
|
+
|
7
|
+
### fix: remove opts, use config (wrapped!!)
|
3
8
|
|
9
|
+
def initialize( logger, opts, config )
|
10
|
+
@logger = logger
|
11
|
+
@opts = opts
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :logger, :opts, :config
|
16
|
+
|
4
17
|
def fetch_file( dest, src )
|
5
18
|
|
6
19
|
## note: code moved to its own gem, that is, fetcher
|
@@ -11,7 +24,7 @@ module Slideshow
|
|
11
24
|
end
|
12
25
|
|
13
26
|
|
14
|
-
def
|
27
|
+
def run
|
15
28
|
logger.debug "fetch_uri=#{opts.fetch_uri}"
|
16
29
|
|
17
30
|
src = opts.fetch_uri
|
@@ -35,7 +48,7 @@ module Slideshow
|
|
35
48
|
|
36
49
|
logger.debug "scheme: #{uri.scheme}, host: #{uri.host}, port: #{uri.port}, path: #{uri.path}"
|
37
50
|
|
38
|
-
dirname = File.dirname( uri.path )
|
51
|
+
dirname = File.dirname( uri.path )
|
39
52
|
basename = File.basename( uri.path, '.*' ) # e.g. fullerscreen (without extension)
|
40
53
|
filename = File.basename( uri.path ) # e.g. fullerscreen.txt (with extension)
|
41
54
|
|
@@ -43,12 +56,12 @@ module Slideshow
|
|
43
56
|
logger.debug "basename: #{basename}, filename: #{filename}"
|
44
57
|
|
45
58
|
dlbase = "#{uri.scheme}://#{uri.host}:#{uri.port}#{dirname}"
|
46
|
-
pkgpath = File.expand_path( "#{config_dir}/templates/#{basename}" )
|
59
|
+
pkgpath = File.expand_path( "#{config.config_dir}/templates/#{basename}" )
|
47
60
|
|
48
61
|
logger.debug "dlpath: #{dlbase}"
|
49
62
|
logger.debug "pkgpath: #{pkgpath}"
|
50
63
|
|
51
|
-
FileUtils.makedirs( pkgpath ) unless File.directory? pkgpath
|
64
|
+
FileUtils.makedirs( pkgpath ) unless File.directory? pkgpath
|
52
65
|
|
53
66
|
puts "Fetching template package '#{basename}'"
|
54
67
|
puts " : from '#{dlbase}'"
|
@@ -79,12 +92,10 @@ module Slideshow
|
|
79
92
|
fetch_file( dest, src )
|
80
93
|
end
|
81
94
|
end
|
82
|
-
puts "Done."
|
95
|
+
puts "Done."
|
83
96
|
end
|
84
|
-
|
85
|
-
end # module Fetch
|
86
|
-
end # module Slideshow
|
87
97
|
|
88
|
-
|
89
|
-
|
90
|
-
|
98
|
+
|
99
|
+
end # class Fetch
|
100
|
+
|
101
|
+
end # module Slideshow
|
@@ -1,507 +1,334 @@
|
|
1
|
-
module Slideshow
|
2
|
-
|
3
|
-
class Gen
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
attr_reader :
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
when :
|
25
|
-
|
26
|
-
when :
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
wrap_markup
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
text
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
text
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
#
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
#
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
@session = {} # reset session hash for plugins/helpers
|
336
|
-
|
337
|
-
inname = "#{dirname}/#{basename}#{extname}"
|
338
|
-
|
339
|
-
logger.debug "inname=#{inname}"
|
340
|
-
|
341
|
-
content = File.read( inname )
|
342
|
-
|
343
|
-
# run text filters
|
344
|
-
|
345
|
-
config.text_filters.each do |filter|
|
346
|
-
mn = filter.tr( '-', '_' ).to_sym # construct method name (mn)
|
347
|
-
content = send( mn, content ) # call filter e.g. include_helper_hack( content )
|
348
|
-
end
|
349
|
-
|
350
|
-
# convert light-weight markup to hypertext
|
351
|
-
|
352
|
-
content = text_to_html( content )
|
353
|
-
|
354
|
-
# post-processing
|
355
|
-
|
356
|
-
# make content2 and slide2 available to erb template
|
357
|
-
# -- todo: cleanup variable names and use attr_readers for content and slide
|
358
|
-
|
359
|
-
if @markup_type == :markdown && config.markdown_post_processing?( Markdown.lib ) == false
|
360
|
-
puts " Skipping post-processing (passing content through as is)..."
|
361
|
-
@content = content # content all-in-one - make it available in erb templates
|
362
|
-
else
|
363
|
-
# sets @content (all-in-one string) and @slides (structured content; split into slides)
|
364
|
-
post_processing_slides( content )
|
365
|
-
end
|
366
|
-
|
367
|
-
|
368
|
-
manifest.each do |entry|
|
369
|
-
outname = entry[0]
|
370
|
-
if outname.include? '__file__' # process
|
371
|
-
outname = outname.gsub( '__file__', basename )
|
372
|
-
puts "Preparing #{outname}..."
|
373
|
-
|
374
|
-
out = File.new( with_output_path( outname, outpath ), "w+" )
|
375
|
-
|
376
|
-
out << render_template( load_template( entry[1] ), binding )
|
377
|
-
|
378
|
-
if entry.size > 2 # more than one source file? assume header and footer with content added inbetween
|
379
|
-
out << content2
|
380
|
-
out << render_template( load_template( entry[2] ), binding )
|
381
|
-
end
|
382
|
-
|
383
|
-
out.flush
|
384
|
-
out.close
|
385
|
-
|
386
|
-
else # just copy verbatim if target/dest has no __file__ in name
|
387
|
-
dest = entry[0]
|
388
|
-
source = entry[1]
|
389
|
-
|
390
|
-
puts "Copying to #{dest} from #{source}..."
|
391
|
-
FileUtils.copy( source, with_output_path( dest, outpath ) )
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
puts "Done."
|
396
|
-
end
|
397
|
-
|
398
|
-
def load_plugins
|
399
|
-
|
400
|
-
patterns = []
|
401
|
-
patterns << "#{config_dir}/lib/**/*.rb"
|
402
|
-
patterns << 'lib/**/*.rb' unless Slideshow.root == File.expand_path( '.' ) # don't include lib if we are in repo (don't include slideshow/lib)
|
403
|
-
|
404
|
-
patterns.each do |pattern|
|
405
|
-
pattern.gsub!( '\\', '/') # normalize path; make sure all path use / only
|
406
|
-
Dir.glob( pattern ) do |plugin|
|
407
|
-
begin
|
408
|
-
puts "Loading plugins in '#{plugin}'..."
|
409
|
-
require( plugin )
|
410
|
-
rescue Exception => e
|
411
|
-
puts "** error: failed loading plugins in '#{plugin}': #{e}"
|
412
|
-
end
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
def run( args )
|
418
|
-
|
419
|
-
opt=OptionParser.new do |cmd|
|
420
|
-
|
421
|
-
cmd.banner = "Usage: slideshow [options] name"
|
422
|
-
|
423
|
-
cmd.on( '-o', '--output PATH', 'Output Path' ) { |path| opts.output_path = path }
|
424
|
-
|
425
|
-
cmd.on( '-g', '--generate', 'Generate Slide Show Templates (Using Built-In S6 Pack)' ) { opts.generate = true }
|
426
|
-
|
427
|
-
cmd.on( "-t", "--template MANIFEST", "Template Manifest" ) do |t|
|
428
|
-
# todo: do some checks on passed in template argument
|
429
|
-
opts.manifest = t
|
430
|
-
end
|
431
|
-
|
432
|
-
# ?? opts.on( "-s", "--style STYLE", "Select Stylesheet" ) { |s| $options[:style]=s }
|
433
|
-
# ?? opts.on( "--version", "Show version" ) {}
|
434
|
-
|
435
|
-
# ?? cmd.on( '-i', '--include PATH', 'Load Path' ) { |s| opts.put( 'include', s ) }
|
436
|
-
|
437
|
-
cmd.on( '-f', '--fetch URI', 'Fetch Templates' ) do |uri|
|
438
|
-
opts.fetch_uri = uri
|
439
|
-
end
|
440
|
-
|
441
|
-
cmd.on( '-c', '--config PATH', 'Configuration Path (default is ~/.slideshow)' ) do |path|
|
442
|
-
opts.config_path = path
|
443
|
-
end
|
444
|
-
|
445
|
-
cmd.on( '-l', '--list', 'List Installed Templates' ) { opts.list = true }
|
446
|
-
|
447
|
-
# todo: find different letter for debug trace switch (use v for version?)
|
448
|
-
cmd.on( "-v", "--verbose", "Show debug trace" ) do
|
449
|
-
logger.datetime_format = "%H:%H:%S"
|
450
|
-
logger.level = Logger::DEBUG
|
451
|
-
end
|
452
|
-
|
453
|
-
usage =<<EOS
|
454
|
-
|
455
|
-
Slide Show (S9) is a free web alternative to PowerPoint or KeyNote in Ruby
|
456
|
-
|
457
|
-
#{cmd.help}
|
458
|
-
|
459
|
-
Examples:
|
460
|
-
slideshow microformats
|
461
|
-
slideshow microformats.textile # Process slides using Textile
|
462
|
-
slideshow microformats.text # Process slides using Markdown
|
463
|
-
slideshow microformats.rst # Process slides using reStructuredText
|
464
|
-
slideshow -o slides microformats # Output slideshow to slides folder
|
465
|
-
|
466
|
-
More examles:
|
467
|
-
slideshow -g # Generate slide show templates using built-in S6 pack
|
468
|
-
|
469
|
-
slideshow -l # List installed slide show templates
|
470
|
-
slideshow -f s5blank # Fetch (install) S5 blank starter template from internet
|
471
|
-
slideshow -t s5blank microformats # Use your own slide show templates (e.g. s5blank)
|
472
|
-
|
473
|
-
Further information:
|
474
|
-
http://slideshow.rubyforge.org
|
475
|
-
|
476
|
-
EOS
|
477
|
-
|
478
|
-
|
479
|
-
cmd.on_tail( "-h", "--help", "Show this message" ) do
|
480
|
-
puts usage
|
481
|
-
exit
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
opt.parse!( args )
|
486
|
-
|
487
|
-
config.load
|
488
|
-
|
489
|
-
puts Slideshow.generator
|
490
|
-
|
491
|
-
if opts.list?
|
492
|
-
list_slideshow_templates
|
493
|
-
elsif opts.generate?
|
494
|
-
create_slideshow_templates
|
495
|
-
elsif opts.fetch?
|
496
|
-
fetch_slideshow_templates
|
497
|
-
else
|
498
|
-
load_plugins # check for optional plugins/extension in ./lib folder
|
499
|
-
|
500
|
-
args.each { |fn| create_slideshow( fn ) }
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
end # class Gen
|
505
|
-
|
506
|
-
|
507
|
-
end # module Slideshow
|
1
|
+
module Slideshow
|
2
|
+
|
3
|
+
class Gen
|
4
|
+
|
5
|
+
include Manifest # gets us methods like installed_template_manifests, etc.
|
6
|
+
|
7
|
+
### fix: remove opts, use config (wrapped!!)
|
8
|
+
|
9
|
+
def initialize( logger, opts, config, headers )
|
10
|
+
@logger = logger
|
11
|
+
@opts = opts
|
12
|
+
@config = config
|
13
|
+
@headers = headers
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :logger, :opts, :config, :headers
|
17
|
+
attr_reader :session # give helpers/plugins a session-like hash
|
18
|
+
|
19
|
+
attr_reader :markup_type # :textile, :markdown, :rest
|
20
|
+
|
21
|
+
# uses configured markup processor (textile,markdown,rest) to generate html
|
22
|
+
def text_to_html( content )
|
23
|
+
content = case @markup_type
|
24
|
+
when :markdown
|
25
|
+
markdown_to_html( content )
|
26
|
+
when :textile
|
27
|
+
textile_to_html( content )
|
28
|
+
when :rest
|
29
|
+
rest_to_html( content )
|
30
|
+
end
|
31
|
+
content
|
32
|
+
end
|
33
|
+
|
34
|
+
def guard_text( text )
|
35
|
+
# todo/fix 2: note for Textile we need to differentiate between blocks and inline
|
36
|
+
# thus, to avoid runs - use guard_block (add a leading newline to avoid getting include in block that goes before)
|
37
|
+
|
38
|
+
# todo/fix: remove wrap_markup; replace w/ guard_text
|
39
|
+
# why: text might be css, js, not just html
|
40
|
+
wrap_markup( text )
|
41
|
+
end
|
42
|
+
|
43
|
+
def guard_block( text )
|
44
|
+
if markup_type == :textile
|
45
|
+
# saveguard with notextile wrapper etc./no further processing needed
|
46
|
+
# note: add leading newlines to avoid block-runons
|
47
|
+
"\n\n<notextile>\n#{text}\n</notextile>\n"
|
48
|
+
else
|
49
|
+
text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def guard_inline( text )
|
54
|
+
wrap_markup( text )
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def wrap_markup( text )
|
59
|
+
if markup_type == :textile
|
60
|
+
# saveguard with notextile wrapper etc./no further processing needed
|
61
|
+
"<notextile>\n#{text}\n</notextile>"
|
62
|
+
else
|
63
|
+
text
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def load_template( path )
|
69
|
+
puts " Loading template #{path}..."
|
70
|
+
return File.read( path )
|
71
|
+
end
|
72
|
+
|
73
|
+
def render_template( content, the_binding )
|
74
|
+
ERB.new( content ).result( the_binding )
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def with_output_path( dest, output_path )
|
79
|
+
dest_full = File.expand_path( dest, output_path )
|
80
|
+
logger.debug "dest_full=#{dest_full}"
|
81
|
+
|
82
|
+
# make sure dest path exists
|
83
|
+
dest_path = File.dirname( dest_full )
|
84
|
+
logger.debug "dest_path=#{dest_path}"
|
85
|
+
FileUtils.makedirs( dest_path ) unless File.directory? dest_path
|
86
|
+
dest_full
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# move into a filter??
|
92
|
+
def post_processing_slides( content )
|
93
|
+
|
94
|
+
# 1) add slide break
|
95
|
+
|
96
|
+
if (@markup_type == :markdown && Markdown.lib == 'pandoc-ruby') || @markup_type == :rest
|
97
|
+
content = add_slide_directive_before_div_h1( content )
|
98
|
+
else
|
99
|
+
content = add_slide_directive_before_h1( content )
|
100
|
+
end
|
101
|
+
|
102
|
+
dump_content_to_file_debug_html( content )
|
103
|
+
|
104
|
+
# 2) use generic slide break processing instruction to
|
105
|
+
# split content into slides
|
106
|
+
|
107
|
+
slide_counter = 0
|
108
|
+
|
109
|
+
slides = []
|
110
|
+
slide_source = ""
|
111
|
+
|
112
|
+
content.each_line do |line|
|
113
|
+
if line.include?( '<!-- _S9SLIDE_' ) then
|
114
|
+
if slide_counter > 0 then # found start of new slide (and, thus, end of last slide)
|
115
|
+
slides << slide_source # add slide to slide stack
|
116
|
+
slide_source = "" # reset slide source buffer
|
117
|
+
end
|
118
|
+
slide_counter += 1
|
119
|
+
end
|
120
|
+
slide_source << line
|
121
|
+
end
|
122
|
+
|
123
|
+
if slide_counter > 0 then
|
124
|
+
slides << slide_source # add slide to slide stack
|
125
|
+
slide_source = "" # reset slide source buffer
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
## split slide source into header (optional) and content/body
|
130
|
+
## plus check for (css style) classes and data attributes
|
131
|
+
|
132
|
+
slides2 = []
|
133
|
+
slides.each do |slide_source|
|
134
|
+
slide = Slide.new
|
135
|
+
|
136
|
+
## check for css style classes
|
137
|
+
from = 0
|
138
|
+
while (pos = slide_source.index( /<!-- _S9(SLIDE|STYLE)_(.*?)-->/m, from ))
|
139
|
+
logger.debug " adding css classes from pi #{$1.downcase}: #{$2.strip}"
|
140
|
+
|
141
|
+
from = Regexp.last_match.end(0) # continue search later from here
|
142
|
+
|
143
|
+
values = $2.strip.dup
|
144
|
+
|
145
|
+
# remove data values (eg. x=-20 scale=4) and store in data hash
|
146
|
+
values.gsub!( /([-\w]+)[ \t]*=[ \t]*([-\w\.]+)/ ) do |_|
|
147
|
+
logger.debug " adding data pair: key=>#{$1.downcase}< value=>#{$2}<"
|
148
|
+
slide.data[ $1.downcase.dup ] = $2.dup
|
149
|
+
" " # replace w/ space
|
150
|
+
end
|
151
|
+
|
152
|
+
values.strip! # remove spaces # todo: use squish or similar and check for empty string
|
153
|
+
|
154
|
+
if slide.classes.nil?
|
155
|
+
slide.classes = values
|
156
|
+
else
|
157
|
+
slide.classes << " #{values}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# try to cut off header using non-greedy .+? pattern; tip test regex online at rubular.com
|
162
|
+
# note/fix: needs to get improved to also handle case for h1 wrapped into div
|
163
|
+
# (e.g. extract h1 - do not assume it starts slide source)
|
164
|
+
if slide_source =~ /^\s*(<h1.*?>.*?<\/h\d>)\s*(.*)/m
|
165
|
+
slide.header = $1
|
166
|
+
slide.content = ($2 ? $2 : "")
|
167
|
+
logger.debug " adding slide with header:\n#{slide.header}"
|
168
|
+
else
|
169
|
+
slide.content = slide_source
|
170
|
+
logger.debug " adding slide with *no* header:\n#{slide.content}"
|
171
|
+
end
|
172
|
+
slides2 << slide
|
173
|
+
end
|
174
|
+
|
175
|
+
# for convenience create a string w/ all in-one-html
|
176
|
+
# no need to wrap slides in divs etc.
|
177
|
+
|
178
|
+
content2 = ""
|
179
|
+
slides2.each do |slide|
|
180
|
+
content2 << slide.to_classic_html
|
181
|
+
end
|
182
|
+
|
183
|
+
# make content2 and slide2 available to erb template
|
184
|
+
# -- todo: cleanup variable names and use attr_readers for content and slide
|
185
|
+
|
186
|
+
@slides = slides2 # strutured content
|
187
|
+
@content = content2 # content all-in-one
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
def create_slideshow( fn )
|
192
|
+
|
193
|
+
manifest_path_or_name = opts.manifest
|
194
|
+
|
195
|
+
# add .txt file extension if missing (for convenience)
|
196
|
+
manifest_path_or_name << ".txt" if File.extname( manifest_path_or_name ).empty?
|
197
|
+
|
198
|
+
|
199
|
+
logger.debug "manifest=#{manifest_path_or_name}"
|
200
|
+
|
201
|
+
# check if file exists (if yes use custom template package!) - allows you to override builtin package with same name
|
202
|
+
if File.exists?( manifest_path_or_name )
|
203
|
+
manifest = load_manifest( manifest_path_or_name )
|
204
|
+
else
|
205
|
+
# check for builtin manifests
|
206
|
+
manifests = installed_template_manifests
|
207
|
+
matches = manifests.select { |m| m[0] == manifest_path_or_name }
|
208
|
+
|
209
|
+
if matches.empty?
|
210
|
+
puts "*** error: unknown template manifest '#{manifest_path_or_name}'"
|
211
|
+
# todo: list installed manifests
|
212
|
+
exit 2
|
213
|
+
end
|
214
|
+
|
215
|
+
manifest = load_manifest( matches[0][1] )
|
216
|
+
end
|
217
|
+
|
218
|
+
# expand output path in current dir and make sure output path exists
|
219
|
+
outpath = File.expand_path( opts.output_path )
|
220
|
+
logger.debug "outpath=#{outpath}"
|
221
|
+
FileUtils.makedirs( outpath ) unless File.directory? outpath
|
222
|
+
|
223
|
+
dirname = File.dirname( fn )
|
224
|
+
basename = File.basename( fn, '.*' )
|
225
|
+
extname = File.extname( fn )
|
226
|
+
logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}"
|
227
|
+
|
228
|
+
# change working dir to sourcefile dir
|
229
|
+
# todo: add a -c option to commandline? to let you set cwd?
|
230
|
+
|
231
|
+
newcwd = File.expand_path( dirname )
|
232
|
+
oldcwd = File.expand_path( Dir.pwd )
|
233
|
+
|
234
|
+
unless newcwd == oldcwd then
|
235
|
+
logger.debug "oldcwd=#{oldcwd}"
|
236
|
+
logger.debug "newcwd=#{newcwd}"
|
237
|
+
Dir.chdir newcwd
|
238
|
+
end
|
239
|
+
|
240
|
+
puts "Preparing slideshow '#{basename}'..."
|
241
|
+
|
242
|
+
if extname.empty? then
|
243
|
+
extname = ".textile" # default to .textile
|
244
|
+
|
245
|
+
config.known_extnames.each do |e|
|
246
|
+
logger.debug "File.exists? #{dirname}/#{basename}#{e}"
|
247
|
+
if File.exists?( "#{dirname}/#{basename}#{e}" ) then
|
248
|
+
extname = e
|
249
|
+
logger.debug "extname=#{extname}"
|
250
|
+
break
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
if config.known_markdown_extnames.include?( extname )
|
256
|
+
@markup_type = :markdown
|
257
|
+
elsif config.known_rest_extnames.include?( extname )
|
258
|
+
@markup_type = :rest
|
259
|
+
else
|
260
|
+
@markup_type = :textile
|
261
|
+
end
|
262
|
+
|
263
|
+
# shared variables for templates (binding)
|
264
|
+
@content_for = {} # reset content_for hash
|
265
|
+
|
266
|
+
@name = basename
|
267
|
+
@extname = extname
|
268
|
+
|
269
|
+
@session = {} # reset session hash for plugins/helpers
|
270
|
+
|
271
|
+
inname = "#{dirname}/#{basename}#{extname}"
|
272
|
+
|
273
|
+
logger.debug "inname=#{inname}"
|
274
|
+
|
275
|
+
content = File.read( inname )
|
276
|
+
|
277
|
+
# run text filters
|
278
|
+
|
279
|
+
config.text_filters.each do |filter|
|
280
|
+
mn = filter.tr( '-', '_' ).to_sym # construct method name (mn)
|
281
|
+
content = send( mn, content ) # call filter e.g. include_helper_hack( content )
|
282
|
+
end
|
283
|
+
|
284
|
+
# convert light-weight markup to hypertext
|
285
|
+
|
286
|
+
content = text_to_html( content )
|
287
|
+
|
288
|
+
# post-processing
|
289
|
+
|
290
|
+
# make content2 and slide2 available to erb template
|
291
|
+
# -- todo: cleanup variable names and use attr_readers for content and slide
|
292
|
+
|
293
|
+
if @markup_type == :markdown && config.markdown_post_processing?( Markdown.lib ) == false
|
294
|
+
puts " Skipping post-processing (passing content through as is)..."
|
295
|
+
@content = content # content all-in-one - make it available in erb templates
|
296
|
+
else
|
297
|
+
# sets @content (all-in-one string) and @slides (structured content; split into slides)
|
298
|
+
post_processing_slides( content )
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
manifest.each do |entry|
|
303
|
+
outname = entry[0]
|
304
|
+
if outname.include? '__file__' # process
|
305
|
+
outname = outname.gsub( '__file__', basename )
|
306
|
+
puts "Preparing #{outname}..."
|
307
|
+
|
308
|
+
out = File.new( with_output_path( outname, outpath ), "w+" )
|
309
|
+
|
310
|
+
out << render_template( load_template( entry[1] ), binding )
|
311
|
+
|
312
|
+
if entry.size > 2 # more than one source file? assume header and footer with content added inbetween
|
313
|
+
out << content2
|
314
|
+
out << render_template( load_template( entry[2] ), binding )
|
315
|
+
end
|
316
|
+
|
317
|
+
out.flush
|
318
|
+
out.close
|
319
|
+
|
320
|
+
else # just copy verbatim if target/dest has no __file__ in name
|
321
|
+
dest = entry[0]
|
322
|
+
source = entry[1]
|
323
|
+
|
324
|
+
puts "Copying to #{dest} from #{source}..."
|
325
|
+
FileUtils.copy( source, with_output_path( dest, outpath ) )
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
puts "Done."
|
330
|
+
end
|
331
|
+
|
332
|
+
end # class Gen
|
333
|
+
|
334
|
+
end # class Slideshow
|