Theppitak's blog

My personal blog.

23 สิงหาคม 2561

LibThai 0.1.28 and its Consequences

บันทึกการเปลี่ยนแปลงต่าง ๆ ที่มาใน LibThai 0.1.28 และผลพวงทั้งหลายหลังจากนั้น

LibThai 0.1.28 ออกไปตั้งแต่ต้นเดือน โดยรุ่นนี้มีรายการเปลี่ยนแปลงสำคัญ ๆ คือ:

  • แก้ปัญหาขาด header <thai/thwchar.h> ใน header ที่เกี่ยวกับฟังก์ชัน wide char หลาย ๆ ตัว เช่น thwbrk.h, thwcoll.h ฯลฯ ซึ่งเป็นปัญหาที่พบระหว่างเขียนโปรแกรมตัวหนึ่งที่เรียกใช้ libthai ทำให้ต้อง include thai/thwchar.h เอง ซึ่งไม่สะดวก ในรุ่นนี้สามารถ include header ที่ต้องการแล้วเรียกใช้งานได้เลย ไม่ต้องเพิ่ม include เองอีกแล้ว
  • ปรับโค้ดให้เป็นไปตาม C90 (ANSI C) มากขึ้น เป็นผลพวงจากที่ได้ทำกับ libdatrie 0.2.12 มาแล้ว
  • ปรับข้อมูลพจนานุกรมตัดคำ โดยในรุ่นนี้ได้รับความช่วยเหลือจากคุณ @nuttee15 จาก metamedia technology ที่ได้เสนอคำเพิ่มเข้ามาใน Issue #2 ที่เปิดไว้รับเสนอคำใหม่ในพจนานุกรมตัดคำ

จากนั้นก็ได้ upload debian package พร้อมความเปลี่ยนแปลงอย่างอื่น คือ เพิ่ม pkg-config ให้เป็น dependency ของ libthai-dev เพื่อให้แน่ใจว่า libthai.pc จะสามารถทำงานได้แม้ในระบบที่ติดตั้งแบบเล็กที่สุด (เป็นปัญหาที่พบระหว่างที่ทำงานชิ้นหนึ่งร่วมกับ metamedia technology) และ การรองรับการ build ที่ไม่ต้องใช้ (fake)root

รายการคำจากพจนานุกรมตัดคำของ libthai ก็ได้นำไปใช้ สร้าง hyphenation pattern ที่โครงการ thailatex ซึ่งขณะนี้กลายสภาพเป็นเพียงที่พักงานพัฒนา hyphenation pattern เท่านั้น จากนั้นจึงได้เสนอ pull request สำหรับ update hyphenation pattern สำหรับภาษาไทยในโครงการ TeX hyphenation patterns ซึ่งต้องรอการ merge เพื่อให้มีผลที่ต้นน้ำต่อไป

จาก TeX hyphenation pattern ก็ต้อง sync มายังเครื่องมือตัดคำสำหรับเอกสาร LaTeX ด้วย คือ swath ซึ่งนอกจากการปรับพจนานุกรมแล้ว ก็ได้ปรับโค้ดเล็ก ๆ น้อย ๆ ตามที่เคยทำในทุกรุ่นที่ผ่านมา โดยสิ่งที่ทำในรุ่นนี้คือ:

  • ทดลอง build โดยใช้ CFLAGS -Wall แล้วแก้ warning ต่าง ๆ
  • จากการแก้ warning ที่พบในโค้ดส่วน RTF filter ทำให้ตรวจพบความผิดปกติใน method หนึ่งที่ตัวฟังก์ชันทำงานตรงข้ามกับชื่อ คือ RTFToken::isEmpty()

    โค้ดส่วนจัดการ RTF นี้ ไม่ค่อยมีใครเรียกใช้ ความจริงผมเคยเสนอจะตัดทิ้งไปแล้ว แต่ด้วยความช่วยเหลือของคนในชุมชน (คุณวิทยา ไตรสารวัฒนะ) ทำให้ได้วิธีทดสอบความถูกต้องของโปรแกรม จึงยังคงเก็บไว้ แต่เนื่องจากเวลานั้น swath ยังไม่เริ่มทำ TDD จึงยังไม่ได้ใส่ test case ไว้ใน source tree

    เพื่อจะตรวจแก้ฟังก์ชันที่สงสัยนี้ ผมจึงต้องไปดึงเอกสารตัวอย่างมาจาก thread เก่าที่ว่า แล้วนำมา เพิ่ม test case เสียก่อน หากคุณสงสัยว่าทำไม source tarball ของ swath รุ่นนี้ถึงโตขึ้นจนผิดสังเกต มันก็มาจากเอกสาร RTF ทดสอบนี้นี่เอง

    จากนั้น จึงได้ แก้ฟังก์ชันที่สงสัย นั้น แล้วรัน test เปรียบเทียบ output ดูโดยใช้ LibreOffice ปรากฏว่าเป็นการแก้ที่ถูกต้องแล้ว เพราะมันทำให้ได้จุดตัดคำครบถ้วนสมบูรณ์ขึ้น

    ไม่ว่าจะมีใครใช้หรือไม่ก็ตาม แต่คอมไพเลอร์ยังคงคอมไพล์มันอยู่ และนำผมเข้ามาเจอและแก้บั๊กจนได้

  • แก้ warning อื่น ๆ และทำความสะอาดโค้ดเล็ก ๆ น้อย ๆ
  • สุดท้าย มี pull request ของคุณ @pepa65 ที่เสนอไว้นานแล้ว เพื่อร่างแฟ้ม INSTALL ที่อธิบายความแตกต่างของวิธี build swath จาก git กับจาก released tarball ซึ่งผมก็เห็นว่ามีประโยชน์กว่าแฟ้ม INSTALL ที่ GNU automake มันเติมให้แบบอัตโนมัติ จึง merge เข้ามาเสีย

แล้วก็ออกรุ่น swath 0.6.1 ตามมาด้วย Debian upload ซึ่งก่อนอัปโหลดก็ได้ปรับ branch layout ของ swath packaging ตาม DEP-14 ด้วย

ป้ายกำกับ: , ,

01 ธันวาคม 2560

swath 0.6.0

swath 0.6.0 ออกแล้วเมื่อวันก่อน โดยมีลำดับความต่อเนื่องนับจากการปรับพจนานุกรมใน libthai 0.1.27 ดังนี้:

แต่การปรับพจนานุกรมตัดคำก็เป็นแค่น้ำจิ้มสำหรับ swath รุ่นนี้ เพราะมีการปรับซอร์สโค้ดตามที่เคยทำมาต่อไป โดยในครั้งนี้เป็นครั้งแรกที่ล้วงเข้าไปปรับกลไกภายในของการตัดคำ หลังจากที่รุ่นก่อน ๆ ทำแค่ส่วน command line parsing และ input/output filter ต่าง ๆ เท่านั้น

สรุปความเปลี่ยนแปลงที่สำคัญคือ

  • ตัดตัวเลือก -l ซึ่งไม่มีเอกสารอธิบายว่าเอาไว้ทำอะไร
  • refactor dictionary ออกจากตัวตัดคำ ทำให้แยก lifetime ของพจนานุกรมออกจากตัวตัดคำ ซึ่งในอนาคตอาจเรียกตัวตัดคำซ้ำหลายครั้งได้โดยไม่ต้องเปิด dictionary ใหม่ หรือสามารถเรียกตัวตัดคำตัวเดิมซ้ำโดยเปลี่ยน dictionary ได้ เป็นต้น
  • simplify โค้ดของตัวตัดคำให้เข้าใจง่าย ลดความซับซ้อน ตัดส่วนที่ไม่จำเป็น รวมส่วนที่สามารถรวมได้
  • แก้ไขการทำงานของ longest matching scheme ที่เดิมทำงานไม่ถูกต้อง เพราะโค้ดทำงานง่ายเกินเหตุ ไม่มีการ backtrack ทำให้ได้คำตอบผิดพลาดในบางกรณี ในรุ่นนี้ได้แก้ให้ทำงานถูกต้องแล้ว (พร้อม test case สำหรับยืนยัน)
  • จัดระเบียบโค้ดยิบย่อยเพื่อความเป็นระเบียบ (ยังเหลือให้ปรับได้อีกในรุ่นถัด ๆ ไป)
  • ปรับแก้การใช้คำพูดใน manpage พร้อมกับการอ้างถึงโปรแกรม trietool ของ libdatrie แทน trietool-0.2 ซึ่งเป็นชื่อเก่า

ด้วยความเปลี่ยนแปลงขนานใหญ่ในกลไกภายใน จึงได้ปรับเลข minor version แทนที่จะปรับแค่ micro version โดยเปลี่ยนจากซีรีส์ 0.5.x ขึ้นเป็น 0.6.0

ในส่วนของ Debian upload ก็ได้เพิ่ม test suite สำหรับ autopkgtest ในทำนองเดียวกับ libthai ด้วย

ป้ายกำกับ:

02 กันยายน 2557

swath 0.5.3

swath 0.5.3 ออกแล้วเมื่อวานนี้ รุ่นนี้เป็นการปรับพจนานุกรมตามหลัง การอัปเดต TeX hyphenation pattern ซึ่งปรับตามพจนานุกรมของ LibThai 0.1.21 อีกทอดหนึ่ง แต่พร้อมกันนี้ก็มีการเปลี่ยนแปลงอย่างอื่นที่น่าสนใจด้วย

คุณ +Sorawee Porncharoenwase รายงานมาใน Google+ ส่วนตัวว่าพบบั๊ก 2 ตัวใน swath เมื่อใช้งานกับ plain text:

  • เมื่อป้อนข้อความ UTF-8 ยาว ๆ ผ่านคำสั่ง swath -u u,u ปรากฏว่าข้อความจะถูกตัดท้ายก่อนจบ
  • swath ทะลึ่งไปแทรกรหัสตัดคำในภาษาอังกฤษและหลังเครื่องหมายวรรคตอนบางตัวในโซนภาษาไทยด้วย เช่น:
    hello (|world)
    สวัสดี (|ครับ|)
    

บั๊กแรกนั้น ความจริง swath จองที่ไว้สำหรับบรรทัดยาวถึง 2000 อักขระ ซึ่งข้อความตัวอย่างที่คุณ Sorawee ให้มาก็ไม่ได้เกินนั้น เมื่อตรวจสอบก็พบว่ามาจากโค้ดส่วนอ่าน-เขียน UTF-8 ที่จองบัฟเฟอร์ไว้รองรับแค่ 1 ไบต์ต่ออักขระ ในขณะที่ UTF-8 ต้องการถึง 6 ไบต์ต่ออักขระใน extreme case จึงได้จองเนื้อที่ไว้ให้เพียงพอ ก็แก้ปัญหาได้

บั๊กที่สอง มีวิธีแก้ได้สองวิธี คือเข้าไปล้วงในอัลกอริทึมตัดคำระดับล่างของ swath เลย หรือแก้ที่ตัวอ่าน token เพื่อให้ส่งเฉพาะภาษาไทยเข้าสู่อัลกอริทึมตัดคำเท่านั้น ผมเลือกอย่างหลัง ด้วยเหตุผลสองประการ:

  1. โค้ดระดับล่างของ swath นั้น เป็นโค้ดที่คนเขียน (ซึ่งไม่ใช่ผม) อ่านรู้เรื่องคนเดียว และไม่ได้ออกแบบให้รองรับการปรับเปลี่ยนอะไรมากนัก การเข้าไปแตะโค้ดส่วนนี้จึงเสี่ยงเกินไป
  2. ใน file filter ทั้งหลาย ทั้งสำหรับ LaTeX, HTML และ RTF ต่างก็ใช้วิธีส่งเฉพาะ token ภาษาไทยไปให้อัลกอริทึมตัดคำทั้งนั้น ในขณะที่ส่วนจัดการ plain text กลับส่งเข้าไปทั้งก้อนโดยไม่แยก การแก้ส่วนจัดการ plain text ให้ทำงานแบบเดียวกันจึงดูสมเหตุสมผล

และก่อนที่จะออก swath ในแต่ละรุ่น ผมพยายามจะทำความสะอาดโค้ดไปทีละนิด สำหรับรุ่นนี้ สิ่งที่ทำคือตัดโค้ดที่ไม่ได้ใช้งานทิ้ง ได้แก่โค้ดส่วนทำ shaping ภาษาไทยใน LaTeX filter ซึ่งไม่มีการเรียกใช้มานานมากแล้ว ตั้งแต่มี thailatex (ซึ่งปัจจุบันคือ babel-thai ใน CTAN) ที่รองรับการทำ shaping ผ่าน virtual font มาตั้งแต่ต้น เมื่อตัดโค้ดส่วนนี้ไป ก็ทำให้ขนาดของโปรแกรมที่ strip แล้วลดลงประมาณ 4 KiB

นอกจากนี้ ก็ได้ปรับข้อความใน man page นิดหน่อยด้วย หลังจากที่ thailatex เปลี่ยนเป็น babel-thai มาระยะหนึ่งแล้ว (ประกาศเมื่อปีกลาย) ก็กล่าวถึง babel-thai ให้เหมาะสม

อัปโหลดเข้า Debian Sid แล้วครับ คุณควรจะเจอแพกเกจใหม่ตั้งแต่เมื่อเช้าแล้วแหละ

ป้ายกำกับ: ,

11 กุมภาพันธ์ 2557

Thanks, and the November-January Diary

เร่งงานตามสัญญาโครงการอยู่หลายเดือน ไม่ได้เขียน blog จึงขอขอบคุณย้อนหลัง สำหรับผู้สนับสนุนงานพัฒนาของผมในเดือนพฤศจิกายน 2556 ถึงเดือนมกราคม 2557ที่ผ่านมาดังนี้ครับ:

ขออวยพรปีใหม่สากลและตรุษจีนย้อนหลังแด่ผู้สนับสนุนทุกท่าน ขอให้เจริญอายุ วรรณะ สุขะ พละ พร้อมทั้งมั่งมีศรีสุขครับ และที่สำคัญคือ 願源碼與你同在。[หงวงหง่วงแบ้อื่อลื่อตั่งต๋อ] May the Source be with you!

สามเดือนที่ผ่านมา นอกจากงานโครงการอักษรอีสานที่เป็นงานหลักแล้ว ก็มีงานพัฒนาอื่น ๆ เช่น

  • swath 0.5.2
    • แก้ปัญหา infinite loop ใน LaTeX filter ซึ่ง นิวตรอน รายงานมาทาง G+ (เป็น private share) พร้อมแพตช์แก้
    • แก้ปัญหาอักขระหายใน token ยาว ๆ ใน HTML filter ซึ่งคุณ Nicolas Brouard จากโครงการ ดีโมพีเดีย ได้พบขณะใช้ swath ช่วยเตรียมเอกสารฉบับพิมพ์ จากการใช้ base-64 encode รูปภาพในแท็ก <img src="data:image/png;base64,...> ซึ่งทำให้ token ยาวพอจะทำให้พบบั๊กได้ ถือเป็น use case ที่น่าสนใจมาก และทำให้รู้ว่ายังมีผู้ใช้ที่ใช้ HTML filter อยู่ ไม่ใช่แค่ LaTeX
    บั๊กทั้งสองนี้ เกิดจากความพยายามในการป้องกัน buffer overflow ใน swath 0.5.1 แต่แก้ไม่สมบูรณ์ (รุ่นก่อนหน้านั้นจะ segfault ในบั๊กหลังเลยทีเดียว ซึ่งเป็นช่องทางของ buffer overflow exploit ได้)
  • libdatrie 0.2.8
    • แก้ warning ใน test suite
    • แก้ปัญหาที่พบในการใช้ datrie เก็บคีย์ที่เป็นข้อมูล binary ซึ่งจะใช้ alphabet เต็มช่วงตั้งแต่ 1 ถึง 255 ทำให้พบปัญหาคีย์ซ้ำสำหรับอักขระ 255 อันเนื่องมาจากค่าสิ้นสุดการวนลูปที่ไม่ถูกต้อง รายงานโดยคุณ Naoki Youshinaga
    • แก้ให้ trie ล้มเหลวเมื่อเดินด้วยอักขระนอกช่วง alphabet แทนที่จะยอมให้อักขระดังกล่าวเดินได้ด้วยค่า 255 แล้วทำให้เกิดคีย์ปลอม ๆ ขึ้น แนะนำโดยคุณ Naoki Youshinaga เช่นกัน
    • เพิ่มเติมรายละเอียดในเอกสารประกอบ ตามที่ทักท้วงโดยคุณ Naoki Youshinaga
  • ปรับแพกเกจใน Debian โดยการเปลี่ยนแปลงที่น่าสนใจคือ
    • libdatrie-dev และ libthai-dev รองรับ multi-arch แล้ว หลังจากที่รองรับแค่ตัว lib package มาก่อนหน้านี้ ขณะนี้ dpkg รองรับการใช้แฟ้มร่วมกันระหว่างหลายแพกเกจแล้ว ทำให้สามารถใช้ header file ร่วมกันระหว่าง architecture ที่ต่างกันได้
    • รัน test suite ในการ build ทั้งใน libdatrie และ libthai ซึ่งทำให้พบ warning เพิ่มเติมใน libthai และแก้ที่ต้นน้ำแล้ว
  • ร่วมแปล VLC หลังจากพบคำสะกดผิดใน UI ก็ได้แปลเพิ่มเติมด้วยพอสมควร โดยเฉพาะชื่อภาษาต่าง ๆ ทำให้ได้ไปสอบทานกับคำแปล ISO 639 และ ISO 639-3 ในแพกเกจ iso-codes ควบคู่กันไปด้วย (ออกมาในรุ่น 3.50)
  • ตรวจทาน คำแปล GNOME ตามที่มีผู้ส่งคำแปลเข้ามา
  • งานแปล Xfce ขณะนี้แปลได้ 70% แล้ว

ป้ายกำกับ: , , , , , , ,

08 พฤศจิกายน 2556

Thanks, and the September-October Diary

ขอขอบคุณผู้สนับสนุนงานพัฒนาของผมในเดือนกันยายน-ตุลาคมที่ผ่านมาดังนี้ครับ:

เป็นอีกครั้งหนึ่งที่ต้องเขียน blog แบบรวบสองเดือน เนื่องจากภารกิจต่าง ๆ ค่อนข้างเร่งรัด จนอยากใช้เวลาสะสางงานให้เต็มที่มากกว่า

งานในช่วงสองเดือนที่ผ่านมา แบ่งเป็นหมวด ๆ ดังนี้ครับ:

โครงการอักษรอีสาน

งานพัฒนาที่ LTN และ Debian

เป็นการปล่อยสิ่งที่พัฒนาสะสมมาตั้งแต่ระลอกที่แล้วเมื่อต้นปี โดยทยอยตรวจสอบความเรียบร้อยและออกรุ่นซอฟต์แวร์ต่าง ๆ ดังนี้:

  • libdatrie 0.2.7
    • แก้ไขประเด็นเรื่อง portability เกี่ยวกับ void pointer arithmatics ซึ่งจะมีปัญหากับคอมไพเลอร์ที่ไม่ใช่ GCC โดยได้รับรายงานจากคุณ Mikhail Korobov ว่าคุณ Gabi Daver ได้พบปัญหานี้ขณะคอมไพล์ด้วย Visual C++ พร้อมแพตช์แก้
    • ระหว่างแก้ ได้ทดลองคอมไพล์ด้วยตัวเลือก -Wall ทำให้เจอ warning เพิ่มเติม และแก้ไขจนหมด
    • เขียน test case เพื่อให้สามารถตรวจสอบความถูกต้องเวลาแก้โค้ดได้ในอนาคต ที่ผ่านมาจะทดสอบผ่าน libthai เป็นหลัก แต่เขียน test case เป็นเรื่องเป็นราวน่าจะสะดวกกว่า ซึ่งในระหว่างที่เขียน test case ก็ทำให้ได้อ่านเอกสารประกอบและแก้ไขที่ผิด พร้อมกับได้เพิ่ม API เพื่อความสะดวกในการใช้งานด้วย
    • ปรับ Doxyfile ที่ใช้สร้างเอกสาร เพื่อตัดสิ่งที่เลิกใช้แล้วใน doxygen 1.8.4
    • ออก libdatrie 0.2.7.1 ตามมา หลังจากพบว่าลืมปรับค่า library version เพื่อให้ SONAME สะท้อนการเพิ่ม API ที่เกิดขึ้น
    • อัปโหลด 0.2.7.1-1 เข้า Debian sid
  • thaixfonts 1.2.6
    • มีการปรับระบบ build ตาม autoconf รุ่นใหม่ และเปลี่ยนมาใช้ XZ tarball แทน GZ tarball ซึ่งเป็นสิ่งที่ทำไว้นานแล้ว ก็ออกรุ่นมาเพื่อปรับตามซอฟต์แวร์อื่นเท่านั้น ส่วนตัวเนื้อหาฟอนต์ไม่มีการเปลี่ยนแปลงอะไร
    • อัปโหลด 1:1.2.6-1 เข้า Debian sid
  • LibThai 0.1.20
    • ปรับข้อมูลพจนานุกรมตัดคำตามที่พบกรณีต่าง ๆ ในช่วงที่ผ่านมา [เกร็ด: รุ่นนี้รู้จักอำเภอขนอมที่ไม่ใช่ ขน-อม แล้ว ;-)]
    • แก้ compiler warning ที่พบใน test case ต่าง ๆ
    • อัปโหลด 0.1.20-1 เข้า Debian sid
  • TeX hyphenation patterns
    • sync ข้อมูลพจนานุกรมตัดคำจาก libthai เข้าไปที่ ThaiLaTeX SVN พร้อมกับปรับแก้ hyphenation patterns ตามข้อมูลใหม่
    • แจ้งไปที่โครงการ tex-hyphen ว่าขอปรับข้อมูล hyphenation patterns ภาษาไทย พร้อมกับรายงานปัญหาของสคริปต์บางตัวที่ใช้สร้างข้อมูลอัตโนมัติ คุณ Mojca Miklavec ก็ได้ช่วยแก้สคริปต์ให้ (rev 652, 653) และรับแพตช์ปรับข้อมูลภาษาไทยไปรวมให้ (rev 654)
    • สอบถามและขอ import source ของ hyphenation patterns ภาษาไทยเข้าใน tex-hyphen โดยตรง เพื่อที่ต่อไปจะได้ไปทำงานที่นั่นแทนที่จะต้องผ่าน ThaiLaTeX แบบนี้ ทั้งนี้เพื่อให้เป็นไปตามแผน ที่เคยคุยกันไว้ จนกระทั่งได้ import source ใน rev 655
    • ไม่มีการอัปโหลดอะไรใน Debian แค่รอ Debian อัปเดตแพกเกจ texlive-base เท่านั้น
    • request ขอลบ thailatex ออกจาก Debian unstable เพื่อไม่ให้มีซอร์สตกค้างอยู่ (ลบแล้ว)
  • swath 0.5.1
    • แก้รหัสตัดคำของ Lambda จาก U+200C (ZWNJ) เป็น U+200B (ZWSP) ...ว่าแต่มีใครใช้ฟีเจอร์นี้ไหมเนี่ย?
    • sync ข้อมูลพจนานุกรมตัดคำจาก ThaiLaTeX/hyph-utf8 (ซึ่ง sync มาจาก LibThai อีกที) เพื่อให้ตัวตัดคำ LaTeX ทำงานสอดคล้องกับ hyphenation patterns
    • ก่อนออกก็ปรับซอร์สโค้ดของ swath เพื่อให้แต่ละรุ่นมีการปรับปรุงด้านความปลอดภัยไปทีละน้อย โดยในรุ่นนี้ได้ป้องกัน buffer overflow ใน file filter ต่าง ๆ (ยังมีให้แก้อีกเยอะในรุ่นถัด ๆ ไป :-P )
    • อัปโหลด 0.5.1-1 เข้า Debian sid
  • IBus-LibThai 0.1.2
    • แก้ปัญหาการกด shortcut (เช่น Ctrl-C) ใน IBus 1.5 อันเนื่องมาจากการเชื่อมรวมกับ XKB ของ IBus รุ่นนี้ ทำให้ผังแป้นพิมพ์ที่ระบุใน metadata ของ IBus-LibThai ว่าเป็น th ทำให้กด Ctrl-C ได้เป็น Ctrl-แ เสมอ แก้ไขโดยปรับผังแป้นพิมพ์เป็น us เท่านั้น
    • อย่างไรก็ดี การแก้ปัญหาในรายการที่แล้วทำให้เกิดปัญหาใหม่ คือทำให้กด accelerator ใน GUI ที่แปลเป็นไทย (เช่น Alt-ฟ เพื่อเรียกเมนู แฟ้ม) ไม่ได้ วิธีแก้ที่เหมาะสมจึงควรให้ IBus-LibThai พยายามแปลง key event ที่มีการกดปุ่มประกอบให้เป็นภาษาไทย แต่ปรากฏว่าไม่สามารถส่ง event ที่แปลงแล้วกลับไปหา event queue ได้ เนื่องจากฟังก์ชัน ibus_engine_forward_key_event() ไม่ทำงานอย่างที่คาด งมอยู่นานก็ไม่สามารถแก้ได้ เวลามีจำกัดจึงใช้วิธีกำหนดผังแป้นพิมพ์เป็น us,th เพื่อให้ GTK+ กับ XKB ไปคุยกันเอง ซึ่งก็ได้ผล แต่ปัญหาคือ มันจะแปลงอักขระตามผังเกษมณีเท่านั้น ใครใช้ผังปัตตะโชติใน IBus-LibThai ก็จะงง ไว้หาวิธีแก้ต่อไปในรุ่นหน้า
    • เพิ่มการรองรับการป้อนเลขไทยด้วยแป้นตัวเลข โดยอาศัยการกด CapsLock ล็อคไว้ หรือใช้การยกแคร่ระดับ 3 (Alt ขวา) อนึ่ง ตามที่เคยได้ ออกแบบไว้ เมื่อสองปีก่อนนั้น จะใช้ ScrollLock ไม่ใช่ CapsLock เนื่องจาก CapsLock จะไปเพิ่มขั้นตอนขณะสลับภาษาไปเป็นภาษาอังกฤษที่จะต้องปลด CapsLock อีกขั้นหนึ่งด้วย แต่ในครั้งนี้ได้ตัดสินใจเปลี่ยนเป็น CapsLock ด้วยเหตุผลสองประการ ประการแรกคือการตรวจสอบสถานะของ ScrollLock ด้วย API ของ IBus เป็นไปได้ยาก เพราะไม่มีการเตรียมการรองรับไว้ ประการที่สองคือในแป้นพิมพ์ย่อส่วน เช่นแป้นพิมพ์โน้ตบุ๊ก หลายรุ่นได้ตัดปุ่ม ScrollLock ออกไปแล้ว ตามที่ วิกิพีเดียว่าไว้ (โน้ตบุ๊กผมก็ไม่มี)
    • อัปโหลด 0.1.2-1 เข้า Debian sid

งานแปล

  • ตรวจทาน คำแปล GNOME ตามที่มีผู้ส่งคำแปลเข้ามา โดยที่ผมไม่ได้แอคทีฟตามแปลเองอีกต่อไปแล้ว
  • แปล Xfce เป็นไทย เพิ่มเติม โดยล่าสุด ได้แปล core package ต่าง ๆ ครบแล้ว พร้อมกับปรับคำแปลทั้งหมดจาก master กลับไปที่ branch xfce-4.10 ด้วย และแปลปลั๊กอินที่ผมใช้อีกนิดหน่อยเพิ่มเติม ทำให้ขณะนี้อัตราการแปลของภาษาไทยอยู่ที่ 54% แล้ว

blog นี้ก็เลยยาวหน่อย ขอขอบคุณทุกท่านที่ติดตามครับ

ป้ายกำกับ: , , , , , , , , , ,

11 กุมภาพันธ์ 2556

swath 0.5.0

swath 0.5.0 ออกแล้ว ถือเป็นชุดเดียวกันกับ thailatex 0.5.1 และ libthai 0.1.19 ที่ออกไปก่อนหน้านี้ในแง่ของพจนานุกรมที่ใช้ในการตัดคำและในการสร้าง hyphenation pattern แต่ยังมีการเปลี่ยนแปลงอย่างอื่นอีกมากมายที่ทำให้ปรับ minor version ขึ้นเป็น 0.5.0

รายละเอียดเคย blog ไว้เมื่อปีกลาย เป็นการเปลี่ยนโครงสร้างโปรแกรมขนานใหญ่พอสมควร แม้ engine สำหรับตัดคำจะยังเหมือนเดิมก็ตาม โดยสรุปคือ:

  • ปรับโครงสร้างการแปลงรหัสอักขระ TIS-620 กับ UTF-8 โดยให้ผลลัพธ์ทันทีโดยไม่ทำบัฟเฟอร์ผ่านแฟ้มชั่วคราว
  • ผลข้างเคียงคือ ได้รื้อโค้ดส่วนจัดการเอกสาร RTF เขียนใหม่ทั้งหมด พร้อมกับทดสอบกับเอกสารจริงด้วย
  • เปลี่ยนการประมวลผลอักขระภายในจาก มอก. 620 มาเป็นยูนิโค้ด เพื่อรักษาอักขระยูนิโค้ดในข้อมูลขาเข้าที่ไม่ใช่ไทย-อังกฤษไว้ในผลลัพธ์ขาออกด้วย
  • ผลข้างเคียงของงานข้างต้นอีกอย่างคือ โค้ดถูกทำความสะอาดครั้งใหญ่อีกครั้ง (แต่ยังเหลืออีกเยอะ)
  • แก้ security bug ตามที่ได้รับรายงาน

และเช่นกัน swath รุ่นนี้เป็นรุ่นแรกที่ใช้ XZ tarball compression ซึ่งลดขนาดลงถึง 33%

-rw-r--r-- 1 thep thep 490028 ก.พ.  11 15:05 swath-0.5.0.tar.gz
-rw-r--r-- 1 thep thep 328292 ก.พ.  11 12:11 swath-0.5.0.tar.xz

อัปโหลดเข้า Debian experimental เรียบร้อยครับ พบได้ที่ Debian mirror ใกล้บ้านท่าน

ป้ายกำกับ:

22 มกราคม 2556

swath vulnerability

เมื่ออาทิตย์ที่แล้ว มีรายงาน Debian #698189 ว่า swath มีช่องโหว่ด้านการรักษาความปลอดภัย คือสามารถเกิด buffer overflow และนำไปสู่การ execute คำสั่งด้วยสิทธิ์ของผู้ใช้ได้

ปฏิกิริยาแรกที่เห็นรายงานนี้คือ ผมไม่แปลกใจเลย เพราะก็เคยบ่นไปบ้างในหลาย ๆ โอกาส ว่าเป็นโค้ดที่ยังต้องทำความสะอาดอีกเยอะ (โดยที่ไม่ใช่โค้ดของตัวเอง) ดังนั้น พอเห็นรายงานบั๊กนี้ ครั้งแรกเลยอยากข้ามไปเสีย แล้วบอกเขาว่า คุณจะเจออีกเยอะเลยแหละ ไม่ใช่แค่จุดนี้ แต่จะตอบแบบนั้นมันก็ซี้ซั้วไปหน่อย ความรับผิดชอบเรายังต้องมีอยู่ ก็เลยดำเนินการแก้ security bug นี้ตามกระบวนการในที่สุด คือ

  1. แก้บั๊กที่ upstream SVN (rev 238)
  2. backport แพตช์มาที่รุ่นใน Sid โดยต้องปรับแพตช์เล็กน้อย แล้วอัปโหลดเป็นรุ่น 0.4.3-3
  3. request ขอ unblock 0.4.3-3 เพื่อให้แพกเกจได้ย้ายเข้า Wheezy ที่กำลัง freeze อยู่
  4. backport แพตช์มาที่รุ่นใน Squeeze โดยต้องปรับแพตช์อีกครั้ง เตรียมแพกเกจรุ่น 0.4.0-4+squeeze1 เอาไว้ แล้วติดต่อ security team ของ Debian เพื่อขออัปโหลดเข้า security.debian.org แต่ปรากฏว่าทีม security เห็นว่าเป็นช่องโหว่ไม่ร้ายแรง สามารถรอได้ จึงบอกให้ผมอัปโหลดเข้า stable-proposed-updates แทน อย่างไรก็ดี ทีม security ได้สร้าง security tracker แบบไม่มีเลขอ้างอิง DSA ให้เพื่อติดตามการแก้ปัญหา
  5. build package ใหม่อีกครั้งโดยเปลี่ยนเป้าหมายจาก stable-security เป็น stable แล้ว request ขอ upload เข้า stable พอได้รับอนุญาตแล้วจึงอัปโหลด จากนั้นก็รอ Debian ออกรุ่น stable update ครั้งต่อไป

ไม่ใช่เรื่องเล่น ๆ เลยนะนี่ กับบั๊กเล็ก ๆ อย่างนี้ กับโค้ดที่เขียนโดยไม่ระวัง ดังนั้น ต่อไปนี้คงต้องพยายามมากขึ้นที่จะทำความสะอาดโค้ดของ swath

สำหรับ swath รุ่นถัดไป โค้ดมีการยกเครื่องขนานใหญ่ ตามที่เคย blog ไป จึงมีการทำความสะอาดบ้างตามสมควร แต่คงยังเหลือให้ทำอีกเยอะ ก็อาจจะทยอยตัดรุ่นออกมาเรื่อย ๆ ให้ช่วยกันทดสอบต่อไปครับ ใครจะมาช่วยกันวิจารณ์โค้ดก็ยินดีครับ

ป้ายกำกับ: ,

06 กรกฎาคม 2555

swath revamp

หลังจากที่ได้ออก swath 0.4.3 ไปพร้อมกับชุด thailatex 0.5.0 แล้ว ก็ได้เวลากลับมาสะสางบั๊กเก่าที่ได้รับรายงานตั้งแต่ 5 เดือนก่อน พร้อมกับบั๊กที่เจอเองด้วย

  • บั๊กแรกที่ได้รับรายงานทางเมลส่วนตัว คือมีผู้ใช้นำ swath ไปใช้ประมวลผลเอกสารในแบบ pipeline โดยเปิดเป็น daemon ไว้แล้วส่งเอกสารไปแบ่งคำทีละบรรทัด แต่ปัญหาคือ ข้อความที่ส่งนั้นเป็น UTF-8 แล้ว swath จะรอข้อมูลจนจบแฟ้มก่อนจึงจะเริ่มทำงาน แทนที่จะให้ผลลัพธ์แบบบรรทัดต่อบรรทัด
  • บั๊กที่สอง เป็นบั๊กที่เจอเองระหว่างทดลองใช้ swath ตัดคำแฟ้ม utf-example.tex ของ thailatex เอง ซึ่งเป็นเอกสารที่มีอักขระมากกว่าสองภาษา โดยมีอักษรกรีก ซีริลลิกด้วย ปรากฏว่า swath จะกรองอักขระที่ไม่ใช่อังกฤษ-ไทย (ตามที่มีใน TIS-620) ทิ้งหมด โดยแทนเป็นอักขระ unknown

สองบั๊กนี้ มีความเกี่ยวพันกันอยู่ คือเกิดจากสาเหตุที่ swath ใช้รหัส TIS-620 ในการทำงาน บั๊กแรกนั้น เกิดจากวิธีจัดการข้อมูลที่เป็น UTF-8 โดยจะแปลงรหัสจาก UTF-8 เป็น TIS-620 ผ่าน แฟ้มชั่วคราว โดยจะแปลงข้อมูล ทั้งแฟ้ม ลงในแฟ้มชั่วคราวก่อน แล้วจึงเปิดแฟ้มชั่วคราวที่แปลงเป็น TIS-620 แล้วมาทำงานตามปกติ จึงทำให้ต้องรอข้อมูลจนจบแฟ้มเสียก่อนจึงเริ่มทำงาน

ส่วนบั๊กที่สองก็เข้าใจไม่ยากว่าเกิดจากการแปลงรหัสยูนิโค้ดเป็น TIS-620 ก่อนนั่นเอง ดังนั้น อักขระใดที่ไม่อยู่ใน TIS-620 ก็จำต้องกรองทิ้งหมด

เนื่องจากโค้ด swath ไม่ใช่โค้ดที่แกะง่ายนัก ผมจึงทำทีละเรื่อง โดยปรับโครงสร้างเรื่องการแปลงรหัสเพื่อแก้บั๊กแรกก่อน กลไกภายในยังคงเป็น TIS-620 เช่นเดิม

แต่ปัญหาคือ swath รองรับเอกสารทั้ง plain text, LaTeX, HTML และ RTF ด้วย จึงต้องไล่แก้และทดสอบทุกฟอร์แมต ซึ่งสามอันแรกนั้นไม่ยากเท่าไร จะติดก็แต่เอกสาร RTF ซึ่งแทบหาผู้ใช้ไม่ได้แล้วในปัจจุบัน จึงได้ โพสต์เสนอว่าจะตัดออก แต่เมื่อสนทนาไป กลับได้รับความช่วยเหลือจาก คุณวิทยา คอยให้ข้อมูลและเตรียมเอกสารทดสอบให้ จนในที่สุดก็ได้การรองรับ RTF ที่ใช้งานได้จริงเสร็จสมบูรณ์ โดยที่โค้ดเดิมก่อนแก้นั้นก็ทำงานไม่ผ่านกับเอกสารทดสอบอยู่แล้ว จึงกลายเป็นการแก้บั๊กและเพิ่มความสามารถไปในตัว

แก้โค้ดส่วนการรองรับ RTF ครั้งนี้ ผมยกเครื่องเขียนใหม่หมดเลย

เมื่อเสร็จแล้ว ก็กลับมาทำเรื่องที่สองต่อ โดยในครั้งนี้ได้ตัดสินใจว่าจะเปลี่ยนการทำงานภายใน จาก TIS-620 เป็น UCS-4 (รหัสยูนิโค้ด 32 บิต) โดยใช้ wide char (wchar_t) แทน char ธรรมดา (มีบันทึกการพูดคุยกับ อ.พฤษภ์ ไว้ที่ Google+)

การแก้รอบหลังนี้ เป็นการยกเครื่องแบบถอนรากถอนโคนกว่ารอบแรก และได้ปรับแก้ระบบแปลงรหัสที่ทำไปรอบแรก ซึ่งดูไม่สวยงาม เป็นลูกผีลูกคน ให้ดูลงตัว สมเหตุสมผลยิ่งขึ้น มีการเรียกใช้โค้ดส่วนแปลงรหัสในระดับที่ลึกกว่าเดิม เพื่อประสิทธิภาพและความสมเหตุสมผล

และแน่นอนว่าต้องไล่ทำทีละฟอร์แมตเหมือนรอบก่อน และได้ปรับปรุงโค้ดส่วน RTF ให้รัดกุมกว่าเดิมด้วย

เดิมทีก็ไม่คิดว่าจะทัน Wheezy freeze อยู่แล้ว แต่ก็พยายามทำเท่าที่กรอบเวลามี เผื่อว่าจะทัน แต่สุดท้ายก็ไม่ทันอยู่ดี ความจริงก็แก้เสร็จ พร้อมแก้บั๊กร้ายแรงเสร็จในวันที่จะเริ่ม freeze นั่นแหละ แต่สำหรับการแก้ไขขนานใหญ่ขนาดนี้ ตัวโปรแกรมคงต้องผ่านการทดสอบปรับปรุงมากกว่านี้จึงจะออกรุ่นได้ ดังนั้น จึงยังไม่เร่งร้อนให้ทัน Debian รุ่นนี้ และยังคงทดสอบต่อไปด้วยจังหวะปกติ ไว้พร้อมเมื่อไรค่อยออก

ป้ายกำกับ:

18 มิถุนายน 2555

ThaiLaTeX 0.5.0 et al

fine-tune แล้ว แถม super-tune อีก โดยผมได้ทดลองใช้กับเอกสารจริงควบคู่กันมาตลอดด้วย ก็ได้เวลาเข็นทุกสิ่งที่ได้พัฒนาสะสมมาสู่ผู้ใช้เสียที

เริ่มจาก LibThai 0.1.18 ก่อน โดยในระหว่างปรับแก้พจนานุกรม hyphenation ของ ThaiLaTeX ก็ทำให้พบคำสะกดผิดในพจนานุกรม จึงกลับไปแก้พจนานุกรมตัดคำของ LibThai ด้วย เมื่อรวมกับการเพิ่มคำใหม่ ๆ ในพจนานุกรมตามปกติ (สำหรับรอบนี้ก็เช่นคำว่า ชยันตี จากงานฉลองพุทธชยันตีที่ผ่านมา) ก็ทำให้ได้เป็น LibThai รุ่นล่าสุดนี้ โดยรายการคำที่เพิ่มทั้งหมด ก็ได้ sync เข้าไปที่ ThaiLaTeX ตาม work flow ที่เตรียมไว้แล้วด้วย

จากนั้น ก็ตามมาด้วย swath 0.4.3 ซึ่งได้ถอดเปลี่ยนพจนานุกรมตัดคำมาใช้ชุดเดียวกับที่ ThaiLaTeX ใช้ เพื่อให้จุดแบ่งคำพอดีกันกับ hyphenation pattern ที่จะมาทำงานต่อ ทั้งนี้ได้ให้ swath ดึงพจนานุกรมมาจาก ThaiLaTeX แทนที่จะดึงจาก LibThai โดยตรง เนื่องจาก ThaiLaTeX อาจมีรายการบางรายการที่ปรับเปลี่ยนเพิ่มเติมตามความเหมาะสมของการทำ hyphenation บ้าง (ซึ่งความจริงแทบไม่มีเลย)

สำหรับ swath นี้ ความจริงยังมีงานพัฒนาบางส่วนที่ผมยังทำค้างไว้ใน local branch ในเครื่องผม เกี่ยวกับการแปลงรหัสอักขระ แต่ยังไม่ได้ merge เข้ามาในรุ่นนี้ ไว้ทำเสร็จจริง ๆ แล้วค่อย merge สำหรับรุ่นหน้าต่อไป

สุดท้าย ก็เป็นพระเอกของชุดนี้ คือ ThaiLaTeX 0.5.0 ซึ่งได้ขึ้น minor version เลขใหม่ อันเนื่องมาจากฟีเจอร์ใหม่ที่เพิ่มขึ้นอย่างมีนัยสำคัญ โดยก็ได้อัปโหลดไว้ที่ CTAN (พร้อม TDS installation image) ด้วย

สำหรับ ThaiLaTeX นี้ ถ้าใครติดตั้งจากซอร์สจะมีขั้นตอนที่ต้องแก้เองด้วยมือหลังจาก make install ด้วย เนื่องจากแต่ละระบบมีระบบจัดการ config เรื่อง hyphenation ไม่เหมือนกัน ซึ่งผมได้ทดลองเพียง Debian unstable และ Fedora 17 เท่านั้น รายละเอียดได้เขียนบันทึกไว้ใน README.hyphen ในซอร์สแล้ว

และแน่นอน ทั้งสามรายการนี้ ได้อัปโหลดเข้า Debian unstable แล้ว บางคนอาจจะเห็นและได้ใช้ไปบ้างแล้ว ส่วน Ubuntu ก็รอพบได้ในรุ่น 12.10 ต่อไป

ความจริงที่พยายามเร่งออกในช่วงนี้ก็เพื่อให้ทันกำหนด Wheeze freeze ที่ใกล้จะถึงนี้ด้วย

แถมท้ายนิดหนึ่ง ว่าก่อนหน้านั้นได้มีการออก scim-thai 0.1.3 ที่ได้ปรับเอา API ที่เลิกใช้แล้วใน GTK+ 3 ออกไป เนื่องจาก GTK+ 3 รุ่นใหม่นี้จะไม่ยอมให้คอมไพล์ผ่านอีกแล้ว ตามที่ได้รับรายงานใน Debian #676060

ป้ายกำกับ: , , , ,

03 กุมภาพันธ์ 2555

A Butterfly in ThaiLaTeX

๏ มาจะกล่าวบทไป
บั๊กหนึ่งใน ThaiLaTeX เล็กนักหนา
เพียงวูบวับขยับปีกกรีดกรายมา
เกิดลมพาถาโถมโพยมบน ฯ

จากที่ได้เขียนถึง ปัญหาอัญประกาศ ใน ThaiLaTeX ไปเมื่อปลายธันวา นับจากวันนั้นถึงวันนี้ เวลาว่างของผมก็หมดไปกับการแก้ ThaiLaTeX และสิ่งที่เกี่ยวข้อง โดยบั๊กนี้ได้กลายเป็นผีเสื้อกระพือปีกที่ทำให้เกิดผลพวงเป็นพายุใหญ่ได้ทีเดียว

เริ่มจาก:

  • พบว่าลำดับ `` และ '' ในเอกสาร ThaiLaTeX ไม่ได้มีการแปลงเป็นอัญประกาศคู่ แต่ยังคงรูปเป็นอัญประกาศเดี่ยวสองตัวเหมือนเดิม ซึ่งพบว่าปัญหาอยู่ที่ฟอนต์
  • ระหว่างตรวจสอบปัญหาในกฎ ligkern ของ virtual font ก็พบว่ามีลำดับอื่นที่ยังไม่มีการแปลงเช่นกัน เช่น ?` (¿), !` (¡), \dag (†), \ddag (‡) ฯลฯ ดังที่กล่าวไปแล้วใน blog ก่อน
  • ขณะทดสอบผลการแก้กฎ ligkern ก็พบว่า swath ไปแทรกรหัสแบ่งคำตรงกลางระหว่างลำดับ `` กลายเป็น `{\wbr}` ในบางกรณี
  • ก่อนจะลงมือแก้ swath ก็ชักทนปวดหัวกับซอร์สที่อ่าน (โคตร) ยากของ swath ไม่ไหว จึงจัดระเบียบซอร์สเสียใหม่ ตั้งแต่ใช้เครื่องมือจัดสไตล์ของซอร์สอัตโนมัติแล้วมาปรับแต่งด้วยมือทีหลัง ปรับเปลี่ยนโครงสร้าง ตัดตัวแปรหรือ member ที่ไม่จำเป็น ซึ่งกลายเป็น commit ชุดใหญ่ คือประมาณ 40 commit ใน 4 วัน ส่งท้ายปีเก่า หลังจากนั้นจึงได้แกะและแก้บั๊กที่ต้องการ และปรับโค้ดต่ออีกนิดหน่อย
  • กลับมาที่ ThaiLaTeX เอง เพื่อจะทดสอบฟอนต์ต่าง ๆ จึงมีการปรับเปลี่ยนเอกสารทดสอบ (teststd.tex) ให้รวมลำดับอักษรพิเศษด้วย แต่เพื่อความสะดวกในการปรับแก้ จึงจัดโครงสร้างเอกสารใหม่เสียก่อนโดยใช้แมโคร แล้วจึงแก้เพิ่ม
  • กลับมาแก้ฟอนต์ที่เหลือต่อ โดยหลังจากที่ทดสอบกับฟอนต์ Norasi ที่มี glyph ค่อนข้างครบแล้ว ก็จำเป็นต้องไล่เพิ่ม glyph พิเศษทั้งหมดที่ lthenc.def ตัวใหม่รองรับในฟอนต์ที่เหลืออีก 11 family ในชุด tlwg ซึ่ง glyph ที่ขาดก็มากบ้างน้อยบ้างแล้วแต่ฟอนต์
  • หลังจากเพิ่ม glyph ที่จำเป็นสำหรับ LaTeX แล้ว ก็จำเป็นต้องเพิ่ม glyph ละตินที่เหลือด้วย มิฉะนั้นการแสดงผลบนเดสก์ท็อปก็จะแหว่งไป ซึ่งปริมาณ glyph ที่เพิ่มนั้นเยอะกว่าชุด LaTeX หลายเท่า
  • การเพิ่ม glyph ละติน มีบางฟอนต์ที่ต้องวาดเพิ่มเอง ไม่สามารถหยิบยืมจากฟอนต์อื่นได้ ก็จำเป็นต้องดูขนาดของเส้นจากอักษรอังกฤษที่มี ซึ่งทำให้พบว่ามีบางฟอนต์ที่เส้นอักษรอังกฤษยังไม่สม่ำเสมอ จึงต้องนั่งปรับเส้น glyph อังกฤษเสียก่อน ได้แก่ฟอนต์ Loma ซึ่งมีการหยิบยืมไปใช้ในฟอนต์ Umpush ด้วย การแก้ครั้งนี้จึงทำให้ฟอนต์ทั้งสองได้เส้นที่สม่ำเสมอยิ่งขึ้นด้วย
  • ระหว่างทดสอบ พบบั๊กในฟอนต์ Loma และ Umpush เมื่อใช้กับเอกสาร LaTeX คือสระบนและวรรณยุกต์จะเยื้องกัน ทำให้คำว่า "ที่" จะวาดไม้เอกและสระอีไม่ตรงแนวกัน ก็แก้บั๊กนี้ในฟอนต์ทั้งสองด้วย

บั๊กตัวแรกที่พบจึงไม่ใช่แมลงธรรมดา แต่เป็นผีเสื้อกระพือปีกด้วยประการฉะนี้

ยังเหลือฟอนต์ชุด Arundina ต้องทำต่ออีกครับ แล้วค่อยออกทั้งชุดพร้อมกันทีเดียว

ป้ายกำกับ: , ,

20 มีนาคม 2554

swath 0.4.1

ตามแผนการที่ได้พูดถึงใน ท้าย blog thaifonts-scalable 0.4.15 ก็มาถึงคิวของ swath ซึ่งขอเปลี่ยนลำดับให้ออกก่อน ThaiLaTeX เพื่อเป็นการเตรียม tool ให้เรียบร้อยก่อน พอ ThaiLaTeX ตัวใหม่มาถึง ผู้ใช้จะได้ใช้ภาษาบาลี-สันสกฤตได้ทันที ประกอบกับจะได้ใช้ swath ตัวใหม่ในการ build เอกสารทดสอบของ ThaiLaTeX ตัวใหม่ด้วย

หลังจากไม่ได้อัปเดตมาถึง 2 ปี swath 0.4.1 ก็มีการเปลี่ยนแปลงเพียงเล็กน้อยในแง่ความสามารถของโปรแกรม คือ:

  • แก้บั๊กเรื่องการตัดคำเมื่อเจอคำบาลีที่ใช้นิคหิตบนสระอิ เช่น กิสมิํ ซึ่ง swath ตัวเก่าจะตัดคำระหว่าง "มิ" กับนิคหิต ซึ่งไม่ถูกต้อง ในรุ่นนี้ได้แก้ไขบั๊กนี้แล้ว รวมทั้งได้แก้บั๊กเดียวกันสำหรับพินทุ ยามักการ และลากข้างยาวด้วย
  • เพื่อให้ผู้ใช้เปลี่ยนพจนานุกรมที่ใช้ตัดคำได้สะดวกขึ้น ก็ได้เปลี่ยนพฤติกรรมของตัวเลือก -d ซึ่งเดิมจะใช้กำหนดไดเรกทอรีที่บรรจุแฟ้มพจนานุกรมของ swath ให้เป็นที่อื่น ก็เปลี่ยนให้มากำหนดเป็นแฟ้มได้ด้วย เนื่องจากหลังจากที่เปลี่ยนมาใช้ libdatrie 0.2 ซึ่งสามารถเก็บข้อมูล trie ทั้งตัวในแฟ้มเดียวได้ ก็ไม่จำเป็นต้องระบุเป็นไดเรกทอรีเหมือนเดิมอีกแล้ว สามารถระบุแฟ้มของ trie ได้เลย ดังนั้น สมมุติว่าคุณอยากเปลี่ยนไปใช้พจนานุกรมของ libthai ในการตัดคำแทนของ swath เอง ก็เพียงสั่งดังนี้:
    $ swath -d /usr/share/libthai/thbrk.tri -f latex < in.tex > out.tex
    
    หรือจะกำหนดตัวแปรสภาพแวดล้อมชื่อ SWATHDICT แทนก็ได้ (ในรุ่นเก่าจะใช้ตัวแปร WORDSEGDATA ซึ่งอิงชื่อโปรแกรมสมัยเริ่มแรกก่อนที่จะเปลี่ยนชื่อเป็น swath รุ่นนี้จึงขอเปลี่ยนชื่อ) เช่น:
    $ export SWATHDICT=/usr/share/libthai/thbrk.tri
    $ swath -f latex < in.tex > out.tex
    

นั่นคือสิ่งที่เห็นภายนอก ส่วนโค้ดภายในก็ได้ทำความสะอาดโค้ด ลดการทำงานที่ไม่จำเป็นลงบ้าง แต่ไม่ได้ปรับอะไรใหญ่โตมากนัก เนื่องจาก swath เป็นโค้ดที่ค่อนข้างเปราะบาง แก้ไปแล้วมีโอกาสพังสูง (เคยพังมาแล้วในรุ่น 0.3.2) จึงต้องค่อย ๆ แก้ไปทีละนิดละหน่อย พร้อมกับมีการทดสอบทุกขั้นตอนที่แก้ ว่ายังทำงานปกติดีหรือเปล่า :-P รุ่นนี้หากพบ regression ก็กรุณาแจ้งผมโดยทันทีครับ

ป้ายกำกับ: ,

26 กรกฎาคม 2552

ThaiLaTeX Now Supports UTF-8

ตามธรรมเนียมปกติ หลังจากออก thaifonts-scalable รุ่นใหม่แล้ว ก็มักจะตามด้วยการ update ฟอนต์มาใช้กับ thailatex ด้วย แต่ปรากฏว่าไม่ได้ทำมาตั้งปีครึ่ง เพราะไม่มีเวลา ตอนนี้ ไหน ๆ ผมก็เริ่มปล่อยมือจากงานแปลแล้ว ทำให้มีเวลากลับมาทำงานพัฒนาอีกครั้ง ก็เลยได้กลับไปปัดฝุ่น thailatex อีก

หลังจาก update ฟอนต์ตามปกติแล้ว ก็มีเรื่องหนึ่งที่คาใจอยู่ คือการใช้ UTF-8 ในเอกสาร LaTeX ซึ่งตามปกติแล้ว thailatex จะรองรับแต่ TIS-620 เท่านั้น เวลาเตรียมเอกสาร จึงยังต้องใช้ xiterm+thai หรือต้องกำหนด editor ให้ใช้ TIS-620 เสียก่อน หรือบางคนก็ใช้วิธีเตรียมเป็น UTF-8 ไปเลย แล้วใช้ iconv แปลงเอา

แต่ตอนนี้ไม่ต้องแล้ว เพราะ LaTeX core นั้น รองรับ UTF-8 เรียบร้อยแล้ว น่าจะนานแล้วแหละ ผ่านแพกเกจ inputenc โดยคุณต้องเพิ่ม preamble ต่อไปนี้ (หลัง babel):

\usepackage[utf8x]{inputenc}

ตรง utf8x นี้ บางระบบอาจใช้ utf8 เฉย ๆ

แต่ปัญหาคือ เท่านี้ยังไม่พอ เพราะตัว thailatex เองนั้น ออกแบบมาใช้กับ TIS-620 โดยเฉพาะ ยังต้องปรับแก้โดยเพิ่มการกำหนด symbol ตามรหัสยูนิโค้ดตามที่ LaTeX ใช้อ้างอักษรไทย แล้วแทนที่คำแปลต่าง ๆ ในข้อกำหนดของ babel ให้ใช้ symbol เหล่านี้แทนการใช้อักขระ TIS-620 โต้ง ๆ เพื่อให้ใช้ได้กับทั้ง TIS-620 และ UTF-8

commit เข้า SVN ไปแล้วครับ ใครสนใจช่วยทดสอบก็เชิญได้ คงรอทดสอบสักพักค่อยออกเป็นรุ่นใหม่ต่อไป

ถึงตอนนั้น คุณจะสามารถเตรียมเอกสาร LaTeX โดยใช้ editor สมัยใหม่ที่เดี๋ยวนี้ใช้ UTF-8 เป็นหลักกันหมดแล้ว ส่วนในขั้นตอนตัดคำด้วย swath นั้น ก็เพิ่มตัวเลือก -u u,u เข้าไปด้วย เพื่อให้ swath พยายามอ่าน input และเขียน output แบบ UTF-8 เช่น:

$ swath -f latex -u u,u < mydoc.tex > mydoc.ttex

แถมอีกเรื่อง ว่า LyX ตั้งแต่รุ่น 1.5 เป็นต้นมา รองรับ UTF-8 แล้ว โดยรองรับภาษาไทยด้วย เพียงแต่ขั้นตอน generate จากซอร์สของ LyX เป็น LaTeX นั้น จะแปลงเป็นรหัส TIS-620 ก่อนถ้าเป็นภาษาไทย ทั้งนี้คงเพราะเขาตรวจสอบจาก thailatex ที่เผยแพร่ที่ CTAN นั่นเอง

ป้ายกำกับ: ,

18 เมษายน 2552

Songkran Updates

ความคืบหน้าต่าง ๆ ในช่วงสงกรานต์ที่ผ่านมา:

  • แพตช์สำหรับ Xlib ที่เคยเขียนถึงใน blog เก่า ได้ check-in หมดแล้วที่ upstream ด้วยความช่วยเหลือของ Julien Cristau ผู้ดูแลแพกเกจ libx11 ของ Debian ตามที่เคย blog ไว้ ว่าเขาเสนอจะผลักดันเข้า upstream ให้ เป็นอีกครั้งหนึ่งที่ทำให้ชอบในสไตล์การทำงานของ Debian ที่พยายามทำงานร่วมกับ upstream ให้มากที่สุด สไตล์นี้มีให้พบเห็นที่ Ubuntu บ้าง แต่น้อยครั้ง ส่วนใหญ่จะรับแพตช์เร็ว แต่ไม่ค่อยช่วยผลักดันเข้า upstream แต่ก็ถือว่าเป็นประโยชน์ในแง่ที่ทำให้ผู้ใช้ได้ช่วยทดสอบเร็วขึ้น
  • ในระหว่างนั้น พบว่า xchat-gnome พัง เรียกไม่ขึ้น โดยมีสาเหตุมาจากคำแปลไทย ก็เลยแก้และ commit เข้า SVN พร้อมได้รายงาน Debian #523739 เอาไว้ด้วย ใครเจอปัญหานี้ก็ไปดูได้ครับ หรือรอรุ่น 0.26.1 ซึ่งรวมรายการแก้นี้แล้วก็ได้
  • ตาม แผนการ migrate libthai ใน Debian ตอนนี้ค่อนข้างเสร็จสมบูรณ์แล้วใน unstable รวมทั้ง binNMU ต่าง ๆ ที่ทำให้ตอนนี้ libdatrie0 ไม่มี reverse dependency เหลืออยู่อีกแล้ว ที่เหลือก็รอให้ผ่านเข้า testing ก่อนที่จะปรับแก้ระบบ build ของ libdatrie ต่อไป
  • swath 0.4.0 ก็เข้าสู่ unstable แล้วเช่นกัน
  • จากที่ได้รับรายงานเรื่องปัญหาการ build libdatrie ในระบบต่าง ๆ เช่น Mac, MinGW หรือแม้แต่ Linux distro ด้วยกันที่ไม่ใช่ Debian อย่าง Fedora ก็ได้ทยอยแก้ไปทีละเรื่อง โดยได้รับข้อมูลเบื้องต้นเกี่ยวกับ Mac จากคุณ bact' ผ่าน twitter และได้รับความช่วยเหลือจากคุณ cwt เกี่ยวกับ Fedora และ Mac ทางห้อง #tlwg, คุณ kengggg เกี่ยวกับ Mac ผ่านเมลลิงลิสต์ thai-linux-foss-devel, คุณ Beamer User และคุณ Sudchai เกี่ยวกับ cygwin และ MinGW ผ่านความเห็นใน blog ตอนนี้น่าจะถือได้ว่าตัว libdatrie เองผ่านในทุกระบบแล้ว ต่อไปก็เหลือตรวจสอบการ build แพกเกจที่ใช้ libdatrie คือ libthai และ swath ในแพลตฟอร์มต่าง ๆ ว่ายังมีปัญหาต้องแก้อีกไหม ก่อนที่จะออก libdatrie ตัวใหม่ต่อไป

นอกจากความคืบหน้าดังกล่าว ก็ปรากฏว่าพบปัญหาเล็กน้อยเกี่ยวกับการ migrate libthai ใน Debian โดยแม้จะมีการ upload libthai ที่ตัด link flag รอไว้แล้วใน unstable ตามที่อธิบายไว้ใน blog ก่อน ก็ปรากฏว่า pango ยังคงลิงก์ตรงกับ libdatrie0 อยู่ดี

ตรงนี้ตัวการยังคงอยู่ที่ libthai.la เจ้าปัญหาตัวเดิม คือแม้ผมจะไปแก้ libthai.pc ให้ประกาศ require datrie แบบ private แล้ว และเมื่อสั่ง 'pkg-config --libs libthai' ดูก็ไม่พบ -ldatrie ในผลลัพธ์แล้วก็ตาม แต่สุดท้าย pango ที่ build ออกมาก็ยังคงลิงก์ตรงกับ libdatrie0 อยู่ดี ทั้งนี้เพราะการติดตั้ง libthai.la ทำให้ระบบ build ของ pango ซึ่งใช้ libtool มันไปเจอไฟล์นี้ แล้วก็ไปลากเอา -ldatrie ตามที่ระบุในไฟล์นี้มาให้อยู่ดี..

แม้อยากจะตัดไฟล์นี้ออกเสียก็ยังทำไม่ได้ในตอนนี้ ในเมื่อ kdelibs 3 ยังคงอยู่ใน Debian ก็เลยต้อง hack ด้วยการแอบลบข้อมูล dependency_libs ออก ซึ่งก็ทำให้ -ldatrie ถูกตัดออกไปจากการ build ของ pango ได้ โดยคาดว่าคงไม่กระทบกับการทำงานของ kdelibs 3

ปัญหานี้ไม่ซีเรียสกับผู้ใช้ เพราะ symbol versioning ได้ช่วยป้องกันการพังเพราะ symbol ชนกันไปแล้ว แต่ปรากฏว่ามีเรื่องที่คาดไม่ถึง คือได้สร้างปัญหาให้กับระบบ buildd ของ Debian อยู่ระยะหนึ่ง เพราะการที่ pango ยังคงลิงก์ตรงกับ libdatrie0 ในระหว่างที่ผมได้ update libdatrie เป็น libdatrie1 ซึ่งทำให้ libdatrie0 หายไปจาก archive นั้น การ build ที่ buildd ที่เกี่ยวข้องกับ pango มีอันเจ๊งไปหมด เพราะ buildd chroot ทั้งหลายไม่สามารถดาวน์โหลด pango มาติดตั้งได้เนื่องจากขาด dependency คือ libdatrie0 ไป ตรงนี้ผมไม่รู้ตัวจนกระทั่งได้ไปติดต่อขอ binNMU กับ release team เขาถึงได้เล่าให้ฟัง..

คราวหน้า แม้จะวางแผนไว้ดียังไง ก็คงคิดเองเออเองแบบนี้ไม่ได้อีกแล้ว ควรจะรีบติดต่อทีมงานที่เกี่ยวข้องให้เร็วที่สุดเท่าที่จะเป็นไปได้

และอีกเรื่องหนึ่งคือ.. รอให้ KDE 3 obsolete ใน Debian เร็ว ๆ จะได้ปลดเปลื้องภาระความปวดหัวกับ libthai.la นี่เสียที

ป้ายกำกับ: , , ,

09 เมษายน 2552

swath 0.4.0 in experimental

ต่อจาก blog ที่แล้ว ตอนนี้ swath 0.4.0 ก็เข้าไปอยู่ใน Debian experimental เรียบร้อยแล้วเช่นกัน

swath รุ่นนี้ นอกจากการเปลี่ยนมาใช้ libdatrie 0.2 ก็มีการเปลี่ยนแปลงย่อย ๆ ตามปกติ โดยคราวนี้ได้ทรมาน swath ด้วย valgrind คล้ายกับที่ เคยทำกับ libthai เพียงแต่ไม่ได้ล้วงลึกลงไปแก้อะไรมากนัก เนื่องจาก swath ไม่ใช่โค้ดของผมเอง (แต่เป็นของ คุณไพศาล ทำไว้) ยังไม่มั่นใจพอที่จะแก้อะไรใหญ่โต

แต่ก็โชคดีที่สิ่งผิดปกติที่ valgrind ตรวจพบ ไม่ได้แก้ยากเกินไป โดยที่ได้แก้ไปก็ได้แก่:

  • หน่วยความจำรั่ว 1 จุด
  • การใช้ new[] กับ delete[] ที่ไม่เข้าคู่กัน
  • การใช้ strcpy() กับสตริงที่ซ้อนทับกัน
  • การ branch โดยอาศัยค่าที่ไม่ได้กำหนดค่าเริ่มต้นไว้

มีรายการสุดท้ายที่ผมยังไม่มั่นใจพอที่จะแก้หนึ่งรายการ เนื่องจากทำให้ผลลัพธ์การตัดคำเปลี่ยนไป เลยทิ้งไว้ก่อน เป็นเรื่องของการ branch โดยอาศัยค่าที่ไม่ได้กำหนดค่าเริ่มต้นไว้

เป็นอันว่า เราได้ swath ที่สามารถปรับพจนานุกรมได้ละ ไว้เดี๋ยวรอย้าย libdatrie1 จาก experimental เข้า unstable ก่อน แล้วจึงย้าย swath ตามมา ระหว่างนี้ ใครสนใจทดสอบก็ลองได้จาก experimental ครับผม

ป้ายกำกับ: ,

07 เมษายน 2552

libthai 0.1.11 ready in experimental

ตาม แผนการ migrate libthai ที่ได้วางไว้ ตอนนี้มีความคืบหน้าเล็กน้อย

หลังจากที่ได้เตรียม libdatrie 0.1.4 ใน debian unstable ไว้แล้ว ก็ออก libdatrie 0.2.1 และ libthai 0.1.11 ตามมา พร้อมกับ upload แพกเกจทั้งสองเข้าใน debian experimental เรียบร้อย โดยการ upload ทั้งหมด ก็เป็นการเพิ่ม symbol versioning ทั้งใน libdatrie0 และ libdatrie1 ก็เป็นอันว่าสามารถปรับรุ่น libthai จาก unstable เป็นรุ่นใน experimental ได้โดยไม่มีปัญหาโปรแกรมพังอีกต่อไป

ต่อไปก็รอ libdatrie 0.1.4 ย้ายเข้า testing (เพื่อเตรียมการปรับรุ่นสำหรับผู้ใช้ testing ด้วย) ซึ่งเหลือเวลาอีก 4 วันสำหรับรอรายงานบั๊กใน unstable ถ้าไม่มีอะไรผิดพลาดก็คงได้เข้า testing ในวันที่ 11-12 เม.ย. จากนั้นจึงเริ่มย้ายแพกเกจใน experimental เข้า unstable ได้

ก่อนหน้านี้ ผมได้ upload scim-thai และ gtk-im-libthai ซึ่ง build กับ libthai-dev 0.1.9-5 ใน unstable ไปแล้ว ซึ่งเป็นการตัดการลิงก์ตรงกับ libdatrie0 ออก โดยพร้อมกันนี้ก็ถือโอกาสตัดการลิงก์ตรงกับไลบรารีอื่นที่ไม่จำเป็นที่ GTK+ ไปดึงมาให้ด้วย เช่น libatk, libfreetype, libcairo ฯลฯ ทำให้ dependency ลดลงไปเยอะ แต่การตัดการลิงก์ตรงกับ libdatrie0 ก็เป็นการลดความเสี่ยงต่อการพังลงทางหนึ่ง แต่ทั้งนี้ทั้งนั้น pango language engine ภาษาไทย รวมทั้ง libm17n-0 ยังคงลิงก์ตรงกับ libdatrie0 อยู่ ดังนั้น libdatrie0 0.1.4 ที่มาช่วยแยกรุ่นของ symbol ก็ยังคงจำเป็น

ในระหว่างนี้ ถ้าใครอยากช่วยทดสอบ libthai ใน experimental ก็สามารถเริ่มทำได้นะครับ ตอนนี้ไม่ทำโปรแกรมพังแล้ว ผมเองก็กำลังใช้อยู่ เพื่อทดสอบการใช้งาน หรือจะรอใช้ใน unstable หรือ testing เพื่อความปลอดภัย ก็ไม่มีปัญหาครับ ส่วนผู้ใช้ Ubuntu ก็คงรอใช้ใน karmic ได้หลังจากนั้น

สาเหตุสำคัญที่ต้องมีการปรับ libdatrie ครั้งนี้ ก็เพื่อขยายขีดจำกัดของพจนานุกรมที่ใช้ในการตัดคำ ทำให้ตอนนี้สามารถเพิ่มคำเข้าในพจนานุกรมได้อย่างอิสระแล้ว ความจริงในอนาคตผมอยากให้ช่วยกันเสนอคำเข้ามา เพื่อทำให้ libthai ตัดคำได้ครอบคลุมยิ่งขึ้น แต่ก็ยังขี้เกียจทำ interface ตอนนี้ก็อาจจะใช้ช่องทางอย่างอีเมลหรืออื่น ๆ ไปก่อน จนกว่าจะติดตั้งระบบติดตามบั๊กเสร็จ

อีกโปรแกรมหนึ่งที่กำลังจะได้อานิสงส์จาก libdatrie ตัวใหม่ ก็คือ swath ซึ่งใน SVN ได้ปรับมาใช้ libdatrie ตัวใหม่แล้ว ทำให้สามารถปรับพจนานุกรมสำหรับตัดคำได้ ตอนนี้กำลังอยู่ระหว่างเก็บกวาดโค้ดเพื่อเตรียมออกรุ่นใหม่

ป้ายกำกับ: , , ,

01 เมษายน 2552

libthai/libdatrie Migration in Debian

ระหว่างนี้ยังคงอยู่ในช่วงเคลียร์ TODO list ต่อไป โดยหลังจาก file bug เกี่ยวกับ X locale และ Pango ไปแล้ว ก็มาที่เรื่องของ libthai ซึ่งต้องทำหลายขั้นตอน ระหว่างที่ต้องหยุดรอกระบวนการ ก็สลับไปหยิบเรื่องการ update แพกเกจภาษาไทยใน Debian มาทำไปพลาง ๆ แล้วก็แวะมาที่เรื่อง ฟอนต์ นิดหน่อย ส่วนเรื่องบั๊กความกว้างของตัวเลขอารบิกในฟอนต์ที่ว่าจะทำนั้น ดูแล้ว เป็นปัญหาเกี่ยวกับ hinting ซึ่งจะกินเวลานานเกินไป เลยข้ามไปก่อน เมื่อรายการที่รอผ่านแล้ว ก็เลยกลับมาดูเรื่อง libthai ต่อ

เรื่องของ libthai ก็เริ่มจากการ ออก libdatrie 0.2.0 ที่ ทำค้างไว้ และก่อนที่จะออก libthai ตามมา ก็ upload libdatrie เข้า Debian experimental ก่อน เพื่อทดสอบความเรียบร้อยให้แน่ใจ แต่เนื่องจากรุ่นนี้มีการเปลี่ยน SONAME ของไลบรารี จาก libdatrie.so.0 เป็น libdatrie.so.1 ทำให้มีแพกเกจไบนารีตัวใหม่ คือ libdatrie1 และอื่น ๆ ก็เลยต้องไปผ่านการตรวจสอบใน NEW queue ของ Debian ก่อน เลยเป็นช่วงให้หยุดรอไปทำอย่างอื่นไปพลางอย่างที่ว่าไป

เมื่อผ่านแล้ว ก็มา ออก libthai 0.1.10 ที่ใช้ libdatrie ตัวใหม่ แล้วอัปโหลดเข้า Debian experimental ตามเข้าไป ซึ่งปรากฏว่าเจอตอเข้าให้ เกี่ยวกับเรื่องการ upgrade ไลบรารีข้ามรุ่น SONAME ใครที่เคยอ่านพบใน Debian New Maintainer's Guide แล้วไม่เข้าใจ ว่าทำไมเขาแนะนำ new maintainer ว่าไม่ควรเริ่มจากแพกเกจที่เป็นไลบรารี ก็ขอให้เชื่อเถอะ ว่าเป็นคำแนะนำที่ควรแก่การรับฟังอย่างยิ่ง

ถ้าผมสาธยายรายละเอียดปลีกย่อยเกี่ยวกับไลบรารีที่พบมาทั้งหมด blog ก็คงจะยาวจนไม่ได้เขียนบันทึกที่ตั้งใจจะเขียน ก็ขอข้ามมาที่ปัญหาที่พบในครั้งนี้เลยละกัน

ปัญหาที่พบในครั้งนี้ พอสรุปได้ 2 ประเด็นใหญ่ ๆ

  1. ปัญหาการจัดการการเปลี่ยนแปลง ABI ที่ไม่เข้ากับของเดิม
  2. ปัญหาของ transitive dependency

อาการเป็นดังนี้:

  • client ที่ลิงก์กับ libthai (เช่น Thai language engine ใน Pango) ไปลิงก์กับ libdatrie ไว้ด้วย ผ่านค่า "-lthai -ldatrie" ใน pkg-config ดังนั้น language engine นั้นจึงลิงก์กับ libdatrie 2 ชุด ลิงก์โดยตรงขณะคอมไพล์ชุดหนึ่ง และลิงก์ผ่าน libthai อีกชุดหนึ่ง
  • เมื่อ libthai มีการปรับรุ่น โดยรุ่นใหม่ไปลิงก์กับ libdatrie1 ในขณะที่ client ยังคงลิงก์กับ libdatrie0 อยู่ เมื่อโหลดขึ้นมาทำงาน จึงกลายเป็นโหลด libdatrie ขึ้นมา 2 รุ่นพร้อมกัน คือ libdatrie0 และ libdatrie1
  • เนื่องจากมีการเปลี่ยนแปลง ABI ที่ไม่เข้ากับของเดิม โดยที่ไม่ได้จัดการเรื่อง symbol ให้ดี ไลบรารีทั้งสองชุดจึงมี symbol ซ้ำกัน แต่ทำงานไม่เหมือนกัน จะเรียกได้ตัวเก่าหรือตัวใหม่ก็สุดแท้แต่ linker จะบังเอิญไปหยิบตัวไหนมาให้
  • ผลคือ โปรแกรมทำงานเพี้ยน หรือบางครั้งก็ segfault ไปเลย

ปัญหานี้ ถ้าสามารถโละทุกอย่างที่เกี่ยวข้องทิ้งแล้วคอมไพล์ใหม่หมดจาก libdatrie ตัวใหม่ ก็จะแก้ปัญหาได้ แต่คุณก็รู้ ว่ามันเป็นไปได้ยากสำหรับ distro ขนาดใหญ่อย่าง Debian โดยเฉพาะเมื่อการเปลี่ยนแปลงมาจากแพกเกจเล็ก ๆ ที่มีผลแค่กับภาษาไทยภาษาเดียว (หรือแม้แต่ถ้าคุณคอมไพล์ทุกอย่างจากซอร์สเอง การคอมไพล์ระบบใหม่หมดก็ไม่ใช่เรื่องสนุก) ดังนั้น การจัดการการปรับรุ่นของไลบรารีจึงมีความละเอียดอ่อนค่อนข้างมาก

ได้สรุปไปแล้วข้างต้น ว่าปัญหามีสองประเด็นหลัก ขอเล่าประเด็นหลังก่อน

Transitive Dependency เป็นปัญหาที่ไม่น่าจะเกิด สำหรับโปรแกรมที่ลิงก์กับ shared library ไม่ใช่ลิงก์แบบ static กล่าวคือ ถ้า client ของ libthai ไม่ได้เรียกใช้อะไรใน libdatrie เลย ก็ไม่ควรต้องลิงก์กับ libdatrie โดยตรง ปล่อยให้ libthai ลิงก์ไปคนเดียวก็พอแล้ว จากนั้น เมื่อมีการปรับรุ่น libthai ก็จะไม่กระทบกับ libdatrie อีก

เรื่องนี้เป็นความบกพร่องของผมเองที่ไม่ระวังเรื่อง link flag ของ libthai โดยแม้จะพยายามหลีกเลี่ยง libtool มาใช้ pkg-config แล้ว ก็ยังคงติดแฟล็ก '-ldatrie' มาในแฟ้ม pkg-config ของ libthai อยู่ กล่าวคือ ถ้าเป็นลิงก์โปรแกรมผ่าน *.la ที่สร้างโดย libtool นั้น มันจะไปดึงเอา dependency ของไลบรารีมาลิงก์ตรงหมด (เป็นสาเหตุหนึ่งที่ Debian และดิสโทรอื่นบางดิสโทรพยายามจะกำจัดแฟ้ม *.la ออกจากระบบให้หมด แต่ของ libthai ยังต้องคงไว้ เพื่อให้ kdelibs 3.x ใช้โดยเฉพาะ แต่ก็ไม่ได้มีผลอะไรกับระบบการลิงก์ เพราะ libthai ใช้ pkg-config เป็นหลัก) ในขณะที่การใช้ pkg-config จะสามารถแยก dependency ที่เป็น private ออกจาก public ได้ แต่พอมาใช้ pkg-config แล้ว ผมก็ยังเข้าใจผิดว่าการลิงก์นั้นยังต้องใช้ link flag เหมือน libtool ซึ่งไม่จำเป็นเลย

ดังนั้น ถ้าก่อนหน้านี้ ผมประกาศให้ libdatrie เป็นรายการ requires แบบ private ในแฟ้ม libthai.pc ก็จะไม่เกิดการลิงก์ client กับ libdatrie โดยตรงเป็นจุดที่สอง นอกเหนือจากผ่าน libthai และปัญหา ABI นี้ก็จะไม่เกิดขึ้นเลย

ปัญหานี้ Loic Minier ซึ่งเคยเป็น sponsor ให้กับแพกเกจ libthai ของผมได้ชี้ให้เห็น เขาไม่ได้พูดละเอียดขนาดนี้หรอก ผมเรียบเรียงและอธิบายเพิ่มเติมเพื่อให้เข้าใจง่ายเข้าน่ะ

แต่ผมกลับไปแก้ไขอดีตไม่ได้ ได้แต่กำจัด flag นั้นเพื่อลดรายการ dependency และการโหลดไลบรารีลงในอนาคต แล้วก็มาแก้ปัญหา ABI ที่พบอยู่ตรงหน้านี้

Incompatible ABI Change จาก libdatrie0 เป็น libdatrie1 มีการเปลี่ยนแปลง API โดยมีชื่อฟังก์ชันซ้ำกับของเดิมบางส่วน ดังนั้น เมื่อถูกโหลดขึ้นมาพร้อมกันโดยไม่มีการจัดการแยกแยะ symbol แบบนี้ loader จึง resolve symbol มั่ว แต่ปัญหานี้สามารถเลี่ยงได้ ด้วยการทำ symbol versioning ซึ่งพูดง่าย ๆ ก็เป็นเหมือนการใส่ namespace ให้กับแต่ละ symbol นั่นเอง โดยแยกแยะ ABI เป็นรุ่น ๆ ทับซ้อนกันได้ วิธีนี้มีข้อแม้ว่าไลบรารีจะต้องลิงก์ตรงกับ client เท่านั้น จะไม่มีผลต่อการโหลดผ่าน dlopen เพราะข้อมูล version ในการเรียก จะรู้ได้ในขณะลิงก์เท่านั้น ส่วนถ้าผ่าน dlopen การเรียกก็จะไม่มีการระบุ version

แต่กรณีของเรา libthai ก็ลิงก์ตรงกับ libdatrie อยู่แล้ว สามารถนำมาใช้แก้ปัญหาได้ โดยผมต้องกลับไปใส่ symbol version ใน libdatrie ตัวเก่า แล้ว ออก libdatrie 0.1.4 เพื่อ upload เข้า unstable รอไว้ก่อน พร้อมกันนั้นก็ใส่ symbol version ให้กับ libdatrie ใน experimental ไว้ด้วย เมื่อ libthai ตัวใหม่ย้ายจาก experimental เข้า unstable จึงจะไม่เกิดปัญหาชื่อชนกัน ซึ่งกว่าผมจะย้ายมาได้ ก็ต้องรอให้ libdatrie 0.1.4 ย้ายเข้าไปถึง testing เสียก่อน (ใช้เวลาประมาณ 10 วัน) เพื่อให้ผู้ใช้ testing สามารถ upgrade ได้โดยไม่สะดุดเหมือนกัน

เรื่องการทำ symbol versioning นี้ Josselin Mouette เป็นคนชี้ให้เห็น แต่ความรู้พื้นฐานเกี่ยวกับ symbol versioning ที่ทำให้เข้าใจในสิ่งที่เขาบอก ก็ต้องขอบคุณ Martin Wuertele ซึ่งเป็น Application Manager ในกระบวนการสมัครเป็น Debian Developer ของผม เพราะข้อสอบภาคทฤษฎีของเขา ทำให้ผมไปค้นคว้าจนได้ความรู้ประดับสมองรอไว้ ตอนนี้ก็ได้เวลางัดออกมาใช้ในภาคสนามละ

จากเงื่อนไขต่าง ๆ ที่เล่ามา แผนการโดยสรุปของผมจึงเป็นขั้น ๆ ดังนี้:

  1. update libthai ใน unstable (0.1.9-5) เพื่อตัด link flag '-ldatrie' ออก รอไว้ ในระหว่างนี้ ถ้าแพกเกจไหนที่ลิงก์กับ libthai มีการ build เกิดขึ้น ก็จะตัดลิงก์ตรงกับ libdatrie0 ออกไป เลี่ยงปัญหาการพังไปโสดหนึ่ง หรืออย่างน้อยก็ตัดการโหลดไลบรารีที่ไม่จำเป็นออกไปหนึ่งรายการ แต่ถ้ายังมีใครไม่ build ก็ไม่เป็นไร ยังมีก๊อกสอง
  2. update libdatrie0 ใน unstable (0.1.4-1) ซึ่งเพิ่ม symbol version รอไว้ เพื่อที่เมื่อ libthai ตัวใหม่ย้ายเข้า unstable แล้ว จะไม่เกิดการชนของ symbol และต้องรอให้แพกเกจนี้ย้ายเข้าไปถึง testing เสียก่อนด้วย จึงจะดำเนินการขั้นต่อไปได้
  3. ออก libdatrie1 ตัวใหม่ที่มี symbol version และ upload เข้า experimental
  4. update libthai ใน experimental อีกครั้ง โดยลิงก์กับ libdatrie1 ที่มี symbol version พร้อมกับตัด link flag เหมือนที่ทำใน unstable ด้วย นอกจากนี้ จากที่ Josselin ได้ท้วงว่าอาจมีปัญหากับการ upgrade เพียงบางส่วนจาก lenny ที่ยังใช้ libdatrie0 ตัวเก่า จึงควรเพิ่ม versioned conflict กับ libdatrie0 (<< 0.1.4) ด้วย
  5. เมื่อถึงเวลาอันควร (ซึ่ง Josselin บอกว่า น่าจะเป็นหลัง GNOME 2.26 migration ล็อตใหญ่ที่กำลังจะเริ่ม) ก็ติดต่อกับ release team เพื่อย้าย libthai เข้า unstable โดยขอ binNMU สำหรับทุกแพกเกจที่ลิงก์กับ libthai ซึ่งน่าจะทำให้ libdatrie0 รุ่นเก่าถูกปลดระวางไปอย่างสมบูรณ์

สำหรับ swath ตัวใหม่ที่ลิงก์กับ libdatrie1 แล้วนั้น คงจะออกเมื่อ libdatrie1 ตัวใหม่อยู่ตัวแล้ว อาจจะระหว่างอยู่ใน experimental หรือหลังจากย้ายเข้า unstable ก็แล้วแต่ความเหมาะสม

ป้ายกำกับ: , , ,

16 มีนาคม 2552

My (Partial) TODO List

ชักยาวเป็นหางว่าวแล้ว TODO list ของผม.. แค่ช่วงที่ติดงานแปล GNOME 2.26 นี่เท่านั้น จดไว้กันลืมเสียหน่อย 2.26 ออกเมื่อไรต้องรีบทยอยเคลียร์..

  • ออก libdatrie, libthai, swath รุ่นใหม่ที่ได้ ทำค้างเอาไว้
  • จัดการเรื่องปัญหา extended cluster ของ pango ซึ่งมีผลกับการเลื่อนเคอร์เซอร์ข้าม cluster ในรูป "เก" และ "กะ" (รวมทั้ง "เกะ") -- สิ่งที่เกี่ยวข้อง: Mozilla #474068, Unicode UAX #29
  • ออกแบบเรื่อง UI การใช้ภาษาอังกฤษในโลแคลไทย เพื่อแก้ปัญหา ผู้ใช้ไม่ยอมใช้โลแคลไทย จนไปกระทบ feature ภาษาไทยของระบบ และหาที่เสนอแนวคิด
  • แก้ปัญหาเรื่องความกว้างของตัวเลข ตามที่ Davide Viti ได้ ตรวจสอบ เอาไว้ แพกเกจที่กระทบคือ ttf-thai-arundina และ ttf-thai-tlwg
  • update Debian package ภาษาไทย โดย update ข้อมูล VCS ของแพกเกจที่ host ที่ LTN จาก CVS เป็น SVN, update ตาม Debian policy 3.8.1, update debhelper เป็น level 7
  • ผลักดัน Thai Fonts Siampradesh (non-free) เข้าใน Debian

มีรายการอื่นอีก ที่คงไม่สะดวกที่จะเขียนลง blog เนื่องจากเป็นการติดต่อเป็นการส่วนตัวกับคนอื่น

วันนี้เป็นวันสุดท้ายก่อน tarballs due ของ GNOME 2.26 แล้ว คงจะพยายามแปล user guide ให้ได้มากที่สุด จากนั้นก็เป็นคิวของ release notes ที่ควรจะเสร็จภายในวันพุธ (18 มี.ค.) แล้วหลังจากนั้นถึงจะเป็นอิสระจากงานแปล ไปเคลียร์ TODO list ได้..

ป้ายกำกับ: , , , , , , , , , ,

19 ธันวาคม 2551

datrie migrations

นับจาก blog ที่แล้ว เรื่อง datrie ก็ได้ทำเพิ่มอีกนิดหน่อย และออก Alpha 1 และ Alpha 2 สำหรับ libdatrie 0.2.0 เพื่อให้มีรุ่นอ้างอิงสำหรับการ configure ซอร์สของ libthai และ swath ที่จะย้ายมาใช้ libdatrie1

ล่าสุด ก็ได้ ย้ายทั้ง libthai และ swath มาใช้ libdatrie1 เรียบร้อยแล้วใน CVS ซึ่งทำให้ขณะนี้:

  • libthai สามารถเพิ่มคำในพจนานุกรมต่อได้แล้ว เมื่อข้อจำกัดเรื่องจำนวนคำหมดไป
  • swath สามารถปรับแก้พจนานุกรมได้แล้ว หลังจากที่ติดปัญหาเรื่องบั๊กในโค้ด Trie รุ่นดึกดำบรรพ์มานาน

เพราะฉะนั้น ผู้ใช้แพกเกจทั้งสอง ไม่ว่าจะใช้ libthai ตัดคำผ่าน Firefox/Iceweasel (บนลินุกซ์เท่านั้น), Epiphany, Konqueror หรือโปรแกรมบน GNOME/KDE อื่น ๆ หรือใช้ swath ในการตัดคำสำหรับ LaTeX หรือ HTML ทั่วไป แล้วพบกรณีการตัดผิด ก็กรุณาแจ้งให้ผมทราบด้วยนะครับ จะทาง blog นี้หรือทาง t-l-f-d mailing list ก็ได้ เพื่อที่จะได้พิจารณาเพิ่มคำในพจนานุกรมต่อไป

ส่วนถ้าเป็นกรณีกำกวม เช่น "ตากลม" นี่ เป็น known bug นะครับ เพราะทั้งสองตัวนี้ ยังไม่มีการใช้ข้อมูลสถิติใด ๆ ทั้งสิ้นมาประกอบการตัดคำ

ป้ายกำกับ: ,

08 ธันวาคม 2551

Unicode datrie

จาก แผนงานครั้งที่แล้ว ที่ได้วางแผนปรับฟอร์แมตของแฟ้มและปรับ API ไปนั้น ตอนนี้ทำเสร็จไปแล้วใน CVS

ในครั้งนี้ ได้เพิ่มข้อมูล alphabet map ลงในแฟ้ม trie ด้วย จากเดิมที่แยกโค้ด Trie กับ SBTrie (single-byte-domain trie) ออกจากกัน โดย SBTrie เป็น wrapper สำหรับแปลงรหัสอักขระไบต์เดียว (TIS-620 หรือรหัส 8 บิตอื่น ๆ) ให้เป็นชุดอักขระที่เป็นโดเมนของ trie คือเป็นค่าลำดับ 1, 2, 3, ... ของแต่ละอักขระเป็นค่าต่อเนื่องกัน เพื่อจำกัดขนาดของโดเมน และเพิ่มความกระชับของ sparse table ที่แทน transition ของแต่ละ state โดยในครั้งนี้ ได้ตัดสินใจผนวก map นี้เข้าใน Trie เสียเลย และเขียนข้อมูลลงในแฟ้มไบนารีของ trie ด้วย เพื่อลดความสับสนของการแยกแฟ้ม *.sbm ใน datrie รุ่นก่อน

แต่ก็หมายความว่า แผนเดิมที่คิดจะทำ wrapper แยกระหว่างรหัสอักขระ 8 บิตกับยูนิโค้ด เช่น SBTrie, UniTrie, ... ก็กลายเป็นว่าต้องรองรับทุกอย่างในโค้ดเดียว จึงถือโอกาสเพิ่มแผนงานอีกอย่าง คือรองรับยูนิโค้ดไปเลย แล้วให้ client แปลงทุกอย่างให้เป็นยูนิโค้ดเอา หรือจะใช้รหัส 8 บิตตามเดิมแต่เก็บในเนื้อที่อักขระ 32 บิตแทนก็ตามแต่ เพราะไม่ว่าจะมาแบบไหน trie ก็จะแปลงเป็นโดเมนของ trie อยู่แล้ว ขอให้ใช้รหัสแบบเดียวกันทั้งตอนสร้าง trie และตอนสืบค้นเป็นอันใช้ได้

ขณะที่แก้ ๆ ไปนั้น กลายเป็นการแก้โค้ดขนานใหญ่ เพราะมีหลายประเด็นให้ทำพร้อมกัน โดยที่ไม่สามารถทดสอบโค้ดในระหว่างกลางได้เลย เพราะเป็นการแก้ API ไปด้วย จึงคอมไพล์ไม่ผ่านจนกว่าจะแก้เสร็จ

เพราะฉะนั้น จึงแยกแพตช์ที่จะ commit นั้นออกเป็นแพตช์ย่อย ๆ ทำทีละเรื่อง เพราะในโครงการซอฟต์แวร์ใด ๆ ก็ตาม:

อย่าทำทุกอย่างในแพตช์เดียว ให้แยกแพตช์เป็นเรื่อง ๆ ค่อย ๆ เปลี่ยนทีละขั้น

การค่อย ๆ เปลี่ยนทีละขั้นนี้ เปิดโอกาสให้ได้ทดสอบและแก้บั๊กทีละเรื่องได้ ช่วยลดโอกาสการเกิดบั๊ก และลดความซับซ้อนในการดีบั๊กได้

ก็เลย checkout CVS ออกมาอีกชุดหนึ่ง แล้วแยกร่างแพตช์ใหญ่นั้นมาทำทีละเรื่อง พร้อมทดสอบก่อน commit ทุกขั้น ขั้นที่ทำเพิ่มไปก็คือ:

  • ผนวก alphabet map เข้าใน class Trie และตัด class SBTrie ออกไป (เขียนภาษาซีแต่เรียก class ซะงั้น เพราะแนวคิดในการออกแบบก็เป็นกึ่ง ๆ OOP อยู่แล้ว)
  • ปรับ API เพื่อให้สามารถใช้ trie แบบไม่อ่าน-เขียนแฟ้มได้ด้วย โดยยังมีเมธอดให้อ่านเขียนแฟ้มได้ถ้าต้องการ

ขั้นต่อไปที่จะทำ ซึ่ง blog นี้จะบอกกล่าวไว้ก่อนสำหรับผู้ที่อาจจะนำ datrie ไปใช้ คือต่อไป datrie จะใช้อักขระขนาด 32 บิตแล้ว แต่ชุด alphabet ที่รองรับ ก็ยังคงจำกัดที่ไม่เกิน 255 ตัวอยู่ดี เพราะไม่มีประโยชน์ที่จะรองรับ alphabet ขนาดโต ๆ (เช่นภาษาจีน) เนื่องจาก transition table จะกว้างเกินเหตุ และทำให้แฟ้ม trie ใช้เนื้อที่อย่างไม่มีประสิทธิภาพ

ช่วงนี้ขอจดจ่อหน่อยนะครับ เรื่องอื่นขอพักไว้ก่อน

ป้ายกำกับ: ,

03 ธันวาคม 2551

32-bit datrie

จากที่เคย เกริ่น ไว้นานแล้ว ถึงปัญหาเรื่อง dict ใน swath ที่เพิ่ม-ลบคำไม่ได้ จำเป็นต้องแทนที่โค้ด trie ด้วย datrie ตัวใหม่ แต่มีปัญหาว่า datrie นั้นใช้ node index ขนาด 16 บิต ซึ่งทำให้จำนวนโหนดไม่เพียงพอกับรายการคำของ swath ประกอบกับปัญหา dict ตัดคำของ libthai ก็มาชนลิมิตนี้เหมือนกัน รวมทั้งมีผู้รายงานเข้ามาบ่อย ว่าต้องการเพิ่มคำให้ได้มากกว่านี้ ก็สรุปว่าต้องแก้ datrie ให้รองรับ node index ขนาดใหญ่ขึ้น

ก็ได้ ประกาศแผน ใน thai-linux-foss-devel mailing list ว่าจะตัดสินใจ break ABI โดยล้มเลิกความคิดเรื่อง backward compatibility กับ trie 16 บิต หรือการใช้ index 24 บิต แต่จะใช้ index 32 บิตอย่างเดียวไปเลย เพื่อความเรียบง่ายของโค้ด พร้อมกันนี้ก็ถือโอกาสปรับ API ให้รองรับการใช้งานที่กว้างขึ้นด้วย สรุปแผนคือ:

  • แตก branch r_0_1_x-branch สำหรับ maintain datrie 0.1.x แล้วพัฒนารุ่นใหม่ใน HEAD ซึ่งจะมุ่งสู่รุ่น 0.2.0 ต่อไป
  • break ABI โดยเปลี่ยน SONAME ของไลบรารีเป็น libdatrie.so.1
  • เปลี่ยนขนาดของ node index จาก 16 บิต เป็น 32 บิต
  • ปรับฟอร์แมตของแฟ้ม จากเดิมที่แยกเป็น *.br และ *.tl ให้รวมอยู่ในแฟ้มเดียว
  • ปรับ API จากที่ต้องอ่าน-เขียนกับแฟ้มเสมอ ให้กลายเป็นแค่ทางเลือกหนึ่งในการ load/save เท่านั้น และให้ใช้ trie ใน memory ล้วน ๆ ได้ด้วย

ตอนนี้ใน CVS ได้ใช้ node index ขนาด 32 บิตแล้ว รวมทั้งปรับโค้ดเรื่องการจัดการ overflow นิดหน่อย ขั้นต่อไปคือทำเรื่อง API และฟอร์แมตของแฟ้ม

ป้ายกำกับ: , ,

hacker emblem