slideshow 1.1.0.beta8 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ Hoe.spec 'slideshow' do
14
14
 
15
15
  self.extra_deps = [
16
16
  ['RedCloth','>= 4.2.9'],
17
- ['markdown','>= 0.3.0'],
17
+ ['markdown','>= 0.4.0'],
18
18
  ['textutils','>= 0.2.0'],
19
19
  ['fetcher','>= 0.1.0'],
20
20
  ['props','>= 0.2.0']
@@ -96,7 +96,11 @@ class Gen
96
96
  if (@markup_type == :markdown && Markdown.lib == 'pandoc-ruby') || @markup_type == :rest
97
97
  content = add_slide_directive_before_div_h1( content )
98
98
  else
99
- content = add_slide_directive_before_h1( content )
99
+ if config.header_level == 2
100
+ content = add_slide_directive_before_h2( content )
101
+ else # assume level 1
102
+ content = add_slide_directive_before_h1( content )
103
+ end
100
104
  end
101
105
 
102
106
  dump_content_to_file_debug_html( content )
@@ -126,65 +130,24 @@ class Gen
126
130
  end
127
131
 
128
132
 
129
- ## split slide source into header (optional) and content/body
130
- ## plus check for (css style) classes and data attributes
131
-
132
133
  slides2 = []
133
134
  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
135
+ slides2 << Slide.new( slide_source, config )
173
136
  end
174
137
 
175
138
  # for convenience create a string w/ all in-one-html
176
139
  # no need to wrap slides in divs etc.
177
140
 
178
141
  content2 = ""
179
- slides2.each do |slide|
142
+ slides2.each do |slide|
180
143
  content2 << slide.to_classic_html
181
144
  end
182
145
 
183
146
  # make content2 and slide2 available to erb template
184
147
  # -- todo: cleanup variable names and use attr_readers for content and slide
185
148
 
186
- @slides = slides2 # strutured content
187
- @content = content2 # content all-in-one
149
+ @slides = slides2 # strutured content
150
+ @content = content2 # content all-in-one
188
151
  end
189
152
 
190
153
 
@@ -207,7 +170,7 @@ class Gen
207
170
  matches = manifests.select { |m| m[0] == manifest_path_or_name }
208
171
 
209
172
  if matches.empty?
210
- puts "*** error: unknown template manifest '#{manifest_path_or_name}'"
173
+ puts "*** error: unknown template manifest '#{manifest_path_or_name}'"
211
174
  # todo: list installed manifests
212
175
  exit 2
213
176
  end
@@ -215,6 +178,7 @@ class Gen
215
178
  manifest = load_manifest( matches[0][1] )
216
179
  end
217
180
 
181
+
218
182
  # expand output path in current dir and make sure output path exists
219
183
  outpath = File.expand_path( opts.output_path )
220
184
  logger.debug "outpath=#{outpath}"
@@ -235,29 +199,16 @@ class Gen
235
199
  logger.debug "oldcwd=#{oldcwd}"
236
200
  logger.debug "newcwd=#{newcwd}"
237
201
  Dir.chdir newcwd
238
- end
202
+ end
239
203
 
240
204
  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
205
+
206
+ if config.known_textile_extnames.include?( extname )
207
+ @markup_type = :textile
257
208
  elsif config.known_rest_extnames.include?( extname )
258
209
  @markup_type = :rest
259
- else
260
- @markup_type = :textile
210
+ else # default/fallback use markdown
211
+ @markup_type = :markdown
261
212
  end
262
213
 
263
214
  # shared variables for templates (binding)
@@ -268,7 +219,7 @@ class Gen
268
219
 
269
220
  @session = {} # reset session hash for plugins/helpers
270
221
 
271
- inname = "#{dirname}/#{basename}#{extname}"
222
+ inname = "#{basename}#{extname}"
272
223
 
273
224
  logger.debug "inname=#{inname}"
274
225
 
@@ -299,6 +250,10 @@ class Gen
299
250
  end
300
251
 
301
252
 
253
+ #### fix/todo:
254
+ ##
255
+ ## check for .erb file extension for trigger for erb processing
256
+
302
257
  manifest.each do |entry|
303
258
  outname = entry[0]
304
259
  if outname.include? '__file__' # process
@@ -320,11 +275,22 @@ class Gen
320
275
  else # just copy verbatim if target/dest has no __file__ in name
321
276
  dest = entry[0]
322
277
  source = entry[1]
323
-
324
- puts "Copying to #{dest} from #{source}..."
278
+
279
+ #### fix/todo:
280
+ ##
281
+ ## check for .erb file extension for trigger for erb processing
282
+
283
+ puts "Copying to #{dest} from #{source}..."
325
284
  FileUtils.copy( source, with_output_path( dest, outpath ) )
326
285
  end
327
286
  end
287
+
288
+
289
+ ## pop/restore working folder/dir
290
+ unless newcwd == oldcwd
291
+ logger.debug "oldcwd=>#{oldcwd}<, newcwd=>#{newcwd}<"
292
+ Dir.chdir( oldcwd )
293
+ end
328
294
 
329
295
  puts "Done."
330
296
  end
@@ -9,6 +9,9 @@ class Config
9
9
 
10
10
  attr_reader :logger, :opts
11
11
 
12
+ def header_level
13
+ @opts.header_level
14
+ end
12
15
 
13
16
  # todo/fix: fix references after this move to here, that is, Config class
14
17
  # - used in syntax/uv_helper (use config.cache_dir to access?)
@@ -28,6 +28,22 @@ def add_slide_directive_before_h1( content )
28
28
  content
29
29
  end
30
30
 
31
+ def add_slide_directive_before_h2( content )
32
+
33
+ slide_count = 0
34
+
35
+ content.gsub!( /<h2/ ) do |match|
36
+ slide_count += 1
37
+ "\n<!-- _S9SLIDE_ -->\n#{Regexp.last_match(0)}"
38
+ end
39
+
40
+ puts " Adding #{slide_count} slide breaks (using h2 rule)..."
41
+
42
+ content
43
+ end
44
+
45
+
46
+
31
47
  # add slide directive before div h1 (for pandoc-generated html)
32
48
  #
33
49
  # e.g. changes:
@@ -3,6 +3,15 @@ module Slideshow
3
3
 
4
4
  class Opts
5
5
 
6
+ def header_level=(value)
7
+ @header_level = value.to_i
8
+ end
9
+
10
+ def header_level
11
+ ## todo: check 0 is not nil?
12
+ @header_level || 1
13
+ end
14
+
6
15
  def generate=(value)
7
16
  @generate = value
8
17
  end
@@ -35,44 +35,103 @@ def load_plugins
35
35
  end
36
36
 
37
37
 
38
+ def find_file_with_known_extension( fn )
39
+ dirname = File.dirname( fn )
40
+ basename = File.basename( fn, '.*' )
41
+ extname = File.extname( fn )
42
+ logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}"
43
+
44
+ config.known_extnames.each do |e|
45
+ newname = File.join( dirname, "#{basename}#{e}" )
46
+ logger.debug "File.exists? #{newname}"
47
+ return newname if File.exists?( newname )
48
+ end # each extension (e)
49
+
50
+ nil # not found; return nil
51
+ end
52
+
53
+
54
+ def find_files( file_or_dir_or_pattern )
55
+
56
+ filtered_files = []
57
+
58
+ ## for now process/assume only single file
59
+
60
+ ## (check for missing extension)
61
+ if File.exists?( file_or_dir_or_pattern )
62
+ file = file_or_dir_or_pattern
63
+ logger.debug " adding file '#{file}'..."
64
+ filtered_files << file
65
+ else # check for existing file w/ missing extension
66
+ file = find_file_with_known_extension( file_or_dir_or_pattern )
67
+ if file.nil?
68
+ puts " skipping missing file '#{file_or_dir_or_pattern}{#{config.known_extnames.join(',')}}'..."
69
+ else
70
+ logger.debug " adding file '#{file}'..."
71
+ filtered_files << file
72
+ end
73
+ end
74
+
75
+ filtered_files
76
+
77
+ end # method find_files
78
+
79
+
80
+
38
81
  def run( args )
39
82
 
40
83
  opt=OptionParser.new do |cmd|
41
84
 
42
85
  cmd.banner = "Usage: slideshow [options] name"
43
-
86
+
44
87
  cmd.on( '-o', '--output PATH', 'Output Path' ) { |path| opts.output_path = path }
45
-
46
- cmd.on( '-g', '--generate', 'Generate Slide Show Templates (Using Built-In S6 Pack)' ) { opts.generate = true }
47
88
 
48
- cmd.on( "-t", "--template MANIFEST", "Template Manifest" ) do |t|
89
+ cmd.on( "-t", "--template MANIFEST", "Template Manifest (default is s6.txt)" ) do |t|
49
90
  # todo: do some checks on passed in template argument
50
91
  opts.manifest = t
51
92
  end
52
93
 
94
+
95
+ # cmd.on( '--header NUM', 'Header Level (default is 1)' ) do |n|
96
+ # opts.header_level = n.to_i
97
+ # end
98
+
99
+ cmd.on( '--h1', 'Set Header Level to 1 (default)' ) { opts.header_level = 1 }
100
+ cmd.on( '--h2', 'Set Header Level to 2' ) { opts.header_level = 2 }
101
+
102
+
53
103
  # ?? opts.on( "-s", "--style STYLE", "Select Stylesheet" ) { |s| $options[:style]=s }
54
- # ?? opts.on( "--version", "Show version" ) {}
55
104
 
56
105
  # ?? cmd.on( '-i', '--include PATH', 'Load Path' ) { |s| opts.put( 'include', s ) }
57
106
 
58
- cmd.on( '-f', '--fetch URI', 'Fetch Templates' ) do |uri|
59
- opts.fetch_uri = uri
60
- end
61
-
62
107
  cmd.on( '-c', '--config PATH', 'Configuration Path (default is ~/.slideshow)' ) do |path|
63
108
  opts.config_path = path
64
109
  end
110
+
111
+ cmd.on( '-f', '--fetch URI', 'Fetch Templates' ) do |uri|
112
+ opts.fetch_uri = uri
113
+ end
114
+
115
+ cmd.on( '-g', '--generate', 'Generate Slide Show Templates (Using Built-In S6 Pack)' ) { opts.generate = true }
65
116
 
66
117
  cmd.on( '-l', '--list', 'List Installed Templates' ) { opts.list = true }
67
118
 
68
119
  # todo: find different letter for debug trace switch (use v for version?)
69
120
  cmd.on( "-v", "--verbose", "Show debug trace" ) do
70
121
  logger.datetime_format = "%H:%H:%S"
71
- logger.level = Logger::DEBUG
122
+ logger.level = Logger::DEBUG
72
123
  end
73
-
74
- usage =<<EOS
124
+
125
+ ## todo: add --version
75
126
 
127
+ cmd.on( '--version', "Show version" ) do
128
+ puts Slideshow.generator
129
+ exit
130
+ end
131
+
132
+ cmd.on_tail( "-h", "--help", "Show this message" ) do
133
+ puts <<EOS
134
+
76
135
  Slide Show (S9) is a free web alternative to PowerPoint or KeyNote in Ruby
77
136
 
78
137
  #{cmd.help}
@@ -95,10 +154,6 @@ Further information:
95
154
  http://slideshow.rubyforge.org
96
155
 
97
156
  EOS
98
-
99
-
100
- cmd.on_tail( "-h", "--help", "Show this message" ) do
101
- puts usage
102
157
  exit
103
158
  end
104
159
  end
@@ -118,8 +173,12 @@ EOS
118
173
  else
119
174
  load_plugins # check for optional plugins/extension in ./lib folder
120
175
 
121
- args.each do |fn|
122
- Gen.new( logger, opts, config, headers ).create_slideshow( fn )
176
+ args.each do |arg|
177
+ files = find_files( arg )
178
+ files.each do |file|
179
+ ### fix/todo: reset/clean headers
180
+ Gen.new( logger, opts, config, headers ).create_slideshow( file )
181
+ end
123
182
  end
124
183
  end
125
184
  end
@@ -1,19 +1,84 @@
1
1
  module Slideshow
2
2
 
3
3
  class Slide
4
-
5
- attr_accessor :header
4
+
5
+ attr_accessor :logger
6
+
7
+ # NB: unparsed html source (use content_without_header
8
+ # for content without option header)
9
+
6
10
  attr_accessor :content
11
+ attr_accessor :content_without_header
12
+ attr_accessor :header
7
13
  attr_accessor :classes
8
- attr_accessor :data
9
14
 
10
- def initialize
11
- @header = nil
12
- @content = nil
13
- @classes = nil
15
+ def initialize( content, options )
16
+ @logger = options.logger
17
+ @header_level = options.header_level
18
+
19
+ @content = content
20
+
21
+ @header = nil
22
+ @content_without_header = nil
23
+ @classes = nil # NB: style classes as all in one string
14
24
  @data = {}
25
+
26
+ parse()
15
27
  end
16
28
 
29
+ def parse
30
+ ## pass 1) check for (css style) classes and data attributes
31
+ ## check for css style classes
32
+ from = 0
33
+ while( pos = @content.index( /<!-- _S9(SLIDE|STYLE)_(.*?)-->/m, from ))
34
+ logger.debug " adding css classes from pi >#{$1.downcase}<: >#{$2.strip}<"
35
+
36
+ from = Regexp.last_match.end(0) # continue search later from here
37
+
38
+ values = $2.strip.dup
39
+
40
+ # remove data values (eg. x=-20 scale=4) and store in data hash
41
+ values.gsub!( /([-\w]+)[ \t]*=[ \t]*([-\w\.]+)/ ) do |_|
42
+ logger.debug " adding data pair: key=>#{$1.downcase}< value=>#{$2}<"
43
+ @data[ $1.downcase.dup ] = $2.dup
44
+ " " # replace w/ space
45
+ end
46
+
47
+ values.strip! # remove spaces # todo: use squish or similar and check for empty string
48
+
49
+ if @classes.nil?
50
+ @classes = values
51
+ else
52
+ @classes << " #{values}"
53
+ end
54
+ end
55
+
56
+ ## pass 2) split slide source into header (optional) and content/body
57
+
58
+ ## todo: add option split on h1/h2 etc.
59
+
60
+ # try to extract first header using non-greedy .+? pattern;
61
+ # tip test regex online at rubular.com
62
+ # note/fix: needs to get improved to also handle case for h1 wrapped into div
63
+
64
+ if @header_level == 2
65
+ pattern = /^(.*?)(<h2.*?>.*?<\/h2>)(.*)/m
66
+ else # assume header level 1
67
+ pattern = /^(.*?)(<h1.*?>.*?<\/h1>)(.*)/m
68
+ end
69
+
70
+ if @content =~ pattern
71
+ @header = $2
72
+ @content_without_header = ($1 ? $1 : '') + ($3 ? $3 : '')
73
+ logger.debug " adding slide with header (h1):\n#{@header}"
74
+ else
75
+ @header = nil # todo: set to '' empty string? why not?
76
+ @content_without_header = @content
77
+ logger.debug " adding slide with *no* header:\n#{@content}"
78
+ end
79
+ end # method parse
80
+
81
+
17
82
  def data_attributes
18
83
  buf = ""
19
84
  @data.each do | key,value |
@@ -21,40 +86,33 @@ module Slideshow
21
86
  end
22
87
  buf
23
88
  end
89
+
90
+ ################################
91
+ #### convenience helpers
24
92
 
25
93
  def to_classic_html
26
-
27
94
  buf = ""
28
95
  buf << "<div class='slide "
29
96
  buf << classes if classes
30
- buf << "'>\n"
31
-
32
- buf << header if header
33
- buf << content if content
34
-
97
+ buf << "'>\n"
98
+ buf << content
35
99
  buf << "</div>\n"
36
- buf
100
+ buf
37
101
  end
38
102
 
39
103
  def to_google_html5
40
-
41
104
  buf = ""
42
105
  buf << "<div class='slide'>\n"
43
-
44
- if header
45
- buf << "<header>#{header}</header>\n"
46
- end
47
-
48
- buf << "<section class='"
49
- buf << classes if classes
106
+ buf << "<header>#{header}</header>\n" if header
107
+ buf << "<section "
108
+ buf << "class='#{classes}'" if classes
50
109
  buf << "'>\n"
51
-
52
- buf << content if content
110
+ buf << content_without_header if content_without_header
53
111
  buf << "</section>\n"
54
112
  buf << "</div>\n"
55
113
  buf
56
114
  end
57
115
 
58
- end # class slide
116
+ end # class Slide
59
117
 
60
118
  end # module Slideshow
@@ -1,3 +1,3 @@
1
1
  module Slideshow
2
- VERSION = '1.1.0.beta8'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,15 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slideshow
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62724110
5
- prerelease: 6
4
+ hash: 19
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
9
  - 0
10
- - beta
11
- - 8
12
- version: 1.1.0.beta8
10
+ version: 1.1.0
13
11
  platform: ruby
14
12
  authors:
15
13
  - Gerald Bauer
@@ -17,7 +15,7 @@ autorequire:
17
15
  bindir: bin
18
16
  cert_chain: []
19
17
 
20
- date: 2012-06-16 00:00:00 Z
18
+ date: 2012-06-17 00:00:00 Z
21
19
  dependencies:
22
20
  - !ruby/object:Gem::Dependency
23
21
  name: RedCloth
@@ -43,12 +41,12 @@ dependencies:
43
41
  requirements:
44
42
  - - ">="
45
43
  - !ruby/object:Gem::Version
46
- hash: 19
44
+ hash: 15
47
45
  segments:
48
46
  - 0
49
- - 3
47
+ - 4
50
48
  - 0
51
- version: 0.3.0
49
+ version: 0.4.0
52
50
  type: :runtime
53
51
  version_requirements: *id002
54
52
  - !ruby/object:Gem::Dependency
@@ -222,14 +220,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
220
  required_rubygems_version: !ruby/object:Gem::Requirement
223
221
  none: false
224
222
  requirements:
225
- - - ">"
223
+ - - ">="
226
224
  - !ruby/object:Gem::Version
227
- hash: 25
225
+ hash: 3
228
226
  segments:
229
- - 1
230
- - 3
231
- - 1
232
- version: 1.3.1
227
+ - 0
228
+ version: "0"
233
229
  requirements: []
234
230
 
235
231
  rubyforge_project: slideshow