December 27, 2012

在 Blogger 貼上程式碼

在 blogger/blogspot 想要貼程式碼並且提供比較清晰的外觀,之前找到的方法不外乎幾種
  1. 把程式碼貼到一些 formatting tool,把程式碼轉成帶有顏色的 html code 之後再貼回 blogger
  2. 把 javascript 檔放到另外一個 host,開啟網頁的時候載入 js 檔對 source code 做修改
第一個方法我不是很喜歡,文章的原始檔變成一堆 html code 完全看不出文意。第二個方法比較貼近我的需求,可惜要額外載入一些 js 檔,我希望盡量保持簡單。

恰好最近學了一點點 js,自己動手做很簡單的 pretty code。先定義幾個 css 格式,網頁下載完成之後,透過 javascript 對於帶有 code 類別的 pre 區塊做修改。

修改的邏輯也很簡單,僅僅只是用 regular expression 找出一些定義好的字串上點顏色罷了。我也不常貼上太多程式碼,因此正規表示式沒有寫得很認真,剛好我夠用而已。

使用方法

貼上程式碼的時候為 pre 加上類別 code 即可,好比
<pre class="code">
int main(void) {
    printf("blah\n"); 
}
</pre>

會變成
int main(void) {
    printf("blah\n")
}

設定方法

打開 blogspot 的設計,直接編輯 html,在 css 的部份加上這一塊

pre {
margin: 5px 20px;
border: 1px dashed #666;
padding: 5px;
color: #000;
background: #f8f8f8;
white-space: pre-wrap;       /* css-3 */
white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
white-space: -pre-wrap;      /* Opera 4-6 */
white-space: -o-pre-wrap;    /* Opera 7 */
word-wrap: break-word;       /* Internet Explorer 5.5+ */
}
span.control{
font-weight: bold;
color: #A00;
}
span.type {
font-weight: bold;
color: #0A0;
}
span.literal {
color: #00C;
}
span.comment {
font-weight: bold;
color: #AAA;
}

接下來找到 javascript 的區塊貼上程式碼,請注意「這一塊不能直接貼上」,這邊是看網頁原始碼的時候看到的結果。真正要貼上的是底下那一塊

onload = function () {
    var elmts,
        count = 0,
        regLiteral = /(('.*?'|".*?"))/g, // 'foo' or "foo"
        regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
        regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
        regClearCmt = /(\/\*.*?)()(.*?)(<\/span>)/g,
        regClearCmts = /(\/\/.*?)()(.*?)(<\/span>)/g,
        regCmtsStart = /\/\*/g, //for /*
        regCmtsEnd = /\*\//g,   //for  */
        regCmt = /\/\/(.*)/g,   //for  //

        replaceLtGt = function (pre) {
            var text = pre.innerHTML;
            // <a> to &lt;a&gt;
            pre.innerHTML = text.replace(/<(.+?)>/gi, "<$1>");
        },

        setColor = function (pre) {
            var text = pre.innerHTML;

            text = text.replace(regLiteral, "$1");
            text = text.replace(regType, "$1$2$3");
            text = text.replace(regControl, "$1$2$3");
            text = text.replace(regClearCmt, "$1$3");
            text = text.replace(regClearCmts, "$1$3");
            text = text.replace(regCmtsStart, "/*");
            text = text.replace(regCmtsEnd, "*/");
            text = text.replace(regCmt, "//$1");
            pre.innerHTML = text;
        };

    elmts = document.querySelectorAll("pre.code"),
    count = elmts && elmts.length;
    while (count > 0) {
        count--;
        replaceLtGt(elmts[count]);
        setColor(elmts[count]);
    }
};


因為貼上的對象是 blogger 的 template,因此要把 & 或 < 或 > 再做一次轉換,實際上真正要貼進 blogger 的 js code 是這一段(看不懂了吧!所以我才要先貼上面比較有人性的部份XD)

onload = function () {
    var elmts,
        count = 0,
        regLiteral = /((&#39;.*?&#39;|&quot;.*?&quot;))/g, // &#39;foo&#39; or &quot;foo&quot;
        regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
        regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
        regClearCmt = /(\/\*.*?)(&lt;span class=&quot;.*?&quot;&gt;)(.*?)(&lt;\/span&gt;)/g,
        regClearCmts = /(\/\/.*?)(&lt;span class=&quot;.*?&quot;&gt;)(.*?)(&lt;\/span&gt;)/g,
        regCmtsStart = /\/\*/g, //for /*
        regCmtsEnd = /\*\//g,   //for  */
        regCmt = /\/\/(.*)/g,   //for  //

        replaceLtGt = function (pre) {
            var text = pre.innerHTML;
            // &lt;a&gt; to &amp;lt;a&amp;gt;
            pre.innerHTML = text.replace(/&lt;(.+?)&gt;/gi, &quot;&amp;lt;$1&amp;gt;&quot;);
        },

        setColor = function (pre) {
            var text = pre.innerHTML;

            text = text.replace(regLiteral, &quot;&lt;span class=\&quot;literal\&quot;&gt;$1&lt;/span&gt;&quot;);
            text = text.replace(regType, &quot;$1&lt;span class=\&quot;type\&quot;&gt;$2&lt;/span&gt;$3&quot;);
            text = text.replace(regControl, &quot;$1&lt;span class=\&quot;control\&quot;&gt;$2&lt;/span&gt;$3&quot;);
            text = text.replace(regClearCmt, &quot;$1$3&quot;);
            text = text.replace(regClearCmts, &quot;$1$3&quot;);
            text = text.replace(regCmtsStart, &quot;&lt;span class=\&quot;comment\&quot;&gt;/*&quot;);
            text = text.replace(regCmtsEnd, &quot;*/&lt;/span&gt;&quot;);
            text = text.replace(regCmt, &quot;&lt;span class=\&quot;comment\&quot;&gt;//$1&lt;/span&gt;&quot;);
            pre.innerHTML = text;
        };

    elmts = document.querySelectorAll(&quot;pre.code&quot;),
    count = elmts &amp;&amp; elmts.length;
    while (count &gt; 0) {
        count--;
        replaceLtGt(elmts[count]);
        setColor(elmts[count]);
    }

};
要把「貼上 template 的醜陋內容再轉一次變成能夠貼上 blog 文章」這樣轉來轉去自己都快被搞混了,希望我沒有貼錯

No comments:

Post a Comment