RedCloth 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of RedCloth might be problematic. Click here for more details.
- data/bin/redcloth +1 -1
- data/doc/CHANGELOG +160 -0
- data/doc/COPYING +25 -0
- data/doc/README +106 -0
- data/doc/REFERENCE +216 -0
- data/doc/make.rb +359 -0
- data/lib/redcloth.rb +77 -60
- data/run-tests.rb +3 -1
- data/setup.rb +1376 -0
- data/tests/hard_breaks.yml +26 -0
- data/tests/table.yml +4 -4
- data/tests/textism.yml +9 -0
- metadata +19 -11
data/doc/make.rb
ADDED
@@ -0,0 +1,359 @@
|
|
1
|
+
$:.unshift '../lib'
|
2
|
+
require 'yaml'
|
3
|
+
require 'redcloth'
|
4
|
+
|
5
|
+
class String
|
6
|
+
#
|
7
|
+
# Flexible HTML escaping
|
8
|
+
#
|
9
|
+
def htmlesc!( mode )
|
10
|
+
gsub!( '&', '&' )
|
11
|
+
gsub!( '"', '"' ) if mode != :NoQuotes
|
12
|
+
gsub!( "'", ''' ) if mode == :Quotes
|
13
|
+
gsub!('<', '<')
|
14
|
+
gsub!('>', '>')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def a_name( phrase )
|
19
|
+
phrase.downcase.
|
20
|
+
gsub( /\W+/, '-' )
|
21
|
+
end
|
22
|
+
|
23
|
+
file_name = ARGV.shift
|
24
|
+
case file_name
|
25
|
+
when 'README'
|
26
|
+
puts <<-HTML
|
27
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
28
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
29
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
30
|
+
<head>
|
31
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
32
|
+
<title>RedCloth [Textile Humane Web Text for Ruby]</title>
|
33
|
+
<style type="text/css">
|
34
|
+
BODY {
|
35
|
+
margin: 10px 60px 40px 60px;
|
36
|
+
font-family: georgia, serif;
|
37
|
+
font-size: 12pt;
|
38
|
+
}
|
39
|
+
TABLE {
|
40
|
+
padding: 15px;
|
41
|
+
width: 250px;
|
42
|
+
}
|
43
|
+
TH {
|
44
|
+
text-align: left;
|
45
|
+
}
|
46
|
+
TD {
|
47
|
+
border-top: solid 1px #eee;
|
48
|
+
}
|
49
|
+
H4 {
|
50
|
+
border: solid 1px #caa;
|
51
|
+
margin: 10px 15px 5px 10px;
|
52
|
+
padding: 5px;
|
53
|
+
color: white;
|
54
|
+
background-color: #333;
|
55
|
+
font-weight: bold;
|
56
|
+
font-size: 12pt;
|
57
|
+
}
|
58
|
+
P {
|
59
|
+
margin: 10px 15px 5px 15px;
|
60
|
+
}
|
61
|
+
P.example1 {
|
62
|
+
background-color: #FEE;
|
63
|
+
font-weight: bold;
|
64
|
+
font-size: 9pt;
|
65
|
+
padding: 5px;
|
66
|
+
}
|
67
|
+
P.example2 {
|
68
|
+
border: solid 1px #DDD;
|
69
|
+
background-color: #EEE;
|
70
|
+
font-size: 9pt;
|
71
|
+
padding: 5px;
|
72
|
+
}
|
73
|
+
.big {
|
74
|
+
font-size: 15pt;
|
75
|
+
}
|
76
|
+
#big-red {
|
77
|
+
font-size: 15pt;
|
78
|
+
color: red;
|
79
|
+
}
|
80
|
+
#big-red2 {
|
81
|
+
font-size: 15pt;
|
82
|
+
color: red;
|
83
|
+
}
|
84
|
+
#sidebar {
|
85
|
+
float: right;
|
86
|
+
font-family: verdana, arial, sans-serif;
|
87
|
+
font-size: 10pt;
|
88
|
+
border-left: solid 1px #999;
|
89
|
+
margin-left: 10px;
|
90
|
+
width: 200px;
|
91
|
+
}
|
92
|
+
/* VARIATION BUTTON STYLING (v2.0) - SIZABLE SIZE */
|
93
|
+
#css-buttons ul{list-style: none;margin: 0 0 10px 0;padding: 0;}
|
94
|
+
#css-buttons li{border: 1px solid #999; margin: 5px 0 0 20px; width:9.0em;}
|
95
|
+
head:first-child+body #css-buttons li{padding-right:2px;}
|
96
|
+
#css-buttons li a{color: #333; text-decoration: none;}
|
97
|
+
|
98
|
+
.css-button {
|
99
|
+
display:block;
|
100
|
+
font: 0.8em verdana, arial, sans-serif;
|
101
|
+
padding: 2px 0 2px 0px; border: 1px solid white;
|
102
|
+
text-decoration: none; width:100%;
|
103
|
+
background: #ddd;color: #333;
|
104
|
+
}
|
105
|
+
|
106
|
+
.css-button span {
|
107
|
+
font: bold 1.0em verdana, arial, sans-serif;
|
108
|
+
padding: 2px 3px 2px 3px; color: #fff;
|
109
|
+
}
|
110
|
+
|
111
|
+
/* BUTTON LOGO STYLING */
|
112
|
+
.rss span{background:#f60;}
|
113
|
+
.w3c span {background: #fff; color: #069; font: bold 1.1em helvetica, arial, Sans-Serif;}
|
114
|
+
.w3c2{background: #fc6;color: black !important;}
|
115
|
+
</style>
|
116
|
+
</head>
|
117
|
+
<body>
|
118
|
+
HTML
|
119
|
+
puts RedCloth.new( File.open( file_name ).read ).to_html
|
120
|
+
puts "</body>"
|
121
|
+
puts "</html>"
|
122
|
+
when 'QUICK-REFERENCE'
|
123
|
+
YAML::add_private_type( "example" ) do |type, val|
|
124
|
+
esc = val.dup
|
125
|
+
esc.htmlesc!( :NoQuotes )
|
126
|
+
[ :example, esc.gsub( /\n/, '<br />' ),
|
127
|
+
RedCloth.new( val ).to_html ]
|
128
|
+
end
|
129
|
+
|
130
|
+
content = YAML::load( File.open( 'REFERENCE' ) )
|
131
|
+
|
132
|
+
sections = content.collect { |c| c.keys.first }
|
133
|
+
sections.shift
|
134
|
+
|
135
|
+
puts <<-HTML
|
136
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
137
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
138
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
139
|
+
<head>
|
140
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
141
|
+
<title>Textile Quick Reference</title>
|
142
|
+
<style type="text/css">
|
143
|
+
BODY {
|
144
|
+
margin: 5px;
|
145
|
+
}
|
146
|
+
TABLE {
|
147
|
+
font-family: georgia, serif;
|
148
|
+
font-size: 10pt;
|
149
|
+
padding: 5px;
|
150
|
+
width: 200px;
|
151
|
+
}
|
152
|
+
TH {
|
153
|
+
padding-top: 10px;
|
154
|
+
}
|
155
|
+
TD {
|
156
|
+
border-top: solid 1px #eee;
|
157
|
+
}
|
158
|
+
H1 {
|
159
|
+
font-size: 18pt;
|
160
|
+
}
|
161
|
+
H4 {
|
162
|
+
color: #999;
|
163
|
+
background-color: #fee;
|
164
|
+
border: solid 1px #caa;
|
165
|
+
margin: 10px 15px 5px 10px;
|
166
|
+
padding: 5px;
|
167
|
+
}
|
168
|
+
P {
|
169
|
+
margin: 2px 5px 2px 5px;
|
170
|
+
}
|
171
|
+
TD.example1 PRE {
|
172
|
+
background-color: #FEE;
|
173
|
+
font-family: georgia, serif;
|
174
|
+
font-size: 8pt;
|
175
|
+
padding: 5px;
|
176
|
+
padding: 5px;
|
177
|
+
}
|
178
|
+
TD.example3 {
|
179
|
+
border: solid 1px #DDD;
|
180
|
+
background-color: #EEE;
|
181
|
+
font-size: 8pt;
|
182
|
+
padding: 5px;
|
183
|
+
}
|
184
|
+
.big {
|
185
|
+
font-size: 12pt;
|
186
|
+
}
|
187
|
+
#big-red {
|
188
|
+
font-size: 12pt;
|
189
|
+
color: red;
|
190
|
+
}
|
191
|
+
#big-red2 {
|
192
|
+
font-size: 15pt;
|
193
|
+
color: red;
|
194
|
+
}
|
195
|
+
</style>
|
196
|
+
</head>
|
197
|
+
<body>
|
198
|
+
<table>
|
199
|
+
<tr><th colspan='3'><h1>Textile Quick Reference</h1></th></tr>
|
200
|
+
<tr><th colspan='3'>Sections: #{ sections.collect { |s| "<a href='##{ a_name( s ) }'>#{ s.gsub( /\s/, ' ' ) }</a>" }.join( ' | ' ) }</th></tr>
|
201
|
+
HTML
|
202
|
+
|
203
|
+
ct = 0
|
204
|
+
content.each do |section|
|
205
|
+
section.each do |header, parags|
|
206
|
+
puts "<tr><th colspan='5'><a name='#{ a_name( header ) }'>#{ header }</a></th></tr>" if ct.nonzero?
|
207
|
+
parags.each do |p|
|
208
|
+
if p.is_a?( Array ) and p[0] == :example
|
209
|
+
puts "<tr><td class='example1'><pre>#{ p[1] }</pre></td><td>→</td>" +
|
210
|
+
"<td class='example2'>#{ p[2] }</td></tr>"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
ct += 1
|
215
|
+
end
|
216
|
+
puts "</table>"
|
217
|
+
puts "</body>"
|
218
|
+
puts "</html>"
|
219
|
+
|
220
|
+
when 'REFERENCE'
|
221
|
+
YAML::add_private_type( "example" ) do |type, val|
|
222
|
+
esc = val.dup
|
223
|
+
esc.htmlesc!( :NoQuotes )
|
224
|
+
[ esc.gsub( /\n/, '<br />' ),
|
225
|
+
RedCloth.new( val ).to_html.
|
226
|
+
gsub( /;(\w)/, '; \1' ).
|
227
|
+
htmlesc!( :NoQuotes ).
|
228
|
+
gsub( /\n/, '<br />' ),
|
229
|
+
RedCloth.new( val ).to_html ]
|
230
|
+
end
|
231
|
+
|
232
|
+
content = YAML::load( File.open( file_name ) )
|
233
|
+
|
234
|
+
sections = content.collect { |c| c.keys.first }
|
235
|
+
sections.shift
|
236
|
+
|
237
|
+
puts <<-HTML
|
238
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
239
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
240
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
241
|
+
<head>
|
242
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
243
|
+
<title>Textile Reference</title>
|
244
|
+
<style type="text/css">
|
245
|
+
BODY {
|
246
|
+
margin: 10px 30px;
|
247
|
+
}
|
248
|
+
TABLE {
|
249
|
+
font-family: georgia, serif;
|
250
|
+
font-size: 11pt;
|
251
|
+
padding: 15px;
|
252
|
+
}
|
253
|
+
TH {
|
254
|
+
border-bottom: solid 1px black;
|
255
|
+
font-size: 24pt;
|
256
|
+
font-weight: bold;
|
257
|
+
padding-top: 30px;
|
258
|
+
}
|
259
|
+
H1 {
|
260
|
+
font-size: 42pt;
|
261
|
+
}
|
262
|
+
H4 {
|
263
|
+
color: #666;
|
264
|
+
background-color: #fee;
|
265
|
+
border: solid 1px #caa;
|
266
|
+
margin: 10px 0px 5px 0px;
|
267
|
+
padding: 5px;
|
268
|
+
}
|
269
|
+
P {
|
270
|
+
margin: 10px 15px 5px 15px;
|
271
|
+
}
|
272
|
+
TD.sections {
|
273
|
+
background: black;
|
274
|
+
color: white;
|
275
|
+
font-family: georgia, serif;
|
276
|
+
font-weight: bold;
|
277
|
+
font-size: 9pt;
|
278
|
+
padding: 5px;
|
279
|
+
}
|
280
|
+
TD.sections A { color: #CCEEFF; }
|
281
|
+
TD.sections A:link { color: #CCEEFF; }
|
282
|
+
TD.sections A:visited { color: #CCEEFF; }
|
283
|
+
TD.sections A:active { color: #EEEEEE; }
|
284
|
+
TD.sections A:hover { color: #EEEEEE; }
|
285
|
+
|
286
|
+
TD.example1 PRE {
|
287
|
+
background-color: #B30;
|
288
|
+
color: white;
|
289
|
+
font-family: georgia, serif;
|
290
|
+
font-weight: bold;
|
291
|
+
font-size: 9pt;
|
292
|
+
padding: 5px;
|
293
|
+
}
|
294
|
+
TD.example2 P {
|
295
|
+
border: solid 1px #DDD;
|
296
|
+
background-color: #EEE;
|
297
|
+
font-family: georgia, serif;
|
298
|
+
font-size: 9pt;
|
299
|
+
padding: 5px;
|
300
|
+
}
|
301
|
+
TD.example3 {
|
302
|
+
border: solid 1px #EED;
|
303
|
+
background-color: #FFE;
|
304
|
+
padding: 5px;
|
305
|
+
}
|
306
|
+
.big {
|
307
|
+
font-size: 15pt;
|
308
|
+
}
|
309
|
+
#big-red {
|
310
|
+
font-size: 15pt;
|
311
|
+
color: red
|
312
|
+
}
|
313
|
+
</style>
|
314
|
+
<script type="text/javascript">
|
315
|
+
function quickRedReference() {
|
316
|
+
window.open(
|
317
|
+
"quick.html",
|
318
|
+
"redRef",
|
319
|
+
"height=600,width=550,channelmode=0,dependent=0," +
|
320
|
+
"directories=0,fullscreen=0,location=0,menubar=0," +
|
321
|
+
"resizable=0,scrollbars=1,status=1,toolbar=0"
|
322
|
+
);
|
323
|
+
}
|
324
|
+
</script>
|
325
|
+
</head>
|
326
|
+
<body>
|
327
|
+
<table>
|
328
|
+
HTML
|
329
|
+
|
330
|
+
ct = 0
|
331
|
+
content.each do |section|
|
332
|
+
section.each do |header, parags|
|
333
|
+
if ct.zero?
|
334
|
+
puts "<tr><th colspan='3'><h1>#{ header }</h1></th></tr>"
|
335
|
+
puts "<tr><td class='sections' colspan='3'>Sections: #{ sections.collect { |s| "<a href='##{ a_name( s ) }'>#{ s.gsub( /\s/, ' ' ) }</a>" }.join( ' | ' ) }</td></tr>"
|
336
|
+
else
|
337
|
+
puts "<tr><th colspan='3'><a name='#{ a_name( header ) }'><small>#{ ct }.</small></a><br />#{ header }</th></tr>"
|
338
|
+
end
|
339
|
+
parags.each do |p|
|
340
|
+
if p.is_a? Array
|
341
|
+
puts "<tr><td class='example1' valign='top'><pre>#{ p[0] }</pre></td><td>→</td>" +
|
342
|
+
"<td class='example2'><p>#{ p[1] }</p></td></tr><tr><td colspan='2'></td>" +
|
343
|
+
"<td class='example3'>#{ p[2] }</td></tr>"
|
344
|
+
else
|
345
|
+
puts "<tr><td class='explain' colspan='3'>"
|
346
|
+
puts RedCloth.new( p ).to_html
|
347
|
+
puts "</td></tr>"
|
348
|
+
end
|
349
|
+
end
|
350
|
+
unless ct.zero?
|
351
|
+
puts "<tr><td colspan='5' style='border-bottom: solid 1px #eee;'></td></tr>"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
ct += 1
|
355
|
+
end
|
356
|
+
puts "</table>"
|
357
|
+
puts "</body>"
|
358
|
+
puts "</html>"
|
359
|
+
end
|
data/lib/redcloth.rb
CHANGED
@@ -166,7 +166,7 @@
|
|
166
166
|
|
167
167
|
class RedCloth < String
|
168
168
|
|
169
|
-
VERSION = '3.0.
|
169
|
+
VERSION = '3.0.4'
|
170
170
|
DEFAULT_RULES = [:textile, :markdown]
|
171
171
|
|
172
172
|
#
|
@@ -193,6 +193,18 @@ class RedCloth < String
|
|
193
193
|
#
|
194
194
|
attr_accessor :hard_breaks
|
195
195
|
|
196
|
+
# Accessor for toggling lite mode.
|
197
|
+
#
|
198
|
+
# In lite mode, block-level rules are ignored. This means
|
199
|
+
# that tables, paragraphs, lists, and such aren't available.
|
200
|
+
# Only the inline markup for bold, italics, entities and so on.
|
201
|
+
#
|
202
|
+
# r = RedCloth.new( "And then? She *fell*!", [:lite_mode] )
|
203
|
+
# r.to_html
|
204
|
+
# #=> "And then? She <strong>fell</strong>!"
|
205
|
+
#
|
206
|
+
attr_accessor :lite_mode
|
207
|
+
|
196
208
|
#
|
197
209
|
# Accessor for toggling span caps.
|
198
210
|
#
|
@@ -219,7 +231,7 @@ class RedCloth < String
|
|
219
231
|
# inline_textile_image:: Textile inline images
|
220
232
|
# inline_textile_link:: Textile inline links
|
221
233
|
# inline_textile_span:: Textile inline spans
|
222
|
-
#
|
234
|
+
# glyphs_textile:: Textile entities (such as em-dashes and smart quotes)
|
223
235
|
#
|
224
236
|
# == Markdown
|
225
237
|
#
|
@@ -260,7 +272,7 @@ class RedCloth < String
|
|
260
272
|
@shelf = []
|
261
273
|
textile_rules = [:refs_textile, :block_textile_table, :block_textile_lists,
|
262
274
|
:block_textile_prefix, :inline_textile_image, :inline_textile_link,
|
263
|
-
:inline_textile_code, :
|
275
|
+
:inline_textile_code, :inline_textile_span, :glyphs_textile]
|
264
276
|
markdown_rules = [:refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule,
|
265
277
|
:block_markdown_bq, :block_markdown_lists,
|
266
278
|
:inline_markdown_reflink, :inline_markdown_link]
|
@@ -278,14 +290,16 @@ class RedCloth < String
|
|
278
290
|
# standard clean up
|
279
291
|
incoming_entities text
|
280
292
|
clean_white_space text
|
281
|
-
no_textile text
|
282
293
|
|
283
294
|
# start processor
|
284
295
|
@pre_list = []
|
285
296
|
rip_offtags text
|
286
|
-
|
287
|
-
|
288
|
-
|
297
|
+
no_textile text
|
298
|
+
hard_break text
|
299
|
+
unless @lite_mode
|
300
|
+
refs text
|
301
|
+
blocks text
|
302
|
+
end
|
289
303
|
inline text
|
290
304
|
smooth_offtags text
|
291
305
|
|
@@ -333,6 +347,8 @@ class RedCloth < String
|
|
333
347
|
C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
|
334
348
|
# PUNCT = Regexp::quote( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' )
|
335
349
|
PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
|
350
|
+
PUNCT_NOQ = Regexp::quote( '!"#$&\',./:;=?@\\`|' )
|
351
|
+
PUNCT_Q = Regexp::quote( '*-_+^~%' )
|
336
352
|
HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(?=\s|<|$)'
|
337
353
|
|
338
354
|
# Text markup tags, don't conflict with block tags
|
@@ -342,41 +358,6 @@ class RedCloth < String
|
|
342
358
|
'br', 'map', 'q', 'sub', 'sup', 'span', 'bdo'
|
343
359
|
]
|
344
360
|
|
345
|
-
# Elements to handle
|
346
|
-
GLYPHS = [
|
347
|
-
# [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing
|
348
|
-
[ /([^\s\[{(>])\'/, '\1’' ], # single closing
|
349
|
-
[ /\'(?=\s|s\b|[#{PUNCT}])/, '’' ], # single closing
|
350
|
-
[ /\'/, '‘' ], # single opening
|
351
|
-
# [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing
|
352
|
-
[ /([^\s\[{(>])"/, '\1”' ], # double closing
|
353
|
-
[ /"(?=\s|[#{PUNCT}])/, '”' ], # double closing
|
354
|
-
[ /"/, '“' ], # double opening
|
355
|
-
[ /\b( )?\.{3}/, '\1…' ], # ellipsis
|
356
|
-
[ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
|
357
|
-
[ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
|
358
|
-
[ /(\.\s)?\s?--\s?/, '\1—' ], # em dash
|
359
|
-
[ /\s->\s/, ' → ' ], # right arrow
|
360
|
-
[ /\s-\s/, ' – ' ], # en dash
|
361
|
-
[ /(\d+) ?x ?(\d+)/, '\1×\2' ], # dimension sign
|
362
|
-
[ /\b ?[(\[]TM[\])]/i, '™' ], # trademark
|
363
|
-
[ /\b ?[(\[]R[\])]/i, '®' ], # registered
|
364
|
-
[ /\b ?[(\[]C[\])]/i, '©' ] # copyright
|
365
|
-
]
|
366
|
-
|
367
|
-
H_ALGN_VALS = {
|
368
|
-
'<' => 'left',
|
369
|
-
'=' => 'center',
|
370
|
-
'>' => 'right',
|
371
|
-
'<>' => 'justify'
|
372
|
-
}
|
373
|
-
|
374
|
-
V_ALGN_VALS = {
|
375
|
-
'^' => 'top',
|
376
|
-
'-' => 'middle',
|
377
|
-
'~' => 'bottom'
|
378
|
-
}
|
379
|
-
|
380
361
|
QTAGS = [
|
381
362
|
['**', 'b'],
|
382
363
|
['*', 'strong'],
|
@@ -398,19 +379,56 @@ class RedCloth < String
|
|
398
379
|
(#{rcq})
|
399
380
|
(#{C})
|
400
381
|
(?::(\S+?))?
|
401
|
-
(
|
382
|
+
(\S.*?\S|\S)
|
402
383
|
#{rcq}
|
403
384
|
(?=\W)/x
|
404
385
|
else
|
405
386
|
/(#{rcq})
|
406
387
|
(#{C})
|
407
|
-
(?::(\S
|
408
|
-
(
|
388
|
+
(?::(\S+))?
|
389
|
+
(\S.*?\S|\S)
|
409
390
|
#{rcq}/xm
|
410
391
|
end
|
411
392
|
[rc, ht, re, rtype]
|
412
393
|
end
|
413
394
|
|
395
|
+
# Elements to handle
|
396
|
+
GLYPHS = [
|
397
|
+
# [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing
|
398
|
+
[ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing
|
399
|
+
[ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing
|
400
|
+
[ /\'/, '‘' ], # single opening
|
401
|
+
[ /</, '<' ], # less-than
|
402
|
+
[ />/, '>' ], # greater-than
|
403
|
+
# [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing
|
404
|
+
[ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing
|
405
|
+
[ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing
|
406
|
+
[ /"/, '“' ], # double opening
|
407
|
+
[ /\b( )?\.{3}/, '\1…' ], # ellipsis
|
408
|
+
[ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
|
409
|
+
[ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
|
410
|
+
[ /(\.\s)?\s?--\s?/, '\1—' ], # em dash
|
411
|
+
[ /\s->\s/, ' → ' ], # right arrow
|
412
|
+
[ /\s-\s/, ' – ' ], # en dash
|
413
|
+
[ /(\d+) ?x ?(\d+)/, '\1×\2' ], # dimension sign
|
414
|
+
[ /\b ?[(\[]TM[\])]/i, '™' ], # trademark
|
415
|
+
[ /\b ?[(\[]R[\])]/i, '®' ], # registered
|
416
|
+
[ /\b ?[(\[]C[\])]/i, '©' ] # copyright
|
417
|
+
]
|
418
|
+
|
419
|
+
H_ALGN_VALS = {
|
420
|
+
'<' => 'left',
|
421
|
+
'=' => 'center',
|
422
|
+
'>' => 'right',
|
423
|
+
'<>' => 'justify'
|
424
|
+
}
|
425
|
+
|
426
|
+
V_ALGN_VALS = {
|
427
|
+
'^' => 'top',
|
428
|
+
'-' => 'middle',
|
429
|
+
'~' => 'bottom'
|
430
|
+
}
|
431
|
+
|
414
432
|
#
|
415
433
|
# Flexible HTML escaping
|
416
434
|
#
|
@@ -530,7 +548,7 @@ class RedCloth < String
|
|
530
548
|
depth.pop
|
531
549
|
end
|
532
550
|
end
|
533
|
-
if depth.last.length == tl.length
|
551
|
+
if depth.last and depth.last.length == tl.length
|
534
552
|
lines[line_id - 1] << '</li>'
|
535
553
|
end
|
536
554
|
end
|
@@ -577,7 +595,7 @@ class RedCloth < String
|
|
577
595
|
end
|
578
596
|
|
579
597
|
def hard_break( text )
|
580
|
-
text.gsub!( /(.)\n(
|
598
|
+
text.gsub!( /(.)\n(?!\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
|
581
599
|
end
|
582
600
|
|
583
601
|
BLOCKS_GROUP_RE = /\n{2,}(?! )/m
|
@@ -705,9 +723,9 @@ class RedCloth < String
|
|
705
723
|
end
|
706
724
|
end
|
707
725
|
|
708
|
-
MARKDOWN_RULE_RE =
|
726
|
+
MARKDOWN_RULE_RE = /^(#{
|
709
727
|
['*', '-', '_'].collect { |ch| '( ?' + Regexp::quote( ch ) + ' ?){3,}' }.join( '|' )
|
710
|
-
}$/
|
728
|
+
})$/
|
711
729
|
|
712
730
|
def block_markdown_rule( text )
|
713
731
|
text.gsub!( MARKDOWN_RULE_RE ) do |blk|
|
@@ -719,9 +737,6 @@ class RedCloth < String
|
|
719
737
|
def block_markdown_lists( text )
|
720
738
|
end
|
721
739
|
|
722
|
-
def inline_markdown_link( text )
|
723
|
-
end
|
724
|
-
|
725
740
|
def inline_textile_span( text )
|
726
741
|
QTAGS.each do |qtag_rc, ht, qtag_re, rtype|
|
727
742
|
text.gsub!( qtag_re ) do |m|
|
@@ -903,12 +918,12 @@ class RedCloth < String
|
|
903
918
|
|
904
919
|
def shelve( val )
|
905
920
|
@shelf << val
|
906
|
-
"
|
921
|
+
" :redsh##{ @shelf.length }:"
|
907
922
|
end
|
908
923
|
|
909
924
|
def retrieve( text )
|
910
925
|
@shelf.each_with_index do |r, i|
|
911
|
-
text.gsub!( "
|
926
|
+
text.gsub!( " :redsh##{ i + 1 }:", r )
|
912
927
|
end
|
913
928
|
end
|
914
929
|
|
@@ -965,7 +980,7 @@ class RedCloth < String
|
|
965
980
|
HASTAG_MATCH = /(<\/?\w[^\n]*?>)/m
|
966
981
|
ALLTAG_MATCH = /(<\/?\w[^\n]*?>)|.*?(?=<\/?\w[^\n]*?>|$)/m
|
967
982
|
|
968
|
-
def
|
983
|
+
def glyphs_textile( text, level = 0 )
|
969
984
|
if text !~ HASTAG_MATCH
|
970
985
|
pgl text
|
971
986
|
footnote_ref text
|
@@ -981,11 +996,11 @@ class RedCloth < String
|
|
981
996
|
codepre = 0 if codepre < 0
|
982
997
|
end
|
983
998
|
elsif codepre.zero?
|
984
|
-
|
999
|
+
glyphs_textile( line, level + 1 )
|
985
1000
|
else
|
986
1001
|
htmlesc( line, :NoQuotes )
|
987
1002
|
end
|
988
|
-
|
1003
|
+
# p [level, codepre, line]
|
989
1004
|
|
990
1005
|
line
|
991
1006
|
end
|
@@ -1033,8 +1048,10 @@ class RedCloth < String
|
|
1033
1048
|
end
|
1034
1049
|
|
1035
1050
|
def inline( text )
|
1036
|
-
|
1037
|
-
|
1051
|
+
[/^inline_/, /^glyphs_/].each do |meth_re|
|
1052
|
+
@rules.each do |rule_name|
|
1053
|
+
method( rule_name ).call( text ) if rule_name.to_s.match( meth_re )
|
1054
|
+
end
|
1038
1055
|
end
|
1039
1056
|
end
|
1040
1057
|
|
@@ -1097,7 +1114,7 @@ class RedCloth < String
|
|
1097
1114
|
q2 = ( q != '' ? q : '\s' )
|
1098
1115
|
if raw[3] =~ /#{prop}\s*=\s*#{q}([^#{q2}]+)#{q}/i
|
1099
1116
|
attrv = $1
|
1100
|
-
next if prop == 'src' and attrv
|
1117
|
+
next if prop == 'src' and attrv =~ %r{^(?!http)\w+:}
|
1101
1118
|
pcs << "#{prop}=\"#{$1.gsub('"', '\\"')}\""
|
1102
1119
|
break
|
1103
1120
|
end
|