ronn-ng 0.7.4 → 0.8.0.SNAPSHOT
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.
- 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
|