slideshow 0.7.6 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/helpers/coderay_helper.rb +78 -0
- data/lib/helpers/text_helper.rb +133 -0
- data/lib/helpers/uv_helper.rb +85 -0
- data/lib/slideshow.rb +125 -138
- data/lib/templates/s6/header.html.erb +4 -0
- data/lib/templates/s6/style.css.erb +2 -0
- metadata +4 -2
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'coderay'
|
2
|
+
|
3
|
+
module CodeRayHelper
|
4
|
+
|
5
|
+
# coderay option defaults
|
6
|
+
CR_LANG = 'ruby'
|
7
|
+
CR_LINE_NUMBERS = 'table' # table | list | inline
|
8
|
+
|
9
|
+
def coderay_worker( code, opts )
|
10
|
+
|
11
|
+
lang = opts.fetch( :lang, CR_LANG )
|
12
|
+
line_numbers = opts.fetch( :line_numbers, headers.get('code-line-numbers', CR_LINE_NUMBERS ) )
|
13
|
+
line_number_start = opts.fetch( :start, nil )
|
14
|
+
|
15
|
+
cr_opts = {}
|
16
|
+
cr_opts[ :line_numbers ] = line_numbers.to_sym
|
17
|
+
cr_opts[ :line_number_start ] = line_number_start.to_i if line_number_start
|
18
|
+
|
19
|
+
# todo: add options for bold_every, tab_width (any others?)
|
20
|
+
|
21
|
+
code_highlighted = CodeRay.scan( code, lang.to_sym ).html(cr_opts)
|
22
|
+
|
23
|
+
# first time? get built-in coderay stylesheet
|
24
|
+
cr_first_time = session.fetch( :cr_first_time, true )
|
25
|
+
if cr_first_time
|
26
|
+
session[ :cr_first_time ] = false
|
27
|
+
|
28
|
+
theme_content = CodeRay::Encoders[:html]::CSS.new.stylesheet
|
29
|
+
|
30
|
+
theme_out = %{/* styles for built-in coderay syntax highlighting theme */\n\n}
|
31
|
+
theme_out << theme_content
|
32
|
+
theme_out << %{\n\n}
|
33
|
+
|
34
|
+
content_for( :css, theme_out )
|
35
|
+
end
|
36
|
+
|
37
|
+
css_class = 'code'
|
38
|
+
css_class_opt = opts.fetch( :class, nil ) # large, small, tiny, etc.
|
39
|
+
css_class << " #{css_class_opt}" if css_class_opt # e.g. use/allow multiple classes -> code small, code large, etc.
|
40
|
+
|
41
|
+
name = opts.fetch( :name, nil )
|
42
|
+
txmt_value = opts.fetch( :txmt, headers.code_txmt )
|
43
|
+
txmt = (txmt_value =~ /true|yes|on/i) ? true : false
|
44
|
+
|
45
|
+
out = %{<div class='CodeRay'>}
|
46
|
+
out << %{<pre '#{css_class}'>\n}
|
47
|
+
out << code_highlighted
|
48
|
+
out << %{</pre>}
|
49
|
+
out << %{</div>}
|
50
|
+
|
51
|
+
# add optional href link for textmate
|
52
|
+
if name
|
53
|
+
out << %{<div class="codeurl">}
|
54
|
+
out << %{<a href="txmt://open?url=file://#{File.expand_path(name)}">} if txmt
|
55
|
+
out << name
|
56
|
+
out << %{</a>} if txmt
|
57
|
+
out << %{</div>\n}
|
58
|
+
end
|
59
|
+
|
60
|
+
return out
|
61
|
+
end
|
62
|
+
|
63
|
+
def coderay( *args, &blk )
|
64
|
+
# check for optional hash for options
|
65
|
+
opts = args.last.kind_of?(Hash) ? args.pop : {}
|
66
|
+
|
67
|
+
code = capture_erb(&blk)
|
68
|
+
return if code.empty?
|
69
|
+
|
70
|
+
code_highlighted = coderay_worker( code, opts )
|
71
|
+
|
72
|
+
concat_erb( wrap_markup( code_highlighted ), blk.binding )
|
73
|
+
return
|
74
|
+
end
|
75
|
+
|
76
|
+
end # module CodeRayHelper
|
77
|
+
|
78
|
+
Slideshow::Gen.__send__( :include, CodeRayHelper )
|
data/lib/helpers/text_helper.rb
CHANGED
@@ -5,6 +5,139 @@ def __include__( name, opts = {} )
|
|
5
5
|
content = File.read( name )
|
6
6
|
end
|
7
7
|
|
8
|
+
def help()
|
9
|
+
|
10
|
+
text = <<EOS
|
11
|
+
*Slide Show Keyboard Controls (Help)*
|
12
|
+
|
13
|
+
| Action | Key |
|
14
|
+
| Go to next slide | Space Bar, Right Arrow, Down Arrow, Page Down |
|
15
|
+
| Go to previous slide | Left Arrow, Up Arrow, Page Up |
|
16
|
+
| Toggle between slideshow and outline view (Ø) | T |
|
17
|
+
| Show/hide slide controls (Ø « ») | C, Move mouse to bottom right corner |
|
18
|
+
EOS
|
19
|
+
|
20
|
+
wrap_markup( textile_to_html( text ) )
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Usage example:
|
25
|
+
# <%= code 'code/file.rb#section', :lang => 'ruby', :class => 'small' %>
|
26
|
+
# or
|
27
|
+
# <% code :lang => 'ruby' do %>
|
28
|
+
# code goes here
|
29
|
+
# <% end %>
|
30
|
+
#
|
31
|
+
|
32
|
+
def code( *args, &blk )
|
33
|
+
# check for optional hash for options
|
34
|
+
opts = args.last.kind_of?(Hash) ? args.pop : {}
|
35
|
+
|
36
|
+
name_plus_part = args.first # check for optional filename
|
37
|
+
|
38
|
+
if name_plus_part
|
39
|
+
name, part = name_plus_part.split( '#' ) # split off optional part/anchor
|
40
|
+
|
41
|
+
content = find_content_from( name, part )
|
42
|
+
|
43
|
+
# add name and part to opts so engine can use paras too
|
44
|
+
opts[ :name ] = name
|
45
|
+
opts[ :part ] = part if part
|
46
|
+
|
47
|
+
return format_code( content, opts )
|
48
|
+
elsif blk # inline code via block?
|
49
|
+
content = capture_erb(&blk)
|
50
|
+
return if content.empty?
|
51
|
+
|
52
|
+
concat_erb( format_code( content, opts ), blk.binding )
|
53
|
+
return
|
54
|
+
else
|
55
|
+
msg = '*** warning: empty code directive; inline code or file para expected'
|
56
|
+
puts msg
|
57
|
+
return wrap_markup( "<!-- #{msg} -->" )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def find_content_from( name, part )
|
63
|
+
begin
|
64
|
+
content = File.read( name )
|
65
|
+
|
66
|
+
# note: for now content with no parts selected gets filtered too and (part) marker lines get removed from source
|
67
|
+
lines = find_part_lines_in( content, part )
|
68
|
+
|
69
|
+
if part
|
70
|
+
puts " Including code part '#{part}' in '#{name}' [#{lines.size} lines]..."
|
71
|
+
## todo: issue warning if no lines found?
|
72
|
+
else
|
73
|
+
puts " Including code in '#{name}' [#{lines.size} lines]..."
|
74
|
+
end
|
75
|
+
|
76
|
+
return lines.join
|
77
|
+
rescue Exception => e
|
78
|
+
puts "*** error: reading '#{name}': #{e}"
|
79
|
+
exit 2
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def find_part_lines_in( content, part )
|
84
|
+
result = []
|
85
|
+
state = part.nil? ? :normal : :skipping
|
86
|
+
content.each_line do |line|
|
87
|
+
if line =~ /(START|END):(\w+)/
|
88
|
+
if $2 == part
|
89
|
+
if $1 == "START"
|
90
|
+
state = :normal
|
91
|
+
else
|
92
|
+
state = :skipping
|
93
|
+
end
|
94
|
+
end
|
95
|
+
next
|
96
|
+
end
|
97
|
+
result << line unless state == :skipping
|
98
|
+
end
|
99
|
+
result
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def format_code( code, opts )
|
104
|
+
|
105
|
+
engine = opts.fetch( :engine, headers.code_engine ).to_s.downcase
|
106
|
+
|
107
|
+
if engine == 'uv' || engine == 'ultraviolet'
|
108
|
+
if respond_to?( :uv_worker )
|
109
|
+
code_highlighted = uv_worker( code, opts )
|
110
|
+
else
|
111
|
+
puts "** error: ultraviolet gem required for syntax highlighting; install with gem install ultraviolet (or use a different engine)"
|
112
|
+
exit 2
|
113
|
+
end
|
114
|
+
elsif engine == 'cr' || engine == 'coderay'
|
115
|
+
if respond_to?( :coderay_worker )
|
116
|
+
code_highlighted = coderay_worker( code, opts )
|
117
|
+
else
|
118
|
+
puts "*** error: coderay gem required for syntax highlighting; install with gem install coderay (or use a different engine)"
|
119
|
+
exit 2
|
120
|
+
end
|
121
|
+
else
|
122
|
+
method_name = "#{engine}_worker".to_sym
|
123
|
+
if respond_to?( method_name )
|
124
|
+
# try to call custom syntax highlighting engine
|
125
|
+
code_highlighted = send( method_name, code, opts )
|
126
|
+
else
|
127
|
+
msg = "*** error: unkown syntax highlighting engine '#{engine}'; available built-in options include: uv, ultraviolet, cr, coderay"
|
128
|
+
puts msg
|
129
|
+
code_highlighted = "<!-- #{msg} -->"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
out = %{<!-- begin code#{opts.inspect} -->\n}
|
134
|
+
out << code_highlighted
|
135
|
+
out << %{<!-- end code -->\n}
|
136
|
+
|
137
|
+
wrap_markup( out ) # saveguard with notextile wrapper etc./no further processing needed
|
138
|
+
end
|
139
|
+
|
140
|
+
|
8
141
|
end # module TextHelper
|
9
142
|
|
10
143
|
Slideshow::Gen.__send__( :include, TextHelper )
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'uv'
|
2
|
+
|
3
|
+
module UvHelper
|
4
|
+
|
5
|
+
# uv option defaults
|
6
|
+
UV_LANG = 'ruby'
|
7
|
+
UV_LINE_NUMBERS = 'true'
|
8
|
+
UV_THEME = 'amy'
|
9
|
+
|
10
|
+
def uv_worker( code, opts )
|
11
|
+
|
12
|
+
lang = opts.fetch( :lang, UV_LANG )
|
13
|
+
line_numbers_value = opts.fetch( :line_numbers, headers.get( 'code-line-numbers', UV_LINE_NUMBERS ))
|
14
|
+
line_numbers = (line_numbers_value =~ /true|yes|on/i) ? true : false
|
15
|
+
|
16
|
+
# change all-hallows-eve (CSS-style/convention) to all_hallows_eve (uv internal-style)
|
17
|
+
theme = opts.fetch( :theme, headers.get( 'code-theme', UV_THEME )).tr( '-', '_' )
|
18
|
+
|
19
|
+
code_highlighted = Uv.parse( code, "xhtml", lang, line_numbers, theme )
|
20
|
+
|
21
|
+
# first time? copy all uv built-in themes (css styles) to temporary cache (~/.slideshow/*)
|
22
|
+
uv_first_time = session.fetch( :uv_first_time, true )
|
23
|
+
if uv_first_time
|
24
|
+
session[ :uv_first_time ] = false
|
25
|
+
logger.debug "cache_dir=#{cache_dir}"
|
26
|
+
|
27
|
+
FileUtils.mkdir(cache_dir) unless File.exists?(cache_dir) if cache_dir
|
28
|
+
Uv.copy_files "xhtml", cache_dir
|
29
|
+
end
|
30
|
+
|
31
|
+
# first time this theme gets used add it to content_for hash for templates to include
|
32
|
+
uv_themes = session[ :uv_themes ] ||= {}
|
33
|
+
if uv_themes[ theme ].nil?
|
34
|
+
uv_themes[ theme ] = true
|
35
|
+
|
36
|
+
theme_content = File.read( "#{cache_dir}/css/#{theme}.css" )
|
37
|
+
|
38
|
+
theme_out = %{/* styles for ultraviolet code syntax highlighting theme '#{theme}' */\n\n}
|
39
|
+
theme_out << theme_content
|
40
|
+
theme_out << %{\n\n}
|
41
|
+
|
42
|
+
content_for( :css, theme_out )
|
43
|
+
end
|
44
|
+
|
45
|
+
css_class = 'code'
|
46
|
+
css_class_opt = opts.fetch( :class, nil ) # large, small, tiny, etc.
|
47
|
+
css_class << " #{css_class_opt}" if css_class_opt # e.g. use/allow multiple classes -> code small, code large, etc.
|
48
|
+
|
49
|
+
name = opts.fetch( :name, nil )
|
50
|
+
txmt_value = opts.fetch( :txmt, headers.code_txmt )
|
51
|
+
txmt = (txmt_value =~ /true|yes|on/i) ? true : false
|
52
|
+
|
53
|
+
out = %{<pre class='#{css_class}'>\n}
|
54
|
+
out << code_highlighted
|
55
|
+
out << %{</pre>\n}
|
56
|
+
|
57
|
+
# add optional href link for textmate
|
58
|
+
if name
|
59
|
+
out << %{<div class="codeurl">}
|
60
|
+
out << %{<a href="txmt://open?url=file://#{File.expand_path(name)}">} if txmt
|
61
|
+
out << name
|
62
|
+
out << %{</a>} if txmt
|
63
|
+
out << %{</div>\n}
|
64
|
+
end
|
65
|
+
|
66
|
+
return out
|
67
|
+
end
|
68
|
+
|
69
|
+
def uv( *args, &blk )
|
70
|
+
# check for optional hash for options
|
71
|
+
opts = args.last.kind_of?(Hash) ? args.pop : {}
|
72
|
+
|
73
|
+
code = capture_erb(&blk)
|
74
|
+
return if code.empty?
|
75
|
+
|
76
|
+
code_highlighted = uv_worker( code, opts )
|
77
|
+
|
78
|
+
concat_erb( wrap_markup( code_highlighted ), blk.binding )
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
end # module UvHelper
|
83
|
+
|
84
|
+
Slideshow::Gen.__send__( :include, UvHelper )
|
85
|
+
|
data/lib/slideshow.rb
CHANGED
@@ -8,27 +8,10 @@ require 'fileutils'
|
|
8
8
|
require 'ftools'
|
9
9
|
require 'pp'
|
10
10
|
|
11
|
-
# todo: move code highlighting in (optional) plugin/extension
|
12
|
-
# require 'hpricot'
|
13
|
-
# require 'uv'
|
14
|
-
|
15
11
|
|
16
12
|
module Slideshow
|
17
13
|
|
18
|
-
VERSION = '0.7.
|
19
|
-
|
20
|
-
class ParamsOldDelete
|
21
|
-
|
22
|
-
def initialize( name, headers )
|
23
|
-
@name = name
|
24
|
-
@headers = headers
|
25
|
-
end
|
26
|
-
|
27
|
-
def params_binding
|
28
|
-
binding
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
14
|
+
VERSION = '0.7.7'
|
32
15
|
|
33
16
|
# todo: split (command line) options and headers?
|
34
17
|
# e.g. share (command line) options between slide shows (but not headers?)
|
@@ -50,10 +33,6 @@ class Opts
|
|
50
33
|
end
|
51
34
|
end
|
52
35
|
|
53
|
-
def code_theme=( value )
|
54
|
-
@hash[ :code_theme ] = value.tr( '-', '_' )
|
55
|
-
end
|
56
|
-
|
57
36
|
def gradient=( value )
|
58
37
|
put_gradient( value, :theme, :color1, :color2 )
|
59
38
|
end
|
@@ -100,14 +79,6 @@ class Opts
|
|
100
79
|
def fullerscreen?
|
101
80
|
get_boolean( 'fuller', false ) || get_boolean( 'fullerscreen', false )
|
102
81
|
end
|
103
|
-
|
104
|
-
def code_theme
|
105
|
-
get( 'code-theme', DEFAULTS[ :code_theme ] )
|
106
|
-
end
|
107
|
-
|
108
|
-
def code_line_numbers?
|
109
|
-
get_boolean( 'code-line-numbers', DEFAULTS[ :code_line_numbers ] )
|
110
|
-
end
|
111
82
|
|
112
83
|
def manifest
|
113
84
|
get( 'manifest', 's6.txt' )
|
@@ -117,6 +88,15 @@ class Opts
|
|
117
88
|
get( 'output', '.' )
|
118
89
|
end
|
119
90
|
|
91
|
+
def code_engine
|
92
|
+
get( 'code-engine', DEFAULTS[ :code_engine ] )
|
93
|
+
end
|
94
|
+
|
95
|
+
def code_txmt
|
96
|
+
get( 'code-txmt', DEFAULTS[ :code_txmt ])
|
97
|
+
end
|
98
|
+
|
99
|
+
|
120
100
|
DEFAULTS =
|
121
101
|
{
|
122
102
|
:title => 'Untitled Slide Show',
|
@@ -125,8 +105,9 @@ class Opts
|
|
125
105
|
:gradient_theme => 'dark',
|
126
106
|
:gradient_color1 => 'red',
|
127
107
|
:gradient_color2 => 'black',
|
128
|
-
|
129
|
-
:
|
108
|
+
|
109
|
+
:code_engine => 'uv', # ultraviolet (uv) | coderay (cr)
|
110
|
+
:code_txmt => 'false', # Text Mate Hyperlink for Source?
|
130
111
|
}
|
131
112
|
|
132
113
|
def set_defaults
|
@@ -135,6 +116,10 @@ class Opts
|
|
135
116
|
end
|
136
117
|
end
|
137
118
|
|
119
|
+
def get( key, default )
|
120
|
+
@hash.fetch( normalize_key(key), default )
|
121
|
+
end
|
122
|
+
|
138
123
|
private
|
139
124
|
|
140
125
|
def normalize_key( key )
|
@@ -150,10 +135,6 @@ private
|
|
150
135
|
end
|
151
136
|
end
|
152
137
|
|
153
|
-
def get( key, default )
|
154
|
-
@hash.fetch( normalize_key(key), default )
|
155
|
-
end
|
156
|
-
|
157
138
|
def get_boolean( key, default )
|
158
139
|
value = @hash[ normalize_key( key ) ]
|
159
140
|
if value.nil?
|
@@ -169,8 +150,9 @@ end # class Opts
|
|
169
150
|
class Gen
|
170
151
|
|
171
152
|
KNOWN_TEXTILE_EXTNAMES = [ '.textile', '.t' ]
|
172
|
-
KNOWN_MARKDOWN_EXTNAMES = [ '.markdown', '.mark', '.
|
173
|
-
|
153
|
+
KNOWN_MARKDOWN_EXTNAMES = [ '.markdown', '.m', '.mark', '.mkdn', '.md', '.txt', '.text' ]
|
154
|
+
KNOWN_EXTNAMES = KNOWN_TEXTILE_EXTNAMES + KNOWN_MARKDOWN_EXTNAMES
|
155
|
+
|
174
156
|
# note: only bluecloth is listed as a dependency in gem specs (because it's Ruby only and, thus, easy to install)
|
175
157
|
# if you want to use other markdown libs install the required/desired lib e.g.
|
176
158
|
# use gem install rdiscount for rdiscount and so on
|
@@ -205,6 +187,20 @@ class Gen
|
|
205
187
|
@opts
|
206
188
|
end
|
207
189
|
|
190
|
+
def headers
|
191
|
+
# give access to helpers to opts with a different name
|
192
|
+
@opts
|
193
|
+
end
|
194
|
+
|
195
|
+
def session
|
196
|
+
# give helpers/plugins a session-like hash
|
197
|
+
@session
|
198
|
+
end
|
199
|
+
|
200
|
+
def markup_type
|
201
|
+
@markup_type # :textile, :markdown
|
202
|
+
end
|
203
|
+
|
208
204
|
def load_markdown_libs
|
209
205
|
# check for available markdown libs/gems
|
210
206
|
# try to require each lib and remove any not installed
|
@@ -223,10 +219,29 @@ class Gen
|
|
223
219
|
logger.debug "Using Markdown library #{@markdown_libs.first[0]}."
|
224
220
|
end
|
225
221
|
|
222
|
+
# todo: move to filter (for easier reuse)
|
226
223
|
def markdown_to_html( content )
|
227
224
|
@markdown_libs.first[1].call( content )
|
228
225
|
end
|
229
226
|
|
227
|
+
# todo: move to filter (for easier reuse)
|
228
|
+
def textile_to_html( content )
|
229
|
+
# turn off hard line breaks
|
230
|
+
# turn off span caps (see http://rubybook.ca/2008/08/16/redcloth)
|
231
|
+
red = RedCloth.new( content, [:no_span_caps] )
|
232
|
+
red.hard_breaks = false
|
233
|
+
content = red.to_html
|
234
|
+
end
|
235
|
+
|
236
|
+
def wrap_markup( text )
|
237
|
+
if markup_type == :textile
|
238
|
+
# saveguard with notextile wrapper etc./no further processing needed
|
239
|
+
"<notextile>\n#{text}\n</notextile>"
|
240
|
+
else
|
241
|
+
text
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
230
245
|
def cache_dir
|
231
246
|
PLATFORM =~ /win32/ ? win32_cache_dir : File.join(File.expand_path("~"), ".slideshow")
|
232
247
|
end
|
@@ -353,26 +368,29 @@ class Gen
|
|
353
368
|
logger.debug "outpath=#{outpath}"
|
354
369
|
File.makedirs( outpath ) unless File.directory? outpath
|
355
370
|
|
356
|
-
dirname = File.dirname( fn )
|
371
|
+
dirname = File.dirname( fn )
|
357
372
|
basename = File.basename( fn, '.*' )
|
358
373
|
extname = File.extname( fn )
|
359
374
|
logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}"
|
360
375
|
|
361
|
-
#
|
362
|
-
|
363
|
-
|
364
|
-
|
376
|
+
# change working dir to sourcefile dir
|
377
|
+
# todo: add a -c option to commandline? to let you set cwd?
|
378
|
+
|
379
|
+
newcwd = File.expand_path( dirname )
|
380
|
+
oldcwd = File.expand_path( Dir.pwd )
|
381
|
+
|
382
|
+
unless newcwd == oldcwd then
|
383
|
+
logger.debug "oldcwd=#{oldcwd}"
|
384
|
+
logger.debug "newcwd=#{newcwd}"
|
385
|
+
Dir.chdir newcwd
|
386
|
+
end
|
365
387
|
|
366
388
|
puts "Preparing slideshow '#{basename}'..."
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
known_extnames = KNOWN_TEXTILE_EXTNAMES + KNOWN_MARKDOWN_EXTNAMES
|
371
389
|
|
372
390
|
if extname.empty? then
|
373
391
|
extname = ".textile" # default to .textile
|
374
392
|
|
375
|
-
|
393
|
+
KNOWN_EXTNAMES.each do |e|
|
376
394
|
logger.debug "File.exists? #{dirname}/#{basename}#{e}"
|
377
395
|
if File.exists?( "#{dirname}/#{basename}#{e}" ) then
|
378
396
|
extname = e
|
@@ -382,27 +400,28 @@ class Gen
|
|
382
400
|
end
|
383
401
|
end
|
384
402
|
|
403
|
+
if KNOWN_MARKDOWN_EXTNAMES.include?( extname )
|
404
|
+
@markup_type = :markdown
|
405
|
+
else
|
406
|
+
@markup_type = :textile
|
407
|
+
end
|
408
|
+
|
409
|
+
# shared variables for templates (binding)
|
410
|
+
@content_for = {} # reset content_for hash
|
411
|
+
@name = basename
|
412
|
+
@headers = @opts # deprecate/remove: use headers method in template
|
413
|
+
|
414
|
+
@session = {} # reset session hash for plugins/helpers
|
415
|
+
|
385
416
|
inname = "#{dirname}/#{basename}#{extname}"
|
386
417
|
|
387
418
|
logger.debug "inname=#{inname}"
|
388
419
|
|
389
|
-
|
390
|
-
|
391
|
-
#
|
392
|
-
source.gsub!(/__SKIP__.*?__END__/m, '')
|
393
|
-
source.sub!(/__END__.*/m, '')
|
394
|
-
|
395
|
-
# allow plugins/helpers; process source (including header) using erb
|
396
|
-
|
397
|
-
# note: include is a ruby keyword; rename to __include__ so we can use it
|
398
|
-
source.gsub!( /<%=[ \t]*include/, '<%= __include__' )
|
399
|
-
|
400
|
-
source = ERB.new( source ).result( binding )
|
401
|
-
|
402
|
-
|
403
|
-
# todo: read headers before command line options (lets you override options using commandline switch)
|
420
|
+
content_with_headers = File.read( inname )
|
421
|
+
|
422
|
+
# todo: read headers before command line options (lets you override options using commandline switch)?
|
404
423
|
|
405
|
-
# read source document
|
424
|
+
# read source document; split off optional header from source
|
406
425
|
# strip leading optional headers (key/value pairs) including optional empty lines
|
407
426
|
|
408
427
|
read_headers = true
|
@@ -410,7 +429,7 @@ class Gen
|
|
410
429
|
|
411
430
|
# fix: allow comments in header too (#)
|
412
431
|
|
413
|
-
|
432
|
+
content_with_headers.each do |line|
|
414
433
|
if read_headers && line =~ /^\s*(\w[\w-]*)[ \t]*:[ \t]*(.*)/
|
415
434
|
key = $1.downcase
|
416
435
|
value = $2.strip
|
@@ -425,6 +444,19 @@ class Gen
|
|
425
444
|
end
|
426
445
|
end
|
427
446
|
|
447
|
+
opts.set_defaults
|
448
|
+
|
449
|
+
# ruby note: .*? is non-greedy (shortest-possible) regex match
|
450
|
+
content.gsub!(/__SKIP__.*?__END__/m, '')
|
451
|
+
content.sub!(/__END__.*/m, '')
|
452
|
+
|
453
|
+
# allow plugins/helpers; process source (including header) using erb
|
454
|
+
|
455
|
+
# note: include is a ruby keyword; rename to __include__ so we can use it
|
456
|
+
content.gsub!( /<%=[ \t]*include/, '<%= __include__' )
|
457
|
+
|
458
|
+
content = ERB.new( content ).result( binding )
|
459
|
+
|
428
460
|
# run pre-filters (built-in macros)
|
429
461
|
# o replace {{{ w/ <pre class='code'>
|
430
462
|
# o replace }}} w/ </pre>
|
@@ -436,28 +468,22 @@ class Gen
|
|
436
468
|
content.gsub!( "_S9BEGIN_", "{{{" )
|
437
469
|
content.gsub!( "_S9END_", "}}}" )
|
438
470
|
|
439
|
-
opts.set_defaults
|
440
|
-
|
441
471
|
# convert light-weight markup to hypertext
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
# turn off span caps (see http://rubybook.ca/2008/08/16/redcloth)
|
450
|
-
red = RedCloth.new( content, [:no_span_caps] )
|
451
|
-
red.hard_breaks = false
|
452
|
-
content = red.to_html
|
453
|
-
end
|
454
|
-
|
472
|
+
|
473
|
+
content = case @markup_type
|
474
|
+
when :markdown
|
475
|
+
markdown_to_html( content )
|
476
|
+
when :textile
|
477
|
+
textile_to_html( content )
|
478
|
+
end
|
455
479
|
|
456
480
|
# post-processing
|
457
481
|
|
458
482
|
slide_counter = 0
|
459
483
|
content2 = ''
|
460
484
|
|
485
|
+
## todo: move this to a filter (for easier reuse)
|
486
|
+
|
461
487
|
# wrap h1's in slide divs; note use just <h1 since some processors add ids e.g. <h1 id='x'>
|
462
488
|
content.each_line do |line|
|
463
489
|
if line.include?( '<h1' ) then
|
@@ -469,45 +495,6 @@ class Gen
|
|
469
495
|
end
|
470
496
|
content2 << "\n\n</div>" if slide_counter > 0
|
471
497
|
|
472
|
-
=begin
|
473
|
-
## todo: run syntax highlighting before markup/textilize? lets us add textile to highlighted code?
|
474
|
-
## avoid undoing escaped entities?
|
475
|
-
|
476
|
-
include_code_stylesheet = false
|
477
|
-
# syntax highlight code
|
478
|
-
# todo: can the code handle escaped entities? e.g. >
|
479
|
-
doc = Hpricot(content2)
|
480
|
-
doc.search("pre.code, pre > code").each do |e|
|
481
|
-
if e.inner_html =~ /^\s*#!(\w+)/
|
482
|
-
lang = $1.downcase
|
483
|
-
if e.inner_html =~ /^\{\{\{/ # {{{ assumes escape/literal #!lang
|
484
|
-
# do nothing; next
|
485
|
-
logger.debug " skipping syntax highlighting using lang=#{lang}; assumimg escaped literal"
|
486
|
-
else
|
487
|
-
logger.debug " syntax highlighting using lang=#{lang}"
|
488
|
-
if Uv.syntaxes.include?(lang)
|
489
|
-
code = e.inner_html.sub(/^\s*#!\w+/, '').strip
|
490
|
-
|
491
|
-
code.gsub!( "<", "<" )
|
492
|
-
code.gsub!( ">", ">" )
|
493
|
-
code.gsub!( "&", "&" )
|
494
|
-
# todo: missing any other entities? use CGI::unescapeHTML?
|
495
|
-
logger.debug "code=>#{code}<"
|
496
|
-
|
497
|
-
code_highlighted = Uv.parse( code, "xhtml", lang, opts.code_line_numbers?, opts.code_theme )
|
498
|
-
# old code: e.inner_html = code_highlighted
|
499
|
-
# todo: is it ok to replace the pre.code enclosing element to avoid duplicates?
|
500
|
-
e.swap( code_highlighted )
|
501
|
-
include_code_stylesheet = true
|
502
|
-
end
|
503
|
-
end
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
content2 = doc.to_s
|
508
|
-
=end
|
509
|
-
|
510
|
-
|
511
498
|
manifest.each do |entry|
|
512
499
|
outname = entry[0]
|
513
500
|
if outname.include? '__file__' # process
|
@@ -535,24 +522,6 @@ class Gen
|
|
535
522
|
end
|
536
523
|
end
|
537
524
|
|
538
|
-
|
539
|
-
=begin
|
540
|
-
if include_code_stylesheet
|
541
|
-
logger.debug "cache_dir=#{cache_dir}"
|
542
|
-
|
543
|
-
FileUtils.mkdir(cache_dir) unless File.exists?(cache_dir) if cache_dir
|
544
|
-
Uv.copy_files "xhtml", cache_dir
|
545
|
-
|
546
|
-
theme = opts.code_theme
|
547
|
-
|
548
|
-
theme_content = File.read( "#{cache_dir}/css/#{theme}.css" )
|
549
|
-
|
550
|
-
out << "/* styles for code syntax highlighting theme '#{theme}' */\n"
|
551
|
-
out << "\n"
|
552
|
-
out << theme_content
|
553
|
-
end
|
554
|
-
=end
|
555
|
-
|
556
525
|
puts "Done."
|
557
526
|
end
|
558
527
|
|
@@ -658,8 +627,26 @@ end
|
|
658
627
|
|
659
628
|
end # module Slideshow
|
660
629
|
|
661
|
-
# load built-in helpers/plugins
|
630
|
+
# load built-in (required) helpers/plugins
|
662
631
|
require "#{File.dirname(__FILE__)}/helpers/text_helper.rb"
|
663
632
|
require "#{File.dirname(__FILE__)}/helpers/capture_helper.rb"
|
664
633
|
|
634
|
+
# load built-in (optional) helpers/plugins
|
635
|
+
# If a helper fails to load, simply ingnore it
|
636
|
+
# If you want to use it install missing required gems e.g.:
|
637
|
+
# gem install coderay
|
638
|
+
# gem install ultraviolet etc.
|
639
|
+
BUILTIN_OPT_HELPERS = [
|
640
|
+
"#{File.dirname(__FILE__)}/helpers/uv_helper.rb",
|
641
|
+
"#{File.dirname(__FILE__)}/helpers/coderay_helper.rb",
|
642
|
+
]
|
643
|
+
|
644
|
+
BUILTIN_OPT_HELPERS.each do |helper|
|
645
|
+
begin
|
646
|
+
require(helper)
|
647
|
+
rescue Exception => e
|
648
|
+
;
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
665
652
|
Slideshow.main if __FILE__ == $0
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
+
<%= content_for :head %>
|
5
|
+
|
4
6
|
<title><%= @headers['title'] %></title>
|
5
7
|
|
6
8
|
<!-- configuration parameters -->
|
@@ -14,6 +16,8 @@
|
|
14
16
|
<script src="s6/jquery.js" type="text/javascript"></script>
|
15
17
|
<script src="s6/slides.js" type="text/javascript"></script>
|
16
18
|
|
19
|
+
<%= content_for :js %>
|
20
|
+
|
17
21
|
</head>
|
18
22
|
<body>
|
19
23
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slideshow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02
|
12
|
+
date: 2009-03-02 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,7 +43,9 @@ extra_rdoc_files: []
|
|
43
43
|
files:
|
44
44
|
- lib/helpers
|
45
45
|
- lib/helpers/capture_helper.rb
|
46
|
+
- lib/helpers/coderay_helper.rb
|
46
47
|
- lib/helpers/text_helper.rb
|
48
|
+
- lib/helpers/uv_helper.rb
|
47
49
|
- lib/slideshow.rb
|
48
50
|
- lib/templates
|
49
51
|
- lib/templates/footer.html.erb
|