> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md).

# Giới thiệu về LuaTeX (Phần 1): Nó là gì—và điều gì làm nó khác biệt đến vậy?

LuaTeX là một *bộ công cụ*—nó chứa các công cụ phần mềm và các thành phần tinh vi mà bạn có thể dùng để xây dựng (dàn trang) rất nhiều loại tài liệu. Tiêu đề phụ của bài viết này cũng đặt ra hai câu hỏi về LuaTeX: Nó là gì — và điều gì khiến nó khác biệt đến vậy? Câu trả lời cho “Nó là gì?” có vẻ hiển nhiên: “Đó là một bộ máy dàn trang TeX!” Quả thực là vậy, nhưng một cách nhìn rộng hơn, và là cách nhìn mà tác giả này cũng đồng tình, là LuaTeX là một hệ thống dựa trên TeX cực kỳ linh hoạt *hệ thống xây dựng và kỹ thuật tài liệu*.

### Giải thích LuaTeX: Bắt đầu từ đâu?

Mục tiêu của bài viết đầu tiên này về LuaTeX là cung cấp một bối cảnh để hiểu bộ máy TeX này mang lại điều gì và vì sao/như thế nào thiết kế của nó cho phép người dùng xây dựng/thiết kế/tạo ra rất nhiều giải pháp cho các vấn đề dàn trang và thiết kế phức tạp — có lẽ cũng mang lại một mức độ “chuẩn bị cho tương lai” nào đó khi người dùng ngày càng cần phần mềm dựa trên TeX có khả năng thích ứng với hệ sinh thái kỹ thuật luôn thay đổi. Theo quan điểm của tác giả này, việc liệt kê và mô tả các tính năng/khả năng của nó không nhất thiết là nơi tốt nhất để bắt đầu khi phát triển sự hiểu biết về năng lực và tiềm năng của LuaTeX. Cách tiếp cận như vậy sẽ không đặc biệt hữu ích cho những độc giả không quen với các bộ máy TeX khác và với họ thì các so sánh dựa trên tính năng khó có ý nghĩa đặc biệt.

Trước nguy cơ làm cạn kiệt sự kiên nhẫn của người đọc (“Cứ đi thẳng vào vấn đề đi!”), tôi sẽ tiếp cận theo cách “toàn diện” hơn, hy vọng cung cấp được bối cảnh hữu ích, nhưng phải trả giá bằng việc đọc thêm — và đi sâu vào một vài chủ đề lập trình để hỗ trợ việc hiểu. Trong [Phần 2](/latex/vi/bai-viet-chuyen-sau/09-an-introduction-to-luatex-part-2-understanding-directlua.md) chúng ta khám phá việc sử dụng `\directlua` nhưng, hiện tại, chúng ta cố gắng đặt nền tảng cơ bản để hiểu LuaTeX.

Bài viết này phản ánh mạnh mẽ “hành trình” cá nhân của tác giả trong việc phát triển sự hiểu biết và trân trọng LuaTeX: rằng bằng cách trước hết biết một chút về triết lý đằng sau sự phát triển của LuaTeX, và nhìn nó như một kho chứa các công cụ phần mềm, bạn sẽ đánh giá cao hơn những miền giải pháp rộng lớn mà phần mềm tuyệt vời này mở ra.

## LuaTeX: Không chỉ dành cho học thuật, hay toán học!

Kho tính năng và chức năng được tích hợp trong LuaTeX không chỉ mang lại chất lượng dàn trang đặc biệt cao thông qua LaTeX truyền thống mà còn mở ra phạm vi rất lớn để phát triển các giải pháp tùy biến, không dựa trên LaTeX, cho các vấn đề sản xuất và kỹ thuật tài liệu phức tạp. LuaTeX được tích hợp ngôn ngữ kịch bản Lua mạnh mẽ, nghĩa là, chẳng hạn, bạn có thể dùng Lua để nạp các “plugin” (thư viện phần mềm bên ngoài) vào LuaTeX; điều này còn cho phép tự động hóa ở mức cao, tích hợp vào các hệ thống hoặc quy trình phần mềm hiện có, và tận dụng phần mềm chuyên dụng để xử lý dữ liệu, văn bản hoặc đồ họa.

Trong lịch sử, TeX gắn liền với việc soạn thảo/xuất bản học thuật, đặc biệt trong toán học, nhưng LuaTeX, nói riêng, có tiềm năng ứng dụng đáng kể trong nhiều lĩnh vực khác — bao gồm cả sản xuất tài liệu PDF thương mại. Một ví dụ như vậy là [speedata publisher](https://speedata.github.io/publisher/) thứ sử dụng LuaTeX thuần túy như bộ máy tạo PDF trong quy trình làm việc dựa trên XML của nó — nó hoàn toàn không dùng LaTeX. Thực ra, speedata publisher hầu như không chứa mã TeX nào — tôi đã hỏi [Patrick Gundlach](https://twitter.com/patrickgundlach)tác giả của speedata publisher, người đã xác nhận rằng, tổng cộng, nó chỉ dùng khoảng ba dòng mã TeX. Các khả năng dàn trang mạnh mẽ của nó được thiết kế và triển khai bằng mã Lua, sử dụng Lua API của LuaTeX (một chủ đề chúng ta sẽ thảo luận sau trong bài viết này).

## Một câu chuyện cá nhân ngắn: Tôi lần đầu phát hiện LuaTeX như thế nào

Tôi lần đầu biết đến LuaTeX vào cuối năm 2009/đầu năm 2010, khi nó vẫn đang ở giai đoạn phát hành beta giữa chừng (phiên bản 0.50). Khi đó tôi đang tìm phần mềm dựa trên TeX để dàn trang các ghi chú viết tay từ nỗ lực học tiếng Ả Rập của mình. Tìm kiếm trên Google cho thấy một bộ video từ hội nghị TUG 2009 ([hiện có trên YouTube](https://www.youtube.com/playlist?list=PL2D4DD50DC9C0BA0E)) trong đó có các minh họa về dàn trang tiếng Ả Rập chất lượng rất cao (thông qua gói [ConTeXt](http://wiki.contextgarden.net/Main_Page)). Các video đó cũng có một bài nói chuyện có tiêu đề [Dự án LuaTeX: nửa đường đến phiên bản 1](https://youtu.be/AKv4po9PGW0).

Bộ máy TeX được dùng để tạo ra kiểu dàn trang tiếng Ả Rập tinh tế ấy là thứ gọi là “LuaTeX”. Lúc đó tôi đang làm trong lĩnh vực xuất bản khoa học (vật lý), nhưng dù hoàn toàn biết về TeX/LaTeX thì tôi chưa từng nghe nói đến LuaTeX: tôi thấy tò mò và muốn tìm hiểu thêm về bộ máy TeX mới này. Vì LuaTeX lúc đó vẫn đang ở giai đoạn phát triển beta và đang phát triển rất nhanh, tôi muốn luôn cập nhật các bản mới nhất, nên lựa chọn tốt nhất (đối với tôi) là tự mình xây dựng (biên dịch) tệp thực thi LuaTeX từ mã nguồn của nó. Ngoài chương trình LuaTeX thực thi, bạn còn cần một “bản cài đặt TeX” để cung cấp môi trường chạy LuaTeX (ví dụ: texmf.cnf, các gói macro, phông chữ, v.v.). Thay vì tải về và cài đặt bản phân phối TeX khổng lồ [TeX Live](https://www.tug.org/texlive/) bản phân phối tôi đã chọn tạo một bản cài đặt TeX tùy biến cực kỳ tối thiểu để khám phá LuaTeX (một bài tập “thú vị” mà tôi [đã ghi lại trên blog cá nhân của mình](http://www.readytext.co.uk/?cat=30)). Mỗi bản phát hành mới của LuaTeX đều đi kèm với Sổ tay Tham khảo của nó (ví dụ, cho[phiên bản 1.0.4](https://www.tug.org/svn/texlive/tags/texlive-2017.1/Master/texmf-dist/doc/luatex/base/luatex.pdf?revision=44591\&view=co)) mô tả các tính năng và chức năng mới nhất của phần mềm. Tuy nhiên, đó là một *tài liệu* tham khảo và (tất yếu) khá ít giải thích phù hợp cho người mới muốn bắt đầu với bộ máy TeX đáng kinh ngạc này — giả định là người đọc đã có một mức độ quen thuộc nào đó với các khái niệm TeX ở mức thấp. Do tôi phát hiện LuaTeX ở một giai đoạn khá sớm trong quá trình phát triển của nó, nên vào thời điểm đó tài liệu nhập môn tốt khá khó tìm, vì vậy tôi phải mất một chút tìm tòi, thử nghiệm (và cả đôi chút bực bội...) trước khi mọi thứ bắt đầu khớp lại. Không cần phải nói, việc học tiếng Ả Rập của tôi đột ngột bị gián đoạn khi tôi say mê phần mềm tuyệt vời này và cuối cùng chuyển sang viết các [plugin LuaTeX để dàn trang tiếng Ả Rập](http://www.readytext.co.uk/?p=3143) thay vào đó!

“Hành trình LuaTeX” của riêng tôi chắc chắn rất phi tuyến tính, nhưng trong suốt chặng đường đó, nó mang lại cơ hội học về (Lua)TeX (và các bản cài đặt TeX) “từ đầu”: blog của tôi lưu trữ một bộ sưu tập đa dạng của các [bài viết](http://www.readytext.co.uk/?cat=3) dựa trên nhiều chủ đề khác nhau mà tôi đã khám phá và làm việc trong thời gian đó. Hy vọng bài viết này sử dụng thích hợp khoảng thời gian và kinh nghiệm đó, giúp những người khác hứng thú để bắt đầu khám phá khả năng của LuaTeX. LuaTeX vẫn đang tiếp tục được phát triển và, tại thời điểm viết bài, nó đã đạt đến phiên bản 1.0.4, được phát hành cùng TeX Live 2017. Các nhà phát triển rất tích cực và mọi lỗi phát hiện ra thường được sửa ngay sau khi được báo cáo — ví dụ, qua [danh sách thư dev-luatex](https://mailman.ntg.nl/mailman/listinfo/dev-luatex) hoặc qua [trình theo dõi lỗi LuaTeX trực tuyến](http://tracker.luatex.org/my_view_page.php). Rất lâu trước khi đạt đến phiên bản 1.0, LuaTeX đã có thể dùng trong sản xuất — dù dĩ nhiên, bạn phải chấp nhận rằng các tính năng vẫn liên tục phát triển và đôi khi thay đổi có thể làm hỏng mã TeX hiện có của bạn. Ngày nay, dĩ nhiên, LuaTeX được hỗ trợ bởi các nền tảng Overleaf và ShareLaTeX (dưới dạng LuaLaTeX).

## TeX trong một thế giới thay đổi: Công nghệ và quy trình làm việc mới

Rõ ràng, các bộ máy TeX không hoạt động trong một thế giới tĩnh về công nghệ và đôi khi xuất hiện các đổi mới là ứng viên tức thì và hiển nhiên để được đưa vào các bộ máy TeX — một đổi mới như vậy là phông chữ biến đổi OpenType, mà chúng ta sẽ bàn ngắn gọn bên dưới. Mặc dù không còn nghi ngờ gì rằng phần mềm dàn trang dựa trên TeX là cực kỳ linh hoạt, các bộ máy TeX hiện nay hoạt động trong một hệ sinh thái phần mềm thay đổi nhanh chóng và rất đa dạng — các quy trình làm việc mới càng nhấn mạnh nhu cầu về tích hợp và tính linh hoạt để triển khai nhiều giải pháp tài liệu/dàn trang khác nhau, trong đó TeX có thể chỉ là một thành phần.

TeX không chỉ phải duy trì tính phù hợp với những người dùng hiện tại mà còn phải thu hút người dùng mới bằng cách cho phép các giải pháp tạo nội dung vẫn hữu ích cho các thế hệ tiếp theo — những người có thể không nhất thiết muốn dùng TeX như một công cụ độc lập mà, có lẽ, như một phần của toàn bộ quy trình làm việc thông qua các nền tảng cộng tác trực tuyến như Overleaf.

Ngay cả việc xem lướt qua [tex.stackexchange](https://tex.stackexchange.com/) cũng cho thấy vô số loại tài liệu và giải pháp đang được tạo ra và triển khai bằng phần mềm dựa trên TeX — thường thể hiện sự khéo léo đáng kinh ngạc khi con người tìm ra ngày càng nhiều trường hợp sử dụng và loại nội dung mà họ muốn tạo ra. Ngoài ra, nhu cầu về các quy trình làm việc có thể xử lý nội dung/đánh dấu dựa trên TeX để tạo ra đầu ra không phải PDF (và không phải DVI) chưa bao giờ lớn hơn — chẳng hạn như MathML/XML và HTML. Ví dụ, việc “chuyển đổi” TeX sang định dạng [JATS XML](https://jats.nlm.nih.gov/) (được dùng lâu nay trong xuất bản tạp chí học thuật) nhưng gần đây hơn còn là sự trỗi dậy của epub được dùng trong xuất bản sách điện tử.

### Công nghệ phông chữ biến đổi — Thời đại đang thay đổi

Vào ngày 14 tháng 9 năm 2016, Microsoft, [Google](https://opensource.googleblog.com/2016/09/introducing-opentype-font-variations.html), [Adobe](https://blog.typekit.com/2016/09/14/variable-fonts-a-new-kind-of-font-for-flexible-design/) và Apple đã công bố một công nghệ phông chữ mới: [phông chữ biến đổi OpenType](https://medium.com/@tiro/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369). Chúng ta sẽ không khám phá công nghệ này chi tiết nhưng chỉ cần nói rằng các chuyên gia phông chữ rất được kính trọng như [Thomas Phinney](https://twitter.com/ThomasPhinney) và [John Hudson](https://twitter.com/TiroTypeworks) đã nhận thấy ([trên Twitter](https://twitter.com/ThomasPhinney/status/917087509342851072)) rằng công nghệ phông chữ biến đổi đang được áp dụng nhanh hơn nhiều so với nhiều đổi mới phông chữ trước đây — rất có thể do nhu cầu của các nhà thiết kế web cần các thiết kế đáp ứng, có thể thích nghi với vô số kích thước/độ phân giải màn hình khác nhau trên thiết bị di động.

Rõ ràng, phông chữ biến đổi OpenType là một phát triển thú vị và đáng chú ý trong công nghệ phông chữ, điều mà người dùng TeX chắc chắn có thể hưởng lợi — thực tế, câu hỏi này tất yếu đã được [đặt ra trên tex.stackexchange](https://tex.stackexchange.com/questions/355104/tex-luatex-xetex-fontspec-support-for-opentype-variable-fonts) với sự hỗ trợ của LuaTeX được thảo luận trong [danh sách thư LuaTeX](https://www.tug.org/pipermail/luatex/2016-September/006204.html).

Nhân tiện, đáng lưu ý rằng công nghệ phông chữ dựa trên việc tạo phông chữ “tham số” không phải là một ý tưởng hoàn toàn mới: METAFONT của Knuth và các công nghệ Multiple Master của Adobe, ở một vài khía cạnh, là những tiền thân sớm, dù chi tiết triển khai khá khác nhau.

### Phông chữ biến đổi: Chúng ta muốn chúng khi nào — ngay bây giờ?

Bất kỳ tiêu chuẩn/quy chuẩn công nghệ mới và hữu ích nào cũng cần thời gian để “thấm” vào hệ sinh thái mục tiêu của các nhà phát triển và người triển khai — bao gồm thời gian để làm rõ mọi điểm mơ hồ hoặc cách diễn giải các cách dùng từ trong chính đặc tả. Các nhà phát triển phải đọc và hiểu tài liệu rồi biến nó thành phần mềm hoạt động thực tế — trong trường hợp này bao gồm cả việc tạo ra các phông chữ và công nghệ để sử dụng chúng: các trình duyệt và bộ máy dàn trang tương thích. Các nhà phát triển TeX rõ ràng sẽ cần quyền truy cập vào các phông chữ biến đổi chất lượng cao có thể dùng như những “chuẩn tham chiếu” đáng tin cậy để triển khai (lập trình) hỗ trợ cho công nghệ phông chữ biến đổi.

Việc triển khai bất kỳ công nghệ mới nào trong TeX, như phông chữ biến đổi, đặt ra *khả năng* cần phải sửa đổi các phần bên trong của bộ máy TeX — tất nhiên, việc có cần làm vậy hay không phụ thuộc vào bản chất của công nghệ đó và, quan trọng hơn, khía cạnh nào trong hành vi của TeX đang bị thay đổi. Không phải lúc nào cũng cần sửa đổi chính bộ máy TeX, mà có thể chỉ cần thay đổi phần mềm hỗ trợ/phụ trợ, bao gồm bất kỳ “thành phần” nào (thư viện mã của bên thứ ba) được dùng trong các chương trình đó. Về mặt nội bộ, các bộ máy TeX vốn *cực kỳ* phức tạp — việc phát triển sự hiểu biết đủ về mã nguồn TeX để thực hiện sửa đổi đáng tin cậy đòi hỏi chuyên môn đáng kể và rất chuyên biệt (mà nguồn lực này rất hạn chế). Điều quan trọng nữa là mọi sửa đổi không được ảnh hưởng xấu đến tính ổn định/tương thích lâu dài của các bộ máy TeX — điều cực kỳ quan trọng đối với cộng đồng TeX và đối với những người sau đó xử lý các tệp (La)TeX của tác giả: nổi bật nhất là các nhà xuất bản học thuật và các dịch vụ dựa trên đám mây như Overleaf và ShareLaTeX.

Nhiều người dùng TeX có thể sẽ muốn tận dụng phông chữ biến đổi; ví dụ, triển khai các khả năng thiết kế mới hoặc tìm giải pháp cho các vấn đề dàn trang hóc búa. Vì vậy, theo một nghĩa nào đó, có một tình thế tiến thoái lưỡng nan: người dùng TeX muốn tiếp cận một công nghệ mới nhưng việc triển khai lại phụ thuộc vào một nguồn lực rất hạn chế: số lượng nhà phát triển đủ năng lực và có khả năng biến nó thành hiện thực. Việc sửa đổi nội bộ TeX là khó khăn, và nhìn chung, tốt nhất nên tránh khi có thể, vậy có cách nào khác để thêm (một số loại) tính năng/khả năng mới vào TeX không? Có! Và LuaTeX đã đi theo con đường đó.

#### Các thử nghiệm ban đầu: phông chữ biến đổi OpenType và LuaTeX

Thiết kế của LuaTeX đã cho phép thử nghiệm nhanh với công nghệ phông chữ biến đổi. Từ tháng 4 năm 2017, định dạng TeX ConTeXt, vốn sử dụng LuaTeX, đã có một [phiên bản beta](https://mailman.ntg.nl/pipermail/ntg-context/2017/088343.html) triển khai phông chữ biến đổi OpenType. Điều này có thể thực hiện được vì hỗ trợ phông chữ của ConTeXt được xây dựng bằng mã Lua (và ConTeXt có trình nạp phông chữ riêng được viết bằng Lua).

## LuaTeX: Bối cảnh và lịch sử

LuaTeX, theo thuật ngữ TeX, là “tân binh” dù đã được phát triển tích cực hơn 10 năm. Trang web LuaTeX [ghi rõ](http://www.luatex.org/roadmap.html) rằng LuaTeX bắt đầu từ năm 2005 và (theo tôi biết) việc phát triển tích cực, liên tục bắt đầu vào năm 2006. Do tính phức tạp vốn có của nó, và sự tận tâm của những người xây dựng nó, LuaTeX thực sự đã mất 10 năm phát triển để đạt đến phiên bản 1.0, được [các nhà phát triển của nó công bố](https://mailman.ntg.nl/pipermail/dev-luatex/2016-September/005882.html) (Hans Hagen, Hartmut Henkel, Taco Hoekwater, Luigi Scarso) vào ngày 27 tháng 9 năm 2016.

Trong thông báo phát hành đó có một tuyên bố nguyên tắc quan trọng:

> “Mục tiêu chính của chúng tôi là cung cấp một biến thể của TeX cho phép mở rộng bởi người dùng mà không cần phải điều chỉnh cơ chế bên trong.”

Cách diễn đạt này cô đọng hoàn hảo triết lý đằng sau sự phát triển của LuaTeX và chỉ ra một con đường mà qua đó phần mềm dựa trên TeX có thể giải quyết những thách thức mà chúng ta đã nhắc đến: tiếp nhận các công nghệ mới và duy trì tính phù hợp với các thế hệ người dùng mới.

Giờ là lúc giải đáp câu hỏi thứ hai trong tiêu đề phụ của bài viết này: “điều gì khiến nó khác biệt đến vậy”. Bằng cách khám phá ý nghĩa của “...cho phép mở rộng bởi người dùng mà không cần phải điều chỉnh cơ chế bên trong”, chúng ta có thể hiểu rõ hơn bản chất của những gì LuaTeX “mang lên bàn”.

## LuaTeX: Mở “hộp đen” của TeX

Chương trình TeX nguyên bản của Knuth là tổ tiên chung của tất cả các bộ máy TeX hiện đại đang được dùng ngày nay và LuaTeX, về thực chất, là bước tiến hóa mới nhất: được phát triển từ chương trình pdfTeX nhưng bổ sung thêm một số thành phần phần mềm mạnh mẽ mang lại rất nhiều chức năng bổ sung. Khi Knuth viết phiên bản gốc của phần mềm TeX, ông cũng cung cấp ngôn ngữ TeX như một cách để điều khiển và lập trình hành vi dàn trang của nó: khoảng 320 lệnh mức thấp (primitive) đã được cung cấp cho người dùng và các nhà phát triển gói macro TeX. Những lệnh đó mang lại các mức độ kiểm soát hoặc ảnh hưởng khác nhau đối với một số khía cạnh trong hành vi dàn trang của TeX, nhưng phần lớn chức năng nội bộ, thuật toán, quy trình ra quyết định, dữ liệu và cấu trúc dữ liệu của TeX đều bị ẩn khỏi người dùng. Có thể nói, chương trình TeX của Knuth không hoàn toàn là một “hộp đen”, nhưng chắc chắn là một sắc xám rất đậm — phải thừa nhận rằng mã nguồn đã được công bố, nhưng đối với đại đa số mọi người, nó cũng là một hộp đen của sự khó hiểu.

Chúng ta gọi các quá trình bên trong TeX là phần nào đó như một “hộp đen”; tuy nhiên, LuaTeX mở các phần nội bộ dựa trên TeX của nó để cung cấp cho người dùng/nhà phát triển quyền truy cập và kiểm soát lớn hơn nhiều đối với nhiều quá trình từng bị ẩn diễn ra sâu bên trong bộ máy TeX. LuaTeX cũng bổ sung nhiều lệnh primitive mới cung cấp quyền điều khiển các tính năng mới.

### LuaTeX: Dẫn xuất từ pdfTeX nhưng không dùng mã của pdfTeX

Để chính xác, cần lưu ý rằng mặc dù chúng ta mô tả LuaTeX là dẫn xuất từ pdfTeX, LuaTeX không trực tiếp sử dụng mã chương trình gốc của pdfTeX. Một trong những nhà phát triển của LuaTeX (Taco Hoekwater) đã thực hiện công việc thật sự *kiểu Herculean* là viết lại lõi bộ máy TeX của LuaTeX bằng mã C sạch và hiện đại (CWEB).

#### Ghi chú lịch sử

Một phần do tuổi đời của mã nguồn TeX nguyên bản của Knuth — từ đó các hậu duệ hiện đại của nó được phát triển — việc sửa đổi nó để thích ứng hoặc tạo ra các bộ máy dàn trang dựa trên TeX mới là một quá trình phức tạp và rắc rối. Một phần của quá trình đó đòi hỏi chuyển đổi mã Pascal sang mã C — điều này không hề thiếu [một mức độ phức tạp nhất định](http://www.readytext.co.uk/?p=2529). Mã C do máy tạo ra vì thế cực kỳ dài dòng và rất khó đọc hay hiểu. Rõ ràng, việc mã của LuaTeX được viết lại hoàn toàn đã tránh được toàn bộ quá trình chuyển đổi từ Pascal sang C.

## Các khối xây dựng của LuaTeX

Trong phần giới thiệu, chúng ta đã nhắc đến LuaTeX như một “bộ công cụ” và mô tả nó là một “hệ thống xây dựng và kỹ thuật tài liệu”. Chúng ta đã thấy rằng trong thông báo LuaTeX 1.0, các nhà phát triển của nó tuyên bố:

> “Mục tiêu chính của chúng tôi là cung cấp một biến thể của TeX cho phép mở rộng bởi người dùng mà không cần phải điều chỉnh cơ chế bên trong.”

Giờ là lúc ghép các mạch này lại với nhau và tập trung vào chi tiết của việc tất cả những điều này *thực sự có nghĩa là gì* trong thực tế.

### Mảnh ghép LuaTeX

Nếu bạn nhìn “dưới nắp máy” sẽ thấy phần mềm LuaTeX, tức là chương trình thực thi thực tế, được cấu thành từ một tập hợp các thành phần phần mềm được kết hợp với nhau để cung cấp toàn bộ chức năng của LuaTeX. Dĩ nhiên, điều này không có gì mới và hầu hết phần mềm đều được xây dựng như vậy. Tuy nhiên, điều làm LuaTeX khác với các bộ máy TeX khác là các thành phần này được kết hợp theo cách cho phép người dùng tiếp cận rộng hơn nhiều đến nhiều khía cạnh trong chức năng nội bộ của TeX: các thuật toán dàn trang, quy trình ra quyết định, dữ liệu và cấu trúc dữ liệu của TeX. Việc mở ra các phần nội bộ của TeX này cho phép người dùng xây dựng các giải pháp dàn trang mới mà không cần phải sửa đổi chính bộ máy TeX thực sự.

### Phần Lua trong LuaTeX: Chìa khóa cho “hộp đen”

Lua là một ngôn ngữ kịch bản rất mạnh mẽ nhưng lại dễ học, [có nguồn gốc từ Brazil](https://www.lua.org/about.html)—nó được tạo ra vào năm 1993 và vẫn đang được phát triển tích cực. Một trong những điểm mạnh của Lua là việc dùng nó như một ngôn ngữ lập trình để “ghép nối” các thành phần phần mềm rời rạc, cho phép bạn sử dụng chúng thông qua một ngôn ngữ kịch bản đơn giản nhưng linh hoạt. Lua đóng vai trò trung tâm trong việc mở ra cơ chế bên trong của bộ máy TeX LuaTeX, nhưng để hiểu rõ hơn cách điều này đạt được, đáng để đi chệch một chút để rất ngắn gọn thảo luận hai khái niệm lập trình:

* Giao diện lập trình ứng dụng (API);
* liên kết ngôn ngữ lập trình.

Hãy thoải mái bỏ qua phần này nếu bạn đã quen với các khái niệm đó. Sẽ không có chủ đề nào được trình bày chi tiết — chúng ta không hướng đến tính nghiêm ngặt kỹ thuật tuyệt đối mà thay vào đó chỉ cung cấp bối cảnh đủ để nhận biết những khái niệm này: ý nghĩa và sự liên quan của chúng đối với LuaTeX.

### Giao diện lập trình ứng dụng (API)

Hãy tưởng tượng bạn là một lập trình viên đã viết một đoạn mã mà người dùng (các lập trình viên khác) có thể thấy hữu ích, nhưng mã của bạn phức tạp và bạn không muốn người dùng phải bận tâm đến những chi tiết cấp thấp đó. Lưu ý rằng các lập trình viên/nhà phát triển đó đang làm việc với cùng một ngôn ngữ lập trình mà bạn đã dùng để viết mã của mình. Hơn nữa, giả sử bạn có kế hoạch viết lại một số phần của mã — ví dụ, để làm cho nó nhanh hơn, cần ít bộ nhớ hơn, v.v. Những người dùng hiện tại của mã bạn không nên phải lo lắng về điều đó: bất kỳ thay đổi nào bạn dự định thực hiện cũng không được làm hỏng các chương trình của họ. Vậy, giải pháp là gì?

Câu trả lời nằm ở thứ gọi là API: một *Giao diện lập trình ứng dụng*. Thay vì yêu cầu người dùng (các lập trình viên khác) truy cập vào các chi tiết cấp thấp của mã của bạn — thứ có thể thay đổi — bạn cung cấp một tập hợp cụ thể các *hàm* mà các lập trình viên khác có thể sử dụng. Những hàm đó là một *giao diện* cho mã của bạn, thông qua đó các nhà phát triển khác có thể xây dựng *ứng dụng* mà không cần biết tường tận cơ chế bên trong chương trình của bạn. Ở một số khía cạnh, bạn có thể xem đây như một lớp bổ sung bao quanh mã của bạn và “cách ly” người dùng khỏi các chi tiết rắc rối, cấp thấp.

Miễn là bạn không thay đổi các hàm đó (giao diện), bạn có thể tự do sửa đổi và cập nhật các chi tiết cấp thấp hơn của phần mềm mà không ảnh hưởng (làm hỏng) công việc của những người đang dựa vào mã của bạn để xây dựng ứng dụng của họ: do đó mới có thuật ngữ Giao diện lập trình ứng dụng.

#### Các API: một phép so sánh với gói LaTeX

Khi bạn dùng các lệnh do một gói LaTeX cung cấp, bạn có thể xem các lệnh của gói đó như một dạng API. Với tư cách là người dùng, bạn không nhất thiết quan tâm đến phép thuật TeX và LaTeX đằng sau những lệnh đó (tức là trong mã của gói): tất cả những gì bạn muốn là tận dụng chức năng mà chúng cung cấp.

### Liên kết ngôn ngữ lập trình

Chúng ta đã thấy rằng các lập trình viên viết/công bố một khối mã hữu ích (gọi là một *thư viện*) có thể cung cấp cái gọi là Giao diện lập trình ứng dụng (một tập hợp các hàm) thông qua đó các lập trình viên khác, sử dụng cùng *cùng* một ngôn ngữ lập trình, có thể sử dụng thư viện đó (tập hợp mã). Điều này là ổn khi cả hai bên (nhà phát triển thư viện và người dùng của nó) đều dùng *cùng* ngôn ngữ lập trình *khác* cũng muốn sử dụng thư viện đó thì sao? Ví dụ, bạn có thể viết các script bằng ngôn ngữ Lua nhưng lại muốn sử dụng một thư viện được viết bằng, chẳng hạn, các ngôn ngữ lập trình như C/C++. Theo cách nào đó, hai ngôn ngữ lập trình khác nhau (Lua và C/C++) cần có khả năng “giao tiếp” với nhau. Một giải pháp cho vấn đề này là cái gọi là [liên kết ngôn ngữ](https://en.wikipedia.org/wiki/Language_binding).

Việc xem xét các chi tiết kỹ thuật của liên kết ngôn ngữ nằm ngoài phạm vi của bài viết này nên chúng ta sẽ đưa ra một tóm tắt ngắn gọn về các nguyên lý chung. Về bản chất, bằng cách thêm một “lớp” mã phù hợp vào thư viện gốc, nó có thể “giao tiếp” với một ngôn ngữ lập trình khác (như Lua): lớp mã đó được gọi là một *liên kết*. Nó cho phép hai ngôn ngữ tương tác với nhau thông qua một API để các lập trình viên ở ngôn ngữ thứ hai (như Lua) có thể dùng để truy cập các tính năng/dịch vụ do thư viện cung cấp.

![Sơ đồ minh họa khái niệm liên kết ngôn ngữ.](/files/9d100dec0a2f128fad601f1b9ddea3eb15b25b34)

**Hình 1**Sơ đồ minh họa khái niệm liên kết ngôn ngữ: cho phép một chương trình viết bằng Lua sử dụng một thư viện bên ngoài được viết bằng ngôn ngữ lập trình khác. Chính nhờ việc sử dụng các liên kết Lua mà các thành phần nội bộ của LuaTeX, và do đó phần lớn chức năng dàn trang bên trong của LuaTeX, được cung cấp cho người dùng để phát triển các giải pháp cho các vấn đề dàn trang phức tạp.

## LuaTeX: Hai lựa chọn cho lập trình — TeX và Lua

Về cơ bản, LuaTeX là một bộ máy TeX hỗ trợ hai ngôn ngữ lập trình: ngôn ngữ dựa trên TeX truyền thống và ngôn ngữ kịch bản Lua. Dĩ nhiên, bạn có thể dùng cả hai ngôn ngữ trong cùng một tài liệu TeX hoặc, nếu muốn, tiếp tục dàn trang theo con đường chỉ dùng TeX: ví dụ, thông qua gói macro LaTeX (LuaLaTeX). TeX (hay LaTeX) không phải là một ngôn ngữ lập trình dễ dùng hay dễ học, và số người thực sự làm chủ được nhiều tính chất đặc thù của TeX là tương đối ít — các khái niệm về [token](https://www.overleaf.com/blog/522-what-is-a-tex-token) và sự mở rộng của TeX khá xa lạ với đa số kỳ vọng và trải nghiệm của mọi người về một ngôn ngữ lập trình.

Việc bổ sung Lua mở ra khả năng sử dụng dàn trang dựa trên TeX thông qua một ngôn ngữ lập trình quen thuộc và dễ tiếp cận hơn nhiều — như đã lưu ý gần đầu bài viết này, bằng cách dùng Lua API bạn có thể thực hiện [dàn trang tinh vi với hầu như không cần mã TeX nào](http://wiki.luatex.org/index.php/TeX_without_TeX).

### LuaTeX bổ sung nhiều primitive mới

Mỗi bộ máy TeX đều cung cấp hàng trăm lệnh primitive được gọi như vậy: những khối xây dựng cơ bản của ngôn ngữ dựa trên TeX mà mỗi bộ máy dàn trang riêng lẻ hỗ trợ. Phiên bản TeX nguyên gốc do Donald Knuth phát hành cung cấp khoảng 320 lệnh, nhưng các bộ máy TeX mới hơn (pdfTeX, XeTeX và LuaTeX) đều đã thêm nhiều primitive mới để cung cấp cho người dùng quyền truy cập vào các tính năng và chức năng bổ sung của mỗi bộ máy. Số lượng primitive mới đáng kể của LuaTeX được ghi trong [Sổ tay Tham khảo](https://www.tug.org/svn/texlive/tags/texlive-2017.1/Master/texmf-dist/doc/luatex/base/luatex.pdf?revision=44591\&view=co).

Trong số nhiều primitive mới do LuaTeX đưa vào có lệnh từng được gọi là `\directlua{...}` đây là cổng để sử dụng mã Lua: truy cập vào các cơ chế bên trong của bộ máy LuaTeX để xây dựng các công cụ và giải pháp dàn trang tinh vi.

### \directlua{...}: Cổng vào lập trình Lua

Như đã thảo luận, ngôn ngữ kịch bản Lua có thể được xem như cung cấp một “lớp” thông qua đó có thể truy cập vào bộ máy dàn trang dựa trên TeX của LuaTeX và chức năng do nhiều thành phần cấu thành LuaTeX cung cấp. Ngôn ngữ Lua cũng là cơ chế cho phép LuaTeX có thể mở rộng — nhờ khả năng của Lua trong việc nạp các thư viện phần mềm/mã chuyên dụng từ bên ngoài.

Tập hợp giao diện Lua (các hàm dựa trên Lua) do LuaTeX cung cấp được gọi là *Lua API*: đó là “liên kết truyền thông” giữa bộ máy/thành phần nội bộ của LuaTeX và tài liệu của người dùng.

### Một ví dụ đơn giản về \directlua{...}

Các *cực kỳ đơn giản* ví dụ này thậm chí còn chưa chạm tới bề mặt của vô vàn khả năng. Tuy nhiên, nó phục vụ để minh họa ý tưởng cơ bản về sự tương tác giữa “cách TeX” và “cách Lua” để truy cập các tham số của TeX.

Lưu ý rằng:

* `\hsize` là một primitive (lệnh) của TeX, lệnh này đặt giá trị của một tham số nội bộ xác định độ rộng của các dòng đã dàn trang — ví dụ, bạn thường đặt nó về một giá trị thích hợp trong một `\vbox{...}`. `\hsize` chỉ là một trong *nhiều* các tham số TeX mà bạn có thể truy cập và/hoặc chỉnh sửa bằng mã Lua.
* Việc truy cập các tham số TeX chỉ là một *khía cạnh* nhỏ bé của Lua API trong LuaTeX: còn rất nhiều điều nữa!

```latex

\documentclass{article}
\begin{document}
\let\\\relax %định nghĩa lại ý nghĩa của \\ để tránh các vấn đề mở rộng
Đây là giá trị hiện tại của {\ttfamily\string\hsize} (qua \LaTeX):
\the\hsize\par
\directlua{
%Lấy giá trị hiện tại của \hsize bằng Lua API
local hs=tex.hsize
% Dùng một hàm của Lua API để in một số
% mã LaTeX và giá trị của \hsize
tex.print("Đây là giá trị của {\\ttfamily\\string\\hsize}
được báo từ mã Lua (tính bằng scaled points): ")
tex.print(hs.."\\par")
% Đặt một giá trị mới cho \hsize bằng Lua API
tex.hsize="400pt" % hoặc dùng tex.hsize=400*65536 (tính bằng scaled points)
}%
% Sau khi \directlua kết thúc, yêu cầu LaTeX
% cho chúng ta biết giá trị mới của \hsize
Đây là giá trị của {\ttfamily\string\hsize} được báo
bởi \LaTeX{} sau khi {\tt\string\directlua} kết thúc:
\the\hsize\par
\end{document}
```

Đây là một hình ảnh cho thấy kết quả của việc LuaTeX dàn trang mã LaTeX (ở trên):

![Kết quả chạy LuaTeX](/files/c91a02cdc9f074e12af2257f04dcb4c06de28adb)

Lưu ý rằng “mánh khóe” TeX của `\let\\\relax` là để tránh các vấn đề do LuaTeX “mở rộng” mã Lua gây ra: một chủ đề chúng ta sẽ lưu ý ngắn gọn bên dưới.

### Sử dụng mã Lua

Có hai lựa chọn chính để dùng mã Lua trong tài liệu TeX/LaTeX của bạn:

1. **Nhúng trực tiếp**: Viết mã Lua trực tiếp trong `.tex` tài liệu của bạn (như trong ví dụ ở trên);
2. **Bên ngoài**: Lưu mã Lua trong các `.lua` tệp mã bên ngoài và dùng các công cụ của Lua để nạp và chạy chúng.

Lựa chọn (1) phù hợp nhất cho các đoạn mã Lua ngắn. Lựa chọn (2) được dùng cho các chương trình lớn hơn hoặc các thư viện mã Lua. Nó có một ưu điểm rõ rệt là bạn có thể tránh những vấn đề rắc rối liên quan đến cái gọi là `\catcode` giá trị (điều có thể “khá bực bội”). Lý do của những `\catcode` vấn đề này là việc “mở rộng” mã Lua trước khi đưa vào bộ thông dịch Lua tích hợp sẵn của LuaTeX. Sự mở rộng này có thể khó hiểu nên chúng ta sẽ khám phá thêm trong một bài viết tiếp theo.

Dĩ nhiên có các gói LaTeX hỗ trợ việc dùng mã Lua trong các tệp .tex của bạn — ví dụ, bạn có thể dùng [gói luacode](https://ctan.org/pkg/luacode?lang=en).

## Tổng kết và giới thiệu Phần 2 của bài viết này

Các thành phần phần mềm tạo nên LuaTeX, cùng với ngôn ngữ kịch bản Lua được nhúng, tạo ra một sự kết hợp mạnh mẽ để xây dựng các giải pháp có khả năng giải quyết một loạt rộng các vấn đề dàn trang phức tạp—và thiết kế các quy trình sản xuất tài liệu có thể hưởng lợi từ sự tích hợp chặt chẽ với một bộ máy dàn trang dựa trên TeX. Trong [Phần 2 của bài viết này](/latex/vi/bai-viet-chuyen-sau/09-an-introduction-to-luatex-part-2-understanding-directlua.md) chúng ta sẽ xem xét chuyên sâu lệnh mạnh mẽ nhất mà LuaTeX cung cấp: `\directlua`.

Cho đến lúc đó, chúc bạn LuaTeX vui vẻ!

## Lời cảm ơn

Tác giả vô cùng biết ơn [Luigi Scarso](https://twitter.com/luigi_scarso), một trong những nhà phát triển của LuaTeX, vì đã dành thời gian đọc bản thảo của bài viết này và đưa ra nhiều nhận xét cũng như gợi ý rất hữu ích. Mọi sai sót còn lại về तथ्य, hoặc thiếu sót, dĩ nhiên là của tác giả. Ngoài ra, tôi cũng muốn cảm ơn [Patrick Gundlach](https://twitter.com/patrickgundlach), nhà phát triển của [speedata publisher](https://speedata.github.io/publisher/), vì đã dành thời gian trả lời các câu hỏi của tôi.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
