หน้าเว็บ

วันจันทร์ที่ 14 กันยายน พ.ศ. 2552

โค้ดสวยๆ ด้วย Syntax highlight

ผมคิดว่าหลายๆคนคงสงสัยสินะครับว่าโค้ดสีสวยที่เห็นผมเขียนลงในบล็อกนั้นมันทำยังไง
การทำโค้ดให้เป็นสีๆแบบนี้เค้าเรียกว่า Syntax highlight

ซึ่งเราสามารถหาเครื่องมือเพื่อช่วยทำ syntax highlight ได้ทั่วไปในเน็ทครับ
ตัวช่วยทำไฮไลท์ยอดนิยมที่เราน่าจะคุ้นๆ เห็นอยู่บ่อยๆก็มาจาก site นี้เลยครับ http://code.google.com/p/syntaxhighlighter/ ลองตามไปอ่านดูนะครับ tool ตัวนี้เป็น javascript

แต่

syntax highlight ที่ทุกท่านเห็นผมใช้ในบล็อกนี้นั้นไม่ได้ใช้ tool จาก link ข้างบนหรอกครับ
ผมใช้ tool อีกตัวที่เขียนด้วยภาษา Ruby ต่างหาก
เอาน่า ไหนๆบล็อกนี้ก็เขียนเกี่ยวกับ Ruby แล้ว Syntax Highlight จะทำจากภาษา Ruby ก็ไม่แปลกใช้ไหนครับ อิอิ

Tool ที่ผมใช้ทำไฮไลท์นั้นเป็นการนำไลบรารี่ gem ที่ชื่อ CodeRay มาใช้ครับ(เราเรียกไลบรารี่ที่ใช้ในภาษา Ruby ว่า gem ครับ) สำหรับ CodeRay เวอร์ชั่นล่าสุด(0.8.3)นั้นก็สามารถรองรับการทำ Syntax highlight ได้หลายภาษาทีเดียว แต่ก็ยังถือว่าไม่สมบูรณ์นักเพราะยังไม่รองรับภาษาที่ฮิตๆอย่าง C++, C#, PHP หรือ Perl ได้ แต่สำหรับการทำ highlight ให้กับโค้ดภาษาเช่น Ruby, Java, JavaScript, HTML หรือ CSS นั้นถือว่าสอบผ่านครับ
ไปดูวิธีเลยดีกว่าว่ามันใช้ยังไง

ติดตั้ง CodeRay ก่อน

เริ่มจากการดาวน์โหลดไลบรารี่ก่อนโดยเรียก Windows command prompt ขึ้นมา แล้วพิมพ์คำสั่งตามนี้
C:\> gem install coderay
เพื่อให้ RubyGem ทำการ download ไลบรารี่ CodeRay ให้โดยอัตโนมัติ เมื่อดาวน์โหลดแล้วก็จะได้ผลลัพธ์ประมาณนี้



พร้อมแล้วก็ Generate โค้ดเลย

ลองดูโค้ดตัวอย่างง่ายๆ สำหรับการสร้างโค้ดที่มีสีสันด้วย CodeRay ซึ่งผลลัพธ์ที่ออกมาจะอยู่ในรูปของ HTML โค้ดที่พร้อมให้เราเอาไปแปะไว้ในบล็อกได้ทันที

1
2
3
4
5
6
7
8
9
10
require 'rubygems'
require 'coderay'
 
my_code = <<-'CODE'
puts "Colorful your code with CodeRay"
3.times { puts "I'm hungry" }

CODE

tokens = CodeRay.scan(my_code, :ruby)
 
puts tokens.div(:line_numbers => :table, :css=> :class)


จากโค้ดตัวอย่าง บรรทัดที่ 1-2 เป็นการเรียกไลบรารีที่จำเป็นเข้ามาใช้ซึ่งในที่นี้คือไลบรารีที่ชื่อ rubygems และ coderay
ในขณะที่โค้ดในบรรทัดที่ 5-6 คือโค้ดต้นแบบที่เราต้องการ ซึ่งในตัวอย่างนี้โค้ดของเราเขียนอยู่ในรูปของ Here document(ครอบอยู่ในคีย์เวิร์ด 'CODE')และถูกนำไปเก็บไว้ในตัวแปร my_code อีกทีหนึ่ง
จากนั้นเราจะทำการแปรโค้ดตาม syntax ของภาษาต่างๆด้วยคลาสเมธอด scan ในบรรทัดที่ 8 ซึ่งผลของการแปลโค้ดทำให้เราได้อ็อบเจกต์ของ coderay ซึ่งจะถูกเก็บอยู่ในตัวแปร token

สุดท้ายเราจะนำเจ้าอ็อบเจกต์ token นี้มาแสดงผลลัพธ์ให้ออกมาเป็นโค้ด HTML โดยการเรียกใช้เมธอด div ในบรรทัดที่ 10
ซึ่งผลลัพธ์ที่ได้ก็จะเป็นโค้ดที่ทำ highlight เรียบร้อยสวยงามแต่มันจะอยู่ในรูปของ HTML โค้ดดังนี้
<table class="CodeRay"><tr><br /> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt><br /></tt>2<tt><br /></tt>3<tt><br /></tt>4<tt><br /></tt>5<tt><br /></tt>6<tt><br /></tt>7<tt><br /></tt>8<tt><br /></tt>9<tt><br /></tt><strong>10</strong><tt><br /></tt></pre></td><br /> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">'</span><span style="">rubygems</span><span style="color:#710">'</span></span><tt><br /></tt>require <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">'</span><span style="">coderay</span><span style="color:#710">'</span></span><tt><br /></tt><tt><br /></tt>my_code = <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">&lt;&lt;-'CODE'</span></span><span style="background-color:#fff0f0;color:#D20"><span style=""><tt><br /></tt> puts &quot;Colorful your code with CodeRay&quot;<tt><br /></tt> 3.times { puts &quot;I'm hungry&quot; }</span><span style="color:#710"><tt><br /></tt> CODE</span></span><tt><br /></tt>tokens = <span style="color:#036;font-weight:bold">CodeRay</span>.scan(my_code, <span style="color:#A60">:ruby</span>)<tt><br /></tt><tt><br /></tt>puts tokens.div(<span style="color:#A60">:line_numbers</span> =&gt; <span style="color:#A60">:table</span>, <span style="color:#A60">:css</span>=&gt; <span style="color:#A60">:class</span>)</pre></td><br /></tr></table>


ทดลองนำไปใช้กันดูนะครับ ไม่ยากเกินไปและสามารถนำไปใช้ประโยชน์ได้แน่นอน
CodeRay นั้นรองรับ

ทำ GUI เอาไว้ใช้เอง

แถมอีกนิดอ่ะครับ เนื่องจากผมเล็งเห็นแล้วว่าต้องใช้ CodeRay เพื่อทำ highlight ให้กับโค้ดแล้วนำลงบล็อกบ่อยแน่เลย
ดังนั้นผมจึงสร้าง GUI ง่ายๆ เพื่อใช้สำหรับ convert โค้ดต้นแบบให้เป็นโค้ด HTML ที่ทำผ่านการทำ highlight เรียบร้อยแล้วและพร้อมจะนำไปแปะบนบล็อกได้เลย ในที่นี้ผมจะใช้ไลบรารี gem อีกตัวหนึ่งคือ wxruby มาช่วยในการสร้าง GUI ซึ่งผมขออนุญาตข้ามในส่วนของรายละเอียดในการสร้าง GUI ด้วย wxruby ไปก่อนนะครับ ไว้จะมาเล่าให้ฟังในคราวต่อๆไป

เมื่อลงโค้ดจนได้ที่แล้ว เจ้า GUI ที่ใช้ทำ syntax highlight ของผมก็เลยมีหน้าตาแบบนี้ครับ



วิธีใช้ก็แค่นำโค้ดต้นแบบมาแปะลงใน text box ด้านซ้ายแล้วกดปุ่ม convert เราก็จะได้โค้ดที่ทำ highlight แล้วที่อยู่ในรูปของ HTML ครับ ซึ่งผมทำ option ให้เลือกได้ด้วยว่าจะทำ highlight เป็นภาษาอะไร