textile.rb

Path: lib/redcloth/textile.rb
Last Update: Thu Nov 09 13:58:32 UTC 2006

Required files

base  

Methods

Constants

TEXTILE_REFS_RE = /(^ *)\[([^\n\[]+?)\](#{HYPERLINK})(?=\s|$)/

Public Instance methods

Parses Textile definition lists and generates HTML

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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? ? "&nbsp;" : 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

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # File lib/redcloth/textile.rb, line 275
275:     def textile_ch( tag, atts, cite, content )
276:       textile_p("h1", atts, cite, content)
277:     end

[Source]

     # 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
textile_h1( tag, atts, cite, content )

Alias for textile_p

textile_h2( tag, atts, cite, content )

Alias for textile_p

textile_h3( tag, atts, cite, content )

Alias for textile_p

textile_h4( tag, atts, cite, content )

Alias for textile_p

textile_h5( tag, atts, cite, content )

Alias for textile_p

textile_h6( tag, atts, cite, content )

Alias for textile_p

[Source]

     # 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

[Source]

     # 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

[Source]

    # File lib/redcloth/textile.rb, line 82
82:     def textile_post_process(text)
83:       post_inline_textile_span(text)
84:     end

[Source]

    # 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

[Validate]