ronn-ng 0.7.4 → 0.8.0.SNAPSHOT
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +12 -3
- data/Gemfile +2 -0
- data/INSTALLING.md +100 -0
- data/README.md +19 -1
- data/Rakefile +39 -49
- data/bin/ronn +93 -75
- data/completion/bash/ronn +32 -0
- data/completion/zsh/_ronn +24 -0
- data/config.ru +3 -3
- data/lib/ronn/document.rb +127 -106
- data/lib/ronn/index.rb +8 -9
- data/lib/ronn/roff.rb +153 -76
- data/lib/ronn/server.rb +19 -22
- data/lib/ronn/template.rb +27 -26
- data/lib/ronn/utils.rb +9 -7
- data/lib/ronn.rb +5 -3
- data/man/ronn-format.7 +6 -62
- data/man/ronn.1 +21 -123
- data/man/ronn.1.ronn +8 -0
- data/ronn-ng.gemspec +38 -13
- data/test/angle_bracket_syntax.html +4 -5
- data/test/backticks.html +14 -0
- data/test/backticks.ronn +10 -0
- data/test/basic_document.html +3 -4
- data/test/basic_document.ronn +2 -2
- data/test/circumflexes.ronn +1 -0
- data/test/code_blocks.7.ronn +41 -0
- data/test/contest.rb +56 -54
- data/test/custom_title_document.html +2 -2
- data/test/definition_list_syntax.html +13 -9
- data/test/definition_list_syntax.roff +2 -9
- data/test/definition_list_syntax.ronn +2 -2
- data/test/dots_at_line_start_test.roff +12 -3
- data/test/dots_at_line_start_test.ronn +8 -0
- data/test/ellipses.roff +7 -0
- data/test/ellipses.ronn +7 -0
- data/test/entity_encoding_test.html +13 -14
- data/test/entity_encoding_test.roff +1 -22
- data/test/entity_encoding_test.ronn +1 -1
- data/test/markdown_syntax.html +4 -5
- data/test/markdown_syntax.roff +1 -561
- data/test/middle_paragraph.html +2 -3
- data/test/middle_paragraph.roff +1 -5
- data/test/middle_paragraph.ronn +1 -1
- data/test/missing_spaces.roff +0 -2
- data/test/nested_list.ronn +19 -0
- data/test/nested_list_with_code.html +15 -0
- data/test/nested_list_with_code.roff +11 -0
- data/test/nested_list_with_code.ronn +6 -0
- data/test/page.with.periods.in.name.5.ronn +4 -0
- data/test/pre_block_with_quotes.roff +0 -5
- data/test/section_reference_links.html +2 -3
- data/test/section_reference_links.roff +1 -4
- data/test/section_reference_links.ronn +1 -1
- data/test/tables.ronn +24 -0
- data/test/test_ronn.rb +49 -35
- data/test/test_ronn_document.rb +81 -81
- data/test/test_ronn_index.rb +11 -11
- data/test/titleless_document.html +0 -1
- data/test/underline_spacing_test.roff +0 -8
- metadata +140 -22
- data/INSTALLING +0 -20
data/lib/ronn/roff.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
|
-
require '
|
1
|
+
require 'nokogiri'
|
2
2
|
require 'ronn/utils'
|
3
3
|
|
4
4
|
module Ronn
|
5
|
+
# Filter for converting HTML to ROFF
|
5
6
|
class RoffFilter
|
6
7
|
include Ronn::Utils
|
7
8
|
|
8
9
|
# Convert Ronn HTML to roff.
|
9
|
-
|
10
|
+
# The html input is an HTML fragment, not a complete document
|
11
|
+
def initialize(html_fragment, name, section, tagline, manual = nil,
|
12
|
+
version = nil, date = nil)
|
10
13
|
@buf = []
|
11
14
|
title_heading name, section, tagline, manual, version, date
|
12
|
-
doc =
|
15
|
+
doc = Nokogiri::HTML.fragment(html_fragment)
|
13
16
|
remove_extraneous_elements! doc
|
14
17
|
normalize_whitespace! doc
|
15
18
|
block_filter doc
|
@@ -20,36 +23,34 @@ module Ronn
|
|
20
23
|
@buf.join.gsub(/[ \t]+$/, '')
|
21
24
|
end
|
22
25
|
|
23
|
-
|
26
|
+
protected
|
27
|
+
|
24
28
|
def previous(node)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
29
|
+
return unless node.respond_to?(:previous)
|
30
|
+
prev = node.previous
|
31
|
+
prev = prev.previous until prev.nil? || prev.elem?
|
32
|
+
prev
|
30
33
|
end
|
31
34
|
|
32
|
-
def title_heading(name, section,
|
35
|
+
def title_heading(name, section, _tagline, manual, version, date)
|
33
36
|
comment "generated with Ronn-NG/v#{Ronn.version}"
|
34
37
|
comment "http://github.com/apjanke/ronn-ng/tree/#{Ronn.revision}"
|
35
38
|
return if name.nil?
|
36
|
-
macro
|
39
|
+
macro 'TH', %("#{escape(name.upcase)}" "#{section}" "#{date.strftime('%B %Y')}" "#{version}" "#{manual}")
|
37
40
|
end
|
38
41
|
|
39
42
|
def remove_extraneous_elements!(doc)
|
40
|
-
doc.
|
41
|
-
|
42
|
-
node.parent.children.delete(node)
|
43
|
-
end
|
43
|
+
doc.traverse do |node|
|
44
|
+
node.parent.children.delete(node) if node.comment?
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
48
|
def normalize_whitespace!(node)
|
48
|
-
|
49
|
-
when node.kind_of?(Array) || node.kind_of?(Hpricot::Elements)
|
49
|
+
if node.is_a?(Array) || node.is_a?(Nokogiri::XML::NodeSet)
|
50
50
|
node.to_a.dup.each { |ch| normalize_whitespace! ch }
|
51
|
-
|
52
|
-
preceding
|
51
|
+
elsif node.text?
|
52
|
+
preceding = node.previous
|
53
|
+
following = node.next
|
53
54
|
content = node.content.gsub(/[\n ]+/m, ' ')
|
54
55
|
if preceding.nil? || block_element?(preceding.name) ||
|
55
56
|
preceding.name == 'br'
|
@@ -60,76 +61,91 @@ module Ronn
|
|
60
61
|
content.rstrip!
|
61
62
|
end
|
62
63
|
if content.empty?
|
63
|
-
node.
|
64
|
+
node.remove
|
64
65
|
else
|
65
66
|
node.content = content
|
66
67
|
end
|
67
|
-
|
68
|
+
elsif node.elem? && node.name == 'pre'
|
68
69
|
# stop traversing
|
69
|
-
|
70
|
+
elsif node.elem? && node.children
|
70
71
|
normalize_whitespace! node.children
|
71
|
-
|
72
|
+
elsif node.elem?
|
72
73
|
# element has no children
|
73
|
-
|
74
|
+
elsif node.document? || node.fragment?
|
74
75
|
normalize_whitespace! node.children
|
76
|
+
elsif node.is_a?(Nokogiri::XML::DTD) || node.is_a?(Nokogiri::XML::Comment)
|
77
|
+
# ignore
|
78
|
+
nop
|
75
79
|
else
|
76
|
-
warn
|
80
|
+
warn 'unexpected node during whitespace normalization: %p', node
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
80
84
|
def block_filter(node)
|
81
|
-
if node.
|
85
|
+
return if node.nil?
|
86
|
+
|
87
|
+
if node.is_a?(Array) || node.is_a?(Nokogiri::XML::NodeSet)
|
82
88
|
node.each { |ch| block_filter(ch) }
|
83
89
|
|
84
|
-
elsif node.
|
90
|
+
elsif node.document? || node.fragment?
|
85
91
|
block_filter(node.children)
|
86
92
|
|
87
93
|
elsif node.text?
|
88
|
-
|
94
|
+
# This hack is necessary to support mixed-child-type dd's
|
95
|
+
inline_filter(node)
|
89
96
|
|
90
97
|
elsif node.elem?
|
91
98
|
case node.name
|
99
|
+
when 'html', 'body'
|
100
|
+
block_filter(node.children)
|
92
101
|
when 'div'
|
93
102
|
block_filter(node.children)
|
94
103
|
when 'h1'
|
95
104
|
# discard
|
105
|
+
nop
|
96
106
|
when 'h2'
|
97
|
-
macro
|
107
|
+
macro 'SH', quote(escape(node.inner_html))
|
98
108
|
when 'h3'
|
99
|
-
macro
|
109
|
+
macro 'SS', quote(escape(node.inner_html))
|
100
110
|
|
101
111
|
when 'p'
|
102
112
|
prev = previous(node)
|
103
113
|
if prev && %w[dd li blockquote].include?(node.parent.name)
|
104
|
-
macro
|
114
|
+
macro 'IP'
|
105
115
|
elsif prev && !%w[h1 h2 h3].include?(prev.name)
|
106
|
-
macro
|
116
|
+
macro 'P'
|
117
|
+
elsif node.previous&.text?
|
118
|
+
macro 'IP'
|
107
119
|
end
|
108
120
|
inline_filter(node.children)
|
109
121
|
|
110
122
|
when 'blockquote'
|
111
123
|
prev = previous(node)
|
112
124
|
indent = prev.nil? || !%w[h1 h2 h3].include?(prev.name)
|
113
|
-
macro
|
125
|
+
macro 'IP', %w["" 4] if indent
|
114
126
|
block_filter(node.children)
|
115
|
-
macro
|
127
|
+
macro 'IP', %w["" 0] if indent
|
116
128
|
|
117
129
|
when 'pre'
|
118
130
|
prev = previous(node)
|
119
131
|
indent = prev.nil? || !%w[h1 h2 h3].include?(prev.name)
|
120
|
-
macro
|
121
|
-
macro
|
122
|
-
|
132
|
+
macro 'IP', %w["" 4] if indent
|
133
|
+
macro 'nf'
|
134
|
+
# HACK: strip an initial \n to avoid extra spacing
|
135
|
+
if node.children && node.children[0].text?
|
136
|
+
text = node.children[0].to_s
|
137
|
+
node.children[0].replace(text[1..-1]) if text.start_with? "\n"
|
138
|
+
end
|
123
139
|
inline_filter(node.children)
|
124
|
-
macro
|
125
|
-
macro
|
140
|
+
macro 'fi'
|
141
|
+
macro 'IP', %w["" 0] if indent
|
126
142
|
|
127
143
|
when 'dl'
|
128
|
-
macro
|
144
|
+
macro 'TP'
|
129
145
|
block_filter(node.children)
|
130
146
|
when 'dt'
|
131
147
|
prev = previous(node)
|
132
|
-
macro
|
148
|
+
macro 'TP' unless prev.nil?
|
133
149
|
inline_filter(node.children)
|
134
150
|
write "\n"
|
135
151
|
when 'dd'
|
@@ -142,15 +158,17 @@ module Ronn
|
|
142
158
|
|
143
159
|
when 'ol', 'ul'
|
144
160
|
block_filter(node.children)
|
145
|
-
macro
|
161
|
+
macro 'IP', %w["" 0]
|
146
162
|
when 'li'
|
147
163
|
case node.parent.name
|
148
164
|
when 'ol'
|
149
|
-
macro
|
165
|
+
macro 'IP', %W["#{node.position + 1}." 4]
|
150
166
|
when 'ul'
|
151
|
-
macro
|
167
|
+
macro 'IP', ['"\\[ci]"', '4']
|
168
|
+
else
|
169
|
+
raise "List element found as a child of non-list parent element: #{node.inspect}"
|
152
170
|
end
|
153
|
-
if node.at('p
|
171
|
+
if node.at('p,ol,ul,dl,div')
|
154
172
|
block_filter(node.children)
|
155
173
|
else
|
156
174
|
inline_filter(node.children)
|
@@ -160,19 +178,68 @@ module Ronn
|
|
160
178
|
when 'span', 'code', 'b', 'strong', 'kbd', 'samp', 'var', 'em', 'i',
|
161
179
|
'u', 'br', 'a'
|
162
180
|
inline_filter(node)
|
181
|
+
|
182
|
+
when 'table'
|
183
|
+
macro 'TS'
|
184
|
+
write "allbox;\n"
|
185
|
+
block_filter(node.children)
|
186
|
+
macro 'TE'
|
187
|
+
when 'thead'
|
188
|
+
# Convert to format section and first row
|
189
|
+
tr = node.children[0]
|
190
|
+
header_contents = []
|
191
|
+
cell_formats = []
|
192
|
+
tr.children.each do |th|
|
193
|
+
style = th['style']
|
194
|
+
cell_format = case style
|
195
|
+
when 'text-align:left;'
|
196
|
+
'l'
|
197
|
+
when 'text-align:right;'
|
198
|
+
'r'
|
199
|
+
when 'text-align:center;'
|
200
|
+
'c'
|
201
|
+
else
|
202
|
+
'l'
|
203
|
+
end
|
204
|
+
header_contents << th.inner_html
|
205
|
+
cell_formats << cell_format
|
206
|
+
end
|
207
|
+
write cell_formats.join(' ') + ".\n"
|
208
|
+
write header_contents.join("\t") + "\n"
|
209
|
+
when 'th'
|
210
|
+
raise 'internal error: unexpected <th> element'
|
211
|
+
when 'tbody'
|
212
|
+
# Let the 'tr' handle it
|
213
|
+
block_filter(node.children)
|
214
|
+
when 'tr'
|
215
|
+
# Convert to a table data row
|
216
|
+
node.children.each do |child|
|
217
|
+
block_filter(child)
|
218
|
+
write "\t"
|
219
|
+
end
|
220
|
+
write "\n"
|
221
|
+
when 'td'
|
222
|
+
inline_filter(node.children)
|
223
|
+
|
163
224
|
else
|
164
|
-
warn
|
225
|
+
warn 'unrecognized block tag: %p', node.name
|
165
226
|
end
|
166
227
|
|
228
|
+
elsif node.is_a?(Nokogiri::XML::DTD)
|
229
|
+
# Ignore
|
230
|
+
nop
|
231
|
+
elsif node.is_a?(Nokogiri::XML::Comment)
|
232
|
+
# Ignore
|
233
|
+
nop
|
167
234
|
else
|
168
|
-
|
235
|
+
raise "unexpected node: #{node.inspect}"
|
169
236
|
end
|
170
237
|
end
|
171
238
|
|
172
239
|
def inline_filter(node)
|
173
240
|
return unless node # is an empty node
|
174
241
|
|
175
|
-
if node.
|
242
|
+
if node.is_a?(Array) || node.is_a?(Nokogiri::XML::NodeSet)
|
176
243
|
node.each { |ch| inline_filter(ch) }
|
177
244
|
|
178
245
|
elsif node.text?
|
@@ -216,7 +283,7 @@ module Ronn
|
|
216
283
|
inline_filter(node.children)
|
217
284
|
write ' '
|
218
285
|
write '\fI'
|
219
|
-
write escape(node.attributes['href'])
|
286
|
+
write escape(node.attributes['href'].content)
|
220
287
|
write '\fR'
|
221
288
|
end
|
222
289
|
|
@@ -227,33 +294,38 @@ module Ronn
|
|
227
294
|
write ')'
|
228
295
|
|
229
296
|
else
|
230
|
-
warn
|
297
|
+
warn 'unrecognized inline tag: %p', node.name
|
231
298
|
end
|
232
299
|
|
233
300
|
else
|
234
|
-
|
301
|
+
raise "unexpected node: #{node.inspect}"
|
235
302
|
end
|
236
303
|
end
|
237
304
|
|
238
|
-
def
|
239
|
-
|
305
|
+
def maybe_new_line
|
306
|
+
write "\n" if @buf.last && @buf.last[-1] != "\n"
|
307
|
+
end
|
308
|
+
|
309
|
+
def macro(name, value = nil)
|
310
|
+
maybe_new_line
|
311
|
+
writeln ".#{[name, value].compact.join(' ')}"
|
240
312
|
end
|
241
313
|
|
242
314
|
HTML_ROFF_ENTITIES = {
|
243
|
-
'
|
244
|
-
'<'
|
245
|
-
'>'
|
246
|
-
'
|
247
|
-
'
|
248
|
-
'
|
249
|
-
'
|
250
|
-
'
|
251
|
-
'
|
252
|
-
'
|
253
|
-
'
|
254
|
-
'
|
255
|
-
'
|
256
|
-
}
|
315
|
+
'•' => '\[ci]',
|
316
|
+
'<' => '<',
|
317
|
+
'>' => '>',
|
318
|
+
' ' => '\~', # That's a literal non-breaking space character there
|
319
|
+
'©' => '\(co',
|
320
|
+
'”' => '\(rs',
|
321
|
+
'—' => '\(em',
|
322
|
+
'®' => '\(rg',
|
323
|
+
'§' => '\(sc',
|
324
|
+
'≥' => '\(>=',
|
325
|
+
'≤' => '\(<=',
|
326
|
+
'≠' => '\(!=',
|
327
|
+
'≡' => '\(=='
|
328
|
+
}.freeze
|
257
329
|
|
258
330
|
def escape(text)
|
259
331
|
return text.to_s if text.nil? || text.empty?
|
@@ -264,8 +336,10 @@ module Ronn
|
|
264
336
|
text.gsub!('\\', '\e') # backslash
|
265
337
|
text.gsub!('...', '\|.\|.\|.') # ellipses
|
266
338
|
text.gsub!(/['.-]/) { |m| "\\#{m}" } # control chars
|
267
|
-
|
268
|
-
|
339
|
+
ent.each do |key, val|
|
340
|
+
text.gsub!(key, val)
|
341
|
+
end
|
342
|
+
text.gsub!('&', '&') # amps
|
269
343
|
text
|
270
344
|
end
|
271
345
|
|
@@ -277,26 +351,29 @@ module Ronn
|
|
277
351
|
def write(text)
|
278
352
|
return if text.nil? || text.empty?
|
279
353
|
# lines cannot start with a '.'. insert zero-width character before.
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
end
|
354
|
+
text = text.gsub(/\n\\\./s, "\n\\\\&\\.")
|
355
|
+
buf_ends_in_newline = @buf.last && @buf.last[-1] == "\n"
|
356
|
+
@buf << '\&' if text[0, 2] == '\.' && buf_ends_in_newline
|
284
357
|
@buf << text
|
285
358
|
end
|
286
359
|
|
287
360
|
# write text to output buffer on a new line.
|
288
361
|
def writeln(text)
|
289
|
-
|
362
|
+
maybe_new_line
|
290
363
|
write text
|
291
364
|
write "\n"
|
292
365
|
end
|
293
366
|
|
294
367
|
def comment(text)
|
295
|
-
writeln %
|
368
|
+
writeln %(.\\" #{text})
|
296
369
|
end
|
297
370
|
|
298
371
|
def warn(text, *args)
|
299
|
-
|
372
|
+
Kernel.warn format("warn: #{text}", args)
|
373
|
+
end
|
374
|
+
|
375
|
+
def nop
|
376
|
+
# Do nothing
|
300
377
|
end
|
301
378
|
end
|
302
379
|
end
|
data/lib/ronn/server.rb
CHANGED
@@ -3,21 +3,20 @@ require 'rack'
|
|
3
3
|
require 'sinatra/base'
|
4
4
|
|
5
5
|
module Ronn
|
6
|
-
|
7
6
|
# Ronn HTTP server. Serves a list of .ronn files as HTML. The options Hash is
|
8
7
|
# passed to Ronn::Document.new on each invocation.
|
9
8
|
#
|
10
9
|
# Use Ronn::Server.new to create a Rack app. See the config.ru file in the
|
11
10
|
# root of the Ronn distribution for example usage.
|
12
11
|
#
|
13
|
-
# Ronn::Server.run starts a server on port
|
12
|
+
# Ronn::Server.run starts a server on port 1207.
|
14
13
|
module Server
|
15
|
-
def self.new(files, options={})
|
14
|
+
def self.new(files, options = {})
|
16
15
|
files = Dir[files] if files.respond_to?(:to_str)
|
17
|
-
raise ArgumentError,
|
16
|
+
raise ArgumentError, 'no files' if files.empty?
|
18
17
|
Sinatra.new do
|
19
18
|
set :show_exceptions, true
|
20
|
-
set :
|
19
|
+
set :public_dir, File.expand_path(__FILE__, '../templates')
|
21
20
|
set :static, false
|
22
21
|
set :views, File.expand_path(__FILE__, '../templates')
|
23
22
|
|
@@ -28,25 +27,22 @@ module Ronn
|
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
[]
|
40
|
-
end
|
41
|
-
end
|
30
|
+
options[:styles] ||= options[:style]
|
31
|
+
my_styles = if options[:styles].respond_to?(:to_ary)
|
32
|
+
options[:styles]
|
33
|
+
elsif options[:styles]
|
34
|
+
options[:styles].split(/[, ]+/)
|
35
|
+
else
|
36
|
+
[]
|
37
|
+
end
|
42
38
|
|
43
39
|
files.each do |file|
|
44
40
|
basename = File.basename(file, '.ronn')
|
45
41
|
|
46
42
|
get "/#{basename}.html" do
|
47
|
-
options = options.merge(:
|
43
|
+
options = options.merge(styles: my_styles)
|
48
44
|
%w[date manual organization].each do |attribute|
|
49
|
-
next
|
45
|
+
next unless params[attribute]
|
50
46
|
options[attribute] = params[attribute]
|
51
47
|
end
|
52
48
|
Ronn::Document.new(file, options).to_html
|
@@ -59,11 +55,12 @@ module Ronn
|
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
62
|
-
def self.run(files, options={})
|
58
|
+
def self.run(files, options = {})
|
59
|
+
port_number = options['port'] || 1207
|
63
60
|
new(files, options).run!(
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
61
|
+
server: %w[mongrel thin webrick],
|
62
|
+
port: port_number,
|
63
|
+
logging: true
|
67
64
|
)
|
68
65
|
end
|
69
66
|
end
|
data/lib/ronn/template.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
require 'mustache'
|
2
2
|
|
3
3
|
module Ronn
|
4
|
+
# A Mustache Template for HTML formatting.
|
4
5
|
class Template < Mustache
|
5
6
|
self.template_path = File.dirname(__FILE__) + '/template'
|
6
7
|
self.template_extension = 'html'
|
7
8
|
|
8
|
-
def initialize(document, style_path=ENV['RONN_STYLE'].to_s.split(':'))
|
9
|
+
def initialize(document, style_path = ENV['RONN_STYLE'].to_s.split(':'))
|
9
10
|
@document = document
|
10
11
|
@style_path = style_path + [Template.template_path]
|
11
12
|
end
|
12
13
|
|
13
|
-
def render(template='default')
|
14
|
-
super template[0,1] == '/' ? File.read(template) : partial(template)
|
14
|
+
def render(template = 'default')
|
15
|
+
super template[0, 1] == '/' ? File.read(template) : partial(template)
|
15
16
|
end
|
16
17
|
|
17
18
|
##
|
@@ -80,8 +81,8 @@ module Ronn
|
|
80
81
|
def section_heads
|
81
82
|
@document.section_heads.map do |id, text|
|
82
83
|
{
|
83
|
-
:
|
84
|
-
:
|
84
|
+
id: id,
|
85
|
+
text: text
|
85
86
|
}
|
86
87
|
end
|
87
88
|
end
|
@@ -98,21 +99,21 @@ module Ronn
|
|
98
99
|
def stylesheets
|
99
100
|
styles.zip(style_files).map do |name, path|
|
100
101
|
base = File.basename(path, '.css')
|
101
|
-
|
102
|
+
raise "style not found: #{style.inspect}" if path.nil?
|
102
103
|
{
|
103
|
-
:
|
104
|
-
:
|
105
|
-
:
|
106
|
-
:
|
104
|
+
name: name,
|
105
|
+
path: path,
|
106
|
+
base: File.basename(path, '.css'),
|
107
|
+
media: base =~ /(print|screen)$/ ? $1 : 'all'
|
107
108
|
}
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
111
112
|
# All embedded stylesheets.
|
112
113
|
def stylesheet_tags
|
113
|
-
stylesheets
|
114
|
-
map { |style| inline_stylesheet(style[:path], style[:media]) }
|
115
|
-
join("\n ")
|
114
|
+
stylesheets
|
115
|
+
.map { |style| inline_stylesheet(style[:path], style[:media]) }
|
116
|
+
.join("\n ")
|
116
117
|
end
|
117
118
|
|
118
119
|
attr_accessor :style_path
|
@@ -123,27 +124,27 @@ module Ronn
|
|
123
124
|
def style_files
|
124
125
|
styles.map do |name|
|
125
126
|
next name if name.include?('/')
|
126
|
-
style_path
|
127
|
-
reject
|
128
|
-
map { |p| File.join(p, "#{name}.css") }
|
129
|
-
detect { |file| File.exist?(file) }
|
127
|
+
style_path
|
128
|
+
.reject { |p| p.strip.empty? }
|
129
|
+
.map { |p| File.join(p, "#{name}.css") }
|
130
|
+
.detect { |file| File.exist?(file) }
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
133
134
|
# Array of style names for which no file could be found.
|
134
135
|
def missing_styles
|
135
|
-
style_files
|
136
|
-
zip(files)
|
137
|
-
select { |
|
138
|
-
map { |style,
|
136
|
+
style_files
|
137
|
+
.zip(files)
|
138
|
+
.select { |_style, file| file.nil? }
|
139
|
+
.map { |style, _file| style }
|
139
140
|
end
|
140
141
|
|
141
142
|
##
|
142
143
|
# TEMPLATE CSS LOADING
|
143
144
|
|
144
|
-
def inline_stylesheet(path, media='all')
|
145
|
+
def inline_stylesheet(path, media = 'all')
|
145
146
|
data = File.read(path)
|
146
|
-
data.gsub!(%r
|
147
|
+
data.gsub!(%r{/\*.+?\*/}m, '') # comments
|
147
148
|
data.gsub!(/([;{,]) *\n/m, '\1') # end-of-line whitespace
|
148
149
|
data.gsub!(/\n{2,}/m, "\n") # collapse lines
|
149
150
|
data.gsub!(/[; ]+\}/, '}') # superfluous trailing semi-colons
|
@@ -155,16 +156,16 @@ module Ronn
|
|
155
156
|
"<style type='text/css' media='#{media}'>",
|
156
157
|
"/* style: #{File.basename(path, '.css')} */",
|
157
158
|
data,
|
158
|
-
|
159
|
+
'</style>'
|
159
160
|
].join("\n ")
|
160
161
|
end
|
161
162
|
|
162
|
-
def remote_stylesheet(name, media='all')
|
163
|
+
def remote_stylesheet(name, media = 'all')
|
163
164
|
path = File.expand_path("../template/#{name}.css", __FILE__)
|
164
165
|
"<link rel='stylesheet' type='text/css' media='#{media}' href='#{path}'>"
|
165
166
|
end
|
166
167
|
|
167
|
-
def stylesheet(
|
168
|
+
def stylesheet(_path, media = 'all')
|
168
169
|
inline_stylesheet(name, media)
|
169
170
|
end
|
170
171
|
end
|
data/lib/ronn/utils.rb
CHANGED
@@ -2,16 +2,17 @@ require 'set'
|
|
2
2
|
require 'cgi'
|
3
3
|
|
4
4
|
module Ronn
|
5
|
+
# Miscellaneous utilities.
|
5
6
|
module Utils
|
6
|
-
|
7
7
|
# All HTML 4 elements and some that are in common use.
|
8
8
|
HTML = %w[
|
9
|
-
a abbr acronym address applet area b base basefont bdo big blockquote body
|
10
|
-
button caption center cite code col colgroup dd del dfn dir div dl dt
|
11
|
-
fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i
|
12
|
-
input ins isindex kbd label legend li link map menu meta
|
13
|
-
object ol optgroup option p param pre q s samp script
|
14
|
-
strong style sub sup table tbody td textarea
|
9
|
+
a abbr acronym address applet area b base basefont bdo big blockquote body
|
10
|
+
br button caption center cite code col colgroup dd del dfn dir div dl dt
|
11
|
+
em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i
|
12
|
+
iframe img input ins isindex kbd label legend li link map menu meta
|
13
|
+
noframes noscript object ol optgroup option p param pre q s samp script
|
14
|
+
select small span strike strong style sub sup table tbody td textarea
|
15
|
+
tfoot th thead title tr tt u ul var
|
15
16
|
].to_set
|
16
17
|
|
17
18
|
# Block elements.
|
@@ -47,6 +48,7 @@ module Ronn
|
|
47
48
|
def child_of?(node, tag)
|
48
49
|
while node
|
49
50
|
return true if node.name && node.name.downcase == tag
|
51
|
+
return false if node.document?
|
50
52
|
node = node.parent
|
51
53
|
end
|
52
54
|
false
|
data/lib/ronn.rb
CHANGED
@@ -11,7 +11,7 @@ module Ronn
|
|
11
11
|
|
12
12
|
# Create a new Ronn::Document for the given ronn file. See
|
13
13
|
# Ronn::Document.new for usage information.
|
14
|
-
def self.new(filename, attributes={}, &block)
|
14
|
+
def self.new(filename, attributes = {}, &block)
|
15
15
|
Document.new(filename, attributes, &block)
|
16
16
|
end
|
17
17
|
|
@@ -26,7 +26,7 @@ module Ronn
|
|
26
26
|
# of the version is incremented by the commit offset, such that version
|
27
27
|
# 0.6.6-5-gdacd74b => 0.6.11
|
28
28
|
def self.version
|
29
|
-
ver = revision[/^[0-9.-]+/].split(/[.-]/).map
|
29
|
+
ver = revision[/^[0-9.-]+/].split(/[.-]/).map(&:to_i)
|
30
30
|
ver[2] += ver.pop while ver.size > 3
|
31
31
|
ver.join('.')
|
32
32
|
end
|
@@ -45,6 +45,8 @@ module Ronn
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# value generated by: rake rev
|
48
|
-
|
48
|
+
# or edit manually; I'm not sure of how rake rev interacts with git
|
49
|
+
# tags -apjanke
|
50
|
+
REV = '0.8.0.SNAPSHOT'.freeze
|
49
51
|
VERSION = version
|
50
52
|
end
|