Hi, This is the updated patch ready for review.
>From 69ba235bce159169862e1eaf8c92951a434d24b0 Mon Sep 17 00:00:00 2001 From: RadioNoiseE <[email protected]> Date: Thu, 4 Dec 2025 21:54:49 +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'. (zh-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 it call `org-latex--insert-fontspec' which already takes care of CJK. --- lisp/ox-latex.el | 59 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 99f662e11..0de2ececf 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -2088,7 +2088,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." @@ -2107,9 +2107,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")) + (t (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 @@ -2247,6 +2250,15 @@ else signal error." (plist-get lang-plist :babel-ini-only) lang))) +(defconst zh-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. +They corresponds to luatexja's Mincho and Gothic font.") + (defconst jp-default-fontspec '(("CJKmain" . "HaranoAjiMincho") ("CJKsans" . "HaranoAjiGothic") @@ -2289,28 +2301,45 @@ 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")) + (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") + ;; Mimic xeCJK's font interface without relying on luatexja-fontspec. + ;; Note that luatexja does not distinguish mono font and sans font. + (insert "\\makeatletter\n +\\def\\setCJKmainfont#1{\\def\\ltj@stdmcfont{#1}}\n +\\def\\setCJKsansfont#1{\\def\\ltj@stdgtfont{#1}}\n +\\def\\setCJKmonofont#1{}\n")) + (t (error "Using xeCJK or luatexja for jp and zh requires compiler xelatex or lualatex"))) (insert "\\usepackage{xeCJK}\n\\usepackage{indentfirst}")) ;; Now the fonts: ;; - ;; Look for CJK fonts in the font configuration - ;; and provide the default fonts by convention for + ;; Look for CJK fonts in the font configuration and + ;; provide the default fonts by convention for Chinese or ;; Japanese documents if there none is found. - (when (string= main-lang "jp") + (when (or (and (string= compiler "xelatex") + (string= main-lang "jp")) + (and (string= compiler "lualatex") + (string= main-lang "zh"))) (unless (cl-loop for (_ . fprops) in doc-fontspec when (string-match-p "^CJK" (plist-get fprops :font)) collect fprops) - (cl-loop for (fname . ffile) in jp-default-fontspec + (cl-loop for (fname . ffile) in + (symbol-value (intern (concat main-lang "-default-fontspec"))) do (insert "\\set" fname "font{" ffile "}\n")))) ;; (cl-loop for (fname . fprops) in doc-fontspec 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 "zh") + (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}"))))) @@ -2375,10 +2404,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)
