Sunday, June 19, 2005

ใช้ jEdit ช่วยทำ Source Highlighting #2

วิธีการเขียน jEdit Plugin ก็คือ
เริ่มต้นที่ Plugin Core Class โดยเขียนง่ายๆดังนี้

package highlight;

public class HighlightPlugin extends EditPlugin {
public void start() {
}

public void stop() {
}

}

ในส่วน start กับ stop ใช้ในการเตรียม resources
ต่างๆที่ plugin จะใช้
ในกรณีของเราไม่ต้องการทำอะไรก็เลยเว้นไว้

จากนั้นก็ทำการเขียน plugin properties file
โดยมีชื่อเดียวกับ plugin class แต่ตัด word "Plugin"
ที่ต่อท้ายออก ในกรณีนี้ใช้ชื่อว่า Highlight.props

plugin.highlight.HighlightPlugin.activate=defer
plugin.highlight.HighlightPlugin.name=HighLight
plugin.highlight.HighlightPlugin.author=pphetra
plugin.highlight.HighlightPlugin.version=0.1
plugin.highlight.HighlightPlugin.depend.0=jedit 04.00.03.00

# Menu
plugin.highlight.HighlightPlugin.menu=highlight.convert

# Menu action labels
highlight.convert.label=convert to clipboard


ในตัว props จะประกอบด้วย 2 ส่วนคือ
ส่วน metadata กับส่วน menu
"highlight.convert" ก็คือ menuItem
ที่จะ add เข้าไปใน Plugin Menu

โดย ค่าของ plugin.highlight.HighLightPlugin.menu
มีความหมายว่า
  • ให้ add menu ที่มี label เป็นชื่อเดียวกับ Plugin Name เข้าไปใต้
    Plugins Menu
  • add menuItem ที่ชื่อ highlight.convert
    เข้าเป็น menuItem ของ menu ข้างบน


ส่วนกรณีที่มี submenu หลายๆอัน ก็แค่ใส่เรียงกันไป
เหมือนตามตัวอย่างข้างล่างนี้

plugin.highlight.HighLightPlugin.menu=highlight.current-buffer highlight.current
-selection highlight.dump

# Menu action labels
highlight.current-buffer.label=Current buffer
highlight.current-selection.label=Current selection
highlight.dump.label=dump


จากนั้นก็เขียน action mapping file
ที่ชื่อ actions.xml

<?xml version="1.0"?>
<!DOCTYPE ACTIONS SYSTEM "actions.dtd">
<ACTIONS>
<ACTION NAME="highlight.convert">
<CODE>
plugin = org.gjt.sp.jedit.jEdit.getPlugin("highlight.HighLightPlugin"
, true);
plugin.convert(textArea, view);
</CODE>
</ACTION>
</ACTIONS>

หลักการของ file นี้ก็คือ เราจะกำหนดว่า
เมื่อ action ถูก trig ให้ทำงาน
จะต้องทำงานอะไร
ซึ่งการสั่งว่าต้องทำงานอะไรนั้น จะใช้ BeanShell script
สำหรับในตัวอย่างนี้ กรณีที่ action highlight.convert
ถูกเรียกใช้ ก็จะทำการเรียกใช้
method convert ใน HighlightPlugin ของเรา

เพิ่ม method convert(..) เข้าไปใน HighlightPlugin ของเราดังนี้

public void dump(JEditTextArea textArea, View view) {
Selection[] selection = textArea.getSelection();
StringWriter sw = new StringWriter();
BufferedWriter out = new BufferedWriter(sw);

int last = 0;
for (int i = 0; i < selection.length; i++) {
if (selection[i].getEndLine() > last) {
last = selection[i].getEndLine();
}
}

// Sort selections by their start lines
MiscUtilities.quicksort(selection, new SelectionStartLineCompare());
int lastLine = -1;
for (int i = 0; i < selection.length; i++) {
int physicalFirst = selection[i].getStartLine();
int physicalLast = selection[i].getEndLine();

if (physicalLast <= lastLine) {
continue;
}

formatText(out, textArea, Math.max(physicalFirst, lastLine + 1),
physicalLast);

lastLine = physicalLast;
}
try {
out.flush();
out.close();
} catch (IOException io) {

}

Registers.setRegister('$', sw.toString());
}

จะเห็นว่าใน source code มีการทำ sorting ด้วย
เนื่องจาก jEdit สามารถทำ multiple selections ได้
จึงต้องจัดเรียงลำดับ block ให้ถูกต้องก่อน
จากนั้นก็ใล่ loop เพื่อทำการ format
แต่ละ block ให้เป็น html

ในการ convert เป็น html นั้น เราจะใช้
feature ของ jedit ในส่วนของ syntax highlighting เอง
โดยเราสามารถ access SyntaxStyle จาก JEditTextArea ได้
ซึ่ง jedit กำหนดไว้ว่า แต่ละภาษา
สามารถ config Token type ได้สูงสุด 18 แบบ
โดยวิธีกำหนด style ของแต่ละ syntax สามารถดูได้จาก
link นี้

source code ในส่วนที่แปลงเป็น html
ไม่ได้ลงไว้ให้ดูครับ เนื่องจากมันค่อนข้างยาว
ผู้ที่สนใจสามารถ download Code2HTML plugin
มาดูเป็นตัวอย่างได้

Related link from Roti

No comments: