บทความ/จัดพิมพ์ โดย: นาย เจษฏา กานต์ประชา
\[ \sum_{n=1}^\infty \frac{1}{n^6+1} = \frac{\pi}{6}\left( \coth\pi + \frac{\sinh\pi + \sqrt 3\sin\pi\sqrt 3}{\cosh\pi - \cos\pi\sqrt 3}\right) - \frac{1}{2} \]คิดว่าหลายคนในที่นี้น่าจะอยากสร้างเว็บไซต์ของกลุ่มหรือส่วนตัว ซึ่งสามารถแสดงผลสมการคณิตศาสตร์ได้เหมือนกับเว็บแห่งนี้ (ตัวอย่างสมการด้านบน) วิธีที่ผมแนะนำคือใช้ MathJaX ซึ่งเป็นชุดคำสั่ง Javascript สำหรับแสดงผลสมการคณิตศาสตร์บนเครื่องของผู้เข้าชมเว็บไซต์
ข้อดีของวิธีนี้คือ ไม่ต้องไปยุ่งยากกับการติดตั้ง LaTeX บน Hosting Server ซึ่งโดยทั่วไปจะมีค่าใช้จ่ายสูงมาก (หากต้องการติดตั้งโปรแกรมต่างๆได้เอง) นอกจากนี้ยังไม่เปลืองเนื้อที่สำหรับเก็บไฟล์รูปสมการคณิตศาสตร์ และไม่เป็นภาระกับ Hosting Server มากเกินไป ไม่จำเป็นต้องเช่า Hosting Server ราคาแพง ใช้ราคาพื้นฐานก็เพียงพอแล้ว
อัพเดท
บทความนี้เป็นการอัพเดทเนื้อหาเพิ่มเติมจากบทความ MathJaX ชุดคำสั่งสำหรับแสดงสมการคณิตศาสตร์บนเว็บ ซึ่งเป็นเวอร์ชัน 2.4 เพราะเวอร์ชัน 3 เป็นการเขียนโค้ดใหม่ทั้งหมด ดีไซน์ใหม่ โครงสร้างโค้ดใหม่ จึงไม่สามารถนำมาแทนที่เวอร์ชัน 2 ได้ทั้งหมด บางฟีเจอร์ดีขึ้น บางฟีเจอร์หายไป อาทิเช่น
สิ่งที่ดีขึ้น
- แสดงผลเร็วขึ้น จะแสดงสมการคณิตศาสตร์ทั้งหน้าพร้อมกัน ไม่เห็นการค่อยๆแสดงผลทีละสมการแบบเวอร์ชัน 2
สิ่งที่แย่ลง
- ไม่รองรับบราวเซอร์เก่า ใช้ได้กับ IE11 ขึ้นไป
- ใช้แบนด์วิธขาดาวน์โหลดตอนเริ่มต้นมากขึ้น เนื่องจากจะดาวน์โหลดทุกโมดุลตอนเริ่มต้น ต่างจากเวอร์ชัน 2 ที่จะดาวน์โหลดเมื่อจำเป็นต้องใช้งานส่วนนั้นเท่านั้น
- ปัจจุบันใช้ได้เพียงฟอนต์เดียวคือ MathJax TeX เท่านั้น ต่างจากเวอร์ชัน 2 ที่สามารถใช้ฟอนต์อื่นๆได้เช่น STIX General, Asana Math, Neo Euler, Gyre Pagella, Gyre Termes, Latin Modern
- เอกสารการใช้งานยังไม่สมบูรณ์ ปล่อยว่างไว้หลายหน้า
เราสามารถเรียกใช้ชุดคำสั่ง MathJaX ได้ 2 วิธีคือ
วิธีนี้เรียบง่ายที่สุด เพราะเราไม่จำเป็นต้องเก็บชุดคำสั่ง Javascript ไว้บน Server ของเราเอง และเมื่อทางผู้พัฒนาแก้ไขปรับปรุงชุดคำสั่ง MathJax เราก็จะได้ชุดคำสั่งตัวล่าสุดใช้งานทันที โดยไม่ต้องไปแก้ไขอะไรทั้งสิ้น นอกจากนั้นชุดคำสั่งเหล่านี้จะวางกระจายไว้ตาม Server ต่างๆทั่วโลก เพื่อให้แน่ใจว่าทุกคนทั่วโลกไม่เสียเวลาโหลดชุดคำสั่งเหล่านี้นานเกินไป :)
วิธีเรียกใช้ ให้เพิ่มคำสั่งโหลดสคริปต์ไปยัง MathJaX CDN บนหน้าเว็บไซต์ที่ต้องการแสดงผล ในส่วนของ <head> ตัวอย่างเช่น
<head> ... <script src="https://cdn.jsdelivr.net/npm/mathjax@3.2.0/es5/tex-svg.js" async></script> ... </head>
วิธีนี้เราต้องไปดาวน์โหลดชุดคำสั่ง MathJaX จากเว็บไซต์ผู้พัฒนามาติดตั้งบน Hosting Server ของเราเอง อาจจะยุ่งยากกว่าเล็กน้อย แต่จะได้ความเป็นอิสระมากกว่า เพราะเราเป็นผู้ควบคุมทุกอย่างเอง รวมถึงตอนอัพเดทเวอร์ชัน เราต้องทำเองทุกขั้นตอน
ขั้นตอนการเรียกใช้ผ่าน Hosting Server
<head> ... <script src="mathjax3.2.0/tex-svg.js"></script> ... </head>
เพียงเท่านี้เราก็สามารถแสดงสมการคณิตศาสตร์บนหน้าเว็บได้แล้ว โดย
สมการแบบ inline ให้เขียน LaTeX ข้างใน \( ... \) ตัวอย่างเช่น
\(\sum_{n=1}^\infty \frac{1}{n^6+1} = \frac{\pi}{6}\left( \coth\pi + \frac{\sinh\pi + \sqrt 3\sin\pi\sqrt 3}{\cosh\pi - \cos\pi\sqrt 3}\right) - \frac{1}{2}\)
จะได้ผลลัพธ์เป็น \(\sum_{n=1}^\infty \frac{1}{n^6+1} = \frac{\pi}{6}\left( \coth\pi + \frac{\sinh\pi + \sqrt 3\sin\pi\sqrt 3}{\cosh\pi - \cos\pi\sqrt 3}\right) - \frac{1}{2}\)
สมการแบบ display ให้เขียน LaTeX ข้างใน \[ ... \] ตัวอย่างเช่น
\[\sum_{n=1}^\infty \frac{1}{n^6+1} = \frac{\pi}{6}\left( \coth\pi + \frac{\sinh\pi + \sqrt 3\sin\pi\sqrt 3}{\cosh\pi - \cos\pi\sqrt 3}\right) - \frac{1}{2}\]
จะได้ผลลัพธ์เป็น \[ \sum_{n=1}^\infty \frac{1}{n^6+1} = \frac{\pi}{6}\left( \coth\pi + \frac{\sinh\pi + \sqrt 3\sin\pi\sqrt 3}{\cosh\pi - \cos\pi\sqrt 3}\right) - \frac{1}{2} \]
หากสังเกตคำสั่งเรียกใช้ MathJaX ข้างต้น จะพบว่ามีการอ่านไฟล์ tex-svg.js มีความหมายว่า เรากำลังใช้การตั้งค่าจากไฟล์ tex-svg.js โดยสามารถเขียนสมการในรูปแบบ LaTeX (รวมถึง Package AMS) และแสดงผลผ่านบราวเซอร์เป็น SVG
นอกเหนือจากการตั้งค่าในรูปแบบดังกล่าวแล้ว MathJaX ยังได้เตรียม การตั้งค่าพื้นฐานอีกหลายแบบ (รูปแบบของชื่อการตั้งค่าคือ InputFormat-OutputFormat หรือ InputFormat_1-InputFormat_2-OutputFormat) ดังนี้
เนื่องจากการแสดงผลที่รวดเร็วและผิดเพี้ยนน้อยที่สุดคือรูปแบบ SVG จึงแนะนำให้ใช้รูปแบบ tex-svg เท่านั้น
ชุดคำสั่ง MathJax (tex-svg.js) มีขนาด 1.66 MB หากต้องดาวน์โหลดโดยที่หน้านั้นไม่มีการใช้งาน LaTeX จะทำให้การแสดงผลเนื้อหาช้าลงโดยไม่จำเป็น และยังเป็นการสิ้นเปลืองแบนด์วิธมากเกินไปด้วย เราสามารถเขียนโค้ดให้ตรวจสอบเนื้อหาของหน้านั้น หากพบว่ามีการใช้งาน LaTeX จึงค่อยดาวน์โหลดชุดคำสั่ง MathJaX มาเรียกใช้
ตัวอย่างการตั้งค่าให้ดาวน์โหลด MathJaX เฉพาะหน้าที่มีการใช้งาน LaTeX
<head> ... <script> function domReady(callback){ if (document.readyState != 'loading') callback(); else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback); } domReady(function () { let body = document.body.textContent; if (body.match(/(?:\$|\\\(|\\\[|\\begin\{.*?})/)) { if (!window.MathJax) { let script = document.createElement('script'); script.src = 'mathjax3.2.0/tex-svg.js'; script.async = true; document.head.appendChild(script); } } }); </script> ... </head>
inline/display delimiter เบื้องต้นที่ชุดคำสั่ง MathJaX กำหนดมาให้คือ \( ... \) และ \[ ... \] เราสามารถกำหนดเพิ่ม delimiter อื่นๆเช่น $ ... $ หรือ $$ ... $$ ได้ผ่าน Object window.MathJax โดย '[+]: ' หมายถึงการเพิ่มค่าต่อจากค่าเริ่มต้นที่กำหนดมาให้
<head> ... <script> function domReady(callback){ if (document.readyState != 'loading') callback(); else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback); } domReady(function () { let body = document.body.textContent; if (body.match(/(?:\$|\\\(|\\\[|\\begin\{.*?})/)) { if (!window.MathJax) { window.MathJax = { tex: { inlineMath: {'[+]': [['$', '$']]}, displayMath: {'[+]': [['$$', '$$']]} } } let script = document.createElement('script'); script.src = 'mathjax3.2.0/tex-svg.js'; script.async = true; document.head.appendChild(script); } } }); </script> ... </head>
จากปัญหาและการตั้งค่าจากเวอร์ชัน 2.4 สามารถนำมาใช้ตั้งค่าในเวอร์ชัน 3.2 ได้ดังนี้
... window.MathJax = { tex: { inlineMath: {'[+]': [['$', '$']]}, displayMath: {'[+]': [['$$', '$$']]}, macros: { bmatrix: ['\\begin{bmatrix}#1\\end{bmatrix}', 1], Bmatrix: ['\\begin{Bmatrix}#1\\end{Bmatrix}', 1], vmatrix: ['\\begin{vmatrix}#1\\end{vmatrix}', 1], Vmatrix: ['\\begin{Vmatrix}#1\\end{Vmatrix}', 1], cases: ['\\begin{cases}#1\\end{cases}', 1], euler: '\\atopwithdelims<>', sech: '\\text{sech}\\,' } }, svg: { mtextInheritFont: true, scale: 1, fontCache: 'global' } } ...