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&#8217;\2' ], # single closing        [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1&#8217;' ], # single closing        [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '&#8217;' ], # single closing        [ /\'/, '&#8216;' ], # single opening        [ /</, '&lt;' ], # less-than        [ />/, '&gt;' ], # greater-than    #   [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing        [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1&#8221;' ], # double closing        [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '&#8221;' ], # double closing        [ /"/, '&#8220;' ], # double opening        [ /\b( )?\.{3}/, '\1&#8230;' ], # 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&#8212;' ], # em dash        [ /\s->\s/, ' &rarr; ' ], # right arrow        [ /\s-\s/, ' &#8211; ' ], # en dash        [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign        [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark        [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered        [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright    ]    H_ALGN_VALS = {        '<' => 'left',        '=' => 'center',        '>' => 'right',        '<>' => 'justify'    }    V_ALGN_VALS = {        '^' => 'top',        '-' => 'middle',        '~' => 'bottom'    }    #    # Flexible HTML escaping    #    def htmlesc( str, mode )        str.gsub!( '&', '&amp;' )        str.gsub!( '"', '&quot;' ) if mode != :NoQuotes        str.gsub!( "'", '&#039;' ) if mode == :Quotes        str.gsub!( '<', '&lt;')        str.gsub!( '>', '&gt;')    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 + -
显示快捷键?