redcloth.rb
来自「用ruby on rails写的一个博客程序,还不错..ruby on rail」· RB 代码 · 共 1,131 行 · 第 1/3 页
RB
1,131 行
/(\W) (#{rcq}) (#{C}) (?::(\S+?))? (\S.*?\S|\S) #{rcq} (?=\W)/x else /(#{rcq}) (#{C}) (?::(\S+))? (\S.*?\S|\S) #{rcq}/xm end [rc, ht, re, rtype] end # Elements to handle GLYPHS = [ # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing [ /\'/, '‘' ], # single opening [ /</, '<' ], # less-than [ />/, '>' ], # greater-than # [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing [ /"/, '“' ], # double opening [ /\b( )?\.{3}/, '\1…' ], # ellipsis [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym [ /(^|[^"][>\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 [ /(\.\s)?\s?--\s?/, '\1—' ], # em dash [ /\s->\s/, ' → ' ], # right arrow [ /\s-\s/, ' – ' ], # en dash [ /(\d+) ?x ?(\d+)/, '\1×\2' ], # dimension sign [ /\b ?[(\[]TM[\])]/i, '™' ], # trademark [ /\b ?[(\[]R[\])]/i, '®' ], # registered [ /\b ?[(\[]C[\])]/i, '©' ] # copyright ] H_ALGN_VALS = { '<' => 'left', '=' => 'center', '>' => 'right', '<>' => 'justify' } V_ALGN_VALS = { '^' => 'top', '-' => 'middle', '~' => 'bottom' } # # Flexible HTML escaping # def htmlesc( str, mode ) str.gsub!( '&', '&' ) str.gsub!( '"', '"' ) if mode != :NoQuotes str.gsub!( "'", ''' ) if mode == :Quotes str.gsub!( '<', '<') str.gsub!( '>', '>') end # Search and replace for Textile glyphs (quotes, dashes, other symbols) def pgl( text ) GLYPHS.each do |re, resub, tog| next if tog and method( tog ).call text.gsub! re, resub end end # Parses Textile attribute lists and builds an HTML attribute string def pba( text_in, element = "" ) return '' unless text_in style = [] text = text_in.dup if element == 'td' colspan = $1 if text =~ /\\(\d+)/ rowspan = $1 if text =~ /\/(\d+)/ style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN end style << "#{ $1 };" if not filter_styles and text.sub!( /\{([^}]*)\}/, '' ) lang = $1 if text.sub!( /\[([^)]+?)\]/, '' ) cls = $1 if text.sub!( /\(([^()]+?)\)/, '' ) style << "padding-left:#{ $1.length }em;" if text.sub!( /([(]+)/, '' ) style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' ) style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/ atts = '' atts << " style=\"#{ style.join }\"" unless style.empty? atts << " class=\"#{ cls }\"" unless cls.to_s.empty? atts << " lang=\"#{ lang }\"" if lang atts << " id=\"#{ id }\"" if id atts << " colspan=\"#{ colspan }\"" if colspan atts << " rowspan=\"#{ rowspan }\"" if rowspan atts end TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m # Parses a Textile table block, building HTML from the result. def block_textile_table( text ) text.gsub!( TABLE_RE ) do |matches| tatts, fullrow = $~[1..2] tatts = pba( tatts, 'table' ) tatts = shelve( tatts ) if tatts rows = [] fullrow. split( /\|$/m ). delete_if { |x| x.empty? }. each do |row| ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m cells = [] row.split( '|' ).each do |cell| ctyp = 'd' ctyp = 'h' if cell =~ /^_/ catts = '' catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. ?)(.*)/ unless cell.strip.empty? catts = shelve( catts ) if catts cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell }</t#{ ctyp }>" end end ratts = shelve( ratts ) if ratts rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>" end "\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n" end end LISTS_RE = /^([#*]+?#{C} .*?)$(?![^#*])/m LISTS_CONTENT_RE = /^([#*]+)(#{A}#{C}) (.*)$/m # Parses Textile lists and generates HTML def block_textile_lists( text ) text.gsub!( LISTS_RE ) do |match| lines = match.split( /\n/ ) last_line = -1 depth = [] lines.each_with_index do |line, line_id| if line =~ LISTS_CONTENT_RE tl,atts,content = $~[1..3] if depth.last if depth.last.length > tl.length (depth.length - 1).downto(0) do |i| break if depth[i].length == tl.length lines[line_id - 1] << "</li>\n\t</#{ lT( depth[i] ) }l>\n\t" depth.pop end end if depth.last and depth.last.length == tl.length lines[line_id - 1] << '</li>' end end unless depth.last == tl depth << tl atts = pba( atts ) atts = shelve( atts ) if atts lines[line_id] = "\t<#{ lT(tl) }l#{ atts }>\n\t<li>#{ content }" else lines[line_id] = "\t\t<li>#{ content }" end last_line = line_id else last_line = line_id end if line_id - last_line > 1 or line_id == lines.length - 1 depth.delete_if do |v| lines[last_line] << "</li>\n\t</#{ lT( v ) }l>" end end end lines.join( "\n" ) end end CODE_RE = /(\W) @ (?:\|(\w+?)\|)? (.+?) @ (?=\W)/x def inline_textile_code( text ) text.gsub!( CODE_RE ) do |m| before,lang,code,after = $~[1..4] lang = " lang=\"#{ lang }\"" if lang rip_offtags( "#{ before }<code#{ lang }>#{ code }</code>#{ after }" ) end end def lT( text ) text =~ /\#$/ ? 'o' : 'u' end def hard_break( text ) text.gsub!( /(.)\n(?!\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks end BLOCKS_GROUP_RE = /\n{2,}(?! )/m def blocks( text, deep_code = false ) text.replace( text.split( BLOCKS_GROUP_RE ).collect do |blk| plain = blk !~ /\A[#*> ]/ # skip blocks that are complex HTML if blk =~ /^<\/?(\w+).*>/ and not SIMPLE_HTML_TAGS.include? $1 blk else # search for indentation levels blk.strip! if blk.empty? blk else code_blk = nil blk.gsub!( /((?:\n(?:\n^ +[^\n]*)+)+)/m ) do |iblk| flush_left iblk blocks iblk, plain iblk.gsub( /^(\S)/, "\t\\1" ) if plain code_blk = iblk; "" else iblk end end block_applied = 0 @rules.each do |rule_name| block_applied += 1 if ( rule_name.to_s.match /^block_/ and method( rule_name ).call( blk ) ) end if block_applied.zero? if deep_code blk = "\t<pre><code>#{ blk }</code></pre>" else blk = "\t<p>#{ blk }</p>" end end # hard_break blk blk + "\n#{ code_blk }" end end end.join( "\n\n" ) ) end def textile_bq( tag, atts, cite, content ) cite, cite_title = check_refs( cite ) cite = " cite=\"#{ cite }\"" if cite atts = shelve( atts ) if atts "\t<blockquote#{ cite }>\n\t\t<p#{ atts }>#{ content }</p>\n\t</blockquote>" end def textile_p( tag, atts, cite, content ) atts = shelve( atts ) if atts "\t<#{ tag }#{ atts }>#{ content }</#{ tag }>" end alias textile_h1 textile_p alias textile_h2 textile_p alias textile_h3 textile_p alias textile_h4 textile_p alias textile_h5 textile_p alias textile_h6 textile_p def textile_fn_( tag, num, atts, cite, content ) atts << " id=\"fn#{ num }\"" content = "<sup>#{ num }</sup> #{ content }" atts = shelve( atts ) if atts "\t<p#{ atts }>#{ content }</p>" end BLOCK_RE = /^(([a-z]+)(\d*))(#{A}#{C})\.(?::(\S+))? (.*)$/m def block_textile_prefix( text ) if text =~ BLOCK_RE tag,tagpre,num,atts,cite,content = $~[1..6] atts = pba( atts ) # pass to prefix handler if respond_to? "textile_#{ tag }", true text.gsub!( $&, method( "textile_#{ tag }" ).call( tag, atts, cite, content ) ) elsif respond_to? "textile_#{ tagpre }_", true text.gsub!( $&, method( "textile_#{ tagpre }_" ).call( tagpre, num, atts, cite, content ) ) end end end SETEXT_RE = /\A(.+?)\n([=-])[=-]* *$/m def block_markdown_setext( text ) if text =~ SETEXT_RE tag = if $2 == "="; "h1"; else; "h2"; end blk, cont = "<#{ tag }>#{ $1 }</#{ tag }>", $' blocks cont text.replace( blk + cont ) end end ATX_RE = /\A(\#{1,6}) # $1 = string of #'s [ ]* (.+?) # $2 = Header text [ ]* \#* # optional closing #'s (not counted) $/x def block_markdown_atx( text ) if text =~ ATX_RE tag = "h#{ $1.length }" blk, cont = "<#{ tag }>#{ $2 }</#{ tag }>\n\n", $' blocks cont text.replace( blk + cont ) end end MARKDOWN_BQ_RE = /\A(^ *> ?.+$(.+\n)*\n*)+/m def block_markdown_bq( text ) text.gsub!( MARKDOWN_BQ_RE ) do |blk| blk.gsub!( /^ *> ?/, '' ) flush_left blk blocks blk blk.gsub!( /^(\S)/, "\t\\1" ) "<blockquote>\n#{ blk }\n</blockquote>\n\n" end end MARKDOWN_RULE_RE = /^(#{ ['*', '-', '_'].collect { |ch| '( ?' + Regexp::quote( ch ) + ' ?){3,}' }.join( '|' ) })$/ def block_markdown_rule( text ) text.gsub!( MARKDOWN_RULE_RE ) do |blk| "<hr />" end end # XXX TODO XXX def block_markdown_lists( text ) end def inline_textile_span( text ) QTAGS.each do |qtag_rc, ht, qtag_re, rtype| text.gsub!( qtag_re ) do |m| case rtype when :limit sta,qtag,atts,cite,content = $~[1..5] else qtag,atts,cite,content = $~[1..4] sta = '' end atts = pba( atts ) atts << " cite=\"#{ cite }\"" if cite atts = shelve( atts ) if atts
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?