Hi! This is my initial attempt at supporting LuaTeX for current CJK code.
However looking through the code I think we should separate CJK related code in a function, so we can reuse the code. Seems like currently only the babel backend has peoper CJK support? Plain fontspec and polyglossia both seem to only call `org-latex--insert-fontspec' which loads only xeCJK or luatexja.
>From 9ce42f667c282da7083a1a6e2dd629a530915675 Mon Sep 17 00:00:00 2001 From: RadioNoiseE <[email protected]> Date: Mon, 1 Dec 2025 22:10:47 +0800 Subject: [PATCH] lisp/ox-latex.el: initial lualatex based cjk support * lisp/ox-latex.el (org-latex--insert-fontspec): Add case for lualatex, and move \includepackage{indentfirst} here to avoid duplicating in `org-latex--utf8latex-fontspec-configure' and `org-latex--utf8latex-polyglossia-config'. (cn-default-fontspec): Chinese alternative to `jp-default-fontspec'. (org-latex--utf8latex-babel-config): Handle lualatex specific case. Create a wrapper around luatexja provided interface so it integrates with existing code. (org-latex--utf8latex-fontspec-config): Remove CJK related code as they use `org-latex--insert-fontspec'. --- lisp/ox-latex.el | 55 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index fd4e8b845..b77795cf5 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -2065,7 +2065,7 @@ DEFAULT-FEATURES is the default features for all fonts DOC-SCRIPTS are the scripts detected in the buffer Will warn about compiler use: - - xelatex is needed for CJK fonts + - xelatex or lualatex is needed for CJK fonts - lualatex is needed for fallbacks This part can be reused in pure fontspec and in fontspec+polyglossia." @@ -2084,9 +2084,12 @@ This part can be reused in pure fontspec and in fontspec+polyglossia." do (setq cjk-packages (or cjk-packages (string-match-p "^CJK" (car font-spec))))) (when cjk-packages - (if (string= compiler "xelatex") - (insert "\\usepackage{xeCJK}\n") - (warn "You need xelatex to use CJK fonts!"))) + (insert "\\usepackage{indentfirst}\n") + (cond ((string= compiler "xelatex") + (insert "\\usepackage{xeCJK}\n")) + ((string= compiler "lualatex") + (insert "\\usepackage{luatexja}\n")) + (warn "You need xelatex or lualatex to use CJK fonts!"))) ;; If there are font features, include them (when default-features (insert (org-latex--create-default-fontspec-features @@ -2224,6 +2227,17 @@ else signal error." (plist-get lang-plist :babel-ini-only) lang))) +(defconst cn-default-fontspec + '(("CJKmain" . "FandolSong") + ("CJKsans" . "FandolHei")) + "The default CJK fonts for Chinese. + +luatexja provides default font settings for Japanese. +They need to be set to follow Chinese convention. +This is an abbreviated representation for luatexja's +NFSS2 font interface, mincho and gothic, corresponding to +main and sans font.") + (defconst jp-default-fontspec '(("CJKmain" . "HaranoAjiMincho") ("CJKsans" . "HaranoAjiGothic") @@ -2265,17 +2279,26 @@ Use fontspec as a last resort and when defined." (save-match-data ;; FIXME: Korean? (let* ((main-lang (car-safe latex-babel-langs)) - (use-xecjk (member main-lang '("jp" "zh")))) - (when use-xecjk - (unless (string= compiler "xelatex") - (error "Using xeCJK for jp and zh requires compiler xelatex")) - (insert "\\usepackage{xeCJK}\n\\usepackage{indentfirst}")) + (with-cjk (member main-lang '("jp" "zh")))) + (when with-cjk + (insert "\\usepackage{indentfirst}\n") + (cond ((string= compiler "xelatex") + (insert "\\usepackage{xeCJK}\n")) + ((string= compiler "lualatex") + (insert (concat "\\makeatletter\n" + "\\def\\setCJKmainfont#1{\\def\\ltj@stdmcfont{#1}}\n" + "\\def\\setCJKsansfont#1{\\def\\ltj@stdgtfont{#1}}\n" + "\\let\\setCJKmonofont\\setCJKsansfont\n"))) + (error "Using xeCJK or luatexja for jp and zh requires compiler xelatex or lualatex"))) ;; Now the fonts: ;; ;; Look for CJK fonts in the font configuration ;; and provide the default fonts by convention for - ;; Japanese documents if there none is found. - (when (string= main-lang "jp") + ;; Chinese or Japanese documents if there none is found. + (when (or (and (string= compiler "xelatex") + (string= main-lang "jp")) + (and (string= compiler "lualatex") + (string= main-lang "cn"))) (unless (cl-loop for (_ . fprops) in doc-fontspec when (string-match-p "^CJK" (plist-get fprops :font)) collect fprops) @@ -2286,7 +2309,11 @@ Use fontspec as a last resort and when defined." do (let ((font (plist-get fprops :font)) (feats (plist-get fprops :features))) (insert "\\set" fname "font{" font "}\n" (org-latex--mk-options feats)))) - (when use-xecjk + (when with-cjk + (when (string= compiler "lualatex") + (when (string= main-lang "cn") + (insert "\\def\\ltj@stdyokojfm{quanjiao}\n")) + (insert "\\makeatother\n")) (insert "\\catcode`\\^^^^200b=\\active\\let^^^^200b\\relax\n") ;; FIXME: agree on ZWS (insert (format "\\parindent=%dem\n" (if (string= main-lang "jp") 1 2))) ;; FIXME: Korean? (insert "\\linespread{1.333}"))))) @@ -2344,10 +2371,6 @@ INFO is the export communication channel." (insert "\\usepackage{fontspec}\n") (insert (format "\\usepackage%s{unicode-math}\n" (org-latex--mk-options unicode-math-options))) - (when cjk-packages - (unless (string= compiler "xelatex") - (error "Using xeCJK for jp and zh requires compiler xelatex")) - (insert "\\usepackage{xeCJK}\n\\usepackage{indentfirst}\n")) (org-latex--insert-fontspec compiler current-fontspec-config current-default-features -- 2.50.1 (Apple Git-155)
