Path: | lib/redcloth/textile.rb |
Last Update: | Sun Oct 15 16:19:38 +0100 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