| Path: | lib/redcloth/textile.rb |
| Last Update: | Thu Nov 09 13:58:32 UTC 2006 |
| TEXTILE_REFS_RE | = | /(^ *)\[([^\n\[]+?)\](#{HYPERLINK})(?=\s|$)/ |
Parses Textile definition lists and generates HTML
# File lib/redcloth/textile.rb, line 216
216: def block_textile_defs( text )
217: text.gsub!(/^-\s+(.*?):=(.*?)=:\s*$/m) do |m|
218: "- #{$1.strip} := <p>"+$2.split(/\n/).map{|w|w.strip}.delete_if{|w|w.empty?}.join("</p><p>")+"</p>"
219: end
220:
221: text.gsub!( DEFS_RE ) do |match|
222: lines = match.split( /\n/ )
223: lines.each_with_index do |line, line_id|
224: if line =~ DEFS_CONTENT_RE
225: dl,continuation,dt,dd = $~[1..4]
226:
227: atts = pba( atts )
228: atts = shelve( atts ) if atts
229: lines[line_id] = line_id == 0 ? "<dl#{ atts }>" : ""
230: lines[line_id] << "\n\t<dt>#{ dt.strip }</dt>\n\t<dd>#{ dd.strip }</dd>"
231: end
232:
233: if line_id == lines.length - 1
234: lines[-1] << "\n</dl>"
235: end
236: end
237: lines.join( "\n" )
238: end
239: end
Parses Textile lists and generates HTML
# File lib/redcloth/textile.rb, line 125
125: def block_textile_lists( text )
126: orig_text = text.dup
127:
128: # Take care of _*'s and _#'s to turn them into paragraphs
129: text.gsub!(/([\*#] )((.*?\n\s*_[\*#].*?)+)/) do |m|
130: "#{$1}<p>"+$2.split(/_[\*#]/).map{|w|w.strip}.delete_if{|w|w.empty?}.join("</p><p>")+"</p>"
131: end
132:
133: @last_line ||= -1
134:
135: text.gsub!( LISTS_RE ) do |match|
136: if text =~ /^#([_0-9]+).*/m
137: if $1 == $1.to_i.to_s # then it is a number, so use it
138: @last_line = $1.to_i - 2
139: end
140: else
141: @last_line = -1
142: end
143: lines = match.split( /\n/ )
144: depth = []
145: lines.each_with_index do |line, line_id|
146: if line =~ LISTS_CONTENT_RE
147:
148: tl,continuation,atts,content = $~[1..4]
149: @last_line += 1 if tl.length == 1
150:
151: unless depth.last.nil?
152: if depth.last.length > tl.length
153: (depth.length - 1).downto(0) do |i|
154: break if depth[i].length == tl.length
155: lines[line_id - 1] << "</li>\n#{"\t"*(depth.size-1)}</#{ lT( depth[i] ) }l>"
156: depth.pop
157: tab_in = true
158: end
159: end
160: if depth.last && depth.last.length == tl.length
161: lines[line_id - 1] << "</li>"
162: end
163: end
164: unless depth.last == tl
165: depth << tl
166: atts = pba( atts )
167: atts << " start=\"#{@last_line + 1}\"" if lT(tl) == "o" && !continuation.empty? && @last_line > 0
168: atts = shelve( atts ) if atts
169: lines[line_id] = "#{"\t"*(depth.size-1)}<#{ lT(tl) }l#{ atts }>\n#{"\t"*depth.size}<li>#{ content }"
170: else
171: lines[line_id] = "#{"\t"*depth.size}<li>#{ content }"
172: end
173: elsif line =~ /^([_]+)(#{A}#{C}) (.*)$/m
174: @last_line += 1
175: tl = "u"
176: atts,content = $~[2..3]
177:
178: unless depth.last.nil?
179: if depth.last.length > tl.length
180: (depth.length - 1).downto(0) do |i|
181: break if depth[i].length == tl.length
182: lines[line_id - 1] << "</li>\n#{"\t"*(depth.size-1)}</#{ lT( depth[i] ) }l>"
183: depth.pop
184: tab_in = true
185: end
186: end
187: if depth.last and depth.last.length == tl.length
188: lines[line_id - 1] << "</li>"
189: end
190: end
191: unless depth.last == tl
192: depth << tl
193: atts = pba( atts )
194: atts = shelve( "#{atts} style=\"list-style-type:none;\"" )
195: lines[line_id] = "#{"\t"*(depth.size-1)}<#{ lT(tl) }l#{ atts }>\n#{"\t"*depth.size}<li>#{ content }"
196: else
197: lines[line_id] = "#{"\t"*depth.size}<li>#{ content }"
198: end
199: end
200:
201: if line_id == lines.length - 1
202: tabs = depth.size-1
203: depth.reverse.delete_if do |v|
204: lines[-1] << "</li>\n#{"\t"*tabs}</#{ lT( v ) }l>"
205: tabs -= 1
206: end
207: end
208: end
209: lines.join( "\n" )
210: end
211:
212: text != orig_text
213: end
# File lib/redcloth/textile.rb, line 279
279: def block_textile_prefix( text )
280: if text =~ BLOCK_RE
281: tag,tagpre,num,atts,cite,content = $~[1..6]
282: atts = pba( atts )
283:
284: # pass to prefix handler
285: if respond_to? "textile_#{ tag }", true
286: text.gsub!( $&, method( "textile_#{ tag }" ).call( tag, atts, cite, content ) )
287: elsif respond_to? "textile_#{ tagpre }_", true
288: text.gsub!( $&, method( "textile_#{ tagpre }_" ).call( tagpre, num, atts, cite, content ) )
289: end
290: end
291: end
Parses a Textile table block, building HTML from the result.
# File lib/redcloth/textile.rb, line 87
87: def block_textile_table( text )
88: text.gsub!( TABLE_RE ) do |matches|
89:
90: caption, id, tatts, fullrow = $~[1..4]
91: tatts = pba( tatts, 'table' )
92: tatts = shelve( tatts ) if tatts
93: rows = []
94:
95: fullrow.
96: split( /\|$/m ).
97: delete_if {|row|row.empty?}.
98: each do |row|
99:
100: ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m
101: row << " "
102:
103: cells = []
104: row.split( '|' ).each_with_index do |cell, i|
105: next if i == 0
106:
107: ctyp = 'd'
108: ctyp = 'h' if cell =~ /^_/
109:
110: catts = ''
111: catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. ?)(.*)/
112:
113: catts = shelve( catts ) if catts
114: cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell.strip.empty? ? " " : row.split( '|' ).size-1 != i ? cell : cell[0...cell.length-1] }</t#{ ctyp }>"
115: end
116: ratts = shelve( ratts ) if ratts
117: rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>"
118: end
119: caption = "\t<p class=\"caption\">#{caption}</p>\n" if caption
120: "#{caption}\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n"
121: end
122: end
# File lib/redcloth/textile.rb, line 400
400: def glyphs_textile( text, level = 0 )
401: return if level > 10
402: if text !~ HASTAG_MATCH
403: pgl text
404: footnote_ref text
405: else
406: codepre = 0
407: text.gsub!( ALLTAG_MATCH ) do |line|
408: ## matches are off if we're between <code>, <pre> etc.
409: if $1
410: if line =~ OFFTAG_OPEN
411: codepre += 1
412: elsif line =~ OFFTAG_CLOSE
413: codepre -= 1
414: codepre = 0 if codepre < 0
415: end
416: elsif codepre.zero?
417: glyphs_textile( line, level + 1 )
418: else
419: htmlesc( line, :NoQuotes )
420: end
421: ## p [level, codepre, orig_line, line]
422:
423: line
424: end
425: end
426: end
Turns all email addresses into clickable links.
# File lib/redcloth/textile.rb, line 446
446: def inline_textile_autolink_emails(text)
447: text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/, '<a href="mailto:\1">\1</a>')
448: end
Turns all urls into clickable links. Taken from ActionPack’s ActionView
# File lib/redcloth/textile.rb, line 434
434: def inline_textile_autolink_urls(text)
435: text.gsub!(AUTO_LINK_RE) do
436: all, a, b, c, d = $&, $1, $2, $3, $5
437: if a =~ /<a\s/i # don't replace URL's that are already linked
438: all
439: else
440: %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}">#{b}#{c}</a>#{d})
441: end
442: end
443: end
# File lib/redcloth/textile.rb, line 241
241: def inline_textile_code( text )
242: text.gsub!( CODE_RE ) do |m|
243: before,lang,code,after = $~[1..4]
244: lang = " lang=\"#{ lang }\"" if lang
245: rip_offtags( "#{ before }<code#{ lang }>#{ code.gsub(/\\@(@?)/,'@\1') }</code>#{ after }" )
246: end
247: end
# File lib/redcloth/textile.rb, line 358
358: def inline_textile_image( text )
359: text.gsub!( IMAGE_RE ) do |m|
360: stln,algn,atts,url,title,href,href_a1,href_a2 = $~[1..8]
361: atts = pba( atts )
362: atts = " src=\"#{ url }\"#{ atts }"
363: atts << " title=\"#{ title }\"" if title
364: atts << " alt=\"#{ title }\""
365: # size = @getimagesize($url);
366: # if($size) $atts.= " $size[3]";
367:
368: href, alt_title = check_refs( href ) if href
369: url, url_title = check_refs( url )
370:
371: out = ''
372: out << "<a#{ shelve( " href=\"#{ href }\"" ) }>" if href
373: out << "<img#{ shelve( atts ) } />"
374: out << "</a>#{ href_a1 }#{ href_a2 }" if href
375:
376: if algn
377: algn = h_align( algn )
378: if stln == "<p>"
379: out = "<p style=\"float:#{ algn }\">#{ out }"
380: else
381: out = "#{ stln }<div style=\"float:#{ algn }\">#{ out }</div>"
382: end
383: else
384: out = stln + out
385: end
386:
387: out
388: end
389: end
# File lib/redcloth/textile.rb, line 332
332: def inline_textile_link( text )
333: text.gsub!( LINK_RE ) do |m|
334: pre,atts,text,title,url,slash,post = $~[1..7]
335:
336: url, url_title = check_refs( url )
337: title ||= url_title
338:
339: atts = pba( atts )
340: atts = " href=\"#{ url }#{ slash }\"#{ atts }"
341: atts << " title=\"#{ title }\"" if title
342: atts = shelve( atts ) if atts
343:
344: "#{ pre }<a#{ atts }>#{ text }</a>#{ post }"
345: end
346: end
# File lib/redcloth/textile.rb, line 293
293: def inline_textile_span( text )
294: QTAGS.each do |qtag_rc, ht, qtag_re, rtype, escaped_re|
295: text.gsub!( qtag_re ) do |m|
296:
297: case rtype
298: when :limit
299: sta,qtag,atts,cite,content = $~[1..5]
300: else
301: qtag,atts,cite,content = $~[1..4]
302: sta = ''
303: end
304: atts = pba( atts )
305: atts << " cite=\"#{ cite }\"" if cite
306: atts = shelve( atts ) if atts
307:
308: "#{ sta }<#{ ht }#{ atts }>#{ content }</#{ ht }>"
309: end
310: end
311: end
# File lib/redcloth/textile.rb, line 391
391: def no_textile( text )
392: text.gsub!( /(^|\s)(\\?)==([^=]+?)\2==(\s|$)?/ ) do |m|
393: $2.empty? ? "#{$1}<notextile>#{$3}</notextile>#{$4}" : "#{$1}==#{$3}==#{$4}"
394: end
395: text.gsub!( /^ *(\\?)==([^=]+?)\1==/m ) do |m|
396: $1.empty? ? "<notextile>#{$2}</notextile>" : "==#{$2}=="
397: end
398: end
# File lib/redcloth/textile.rb, line 313
313: def post_inline_textile_span( text )
314: QTAGS.each do |qtag_rc, ht, qtag_re, rtype, escaped_re|
315: text.gsub!( escaped_re ) do |m|
316:
317: case rtype
318: when :limit
319: sta,qtag,atts,cite,content = $~[1..5]
320: else
321: qtag,atts,cite,content = $~[1..4]
322: sta = ''
323: end
324: atts = pba( atts )
325: atts << " cite=\"#{ cite }\"" if cite
326:
327: "#{ sta }<#{ ht }#{ atts }>#{ content }</#{ ht }>"
328: end
329: end
330: end
# File lib/redcloth/textile.rb, line 350
350: def refs_textile( text )
351: text.gsub!( TEXTILE_REFS_RE ) do |m|
352: flag, url = $~[2..3]
353: @urlrefs[flag.downcase] = [url, nil]
354: nil
355: end
356: end
# File lib/redcloth/textile.rb, line 249
249: def textile_bq( tag, atts, cite, content )
250: cite, cite_title = check_refs( cite )
251: cite = " cite=\"#{ cite }\"" if cite
252: atts = shelve( atts ) if atts
253: "\t<blockquote#{ cite }>\n\t\t<p#{ atts }>#{ content }</p>\n\t</blockquote>"
254: end
# File lib/redcloth/textile.rb, line 275
275: def textile_ch( tag, atts, cite, content )
276: textile_p("h1", atts, cite, content)
277: end
# File lib/redcloth/textile.rb, line 268
268: def textile_fn_( tag, num, atts, cite, content )
269: atts << " id=\"fn#{ num }\""
270: content = "<sup>#{ num }</sup> #{ content }"
271: atts = shelve( atts ) if atts
272: "\t<p#{ atts }>#{ content }</p>"
273: end
# File lib/redcloth/textile.rb, line 256
256: def textile_p( tag, atts, cite, content )
257: atts = shelve( atts ) if atts
258: "\t<#{ tag }#{ atts }>#{ content }</#{ tag }>"
259: end
# File lib/redcloth/textile.rb, line 428
428: def textile_popup_help( name, windowW, windowH )
429: ' <a target="_blank" href="http://hobix.com/textile/#' + helpvar + '" onclick="window.open(this.href, \'popupwindow\', \'width=' + windowW + ',height=' + windowH + ',scrollbars,resizable\'); return false;">' + name + '</a><br />'
430: end
# File lib/redcloth/textile.rb, line 82
82: def textile_post_process(text)
83: post_inline_textile_span(text)
84: end
# File lib/redcloth/textile.rb, line 47
47: def textile_pre_process(text)
48: {'w' => 'warning', 'n' => 'note', 'c' => 'comment', 'pro' => 'production', 'dt' => 'dt', 'dd' => 'dd'}.each do |char, word|
49: parts = text.split(/^\s*#{char}\./)
50: text.replace(parts.first + "\n" + parts[1..-1].map do |part|
51: if part =~ /\.#{char}\s*$/
52: "div(#{word})." + part.sub(/\.#{char}\s*$/, "div(#{word}). \n")
53: else
54: "#{char}.#{part}"
55: end
56: end.join("\n"))
57:
58: self.class.class_eval %!
59: def textile_#{char}(tag, atts, cite, content)
60: textile_p('p', %{ class=#{word.inspect}}, cite, content)
61: end
62: !
63: end
64: {'bq' => 'blockquote'}.each do |char, word|
65: parts = text.split(/^\s*#{char}\./)
66: text.replace(parts.first + "\n" + parts[1..-1].map do |part|
67: if part =~ /\.#{char}\s*$/
68: "div(#{word})." + part.sub(/\.#{char}\s*$/, "div(#{word}). ")
69: else
70: "#{char}.#{part}"
71: end
72: end.join("\n"))
73: end
74:
75: text.gsub!( BACKTICK_CODE_RE ) do |m|
76: before,lang,code,after = $~[1..4]
77: lang = " lang=\"#{ lang }\"" if lang
78: rip_offtags( "#{ before }<pre><code#{ lang }>#{ code.gsub(/\\\`\`\`/,'```') }</code></pre>#{ after }" )
79: end
80: end