Thursday, 15 November 2012

New code colorizer

I recevied the requesto to use small code box in order to improve site readability, so I added the following code to CSS:

div.code {
resize:vertical;
}

and I modified the code colorer script this way:

REBOL [
    Title: "Color REBOL Code in HTML"
    Date: 8-Feb-2012
    File: %color-code.r
    Author: ["Carl Sassenrath" "Ross Gill" "Massimilano Vessi"]
    Purpose: {
        Colorize source code based on datatype.   Result is HTML a good <code> block.
        Works with R3        
    }
    version: 3.1.5
]
;colorize function
color-code: use [out emit emit-var rule value] [
    out: none
    envelop: func [data] [either block? data [data] [compose [(data)]]]
    emit: func [data] [data: reduce envelop data until [append out take data empty? data]]
    emit-var: func [value start stop /local type] [
        either none? :value [type: "cmt"] [
            if path? :value [value: first :value]
            type: either word? :value [
                any [
                    all [value? :value any-function? get :value "function"]
                    all [value? :value datatype? get :value "datatype"]
                ]
            ] [
                any [replace to-string type?/word :value "!" ""]
            ]
        ]
        either type [; (Done this way so script can color itself.)
            emit ["-[" {-var class="dt-} type {"-} "]-"
                copy/part start stop "-[" "-/var-" "]-"]
        ] [emit copy/part start stop ]
    ]
    rule: use [str new] [
        [
            some [
                str:
                some [" " | tab] new: (emit copy/part str new) |
                newline (emit "^/") |
                #";" [thru newline | to end] new:
                (emit-var none str new) |
                [#"[" | #"("] (emit first str) rule |
                [#"]" | #")"] (emit first str) break |
                skip (
                    set [value new] load/next str
                    emit-var :value str new
                ) :new
            ]
        ]
    ]
   
    func [
        "Return color source code as HTML."
        text [string!] "Source code text"
        /br "Add <br> tag."
        /hd "Add rebol header"
        /resize "Insert code in a resizable DIV"
    ] [
        if hd [insert text "Rebol[]" ]
        append text "^/" ;avoid errors  
        if   resize [
            resize: false
            count: 0
            text-t: copy text
            while [text-t: find/tail text-t newline] [count: count + 1]
            if count > 30 [resize:   true ]
            ]  
           
        ;these put on one line all simple code, to enhance readability
        tutto: copy " "
        appendi: func [temp] [if temp [append tutto temp ] ]
        veryclean-script: func [temp ] [
            either   (parse temp [ "^/" thru "^/" end ]   ) [appendi   replace/all   (trim temp)   "^/"   " " ] [appendi temp]    
            ]      
        parse text [
            some [ copy temp3   thru "[" (appendi temp3   )   copy temp   to   "]"   (if temp [veryclean-script temp])   ]  
            copy temp2   to end   (appendi temp2)
            ]  
        text: copy tutto    
        ;here start rebol to html converter
        out: make binary! 3 * length? text
        set [value text] load/next/header detab text        
        emit copy/part head text text
        parse/all text rule
        out: to-string out
        foreach [from to] reduce [; (join avoids the pattern)
            "&" "&amp;" "<" "&lt;" ">" "&gt;"
            join "-[" "-" "<" join "-" "]-" ">"
        ] [replace/all out from to ]
        if hd [remove/part out 9 ]      
        while [find out "^/^/"] [replace/all out "^/^/" "^/"] ;removing empty lines
        insert out {<code class="rebol-script">}
        append out {</code>}
        replace/all out "   "   " &nbsp;   "      
        if br [replace/all out "^/"   " <br>^/   "]   ; if you can't see new lines
        if resize [
            insert out   {<div class=code style="width:100%;height:400px;overflow-y: scroll; border:1px solid grey;">}
            append out "</div>"
            ]
        return out
    ]
]
;GUI
view layout [
    across
    a: area 500x400
    return
    b: check false
    text "Add <br> tags"
    c: check false
    text "Add rebol header"
    d: check true
    text "Resizable"
    return
    button 80x35 "Convert in HTML" [
        temp2: copy "a/text: color-code"        
        if b/data [append temp2 "/br"]
        if c/data [append temp2 "/hd"]
        if d/data [append temp2 "/resize"]
        append temp2 " a/text"
        do temp2        
        show a
        write clipboard://   a/text
        ]
    text italic 300 {It automatically copy to clipboard, but you can use CTRL+C to copy, CTRL+V to paste, CTRL+A to select all, and more...}
    return
    button "CLEAR" [a/text: none
        show a
        focus a
        ]
    ]

code box is resizable, so you can expand it.
What do you think? Do you like this blog change?
Let me know in the comments.

1 comment: