texlive[73925] Master/texmf-dist: sjtutex (12feb25)

commits+karl at tug.org commits+karl at tug.org
Wed Feb 12 22:06:31 CET 2025


Revision: 73925
          https://tug.org/svn/texlive?view=revision&revision=73925
Author:   karl
Date:     2025-02-12 22:06:30 +0100 (Wed, 12 Feb 2025)
Log Message:
-----------
sjtutex (12feb25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/sjtutex/sjtutex.pdf
    trunk/Master/texmf-dist/source/latex/sjtutex/sjtutex.dtx
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-cambria.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-libertinus.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-lm.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newcm.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newpx.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newtx.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-stixtwo.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-times.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-xits.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-cambria.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-libertinus.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-lm.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newcm.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newpx.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newtx.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-stixtwo.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-times.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-xits.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-de.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-en.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuarticle.cls
    trunk/Master/texmf-dist/tex/latex/sjtutex/sjtureport.cls
    trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuthesis.cls

Added Paths:
-----------
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-hanyi.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-de.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-en.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/
    trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-de.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-en.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf

Removed Paths:
-------------
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-de.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-en.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-de.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-en.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-ja.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-zh.def
    trunk/Master/texmf-dist/tex/latex/sjtutex/name/
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-small-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-small-red.pdf
    trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-name-red.pdf

Modified: trunk/Master/texmf-dist/doc/latex/sjtutex/sjtutex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/sjtutex/sjtutex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/sjtutex/sjtutex.dtx	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/source/latex/sjtutex/sjtutex.dtx	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,8 +1,9 @@
 % \iffalse meta-comment
 %
 % Copyright (C) SJTUG
-%   2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%   2022--2024 Zilong Li    <logcreative at outlook.com>
+%   2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%   2022--2025 Zilong Li    <logcreative at outlook.com>
+%   2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either
@@ -34,8 +35,9 @@
 \preamble
 
     Copyright (C) SJTUG
-      2018--2024 Weijian Wu   <alexarawu at outlook.com>
-      2022--2024 Zilong Li    <logcreative at outlook.com>
+      2018--2025 Weijian Wu   <alexarawu at outlook.com>
+      2022--2025 Zilong Li    <logcreative at outlook.com>
+      2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 
     This work may be distributed and/or modified under the
     conditions of the LaTeX Project Public License, either
@@ -54,62 +56,43 @@
     \file{sjtuthesis.cls}               {\from{\jobname.dtx}{class,thesis}}
     \file{sjtureport.cls}               {\from{\jobname.dtx}{class,report}}
     \file{sjtuarticle.cls}              {\from{\jobname.dtx}{class,article}}
-    \file{sjtu-lang-thesis-zh.def}      {\from{\jobname.dtx}{lang,thesis,zh}}
-    \file{sjtu-lang-thesis-en.def}      {\from{\jobname.dtx}{lang,thesis,en}}
-    \file{sjtu-lang-thesis-de.def}      {\from{\jobname.dtx}{lang,thesis,de}}
-    \file{sjtu-lang-thesis-ja.def}      {\from{\jobname.dtx}{lang,thesis,ja}}
-    \file{sjtu-lang-generic-zh.def}     {\from{\jobname.dtx}{lang,generic,zh}}
-    \file{sjtu-lang-generic-en.def}     {\from{\jobname.dtx}{lang,generic,en}}
-    \file{sjtu-lang-generic-de.def}     {\from{\jobname.dtx}{lang,generic,de}}
-    \file{sjtu-lang-generic-ja.def}     {\from{\jobname.dtx}{lang,generic,ja}}
-    \file{sjtu-name-thesis-zh.def}      {\from{\jobname.dtx}{name,thesis,zh}}
-    \file{sjtu-name-thesis-en.def}      {\from{\jobname.dtx}{name,thesis,en}}
-    \file{sjtu-name-thesis-de.def}      {\from{\jobname.dtx}{name,thesis,de}}
-    \file{sjtu-name-thesis-ja.def}      {\from{\jobname.dtx}{name,thesis,ja}}
-    \file{sjtu-name-generic-zh.def}     {\from{\jobname.dtx}{name,generic,zh}}
-    \file{sjtu-name-generic-en.def}     {\from{\jobname.dtx}{name,generic,en}}
-    \file{sjtu-name-generic-de.def}     {\from{\jobname.dtx}{name,generic,de}}
-    \file{sjtu-name-generic-ja.def}     {\from{\jobname.dtx}{name,generic,ja}}
+    \file{sjtu-lang-zh.def}             {\from{\jobname.dtx}{lang,zh}}
+    \file{sjtu-lang-en.def}             {\from{\jobname.dtx}{lang,en}}
+    \file{sjtu-lang-de.def}             {\from{\jobname.dtx}{lang,de}}
+    \file{sjtu-lang-ja.def}             {\from{\jobname.dtx}{lang,ja}}
     \file{sjtu-scheme-zh.def}           {\from{\jobname.dtx}{scheme,zh}}
     \file{sjtu-scheme-en.def}           {\from{\jobname.dtx}{scheme,en}}
     \file{sjtu-scheme-de.def}           {\from{\jobname.dtx}{scheme,de}}
     \file{sjtu-scheme-ja.def}           {\from{\jobname.dtx}{scheme,ja}}
-    \file{sjtu-text-font-newtx.def}     {\from{\jobname.dtx}{font,text,newtx}}
-    \file{sjtu-text-font-newpx.def}     {\from{\jobname.dtx}{font,text,newpx}}
-    \file{sjtu-text-font-lm.def}        {\from{\jobname.dtx}{font,text,lm}}
+    \file{sjtu-thesis-zh.def}           {\from{\jobname.dtx}{thesis-i18n,zh}}
+    \file{sjtu-thesis-en.def}           {\from{\jobname.dtx}{thesis-i18n,en}}
+    \file{sjtu-thesis-de.def}           {\from{\jobname.dtx}{thesis-i18n,de}}
+    \file{sjtu-thesis-ja.def}           {\from{\jobname.dtx}{thesis-i18n,ja}}
+    \file{sjtu-text-font-newtx.def}     {\from{\jobname.dtx}{font,text,type1,newtx}}
+    \file{sjtu-text-font-newpx.def}     {\from{\jobname.dtx}{font,text,type1,newpx}}
+    \file{sjtu-text-font-lm.def}        {\from{\jobname.dtx}{font,text,type1,lm}}
+    \file{sjtu-text-font-times.def}     {\from{\jobname.dtx}{font,text,type1,times}}
     \file{sjtu-text-font-libertinus.def}{\from{\jobname.dtx}{font,text,libertinus}}
     \file{sjtu-text-font-stixtwo.def}   {\from{\jobname.dtx}{font,text,stixtwo}}
-    \file{sjtu-text-font-xits.def}      {\from{\jobname.dtx}{font,text,xits}}
-    \file{sjtu-text-font-newcm.def}     {\from{\jobname.dtx}{font,text,newcm}}
-    \file{sjtu-text-font-cambria.def}   {\from{\jobname.dtx}{font,text,cambria}}
-    \file{sjtu-text-font-times.def}     {\from{\jobname.dtx}{font,text,times}}
-    \file{sjtu-math-font-newtx.def}     {\from{\jobname.dtx}{font,math,newtx}}
-    \file{sjtu-math-font-newpx.def}     {\from{\jobname.dtx}{font,math,newpx}}
-    \file{sjtu-math-font-lm.def}        {\from{\jobname.dtx}{font,math,lm}}
+    \file{sjtu-text-font-cambria.def}   {\from{\jobname.dtx}{font,text,otf,cambria}}
+    \file{sjtu-text-font-newcm.def}     {\from{\jobname.dtx}{font,text,otf,newcm}}
+    \file{sjtu-text-font-xits.def}      {\from{\jobname.dtx}{font,text,otf,xits}}
+    \file{sjtu-math-font-newtx.def}     {\from{\jobname.dtx}{font,math,type1,newtx}}
+    \file{sjtu-math-font-newpx.def}     {\from{\jobname.dtx}{font,math,type1,newpx}}
+    \file{sjtu-math-font-lm.def}        {\from{\jobname.dtx}{font,math,type1,lm}}
+    \file{sjtu-math-font-times.def}     {\from{\jobname.dtx}{font,math,type1,times}}
     \file{sjtu-math-font-libertinus.def}{\from{\jobname.dtx}{font,math,libertinus}}
     \file{sjtu-math-font-stixtwo.def}   {\from{\jobname.dtx}{font,math,stixtwo}}
-    \file{sjtu-math-font-xits.def}      {\from{\jobname.dtx}{font,math,xits}}
-    \file{sjtu-math-font-newcm.def}     {\from{\jobname.dtx}{font,math,newcm}}
-    \file{sjtu-math-font-cambria.def}   {\from{\jobname.dtx}{font,math,cambria}}
-    \file{sjtu-math-font-times.def}     {\from{\jobname.dtx}{font,math,times}}
-    \file{sjtu-cjk-font-windows.def}    {\from{\jobname.dtx}{font,cjk,windows,und}}
-    \file{sjtu-cjk-font-windows-zh.def} {\from{\jobname.dtx}{font,cjk,windows,zh}}
-    \file{sjtu-cjk-font-windows-ja.def} {\from{\jobname.dtx}{font,cjk,windows,ja}}
-    \file{sjtu-cjk-font-mac.def}        {\from{\jobname.dtx}{font,cjk,mac,und}}
-    \file{sjtu-cjk-font-mac-zh.def}     {\from{\jobname.dtx}{font,cjk,mac,zh}}
-    \file{sjtu-cjk-font-mac-ja.def}     {\from{\jobname.dtx}{font,cjk,mac,ja}}
-    \file{sjtu-cjk-font-ubuntu.def}     {\from{\jobname.dtx}{font,cjk,ubuntu,und}}
-    \file{sjtu-cjk-font-ubuntu-zh.def}  {\from{\jobname.dtx}{font,cjk,ubuntu,zh}}
-    \file{sjtu-cjk-font-ubuntu-ja.def}  {\from{\jobname.dtx}{font,cjk,ubuntu,ja}}
-    \file{sjtu-cjk-font-adobe.def}      {\from{\jobname.dtx}{font,cjk,adobe,und}}
-    \file{sjtu-cjk-font-adobe-zh.def}   {\from{\jobname.dtx}{font,cjk,adobe,zh}}
-    \file{sjtu-cjk-font-adobe-ja.def}   {\from{\jobname.dtx}{font,cjk,adobe,ja}}
-    \file{sjtu-cjk-font-fandol.def}     {\from{\jobname.dtx}{font,cjk,fandol,und}}
-    \file{sjtu-cjk-font-fandol-zh.def}  {\from{\jobname.dtx}{font,cjk,fandol,zh}}
-    \file{sjtu-cjk-font-fandol-ja.def}  {\from{\jobname.dtx}{font,cjk,fandol,ja}}
-    \file{sjtu-cjk-font-founder.def}    {\from{\jobname.dtx}{font,cjk,founder,und}}
-    \file{sjtu-cjk-font-founder-zh.def} {\from{\jobname.dtx}{font,cjk,founder,zh}}
-    \file{sjtu-cjk-font-founder-ja.def} {\from{\jobname.dtx}{font,cjk,founder,ja}}
+    \file{sjtu-math-font-cambria.def}   {\from{\jobname.dtx}{font,math,otf,cambria}}
+    \file{sjtu-math-font-newcm.def}     {\from{\jobname.dtx}{font,math,otf,newcm}}
+    \file{sjtu-math-font-xits.def}      {\from{\jobname.dtx}{font,math,otf,xits}}
+    \file{sjtu-cjk-font-windows.def}    {\from{\jobname.dtx}{font,cjk,windows}}
+    \file{sjtu-cjk-font-mac.def}        {\from{\jobname.dtx}{font,cjk,mac}}
+    \file{sjtu-cjk-font-ubuntu.def}     {\from{\jobname.dtx}{font,cjk,ubuntu}}
+    \file{sjtu-cjk-font-adobe.def}      {\from{\jobname.dtx}{font,cjk,adobe}}
+    \file{sjtu-cjk-font-fandol.def}     {\from{\jobname.dtx}{font,cjk,fandol}}
+    \file{sjtu-cjk-font-founder.def}    {\from{\jobname.dtx}{font,cjk,founder}}
+    \file{sjtu-cjk-font-hanyi.def}      {\from{\jobname.dtx}{font,cjk,hanyi}}
 %</install>
 %<*internal>
   \usedir{source/latex/sjtutex}
@@ -129,26 +112,18 @@
 \Msg{*     sjtuthesis.cls                                        *}
 \Msg{*     sjtureport.cls                                        *}
 \Msg{*     sjtuarticle.cls                                       *}
-\Msg{*     sjtu-lang-generic-de.def                              *}
-\Msg{*     sjtu-lang-generic-en.def                              *}
-\Msg{*     sjtu-lang-generic-ja.def                              *}
-\Msg{*     sjtu-lang-generic-zh.def                              *}
-\Msg{*     sjtu-lang-thesis-de.def                               *}
-\Msg{*     sjtu-lang-thesis-en.def                               *}
-\Msg{*     sjtu-lang-thesis-ja.def                               *}
-\Msg{*     sjtu-lang-thesis-zh.def                               *}
-\Msg{*     sjtu-name-generic-de.def                              *}
-\Msg{*     sjtu-name-generic-en.def                              *}
-\Msg{*     sjtu-name-generic-ja.def                              *}
-\Msg{*     sjtu-name-generic-zh.def                              *}
-\Msg{*     sjtu-name-thesis-de.def                               *}
-\Msg{*     sjtu-name-thesis-en.def                               *}
-\Msg{*     sjtu-name-thesis-ja.def                               *}
-\Msg{*     sjtu-name-thesis-zh.def                               *}
+\Msg{*     sjtu-lang-de.def                                      *}
+\Msg{*     sjtu-lang-en.def                                      *}
+\Msg{*     sjtu-lang-ja.def                                      *}
+\Msg{*     sjtu-lang-zh.def                                      *}
 \Msg{*     sjtu-scheme-de.def                                    *}
 \Msg{*     sjtu-scheme-en.def                                    *}
 \Msg{*     sjtu-scheme-ja.def                                    *}
 \Msg{*     sjtu-scheme-zh.def                                    *}
+\Msg{*     sjtu-thesis-de.def                                    *}
+\Msg{*     sjtu-thesis-en.def                                    *}
+\Msg{*     sjtu-thesis-ja.def                                    *}
+\Msg{*     sjtu-thesis-zh.def                                    *}
 \Msg{*     sjtu-text-font-cambria.def                            *}
 \Msg{*     sjtu-text-font-libertinus.def                         *}
 \Msg{*     sjtu-text-font-lm.def                                 *}
@@ -167,29 +142,23 @@
 \Msg{*     sjtu-math-font-stixtwo.def                            *}
 \Msg{*     sjtu-math-font-times.def                              *}
 \Msg{*     sjtu-math-font-xits.def                               *}
-\Msg{*     sjtu-cjk-font-adobe-ja.def                            *}
-\Msg{*     sjtu-cjk-font-adobe-zh.def                            *}
 \Msg{*     sjtu-cjk-font-adobe.def                               *}
-\Msg{*     sjtu-cjk-font-fandol-ja.def                           *}
-\Msg{*     sjtu-cjk-font-fandol-zh.def                           *}
 \Msg{*     sjtu-cjk-font-fandol.def                              *}
-\Msg{*     sjtu-cjk-font-founder-ja.def                          *}
-\Msg{*     sjtu-cjk-font-founder-zh.def                          *}
 \Msg{*     sjtu-cjk-font-founder.def                             *}
-\Msg{*     sjtu-cjk-font-mac-ja.def                              *}
-\Msg{*     sjtu-cjk-font-mac-zh.def                              *}
+\Msg{*     sjtu-cjk-font-hanyi.def                               *}
 \Msg{*     sjtu-cjk-font-mac.def                                 *}
-\Msg{*     sjtu-cjk-font-ubuntu-ja.def                           *}
-\Msg{*     sjtu-cjk-font-ubuntu-zh.def                           *}
 \Msg{*     sjtu-cjk-font-ubuntu.def                              *}
-\Msg{*     sjtu-cjk-font-windows-ja.def                          *}
-\Msg{*     sjtu-cjk-font-windows-zh.def                          *}
 \Msg{*     sjtu-cjk-font-windows.def                             *}
-\Msg{*     sjtu-vi-badge-red.pdf                                 *}
-\Msg{*     sjtu-vi-badge-small-red.pdf                           *}
-\Msg{*     sjtu-vi-logo-red.pdf                                  *}
-\Msg{*     sjtu-vi-logo-small-red.pdf                            *}
-\Msg{*     sjtu-vi-name-red.pdf                                  *}
+\Msg{*     sjtu-vi-badge-cor-red.pdf                             *}
+\Msg{*     sjtu-vi-badge-reg-red.pdf                             *}
+\Msg{*     sjtu-vi-logo-eng-h-cor-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-eng-h-reg-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-c-cor-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-c-reg-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-h-cor-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-h-reg-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-v-cor-red.pdf                        *}
+\Msg{*     sjtu-vi-logo-std-v-reg-red.pdf                        *}
 \Msg{*                                                           *}
 \Msg{* To produce the documentation, run the file sjtutex.dtx    *}
 \Msg{* through XeLaTeX.                                          *}
@@ -206,17 +175,17 @@
 %</internal>
 %
 %<*class>
-\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+\NeedsTeXFormat{LaTeX2e}[2024-06-01]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
-\IfFormatAtLeastTF{2020/10/01}{}
+\IfFormatAtLeastTF{2024-06-01}{}
  {\PackageError{sjtutex}
    {Your LaTeX format is outdated!\MessageBreak\MessageBreak
-    Release `2020/10/01' or newer is required to\MessageBreak
+    Release '2024-06-01' or newer is required to\MessageBreak
     compile this document.\MessageBreak\MessageBreak
     Please update your TeX distribution}{}}
 %</class>
 %<*!(driver|install)>
-%<+!driver>\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+%<+!driver>\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
 %<class&thesis>  {Thesis document class for Shanghai Jiao Tong University (SJTUTeX)}
 %<class&thesis>\ProvidesExplClass{sjtuthesis}
 %<class&report>  {Report document class for Shanghai Jiao Tong University (SJTUTeX)}
@@ -223,38 +192,14 @@
 %<class&report>\ProvidesExplClass{sjtureport}
 %<class&article>  {Article document class for Shanghai Jiao Tong University (SJTUTeX)}
 %<class&article>\ProvidesExplClass{sjtuarticle}
-%<lang&thesis&zh>  {Chinese specific definition for thesis (SJTUTeX)}
-%<lang&thesis&zh>\ProvidesExplFile{sjtu-lang-thesis-zh.def}
-%<lang&thesis&en>  {English specific definition for thesis (SJTUTeX)}
-%<lang&thesis&en>\ProvidesExplFile{sjtu-lang-thesis-en.def}
-%<lang&thesis&de>  {German specific definition for thesis (SJTUTeX)}
-%<lang&thesis&de>\ProvidesExplFile{sjtu-lang-thesis-de.def}
-%<lang&thesis&ja>  {Japanese specific definition for thesis (SJTUTeX)}
-%<lang&thesis&ja>\ProvidesExplFile{sjtu-lang-thesis-ja.def}
-%<lang&generic&zh>  {Chinese specific definition for generic (SJTUTeX)}
-%<lang&generic&zh>\ProvidesExplFile{sjtu-lang-generic-zh.def}
-%<lang&generic&en>  {English specific definition for generic (SJTUTeX)}
-%<lang&generic&en>\ProvidesExplFile{sjtu-lang-generic-en.def}
-%<lang&generic&de>  {German specific definition for generic (SJTUTeX)}
-%<lang&generic&de>\ProvidesExplFile{sjtu-lang-generic-de.def}
-%<lang&generic&ja>  {Japanese specific definition for generic (SJTUTeX)}
-%<lang&generic&ja>\ProvidesExplFile{sjtu-lang-generic-ja.def}
-%<name&thesis&zh>  {Chinese name config for thesis (SJTUTeX)}
-%<name&thesis&zh>\ProvidesExplFile{sjtu-name-thesis-zh.def}
-%<name&thesis&en>  {English name config for thesis (SJTUTeX)}
-%<name&thesis&en>\ProvidesExplFile{sjtu-name-thesis-en.def}
-%<name&thesis&de>  {German name config for thesis (SJTUTeX)}
-%<name&thesis&de>\ProvidesExplFile{sjtu-name-thesis-de.def}
-%<name&thesis&ja>  {Japanese name config for thesis (SJTUTeX)}
-%<name&thesis&ja>\ProvidesExplFile{sjtu-name-thesis-ja.def}
-%<name&generic&zh>  {Chinese name config for generic (SJTUTeX)}
-%<name&generic&zh>\ProvidesExplFile{sjtu-name-generic-zh.def}
-%<name&generic&en>  {English name config for generic (SJTUTeX)}
-%<name&generic&en>\ProvidesExplFile{sjtu-name-generic-en.def}
-%<name&generic&de>  {German name config for generic (SJTUTeX)}
-%<name&generic&de>\ProvidesExplFile{sjtu-name-generic-de.def}
-%<name&generic&ja>  {Japanese name config for generic (SJTUTeX)}
-%<name&generic&ja>\ProvidesExplFile{sjtu-name-generic-ja.def}
+%<lang&zh>  {Chinese specific definition (SJTUTeX)}
+%<lang&zh>\ProvidesExplFile{sjtu-lang-zh.def}
+%<lang&en>  {English specific definition (SJTUTeX)}
+%<lang&en>\ProvidesExplFile{sjtu-lang-en.def}
+%<lang&de>  {German specific definition (SJTUTeX)}
+%<lang&de>\ProvidesExplFile{sjtu-lang-de.def}
+%<lang&ja>  {Japanese specific definition (SJTUTeX)}
+%<lang&ja>\ProvidesExplFile{sjtu-lang-ja.def}
 %<scheme&zh>  {Chinese scheme (SJTUTeX)}
 %<scheme&zh>\ProvidesExplFile{sjtu-scheme-zh.def}
 %<scheme&en>  {English scheme (SJTUTeX)}
@@ -263,79 +208,65 @@
 %<scheme&de>\ProvidesExplFile{sjtu-scheme-de.def}
 %<scheme&ja>  {Japanese scheme (SJTUTeX)}
 %<scheme&ja>\ProvidesExplFile{sjtu-scheme-ja.def}
+%<thesis-i18n&zh>  {Chinese config for thesis (SJTUTeX)}
+%<thesis-i18n&zh>\ProvidesExplFile{sjtu-thesis-zh.def}
+%<thesis-i18n&en>  {English config for thesis (SJTUTeX)}
+%<thesis-i18n&en>\ProvidesExplFile{sjtu-thesis-en.def}
+%<thesis-i18n&de>  {German config for thesis (SJTUTeX)}
+%<thesis-i18n&de>\ProvidesExplFile{sjtu-thesis-de.def}
+%<thesis-i18n&ja>  {Japanese config for thesis (SJTUTeX)}
+%<thesis-i18n&ja>\ProvidesExplFile{sjtu-thesis-ja.def}
 %<font&text&newtx>  {New TX text fonts definition (SJTUTeX)}
 %<font&text&newtx>\ProvidesExplFile{sjtu-text-font-newtx.def}
 %<font&text&newpx>  {New PX text fonts definition (SJTUTeX)}
 %<font&text&newpx>\ProvidesExplFile{sjtu-text-font-newpx.def}
+%<font&text&lm>  {Latin Modern text fonts definition (SJTUTeX)}
+%<font&text&lm>\ProvidesExplFile{sjtu-text-font-lm.def}
+%<font&text&times>  {Times text fonts definition (SJTUTeX)}
+%<font&text&times>\ProvidesExplFile{sjtu-text-font-times.def}
 %<font&text&stixtwo>  {STIX Two text fonts definition (SJTUTeX)}
 %<font&text&stixtwo>\ProvidesExplFile{sjtu-text-font-stixtwo.def}
-%<font&text&xits>  {XITS text fonts definition (SJTUTeX)}
-%<font&text&xits>\ProvidesExplFile{sjtu-text-font-xits.def}
-%<font&text&lm>  {Latin Modern text fonts definition (SJTUTeX)}
-%<font&text&lm>\ProvidesExplFile{sjtu-text-font-lm.def}
 %<font&text&libertinus>  {Libertinus text fonts definition (SJTUTeX)}
 %<font&text&libertinus>\ProvidesExplFile{sjtu-text-font-libertinus.def}
+%<font&text&cambria>  {Cambria text fonts definition (SJTUTeX)}
+%<font&text&cambria>\ProvidesExplFile{sjtu-text-font-cambria.def}
 %<font&text&newcm>  {New Computer Modern text fonts definition (SJTUTeX)}
 %<font&text&newcm>\ProvidesExplFile{sjtu-text-font-newcm.def}
-%<font&text&cambria>  {Cambria text fonts definition (SJTUTeX)}
-%<font&text&cambria>\ProvidesExplFile{sjtu-text-font-cambria.def}
-%<font&text&times>  {Times text fonts definition (SJTUTeX)}
-%<font&text&times>\ProvidesExplFile{sjtu-text-font-times.def}
+%<font&text&xits>  {XITS text fonts definition (SJTUTeX)}
+%<font&text&xits>\ProvidesExplFile{sjtu-text-font-xits.def}
 %<font&math&newtx>  {New TX math fonts definition (SJTUTeX)}
 %<font&math&newtx>\ProvidesExplFile{sjtu-math-font-newtx.def}
 %<font&math&newpx>  {New PX math fonts definition (SJTUTeX)}
 %<font&math&newpx>\ProvidesExplFile{sjtu-math-font-newpx.def}
+%<font&math&lm>  {Latin Modern math fonts definition (SJTUTeX)}
+%<font&math&lm>\ProvidesExplFile{sjtu-math-font-lm.def}
+%<font&math&times>  {Times math fonts definition (SJTUTeX)}
+%<font&math&times>\ProvidesExplFile{sjtu-math-font-times.def}
 %<font&math&stixtwo>  {STIX Two math fonts definition (SJTUTeX)}
 %<font&math&stixtwo>\ProvidesExplFile{sjtu-math-font-stixtwo.def}
-%<font&math&xits>  {XITS math fonts definition (SJTUTeX)}
-%<font&math&xits>\ProvidesExplFile{sjtu-math-font-xits.def}
-%<font&math&lm>  {Latin Modern math fonts definition (SJTUTeX)}
-%<font&math&lm>\ProvidesExplFile{sjtu-math-font-lm.def}
 %<font&math&libertinus>  {Libertinus math fonts definition (SJTUTeX)}
 %<font&math&libertinus>\ProvidesExplFile{sjtu-math-font-libertinus.def}
+%<font&math&cambria>  {Cambria math fonts definition (SJTUTeX)}
+%<font&math&cambria>\ProvidesExplFile{sjtu-math-font-cambria.def}
 %<font&math&newcm>  {New Computer Modern math fonts definition (SJTUTeX)}
 %<font&math&newcm>\ProvidesExplFile{sjtu-math-font-newcm.def}
-%<font&math&cambria>  {Cambria math fonts definition (SJTUTeX)}
-%<font&math&cambria>\ProvidesExplFile{sjtu-math-font-cambria.def}
-%<font&math&times>  {Times math fonts definition (SJTUTeX)}
-%<font&math&times>\ProvidesExplFile{sjtu-math-font-times.def}
-%<font&cjk&windows&und>  {Windows CJK fonts definition (SJTUTeX)}
-%<font&cjk&windows&und>\ProvidesExplFile{sjtu-cjk-font-windows.def}
-%<font&cjk&windows&zh>  {Windows CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&windows&zh>\ProvidesExplFile{sjtu-cjk-font-windows-zh.def}
-%<font&cjk&windows&ja>  {Windows CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&windows&ja>\ProvidesExplFile{sjtu-cjk-font-windows-ja.def}
-%<font&cjk&mac&und>  {macOS CJK fonts definition (SJTUTeX)}
-%<font&cjk&mac&und>\ProvidesExplFile{sjtu-cjk-font-mac.def}
-%<font&cjk&mac&zh>  {macOS CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&mac&zh>\ProvidesExplFile{sjtu-cjk-font-mac-zh.def}
-%<font&cjk&mac&ja>  {macOS CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&mac&ja>\ProvidesExplFile{sjtu-cjk-font-mac-ja.def}
-%<font&cjk&ubuntu&und>  {Ubuntu CJK fonts definition (SJTUTeX)}
-%<font&cjk&ubuntu&und>\ProvidesExplFile{sjtu-cjk-font-ubuntu.def}
-%<font&cjk&ubuntu&zh>  {Ubuntu CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&ubuntu&zh>\ProvidesExplFile{sjtu-cjk-font-ubuntu-zh.def}
-%<font&cjk&ubuntu&ja>  {Ubuntu CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&ubuntu&ja>\ProvidesExplFile{sjtu-cjk-font-ubuntu-ja.def}
-%<font&cjk&adobe&und>  {Adobe CJK fonts definition (SJTUTeX)}
-%<font&cjk&adobe&und>\ProvidesExplFile{sjtu-cjk-font-adobe.def}
-%<font&cjk&adobe&zh>  {Adobe CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&adobe&zh>\ProvidesExplFile{sjtu-cjk-font-adobe-zh.def}
-%<font&cjk&adobe&ja>  {Adobe CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&adobe&ja>\ProvidesExplFile{sjtu-cjk-font-adobe-ja.def}
-%<font&cjk&fandol&und>  {Fandol CJK fonts definition (SJTUTeX)}
-%<font&cjk&fandol&und>\ProvidesExplFile{sjtu-cjk-font-fandol.def}
-%<font&cjk&fandol&zh>  {Fandol CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&fandol&zh>\ProvidesExplFile{sjtu-cjk-font-fandol-zh.def}
-%<font&cjk&fandol&ja>  {Fandol CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&fandol&ja>\ProvidesExplFile{sjtu-cjk-font-fandol-ja.def}
-%<font&cjk&founder&und>  {Founder CJK fonts definition (SJTUTeX)}
-%<font&cjk&founder&und>\ProvidesExplFile{sjtu-cjk-font-founder.def}
-%<font&cjk&founder&zh>  {Founder CJK fonts definition for Chinese (SJTUTeX)}
-%<font&cjk&founder&zh>\ProvidesExplFile{sjtu-cjk-font-founder-zh.def}
-%<font&cjk&founder&ja>  {Founder CJK fonts definition for Japanese (SJTUTeX)}
-%<font&cjk&founder&ja>\ProvidesExplFile{sjtu-cjk-font-founder-ja.def}
-%<!driver>  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+%<font&math&xits>  {XITS math fonts definition (SJTUTeX)}
+%<font&math&xits>\ProvidesExplFile{sjtu-math-font-xits.def}
+%<font&cjk&windows>  {Windows CJK fonts definition (SJTUTeX)}
+%<font&cjk&windows>\ProvidesExplFile{sjtu-cjk-font-windows.def}
+%<font&cjk&mac>  {macOS CJK fonts definition (SJTUTeX)}
+%<font&cjk&mac>\ProvidesExplFile{sjtu-cjk-font-mac.def}
+%<font&cjk&ubuntu>  {Ubuntu CJK fonts definition (SJTUTeX)}
+%<font&cjk&ubuntu>\ProvidesExplFile{sjtu-cjk-font-ubuntu.def}
+%<font&cjk&adobe>  {Adobe CJK fonts definition (SJTUTeX)}
+%<font&cjk&adobe>\ProvidesExplFile{sjtu-cjk-font-adobe.def}
+%<font&cjk&fandol>  {Fandol CJK fonts definition (SJTUTeX)}
+%<font&cjk&fandol>\ProvidesExplFile{sjtu-cjk-font-fandol.def}
+%<font&cjk&founder>  {Founder CJK fonts definition (SJTUTeX)}
+%<font&cjk&founder>\ProvidesExplFile{sjtu-cjk-font-founder.def}
+%<font&cjk&hanyi>  {Hanyi CJK fonts definition (SJTUTeX)}
+%<font&cjk&hanyi>\ProvidesExplFile{sjtu-cjk-font-hanyi.def}
+%<!driver>  {\ExplFileDate}{2.2}{\ExplFileDescription}
 %</!(driver|install)>
 %
 %<*driver>
@@ -343,7 +274,7 @@
 \documentclass{ctxdoc}
 \newcommand{\sjtutex}{SJTU\TeX}
 \expandafter\def\csname ver@\jobname.dtx\endcsname
-  {2024/11/06 v2.1.5 SJTUTeX}
+  {2025/02/12 v2.2 SJTUTeX}
 \usepackage{float}
 \usepackage{multirow}
 \usepackage{longtable}
@@ -448,15 +379,14 @@
 %   {\LaTeX{} Project Public License (1.3c)},使用前请认真阅读协议内容。
 % \item 学位论文模板根据 \href{https://www.gs.sjtu.edu.cn/post/detail/Z3MxNDc=}
 %   {《上海交通大学博士、硕士学位论文撰写指南》} ,并参考
-%   \href{https://bysj.jwc.sjtu.edu.cn/ShowNews.aspx?newsno=Yr2wg3ibJJhIZh0A52amXw....}
+%   \href{https://www.jwc.sjtu.edu.cn/info/1041/117021.htm}
 %   {《上海交通大学本科生毕业设计(论文)撰写规范》}
-%   编写而成。旨在供上海交通大学准毕业生撰
-%   写学位论文使用。
-% \item 学位论文模板仅为撰写指南的参考实现,不保证审查老师不提意见。任何由于使用本模板
-%   而引起的论文格式审查问题均与本模板作者无关。
+%   编写而成。旨在供上海交通大学准毕业生撰写学位论文使用。
+% \item 学位论文模板仅为撰写指南的参考实现,不保证审查老师不提意见。任何由于使用
+%   本模板而引起的论文格式审查问题均与本模板作者无关。
 % \item 任何个人或组织以本模板为基础进行修改、扩展而生成的新的专用模板,请严格遵
-%   守 \LaTeX{} Project Public License 协议。由于违犯协议而引起的任何纠纷
-%   争端均与本模板作者无关。
+%   守 \LaTeX{} Project Public License 协议。由于违犯协议而引起的任何纠纷争端均
+%   与本模板作者无关。
 % \end{enumerate}
 % \end{abstract}
 %
@@ -466,33 +396,35 @@
 %
 % \section{介绍}
 %
-% 最早的一版 \LaTeX{} 学位论文模板由一位热心的物理系同学制作,中文字符处理采用了当时最为流行的
-% CJK--\LaTeX{} 方案。在此基础上,weijianwen 根据交大研究生院对学位论文的要求,完成
-% 了一份基本可用的交大 \LaTeX{} 学位论文模板。由于 CJK--\LaTeX{} 方案不易使用,
-% weijianwen 与 William Wang 开始着手把模板向 \XeTeX{} 引擎移植。之后 weijianwen
-% 又断断续续做了一些完善模板的工作,在原有硕士学位论文模板的基础上完成了交大学士
-% 和博士学位论文模板。
+% 最早的一版 \LaTeX{} 学位论文模板由一位热心的物理系同学制作,中文字符处理采用了
+% 当时最为流行的 CJK--\LaTeX{} 方案。在此基础上,weijianwen 根据交大研究生院对学
+% 位论文的要求,完成了一份基本可用的交大 \LaTeX{} 学位论文模板。由于 CJK--\LaTeX{}
+% 方案不易使用,weijianwen 与 William Wang 开始着手把模板向 \XeTeX{} 引擎移植。
+% 之后 weijianwen又断断续续做了一些完善模板的工作,在原有硕士学位论文模板的基础
+% 上完成了交大学士和博士学位论文模板。
 %
 % 2012 年 5 月模板开始在 GitHub^^A
 % \footnote{\url{https://github.com/weijianwen/SJTUThesis},项目转移后该链接已重定向。}^^A
-% 上管理和更新,2018 年 1 月项目转移至 SJTUG 名
-% 下。2019 年 6 月 Alexara Wu 重构了整个宏包的代码,并使用 Doc\TeX{} 文档和
-% \textsc{DocStrip} 工具进行代码的管理,升级版本号为 1.0。2022 年 11 月,论文模板
-% 改版后,使用 \LaTeXiii{} 重构了代码,添加 \cls{sjtureport} 和 \cls{sjtuarticle}
-% 文档类,升级版本号为 2.0。
+% 上管理和更新,2018 年 1 月项目转移至 SJTUG 名下。2019 年 6 月 Alexara Wu 重构
+% 了整个宏包的代码,并使用 Doc\TeX{} 文档和\textsc{DocStrip} 工具进行代码的管理,
+% 升级版本号为 1.0。2022 年 11 月,论文模板改版后,使用 \LaTeXiii{} 重构了代码,
+% 添加 \cls{sjtureport} 和 \cls{sjtuarticle} 文档类,升级版本号为 2.0。
+% 2024 年 2 月,\pkg{sjtutex} 文档类集在 CTAN 上发布,被 \TeX{} Live 2024 及之后
+% 的版本收录。
 %
 % 现在,\sjtutex{} 代码在 GitHub^^A
 % \footnote{\url{https://github.com/sjtug/SJTUTeX}}^^A
-% 上维护。
-% 原 \href{https://github.com/sjtug/SJTUThesis}{SJTUThesis} 仓库则作为学位论文示例文档,提供开箱即用的模板。
-% 学位论文模板用户可以在 \href{https://github.com/sjtug/SJTUThesis/discussions}{Discussions}
-% 上提问使用问题,也可以在 \href{https://github.com/sjtug/SJTUThesis/issues}{Issues}
+% 上维护,并同步发布至 CTAN\footnote{\url{https://www.ctan.org/pkg/sjtutex}} 上。
+% 原 \href{https://github.com/sjtug/SJTUThesis}{SJTUThesis} 仓库则作为学位论文
+% 示例文档,提供开箱即用的模板。学位论文模板用户可以在
+% \href{https://github.com/sjtug/SJTUThesis/discussions}{Discussions}
+% 上提问使用问题,也可以在
+% \href{https://github.com/sjtug/SJTUThesis/issues}{Issues}
 % 中进行 Bug 反馈与新功能提案。如果需要对文档类代码进行修改,欢迎前往
 % \href{https://github.com/sjtug/SJTUTeX}{\sjtutex} 仓库进行 Pull Request。
 % \sjtutex{} 模板的许多实现细节离不开
-% \href{https://github.com/sjtug/SJTUThesis/graphs/contributors}
-% {热心同学们} 的贡献,在此感谢所有为模板贡献过代码的同学们,以及所有测试和使用
-% 模板的各位同学!
+% \href{https://github.com/sjtug/SJTUThesis/graphs/contributors}{热心同学们}
+% 的贡献,在此感谢所有为模板贡献过代码的同学们,以及所有测试和使用模板的各位同学!
 %
 % \note{模板的作用在于减少论文写作过程中格式调整的时间,前提是遵守模板的用法,否
 %   则即便用了 \sjtutex{} 也难以保证输出的论文符合学校规范。}
@@ -507,8 +439,8 @@
 % \href{https://github.com/sjtug/SJTUThesis/wiki/TeX-发行版及其安装}
 % {Wiki 页面《\TeX{} 发行版及其安装》}。
 %
-% \sjtutex{} 最低支持至 2021 年发行的 \TeX{} 发行版,\pkg{ctex} 宏包版本应当在
-% v2.5 及以上。版本过低将无法正常编译。
+% \sjtutex{} 需要 \LaTeXe{} 内核 2024-06-01 或以上版本,\pkg{ctex} 宏包版本应当
+% 在 v2.5 及以上。版本过低将无法正常编译。
 %
 % \subsection{文件组成}
 %
@@ -521,22 +453,21 @@
 %   \label{tab:files}
 %   \begin{tabular}{l|l|p{4cm}}
 %     \toprule
-%     \strong{类别}         & \strong{文件}               & \strong{说明}  \\
+%     \strong{类别}         & \strong{文件}               & \strong{说明}    \\
 %     \midrule
-%     文档类                & \file{sjtuthesis.cls}       & 学位论文文档类 \\
-%                           & \file{sjtureport.cls}       & 报告文档类     \\
-%                           & \file{sjtuarticle.cls}      & 文稿文档类     \\
-%                           & \file{sjtu-name-*.def}      & 文档类名称配置 \\
-%                           & \file{sjtu-lang-*.def}      & 文档类语言配置 \\
-%                           & \file{sjtu-scheme-*.def}    & 文档类语言方案 \\
+%     文档类                & \file{sjtuthesis.cls}       & 学位论文文档类   \\
+%                           & \file{sjtureport.cls}       & 报告文档类       \\
+%                           & \file{sjtuarticle.cls}      & 文稿文档类       \\
+%                           & \file{sjtu-lang-*.def}      & 文档类语言配置   \\
+%                           & \file{sjtu-scheme-*.def}    & 文档类语言方案   \\
+%                           & \file{sjtu-thesis-*.def}    & 学位论文语言配置 \\
 %     \midrule
-%     字体配置文件          & \file{sjtu-text-font-*.def} & 西文字体配置   \\
-%                           & \file{sjtu-math-font-*.def} & 数学字体配置   \\
-%                           & \file{sjtu-cjk-font-*.def}  & CJK 字体配置   \\
+%     字体配置文件          & \file{sjtu-text-font-*.def} & 西文字体配置     \\
+%                           & \file{sjtu-math-font-*.def} & 数学字体配置     \\
+%                           & \file{sjtu-cjk-font-*.def}  & CJK 字体配置     \\
 %     \midrule
-%     视觉形象系统\tnote{a} & \file{sjtu-vi-logo-*.pdf}   & 校标图片       \\
-%                           & \file{sjtu-vi-badge-*.pdf}  & 校徽图片       \\
-%                           & \file{sjtu-vi-name-*.pdf}   & 校名图片       \\
+%     视觉形象系统\tnote{a} & \file{sjtu-vi-logo-*.pdf}   & 校标图片         \\
+%                           & \file{sjtu-vi-badge-*.pdf}  & 校徽图片         \\
 %
 %     \bottomrule
 %   \end{tabular}
@@ -549,16 +480,21 @@
 %
 % \subsection{使用文档类}
 %
-% 共有 3 种文档类,\cls{sjtuthesis} 用于学位论文的排版,\cls{sjtureport} 用于课程大报告的排版,
-% \cls{sjtuarticle} 用于课程小论文的排版。
+% 共有 3 种文档类,\cls{sjtuthesis} 用于学位论文的排版,\cls{sjtureport}
+% 用于课程大报告的排版,\cls{sjtuarticle} 用于课程小论文的排版。
 %
-% 将文档保存在下载好的 \sjtutex{} 模板根目录下,文件以 \texttt{.tex} 后缀结尾。
-% 注意在使用文档类时,需要将涉及到的所有源文件使用 UTF-8 编码保存。对于不同的文档类,使用方法
-% 略有不同,这里给出这三种文档类的最小使用示例。
+% 将文档保存在下载好的 \sjtutex{} 模板根目录下,或者直接使用 \TeX{} 发行版
+% 中的 \pkg{sjtutex} 文档类集^^A
+% \footnote{为了使用最新版本的 \sjtutex{},请及时更新发行版至最新的版本:^^A
+% \TeX{} Live 用户请使用命令 \texttt{tlmgr update --self --all} 来更新全部宏包;^^A
+% \hologo{MiKTeX} 用户请在 MiKTeX Console 更新选项卡中更新所有宏包。},
+% 文件以 \texttt{.tex} 后缀结尾。
+% 注意在使用文档类时,需要将涉及到的所有源文件使用 UTF-8 编码保存。
+% 对于不同的文档类,使用方法略有不同,这里给出这三种文档类的最小使用示例。
 %
-% 下面这份 \TeX{} 文档展示了 \cls{sjtuthesis} 文档类的基本用法,一般需要指定中英文名称。
-% 该文档将包含中英文封面,页眉为文档主题及章节名称。
-% \begin{latex}[moretexcs={\sjtusetup,\maketitle,\tableofcontents*,\chapter},
+% 下面这份 \TeX{} 文档展示了 \cls{sjtuthesis} 文档类的基本用法,一般需要指定
+% 中英文名称。该文档将包含中英文封面,页眉为文档主题及章节名称。
+% \begin{latex}[moretexcs={\sjtusetup,\maketitle,\tableofcontents,\chapter},
 %   morekeywords={\frontmatter,\mainmatter}, emph={[1]sjtuthesis,document},
 %   emph={[2]info},emph={[3]type,zh,en,title,author}]
 % \documentclass[type=master]{sjtuthesis}
@@ -573,7 +509,7 @@
 % \begin{document}
 %   \maketitle
 %   \frontmatter
-%   \tableofcontents*
+%   \tableofcontents
 %   \mainmatter
 %   \chapter{欢迎}
 %   \section{欢迎使用 SJTUThesis}
@@ -581,8 +517,8 @@
 % \end{document}
 % \end{latex}
 %
-% 下面这份 \TeX{} 文档展示了 \cls{sjtureport} 文档类的基本用法,建议使用标准命令定义中文名称。
-% 该文档将包含标题页,页眉为校标图片、文档主题及章节名称。
+% 下面这份 \TeX{} 文档展示了 \cls{sjtureport} 文档类的基本用法,建议使用标准命令
+% 定义中文名称。该文档将包含标题页,页眉为校标图片、文档主题及章节名称。
 % \begin{latex}[moretexcs={\subject,\keywords,\maketitle,\chapter},
 %   emph={[1]sjtureport,document}]
 % \documentclass{sjtureport}
@@ -598,8 +534,9 @@
 % \end{document}
 % \end{latex}
 %
-% 下面这份 \TeX{} 文档展示了 \cls{sjtuarticle} 文档类的基本用法,建议使用标准命令定义中文名称,
-% 不能够使用 \tn{chapter} 这一级。该文档包含标题栏,页眉为校标图片、文档主题及章节名称。
+% 下面这份 \TeX{} 文档展示了 \cls{sjtuarticle} 文档类的基本用法,建议使用标准
+% 命令定义中文名称,不能够使用 \tn{chapter} 这一级。该文档包含标题栏,页眉为
+% 校标图片、文档主题及章节名称。
 % \begin{latex}[moretexcs={\maketitle}, emph={[1]sjtuarticle,document}]
 % \documentclass{sjtuarticle}
 % \title{示例文档}
@@ -619,7 +556,7 @@
 % 在实际使用中,一般推荐使用自动生成工具 \pkg{latexmk} 编译文档。\pkg{latexmk}
 % 命令可以自动进行多步编译,直到交叉引用都被解决。
 % 假设您的 \TeX{} 源文件名为 \file{main.tex},
-% 可在命令行中执行如下命令使用 \XeLaTeX{} 编译文档
+% 可在命令行中执行如下命令使用 \XeLaTeX{} 编译文档:
 % \begin{shell}[morekeywords={latexmk},emph={-xelatex}]
 % latexmk -xelatex main
 % \end{shell}
@@ -630,9 +567,12 @@
 %
 % 本模板中的选项、命令或环境可以分为以下三类:
 % \begin{itemize}
-%   \item 名字后面带有 \rexptarget\rexpstar{} 的,表示只能在 \cls{sjtuthesis} 文档类中使用;
-%   \item 名字后面带有 \exptarget\expstar{} 的,表示只能在 \cls{sjtureport} 和 \cls{sjtuarticle} 文档类中使用;
-%   \item 名字后面不带有特殊符号的,一般表示在 \cls{sjtuthesis}、\cls{sjtureport} 和 \cls{sjtuarticle} 文档类中都可以使用,特殊情况另作说明。
+%   \item 名字后面带有 \rexptarget\rexpstar{} 的,表示只能在 \cls{sjtuthesis}
+%     文档类中使用;
+%   \item 名字后面带有 \exptarget\expstar{} 的,表示只能在 \cls{sjtureport}
+%     和 \cls{sjtuarticle} 文档类中使用;
+%   \item 名字后面不带有特殊符号的,一般表示在 \cls{sjtuthesis}、\cls{sjtureport}
+%     和 \cls{sjtuarticle} 文档类中都可以使用,特殊情况另作说明。
 % \end{itemize}
 %
 % \subsection{文档类选项}
@@ -644,7 +584,8 @@
 % \end{latex}
 %
 % 部分选项采用 \meta{key}|=|\meta{value} 的形式,需要使用逗号分隔各选项。
-% 当 \meta{value} 省略时,将采用默认值。在下文的说明中,将用\textbf{粗体}表示默认值。
+% 当 \meta{value} 省略时,将采用默认值。
+% 在下文的说明中,将用\textbf{粗体}表示默认值。
 %
 % \subsubsection{通用选项}
 %
@@ -670,9 +611,11 @@
 %   默认为 \opt{final}。
 % \end{function}
 %
-% \begin{function}[rEXP]{review}
-%   盲审模式。开启盲审模式将隐去作者姓名、导师姓名、班级、学号等个人信息,
-%   删去版权使用授权书、原创性声明和致谢页。默认关闭。
+% \begin{function}[rEXP,updated=2025-01-14]{review}
+%   盲审模式。开启盲审模式会将作者姓名、导师姓名、学号、基金等个人信息留空,
+%   并使得标题页的信息表格强制显示相关字段,
+%   相关说明详见第 \ref{sec:sjtuthesiskey} 节;
+%   开启盲审模式还会删去版权使用授权书、原创性声明和致谢页。默认关闭。
 % \end{function}
 %
 % \subsubsection{页面设置}
@@ -748,7 +691,7 @@
 %
 % \begin{function}{cjk-font}
 %   \begin{syntax}
-%     \OPT{cjk-font} = <(auto)|(fandol)|windows|mac|ubuntu|adobe|founder|none>
+%     \OPT{cjk-font} = <(auto)|windows|mac|ubuntu|adobe|(fandol)|founder|hanyi|none>
 %   \end{syntax}
 %   指定 CJK 字体集。\sjtutex{} 预定义了一些 CJK 字体组合,
 %   具体配置见表 \ref{tab:cjkfonts}。
@@ -758,7 +701,7 @@
 %   Linux 系统默认使用 \opt{fandol}。
 %   找不到对应定义的 CJK 字体集时的回退选项为 \opt{fandol}。
 %
-%   \textbf{仅} \opt{windows} 和 \opt{founder} 字体集支持 \pdfLaTeX{} 直接生成 PDF。
+%   \textbf{仅} \opt{windows}、\opt{founder} 和 \opt{hanyi} 字体集支持 \pdfLaTeX{} 直接生成 PDF。
 %   其他 CJK 字体集使用 \pdfTeX{} 引擎需要先通过 \LaTeX{} 生成 DVI,
 %   然后再使用 DVIPDFM\textit{x} 转换为 PDF。
 % \end{function}
@@ -774,12 +717,13 @@
 %     \toprule
 %     	                   & \strong{宋体}     & \strong{黑体}    & \strong{仿宋} & \strong{楷体}   & \strong{明朝体}\tnote{c} & \strong{哥特体}\tnote{c}  \\
 %     \midrule
-%       |fandol|\tnote{a}  & Fandol 宋体       & Fandol 黑体      & Fandol 仿宋   & Fandol 楷体     & HaranoAjiMincho          & HaranoAjiGothic           \\
 %       |windows|          & (中易)宋体      & (中易)黑体     & (中易)仿宋  & (中易)楷体    & MS Mincho                & MS Gothic                 \\
 %       |mac|              & (华文)宋体-简   & (华文)黑体-简  & 华文仿宋      & (华文)楷体-简 & Hiragino Mincho ProN     & Hiragino Kaku Gothic ProN \\
 %       |ubuntu|           & Noto Serif CJK SC & Noto Sans CJK SC & ---           & 文鼎 PL 简中楷  & Noto Serif CJK JP        & Noto Sans CJK JP          \\
-%       |adobe|            & Adobe 宋体        & Adobe  黑体      & Adobe  仿宋   & Adobe 楷体      & Kozuka Mincho Pr6N       & Kozuka Gothic Pr6N        \\
+%       |adobe|            & Adobe 宋体        & Adobe 黑体       & Adobe 仿宋    & Adobe 楷体      & Kozuka Mincho Pr6N       & Kozuka Gothic Pr6N        \\
+%       |fandol|\tnote{a}  & Fandol 宋体       & Fandol 黑体      & Fandol 仿宋   & Fandol 楷体     & HaranoAjiMincho          & HaranoAjiGothic           \\
 %       |founder|\tnote{b} & 方正书宋          & 方正黑体         & 方正仿宋      & 方正楷体        & IPAMincho                & IPAGothic                 \\
+%       |hanyi|            & 汉仪书宋二 S      & 汉仪中黑 S       & 汉仪仿宋 S    & 汉仪楷体 S      & HaranoAjiMincho          & HaranoAjiGothic           \\
 %     \bottomrule
 %   \end{tabular}
 %   \begin{tablenotes}
@@ -883,6 +827,11 @@
 %   该选项只影响行间公式,行内公式统一居右侧,不受影响。
 % \end{function}
 %
+% \subsubsection{其他选项}
+%
+% 其他的文档类选项会被传递给对应的 \CTeX{} 文档类,
+% 请注意 \opt{GBK}、\opt{scheme} 等选项不受 \sjtutex{} 支持。
+%
 % \subsection{论文信息设置}
 %
 % \begin{function}{\sjtusetup}
@@ -919,7 +868,7 @@
 %
 % \subsubsection{信息域}
 %
-% \begin{function}[updated=2023-03-14]{info}
+% \begin{function}[updated=2025-01-14]{info}
 %   \begin{syntax}
 %     \OPS{info} = \marg{键值列表}
 %   \end{syntax}
@@ -929,7 +878,13 @@
 %           (比如 \opt{zh} 或 \opt{en})的键来设定对应语言的论文信息,见第
 %           \ref{sec:sjtuthesiskey} 节;省略语言前缀不带“*”的项目表示对应的中文
 %           字段、带“*”的项目表示对应的英文字段属于老用法,仍然兼容但请及时更新
-%           至新用法。
+%           至新用法;各标题页中的信息表格会根据设定信息的顺序进行显示与排列,
+%           未设置的信息将不会显示,但在盲审模式开启时会例外地强制显示相关字段,
+%           中文标题页会强制显示 \texttt{info/zh} 中的 \texttt{author, id,
+%           supervisor, assoc_supervisor, co_supervisor, department, major, degree}
+%           字段,其他语言标题页会强制显示 \texttt{info/<lang>} 中的
+%           \texttt{author, supervisor, assoc_supervisor, co_supervisor} 字段,
+%           这种顺序也是这些信息的推荐设置顺序。
 %     \item 在 \cls{sjtureport} 和 \cls{sjtuarticle} 文档类中,不需要使用语言代
 %           码前缀。此时推荐直接使用标准接口来设定这些信息,这些标准接口不属于键
 %           值列表,应当直接写在导言区内,见第 \ref{sec:sjtureportcmd} 节。
@@ -995,15 +950,6 @@
 %   导师、副导师、联合导师姓名。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2023-03-14]{info/<lang>/degree}
-%   \begin{syntax}
-%     \OPT{\meta{lang}}/\OPT{degree} = \marg{学位名称}
-%   \end{syntax}
-%   申请学位中英文名称。
-%   包括申请的学位类别和级别,如“工学硕士”、“理学博士”等。
-%   学士论文无需标注。
-% \end{function}
-%
 % \begin{function}[rEXP,updated=2023-03-14]{info/<lang>/department}
 %   \begin{syntax}
 %     \OPT{\meta{lang}}/\OPT{department} = \marg{院系名称}
@@ -1018,6 +964,14 @@
 %   专业名称。
 % \end{function}
 %
+% \begin{function}[rEXP,updated=2023-03-14]{info/<lang>/degree}
+%   \begin{syntax}
+%     \OPT{\meta{lang}}/\OPT{degree} = \marg{学位名称}
+%   \end{syntax}
+%   申请学位中英文名称。
+%   包括申请的学位类别和级别,如“工学硕士”、“理学博士”等。
+% \end{function}
+%
 % \begin{function}[rEXP,updated=2023-03-14]{info/<lang>/fund}
 %   \begin{syntax}
 %     \OPT{\meta{lang}}/\OPT{fund} = \marg{资助基金名称}
@@ -1042,6 +996,19 @@
 %   设定该键时,将会覆盖 \opt{info/date} 键在对应语言下的设定。
 % \end{function}
 %
+% \begin{function}[rEXP,added=2025-01-14]{info/<lang>/custom}
+%   \begin{syntax}
+%     \OPT{\meta{lang}}/\OPT{custom}/\OPT{\meta{变量名}} = \marg{第一列内容}\marg{第二列内容}
+%   \end{syntax}
+%   对应语言标题页信息表格中显示的额外信息,可以设置多个变量。
+%   需要使用一个变量名作为索引键(变量名应当由英文字母、数字、
+%   连字符 \texttt{-} 组成,且第一个位置只能为英文字母);
+%   并赋予两个参数来设置信息表格中两列的内容:
+%   通常第一列作为该信息的属性名称会被加粗,第二列作为该信息的内容。
+%   该信息会根据在 \cmd{\sjtusetup} 中的设置相对位置显示在对应的位置上。
+%   当 \opt{review} 选项开启时,该选项的设置不会生效。
+% \end{function}
+%
 % \paragraph{适用于 \cls{sjtureport} 和 \cls{sjtuarticle} 文档类的命令}
 % \label{sec:sjtureportcmd}
 %
@@ -1228,12 +1195,13 @@
 %   页脚字体。默认为 |\zihao{-5}|,小五号字。
 % \end{function}
 %
-% \begin{function}[added=2022-12-03]{style/page-number}
+% \begin{function}[added=2022-12-03,updated=2024-12-30]{style/page-number}
 %   \begin{syntax}
-%     \OPT{page-number} = \marg{页码设置}
+%     \OPT{page-number} = \marg{格式定义}
 %   \end{syntax}
-%   设置页码的显示样式,其中 |#1| 代表当前页码。
-%   默认为 |{#1}|,即仅显示页码本身。
+%   设置页码的显示格式,\meta{格式定义} 有两个参数:参数 |#1| 是当前页码,参数 |#2| 是当前编码的总页码数。
+%   获取总页码数需要使用 \pkg{pageslts} 宏包。
+%   默认为 |{#1}|,即仅显示当前页码。
 % \end{function}
 %
 % \begin{function}[added=2023-11-30]{style/keywords-format}
@@ -1283,7 +1251,7 @@
 %     |listtable|          & 表格                   & List of Tables                & Tabellenverzeichnis    & 表目次               \\
 %     |figure|             & 图                     & Figure                        & Abbildung              & 図                   \\
 %     |table|              & 表                     & Table                         & Tabelle                & 表                   \\
-%     |abstract| \rexpstar & 摘要                   & Abstract                      & Zusammenfassung        & 概要                 \\
+%     |abstract| \expstar  & 摘要                   & Abstract                      & Zusammenfassung        & 概要                 \\
 %     |index|              & 索引                   & Index                         & Index                  & 索引                 \\
 %     |appendix|           & 附录                   & Appendix                      & Anhang                 & 付録                 \\
 %     |proof|              & 证明                   & Proof                         & Beweis                 & 证明                 \\
@@ -1310,9 +1278,56 @@
 %     \  \meta{文档内容}
 %     \EEV{document}
 %   \end{syntax}
-% 在文档开始后进行内容编写,文档内容由 |document| 环境包裹。
+%   在文档开始后进行内容编写,文档内容由 |document| 环境包裹。
 % \end{function}
 %
+% \subsection{用于本节环境或命令的参数}
+%
+% 本节描述的部分环境和命令提供 \meta{标题参数},用于进行局部的标题相关设置。
+% 可以使用逗号分隔的选项列表作为可选参数传入该环境,例如:
+% \begin{latex}
+% \begin{acknowledgements}[intoc,title={自定义标题}]
+% \end{acknowledgements}
+% \end{latex}
+%
+% \begin{function}[added=2025-01-12]{intoc, notintoc}
+%   指明该环境的小标题是否在目录中出现。
+%   \opt{intoc} 表示出现在目录中,
+%   \opt{notintoc} 表示不出现在目录中。
+%   默认 \tn{mainmatter} 之前的环境为 \opt{notintoc},
+%   \tn{mainmatter} 之后的环境为 \opt{intoc}。
+% \end{function}
+%
+% \begin{function}[added=2025-01-12]{title}
+%   \begin{syntax}
+%     \OPT{title} = \marg{小标题}
+%   \end{syntax}
+%   设置该环境的小标题,默认是全局语言下的小标题。
+% \end{function}
+%
+% \begin{function}[added=2025-01-12]{marking}
+%   \begin{syntax}
+%     \OPT{marking} = \marg{目录中的小标题}
+%   \end{syntax}
+%   设置该环境在目录中的小标题,默认与小标题相同。
+%   只有在设置 \opt{intoc} 小标题出现在目录中才会显示。
+% \end{function}
+%
+% 部分环境还提供了参数 \opt{lang},用于设置环境的语言。
+% \begin{function}[added=2025-01-12,label=]{lang}
+%   \begin{syntax}
+%     \OPT{lang} = <(zh)|en|de|ja>
+%   \end{syntax}
+%   设置该环境的局部语言选项,默认与全局语言选项相同。
+%   该选项会设置该环境的局部语言排版设置。
+% \end{function}
+%
+% 对于同时提供了 \meta{标题参数} 和 \opt{lang} 参数的环境,二者可以一同使用,例如:
+% \begin{latex}
+% \begin{abstract}[lang=en,intoc,title={自定义标题},marking={目录中的标题}]
+% \end{abstract}
+% \end{latex}
+%
 % \subsection{标题页和声明页}
 %
 % \begin{function}[updated=2022-12-03]{\maketitle}
@@ -1330,13 +1345,14 @@
 %   \end{itemize}
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-12-20]{\copyrightpage}
+% \begin{function}[rEXP,updated=2024-12-21]{\copyrightpage}
 %   \begin{syntax}
 %     \TNA{copyrightpage}
-%     \TNA{copyrightpage}\oarg{授权书扫描件}
+%     \TNA{copyrightpage}\oarg{file=授权书扫描件,额外选项}
 %   \end{syntax}
 %   生成空白版权使用授权书。
-%   接受一个可选参数用于插入版权使用授权书扫描件,使用可选参数时需要手动加载 \pkg{pdfpages} 宏包。
+%   接受可选参数用于插入版权使用授权书扫描件,插入外置 PDF 页时需要手动加载 \pkg{pdfpages} 宏包。
+%   额外选项将传递给 \tn{includepdf} 命令。
 % \end{function}
 %
 % \subsection{前文部分}
@@ -1348,31 +1364,32 @@
 %   声明前文部分开始。
 % \end{function}
 %
-% \begin{function}[updated=2023-11-29]{abstract}
+% \begin{function}[updated=2024-12-20]{abstract}
 %   \begin{syntax}
-%     \BEV{abstract}\oarg{lang}
-%     \  \meta{摘要}
+%     \BEV{abstract}\oarg{lang=<(zh)|en|de|ja>,标题参数}
+%     \  \meta{\textup{\cls{sjtuthesis}} 中的摘要}
 %     \EEV{abstract}
 %     \BEV{abstract}
-%     \  \meta{摘要}
+%     \  \meta{\textup{\cls{sjtuarticle}} 和 \textup{\cls{sjtureport}} 中的摘要}
 %     \EEV{abstract}
 %   \end{syntax}
 %   摘要环境。会在结尾添加关键词。
 %   \begin{itemize}
-%     \item \cls{sjtuthesis} 文档类中,可以设置可选参数指定摘要的语言,
-%           默认为 \opt{zh}。
-%     \item \cls{sjtuarticle} 和 \cls{sjtureport} 文档类中,不需要可选参数。
+%     \item \cls{sjtuthesis} 文档类中,可以设置可选参数,
+%           指定摘要的局部语言会同步更改小标题为对应语言设置。
+%     \item \cls{sjtuarticle} 和 \cls{sjtureport} 文档类中,不设置可选参数。
 %   \end{itemize}
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2023-11-29]{abstract*}
-%   \cls{sjtuthesis} 文档类中使用带星号的 \env{abstract*} 环境不会出现在目录中。
-% \end{function}
-%
-% \begin{function}{\tableofcontents,\tableofcontents*,\listoffigures,\listoffigures*,
-%   \listoftables,\listoftables*,\listofalgorithms,\listofalgorithms*}
+% \begin{function}[updated=2024-12-20]{\tableofcontents,\listoffigures,\listoftables,\listofalgorithms}
+%   \begin{syntax}
+%     \TNA{tableofcontents}\oarg{标题参数}
+%     \TNA{listoffigures}\oarg{标题参数}
+%     \TNA{listoftables}\oarg{标题参数}
+%     \TNA{listofalgorithms}\oarg{标题参数}
+%   \end{syntax}
 %   目录、插图、表格和算法等索引命令如表 \ref{tab:list} 所示,将其插入到期望的
-%   位置即可。带*的命令表示对应的索引表不会出现在目录中。
+%   位置即可,这些命令可以使用可选的 \meta{标题参数} 来调整标题相关设置。
 %   \begin{table}[H]
 %     \centering\small
 %     \begin{threeparttable}
@@ -1383,10 +1400,8 @@
 %         \strong{用途}     & \strong{命令}         & \strong{用途}     & \strong{命令}          \\
 %         \midrule
 %         目录              & \tn{tableofcontents}  & 插图索引          & \tn{listoffigures}     \\
-%                           & \tn{tableofcontents*} &                   & \tn{listoffigures*}    \\
 %         \midrule
 %         表格索引          & \tn{listoftables}     & 算法索引\tnote{a} & \tn{listofalgorithms}  \\
-%                           & \tn{listoftables*}    &                   & \tn{listofalgorithms*} \\
 %         \bottomrule
 %       \end{tabular}
 %       \begin{tablenotes}
@@ -1447,24 +1462,24 @@
 %   附录由 \tn{appendix} 命令开启,然后像正文一样书写。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-03-02]{nomenclature,nomenclature*}
+% \begin{function}[rEXP,updated=2024-12-20]{nomenclature}
 %   \begin{syntax}
-%     \BEV{nomenclature}\oarg{标题}
+%     \BEV{nomenclature}\oarg{标题参数}
 %     \  \meta{符号对照表}
 %     \EEV{nomenclature}
 %   \end{syntax}
-%   符号对照表环境。带星号的版本不会出现在目录中。可以使用可选参数手动设置标题。
-%   符号对照表环境仅设置标题,内部实现可由用户自行决定。
+%   符号对照表环境。可以使用 \meta{标题参数} 手动设置标题。
+%   符号对照表环境仅设置标题,内部实现可由用户自行决定:
 %   可以使用 \pkg{longtable},也可以使用 \pkg{nomencl} 宏包。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-03-02]{abbreviation,abbreviation*}
+% \begin{function}[rEXP,updated=2024-12-20]{abbreviation}
 %   \begin{syntax}
-%     \BEV{abbreviation}\oarg{标题}
+%     \BEV{abbreviation}\oarg{标题参数}
 %     \  \meta{缩略语对照表}
 %     \EEV{abbreviation}
 %   \end{syntax}
-%   缩略语对照表环境。带星号的版本不会出现在目录中。可以使用可选参数手动设置标题。
+%   缩略语对照表环境。可以使用可选参数手动设置标题。
 %   缩略语对照表环境仅设置标题,内部实现可由用户自行决定。
 % \end{function}
 %
@@ -1477,60 +1492,61 @@
 %   声明后文部分开始。 后文部分包含致谢等。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-02-24]{acknowledgements}
+% \begin{function}[rEXP,updated=2024-12-20]{acknowledgements}
 %   \begin{syntax}
-%     \BEV{acknowledgements}\oarg{标题}
+%     \BEV{acknowledgements}\oarg{标题参数}
 %     \  \meta{致谢内容}
 %     \EEV{acknowledgements}
 %   \end{syntax}
-%   致谢环境。盲审模式下致谢将被隐去。可以使用可选参数手动设置标题。
+%   致谢环境。盲审模式下致谢将被隐去。可以使用 \meta{标题参数} 手动设置标题。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-02-24]{achievements}
+% \begin{function}[rEXP,updated=2024-12-20]{achievements}
 %   \begin{syntax}
-%     \BEV{achievements}\oarg{标题}
+%     \BEV{achievements}\oarg{标题参数}
 %     \  \meta{获得的科研成果}
 %     \EEV{achievements}
 %   \end{syntax}
-%   科研成果环境,可以使用可选参数手动设置标题。内部请配合使用下面的附录用文献列表环境
+%   科研成果环境,可以使用 \meta{标题参数} 手动设置标题。内部请配合使用下面的附录用文献列表环境
 %   \env{bibliolist} 和 \env{bibliolist*}。你可以在该环境中使用带星号的节次命令
 %   以分隔不同的类型的成果(比如学术论文、专利等);你也可以使用多个 \env{achievements}
-%   环境,配合不同的可选参数作为标题,展示不同类型的成果。
+%   环境,配合不同的 \meta{标题参数},展示不同类型的成果。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-03-23]{bibliolist,bibliolist*}
+% \begin{function}[rEXP,updated=2024-12-08]{bibliolist,bibliolist*}
 %   \begin{syntax}
-%     \BEV{bibliolist}\marg{最长条目编号}
+%     \BEV{bibliolist}\oarg{可选参数}\marg{最长条目编号}
 %     \  \TNA{item} \meta{文献条目}
 %     \EEV{bibliolist}
-%     \BEV{bibliolist*}\marg{最长条目编号}
+%     \BEV{bibliolist*}\oarg{可选参数}\marg{最长条目编号}
 %     \  \TNA{item} \meta{文献条目(隐去姓名)}
 %     \EEV{bibliolist*}
 %   \end{syntax}
-%   附录用文献环境,只允许在 \env{achievements} 环境中使用。
+%   用于展示科研成果的文献列表,比如学术论文、专利等。
 %   需要指定最长条目的编号作为参数,比如 \opt{99};
 %   如果将该强制参数被指定为空,将不显示编号,每条以悬挂缩进做区分。
-%   环境内部使用 \tn{item} 来分隔各条目,在同一个 \env{achievements} 环境内、不同的
-%   \env{bibliolist} 或 \env{bibliolist*} 环境中编号连续递增、不会间断。
+%   可以使用可选参数 \opt{resume} 设置连续编号。
+%   环境内部使用 \tn{item} 来分隔各条目。
 %   普通模式下显示 \env{bibliolist} 中的内容,盲审模式下显示 \env{bibliolist*} 中的内容。
 % \end{function}
 %
-% \begin{function}[rEXP,updated=2022-02-24]{resume}
+% \begin{function}[rEXP,updated=2024-12-20]{resume}
 %   \begin{syntax}
-%     \BEV{resume}\oarg{标题}
+%     \BEV{resume}\oarg{标题参数}
 %     \  \meta{简历内容}
 %     \EEV{resume}
 %   \end{syntax}
-%   简历环境。盲审模式下简历将被隐去。可以使用可选参数手动设置标题。
+%   简历环境。盲审模式下简历将被隐去。可以使用 \meta{标题参数} 手动设置标题。
 % \end{function}
 %
-% \begin{function}[rEXP]{digest}
+% \begin{function}[rEXP,updated=2024-12-20]{digest}
 %   \begin{syntax}
-%     \BEV{digest}\oarg{lang}
+%     \BEV{digest}\oarg{lang=<zh|(en)|de|ja>,标题参数}
 %     \  \meta{大摘要}
 %     \EEV{digest}
 %   \end{syntax}
-%   学士论文大摘要,使用可选参数设定语言,默认为 \opt{en}。
+%   学士论文大摘要,可以设置可选参数,指定大摘要的局部语言会同步更改小标题
+%   为对应语言设置,默认为 \opt{lang=en}。
 % \end{function}
 %
 % \section{宏包依赖情况}
@@ -1543,6 +1559,7 @@
 %     \begin{itemize}
 %       \item \cls{ctexbook}、\cls{ctexrep} 和 \cls{ctexart},
 %         提供中文排版的通用框架。属于 \CTeX{} 宏集 \cite{CTeX}。
+%       \item \pkg{array},提供表格环境的增强功能。
 %       \item \pkg{mathtools},对 \LaTeX{} 的数学排版功能进行了全面扩展。
 %         是 \pkg{amsmath} 的扩充。
 %       \item \pkg{geometry},用于调整页面尺寸。
@@ -1553,13 +1570,12 @@
 %       \item \pkg{graphicx},提供图形插入的接口。
 %       \item \pkg{enumitem},设置列表环境格式。
 %     \end{itemize}
-%   \item \cls{sjtuthesis} 会调用 \pkg{xtemplate} 和 \pkg{array},用于辅助
-%     标题页等特殊页面的排版。
 %   \item 部分西文与数学字体预设会调用相关的字体宏包,具体调用情况请参见对应的
 %     字体预设文件。
 %   \item 部分数字字体预设会调用 \pkg{unicode-math} 处理 Unicode 编码的
 %     OpenType 数学字体。在未启用 \pkg{unicode-math} 的情况下,会调用 \pkg{bm}
 %     来选择粗体数学符号。
+%   \item 当需要显示总页码数时,会调用 \pkg{pageslts} 宏包。
 % \end{itemize}
 %
 % 这里只列出了本模板直接调用的宏包。这些宏包自身的调用情况,
@@ -1619,7 +1635,7 @@
 % \bibitem{source2e}
 % \textsc{Braams J}, \textsc{Carlisle D}, \textsc{Jeffrey A}, et~al.
 % \newblock \textit{The \LaTeXe{} Sources}\allowbreak[CP/OL].
-% \newblock (2023-11-01).
+% \newblock (2024-11-01).
 % \urlprefix\url{https://ctan.org/pkg/latex}
 % \urlprefix\CTANurl[源代码:]{macros/latex/base/source2e.pdf}
 %
@@ -1626,7 +1642,7 @@
 % \bibitem{interface3}
 % \textsc{The \LaTeX{} Project}.
 % \newblock \textit{The \LaTeXiii{} Interfaces}\allowbreak[EB/OL].
-% \newblock (2023-11-09).
+% \newblock (2024-11-02).
 % \urlprefix\url{https://ctan.org/pkg/l3kernel}
 % \urlprefix\CTANurl[文档:]{macros/latex/l3kernel/interface3.pdf}
 %
@@ -1657,8 +1673,8 @@
 % \bibitem{thuthesis}
 % 清华大学 TUNA 协会.
 % \newblock \textit{\textsc{ThuThesis}:清华大学学位论文模板}\allowbreak[EB/OL].
-% \newblock version 7.4.0,
-% \newblock (2023-05-15).
+% \newblock version 7.5.2,
+% \newblock (2025-07-01).
 % \urlprefix\url{https://ctan.org/pkg/thuthesis}
 % \urlprefix\CTANurl[文档及源代码:]{macros/latex/contrib/thuthesis/thuthesis.pdf}
 %
@@ -1671,30 +1687,140 @@
 % \clearpage
 % \section{代码实现}
 %
-% \changes{v2.1}{2023/12/05}{同步 \LaTeX{} 2020/10/01,无需显式调用
+% \changes{v2.1}{2023/12/05}{同步 \LaTeX{} 2020-10-01,无需显式调用
 % \pkg{expl3} 和 \pkg{xparse} 宏包。}
+% \changes{v2.2}{2024/11/22}{同步 \LaTeX{} 2024-06-01,无需显式调用
+% \pkg{xtemplate} 宏包。}
+% \changes{v2.2}{2025/02/10}{重命名视觉形象系统文件名称。}
 % 本模板使用 \LaTeXiii{} 语法编写,依赖 \pkg{expl3} 环境,
 % 并需调用 \pkg{l3packages} 中的相关宏包。
 %
+% \subsection{前置准备}
+%
+% 目前 \pkg{sjtutex} 文档类仅支持 \XeLaTeX{}、\LuaLaTeX{} 和 \pdfLaTeX{} 编译。
 %    \begin{macrocode}
 %<@@=sjtu>
+%<*class>
+\msg_new:nnn { sjtutex } { unsupported-engine }
+  {
+    The~sjtutex~classes~does~NOT~support~'#1'~engine. \\\\
+    Please~set~your~typesetting~program~to~either~
+    'xelatex'~or~'lualatex'.
+  }
+\bool_lazy_any:nF
+  {
+    { \sys_if_engine_xetex_p:  }
+    { \sys_if_engine_luatex_p: }
+    { \sys_if_engine_pdftex_p: }
+  }
+  { \msg_fatal:nnV { sjtutex } { unsupported-engine } \c_sys_engine_str }
 %    \end{macrocode}
 %
-% \subsection{内部变量}
+% \subsection{内部定义}
 %
-% \begin{variable}{\l_@@_tmp_bool,\l_@@_tmp_clist,\l_@@_tmp_dim,
-% \l_@@_tmp_skip,\l_@@_tmp_box}
+% \begin{variable}{\l_@@_tmp_tl,\l_@@_tmp_clist,\l_@@_tmp_box}
 % 临时变量。
 %    \begin{macrocode}
-%<*class>
-%<thesis>\bool_new:N \l_@@_tmp_bool
-%<thesis>\clist_new:N \l_@@_tmp_clist
-\dim_new:N \l_@@_tmp_dim
-\skip_new:N \l_@@_tmp_skip
-\box_new:N \l_@@_tmp_box
+\tl_new:N \l_@@_tmp_tl
+\clist_new:N \l_@@_tmp_clist
+%<thesis>\box_new:N \l_@@_tmp_box
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{macro}[int]{\clist_use:Nv,\clist_use:cv,
+% \exp_args:NNnv,\exp_last_unbraced:ce}
+% \LaTeX3{} 函数变体。
+%    \begin{macrocode}
+\cs_generate_variant:Nn \clist_use:Nn { Nv, cv }
+\exp_args_generate:n { Nnv }
+\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_conditional_const:nn}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_conditional_const:nn #1#2
+  {
+    \bool_if:nTF {#2}
+      {
+        \cs_new_eq:cN { @@_if_ #1 :T  } \use:n
+        \cs_new_eq:cN { @@_if_ #1 :F  } \use_none:n
+        \cs_new_eq:cN { @@_if_ #1 :TF } \use_i:nn
+        \cs_new_eq:cN { @@_if_ #1 _p: } \c_true_bool
+      }
+      {
+        \cs_new_eq:cN { @@_if_ #1 :T  } \use_none:n
+        \cs_new_eq:cN { @@_if_ #1 :F  } \use:n
+        \cs_new_eq:cN { @@_if_ #1 :TF } \use_ii:nn
+        \cs_new_eq:cN { @@_if_ #1 _p: } \c_false_bool
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,pTF]{\@@_if_engine_opentype:}
+%    \begin{macrocode}
+\@@_conditional_const:nn { engine_opentype }
+  {
+    \bool_lazy_or_p:nn
+      { \sys_if_engine_xetex_p:  }
+      { \sys_if_engine_luatex_p: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_disable_package_load:n}
+%    \begin{macrocode}
+\msg_new:nnn { sjtutex } { package-disabled }
+  { The~loading~of~package~'#1'~is~disabled. }
+\cs_new_protected:Npn \@@_disable_package_load:n #1
+  {
+    \disable at package@load {#1}
+      { \msg_warning:nnn { sjtutex } { package-disabled } {#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \changes{v2.0.2}{2023/03/31}{区分 \texttt{dim} 与 \texttt{skip} 类型变量。}
+% \begin{macro}[int]{\@@_dim_set_to_wd:Nn}
+% 操作长度变量的辅助函数。
+%    \begin{macrocode}
+%<*thesis>
+\cs_new:Npn \@@_dim_set_to_wd:Nn #1#2
+  {
+    \hbox_set:Nn \l_@@_tmp_box {#2}
+    \dim_set:Nn #1 { \box_wd:N \l_@@_tmp_box }
+  }
+\cs_generate_variant:Nn \@@_dim_set_to_wd:Nn { Nv }
+%</thesis>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_cs_provide_eq:NN}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cs_provide_eq:NN #1#2
+  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
+\cs_generate_variant:Nn \@@_cs_provide_eq:NN { cc }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_name_set:nnn,\@@_name_const:nnn,
+% \@@_name_const_from_clist:nnnn}
+% 定义默认名称的辅助函数。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_name_set:nnn #1#2#3
+  { \tl_set:cn   { l_@@_name_ #2 _ #1 _tl } {#3} }
+\cs_new_protected:Npn \@@_name_const:nnn #1#2#3
+  { \tl_const:cn { c_@@_name_ #2 _ #1 _tl } {#3} }
+%<*thesis>
+\cs_new_protected:Npn \@@_name_const_from_clist:nnnn #1#2#3#4
+  { \tl_const:ce { c_@@_name_ #2 _ #1 _tl } { \clist_item:nn {#4} {#3} } }
+%</thesis>
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{文档选项}
+%
 % \begin{variable}{\g_@@_thesis_type_int}
 % 论文类型。
 %    \begin{macrocode}
@@ -1702,33 +1828,23 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\g_@@_lang_tl,\g_@@_lang_clist,
-% \c_@@_lang_de_tl,\c_@@_lang_ja_tl }
-% 论文语言。
+% \begin{variable}{\g_@@_lang_tl,\g_@@_lang_clist}
+% 论文主要语言。
 %    \begin{macrocode}
 \tl_new:N \g_@@_lang_tl
 %<thesis>\clist_set:Nn \g_@@_lang_clist { zh, en }
-\tl_const:Nn \c_@@_lang_de_tl { de }
-\tl_const:Nn \c_@@_lang_ja_tl { ja }
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}
-%   {\g_@@_zihao_tl,\g_@@_font_size_int,\g_@@_font_size_dim,
-%    \g_@@_baseline_skip_dim,\g_@@_fixed_baselineskip_bool,\g_@@_line_spread_fp}
-% 字号大小与行距。
+% \begin{variable}{\g_@@_baseline_skip_dim,\g_@@_fixed_baselineskip_bool}
+% 固定行距。
 %    \begin{macrocode}
-\tl_new:N \g_@@_zihao_tl
-\int_new:N \g_@@_font_size_int
-\dim_new:N \g_@@_font_size_dim
 \dim_new:N \g_@@_baseline_skip_dim
 \bool_new:N \g_@@_fixed_baselineskip_bool
-\fp_new:N \g_@@_line_spread_fp
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}
-%   {\g_@@_text_font_tl,\g_@@_math_font_tl,\g_@@_cjk_font_tl}
+% \begin{variable}{\g_@@_text_font_tl,\g_@@_math_font_tl,\g_@@_cjk_font_tl}
 % 字体配置。
 %    \begin{macrocode}
 \tl_new:N \g_@@_text_font_tl
@@ -1776,9 +1892,17 @@
 % 保存由 \pkg{sjtutex} 传入 \pkg{ctex} 文档类的选项列表。
 % 默认 \pkg{ctex} 文档类的选项:
 % 使用 UTF8 编码,不调整基础类的版式以及不载入 \pkg{ctex} 字体预设配置。
+% \cls{sjtuthesis} 和 \cls{sjtureport} 文档类默认字号为小四号。
+% \cls{sjtureport} 和 \cls{sjtuarticle} 文档类默认使用 1.3 行距倍数。
 %    \begin{macrocode}
 \clist_set:Nn \g_@@_options_to_ctex_class_clist
-  { a4paper, UTF8, scheme = plain, fontset = none }
+  {
+    UTF8,
+%<!article>    zihao = -4,
+%<!thesis>    linespread = 1.3,
+    scheme = plain,
+    fontset = none
+  }
 %    \end{macrocode}
 % \end{variable}
 %
@@ -1785,60 +1909,40 @@
 % \begin{variable}{\g_@@_options_to_packages_clist}
 % 保存由传入其他宏包的选项列表。
 %    \begin{macrocode}
-\clist_new:N \g_@@_options_to_packages_clist
+\clist_set:Nn \g_@@_options_to_packages_clist
+  {
+    { no-math           } { fontspec     } ,
+    { list = off        } { bicaption    } ,
+    { warnings-off =
+      {
+        mathtools-overbracket,
+        mathtools-colon
+      }
+    }                     { unicode-math } ,
+%<!article>    { chapter           } { algorithm    } ,
+%<!article>    { algochapter       } { algorithm2e  } ,
+    { amsmath, thmmarks } { ntheorem     }
+  }
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\g_@@_twoside_bool}
-% 是否开启双页模式。
-%    \begin{macrocode}
-\bool_new:N \g_@@_twoside_bool
-%<thesis>\bool_set_true:N \g_@@_twoside_bool
-%<!thesis>\bool_set_false:N \g_@@_twoside_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_openright_bool}
-% 是否在奇数页开始新章。
-%    \begin{macrocode}
-%<!article>\bool_new:N \g_@@_openright_bool
-%<thesis>\bool_set_true:N \g_@@_openright_bool
-%<report>\bool_set_false:N \g_@@_openright_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_titlepage_bool}
-% 是否生成标题页。
-%    \begin{macrocode}
-%<!thesis>\bool_new:N \g_@@_titlepage_bool
-%<report>\bool_set_true:N \g_@@_titlepage_bool
-%<article>\bool_set_false:N \g_@@_titlepage_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_draft_bool}
-% 是否开启草稿模式。
-%    \begin{macrocode}
-\bool_new:N \g_@@_draft_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[int]{\@@_deprecated_option:n,\@@_set_deprecated_option:n}
+% \begin{macro}[int]{\@@_set_deprecated_option:n}
 % 对过时选项给出警告。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_deprecated_option:n
-  { \msg_warning:nnn { sjtutex } { deprecated-option } }
+\msg_new:nnn { sjtutex } { deprecated-option }
+  { Option~'\l_keys_key_str'~is~deprecated! \\ #1 }
 \cs_new_protected:Npn \@@_set_deprecated_option:n #1
   {
-    \@@_deprecated_option:n { Option~ `#1'~ is~ set. }
+    \msg_warning:nnn { sjtutex } { deprecated-option } { Option~'#1'~is~set. }
     \keys_set:nn { sjtu / option } {#1}
   }
-\msg_new:nnn { sjtutex } { deprecated-option }
-  { Option~ `\l_keys_key_tl'~ is~ deprecated. \\ #1 }
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{选项处理}
+%    \begin{macrocode}
+\msg_new:nnn { sjtutex } { unsupported-option }
+  { Option~'\l_keys_key_str'~is~not~supported! \\ Will~be~ignored. }
+%    \end{macrocode}
 %
 % 定义 |sjtu/option| 键值类。
 %    \begin{macrocode}
@@ -1882,37 +1986,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{zihao}
-% 字号大小。
-%    \begin{macrocode}
-    zihao .choice: ,
-    zihao .value_required:n = true ,
-    zihao /  5 .code:n =
-      {
-        \tl_gset:Nn  \g_@@_zihao_tl {#1}
-        \int_gset:Nn \g_@@_font_size_int { 1 }
-        \dim_gset:Nn \g_@@_font_size_dim { 10.5 bp }
-      } ,
-    zihao / -4 .code:n =
-      {
-        \tl_gset:Nn  \g_@@_zihao_tl {#1}
-        \int_gset:Nn \g_@@_font_size_int { 2 }
-        \dim_gset:Nn \g_@@_font_size_dim { 12   bp }
-      } ,
-%<!article>    zihao .initial:n = { -4 } ,
-%<article>    zihao .initial:n = {  5 } ,
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{linespread}
-% 行距倍数。
-%    \begin{macrocode}
-    linespread .fp_gset:N = \g_@@_line_spread_fp ,
-    linespread .initial:n = { \c_nan_fp } ,
-    linespread .value_required:n = true ,
-%    \end{macrocode}
-% \end{macro}
-%
 % \changes{v2.0}{2022/12/03}{添加 \opt{lineskip} 文档类选项。}
 % \changes{v2.1}{2023/10/24}{添加 \opt{baselineskip} 文档类选项,
 % 替换原 \opt{lineskip} 选项。}
@@ -1943,9 +2016,12 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \opt{fontset} 是过时选项。
+% \opt{fontset} 等是过时选项。
 %    \begin{macrocode}
-    fontset .code:n = { \@@_set_deprecated_option:n { cjk-font = #1 } } ,
+    fontset    .code:n = { \@@_set_deprecated_option:n { cjk-font = #1 } } ,
+    nofonts    .code:n = { \@@_set_deprecated_option:n { cjk-font = none } } ,
+    adobefonts .code:n = { \@@_set_deprecated_option:n { cjk-font = adobe } } ,
+    winfonts   .code:n = { \@@_set_deprecated_option:n { cjk-font = windows } } ,
 %    \end{macrocode}
 %
 % \changes{v2.0}{2023/01/05}{添加 \opt{math-style} 文档类选项,默认值为 \opt{ISO}。}
@@ -2006,136 +2082,89 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{oneside,twoside}
-% 单面或双面模式。
+% \begin{macro}{review}
+% 盲审模式。
 %    \begin{macrocode}
-    oneside .value_forbidden:n = true,
-    twoside .value_forbidden:n = true,
-    oneside .code:n =
-      { \bool_gset_false:N \g_@@_twoside_bool } ,
-    twoside .code:n =
-      { \bool_gset_true:N  \g_@@_twoside_bool } ,
+%<thesis>    review .bool_gset:N = \g_@@_review_bool ,
+%<thesis>    review .initial:n = false ,
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{openany,openright}
-% 是否奇数页开章。
+% 将未知选项传给标准文档类。
 %    \begin{macrocode}
-%<*!article>
-    openany   .value_forbidden:n = true,
-    openright .value_forbidden:n = true,
-    openany   .code:n =
-      { \bool_gset_false:N \g_@@_openright_bool } ,
-    openright .code:n =
-      { \bool_gset_true:N  \g_@@_openright_bool } ,
-%</!article>
+    unknown .code:n =
+      { \clist_gput_right:No \g_@@_options_to_ctex_class_clist { \CurrentOption } }
+  }
 %    \end{macrocode}
-% \end{macro}
 %
-% \begin{macro}{titlepage,notitlepage}
-% 是否生成标题页。
+% 屏蔽不支持的 \pkg{ctex} 选项。
 %    \begin{macrocode}
-%<*!thesis>
-    titlepage   .value_forbidden:n = true,
-    notitlepage .value_forbidden:n = true,
-    titlepage   .code:n =
-      { \bool_gset_true:N  \g_@@_titlepage_bool } ,
-    notitlepage .code:n =
-      { \bool_gset_false:N \g_@@_titlepage_bool } ,
-%</!thesis>
+\clist_map_inline:nn
+  { GBK, scheme, cap, nocap }
+  {
+    \keys_define:nn { sjtu / option }
+      {
+        #1 .code:n =
+          { \msg_warning:nn { sjtutex } { unsupported-option } }
+      }
+  }
 %    \end{macrocode}
-% \end{macro}
 %
-% \begin{macro}{draft,final}
-% 是否开启草稿模式。
+% 将文档类选项传给 |sjtu/option|。
 %    \begin{macrocode}
-    draft .value_forbidden:n = true,
-    final .value_forbidden:n = true,
-    draft .code:n =
-      { \bool_gset_true:N  \g_@@_draft_bool } ,
-    final .code:n =
-      { \bool_gset_false:N \g_@@_draft_bool } ,
+\ProcessKeyOptions [ sjtu / option ]
 %    \end{macrocode}
-% \end{macro}
 %
-% \begin{macro}{review}
-% 盲审模式。
+% \begin{macro}[int,pTF]{\@@_if_main_lang_de:,\@@_if_main_lang_ja:}
+% 快捷判断主要语言。
 %    \begin{macrocode}
-%<thesis>    review .bool_gset:N = \g_@@_review_bool ,
-%<thesis>    review .initial:n = false ,
+\@@_conditional_const:nn { main_lang_de }
+  { \str_if_eq_p:Vn \g_@@_lang_tl { de } }
+\@@_conditional_const:nn { main_lang_ja }
+  { \str_if_eq_p:Vn \g_@@_lang_tl { ja } }
 %    \end{macrocode}
 % \end{macro}
 %
-% 处理未知选项。
+% 数字字体宏包选项。
 %    \begin{macrocode}
-    unknown .code:n = { \msg_error:nn { sjtutex } { unknown-option } }
-  }
-\msg_new:nnn { sjtutex } { unknown-option }
-  { Class~ option~ "\l_keys_key_tl"~ is~ unknown. }
+\bool_if:NT \g_@@_slanted_uppercase_greek_bool
+  { \clist_put_right:Nn \g_@@_math_font_options_clist { slantedGreek } }
+\bool_if:NT \g_@@_upright_integral_bool
+  { \clist_put_right:Nn \g_@@_math_font_options_clist { upint } }
 %    \end{macrocode}
 %
-% 将文档类选项传给 |sjtu/option|。
+% 追加选项。
 %    \begin{macrocode}
-\cs_if_exist:NTF \ProcessKeyOptions
-  { \ProcessKeyOptions [ sjtu / option ] }
+\clist_put_left:Nn \@classoptionslist { a4paper }
+\@@_if_main_lang_de:T
+  { \clist_put_right:Nn \@classoptionslist { german, ngerman } }
+\bool_if:NTF \g_@@_integral_limits_bool
   {
-    \RequirePackage { l3keys2e }
-    \ProcessKeysOptions { sjtu / option }
+    \clist_put_right:Nn \@classoptionslist { intlimits }
+    \clist_put_right:Nn \g_@@_options_to_packages_clist
+      { { displaylimits } { cmupint } }
   }
-%    \end{macrocode}
-% \cls{sjtureport} 和 \cls{sjtuarticle} 文档类默认使用 1.3 行距倍数。
-%    \begin{macrocode}
-%<*!thesis>
-\bool_if:NF \g_@@_fixed_baselineskip_bool
   {
-    \fp_if_nan:nT { \g_@@_line_spread_fp }
-      { \fp_set:Nn \g_@@_line_spread_fp { 1.3 } }
+    \clist_put_right:Nn \g_@@_options_to_packages_clist
+      { { nolimits      } { cmupint } }
   }
-%</!thesis>
+\clist_concat:NNN \@classoptionslist
+  \@classoptionslist \g_@@_math_font_options_clist
 %    \end{macrocode}
 %
-% 数字字体宏包选项。
+% 内部设置接口。
 %    \begin{macrocode}
-\clist_set:Nx \g_@@_math_font_options_clist
+%<*thesis>
+\cs_set_protected:Npe \@@_setup:n
   {
-    \bool_if:NT \g_@@_slanted_uppercase_greek_bool
-      { slantedGreek } ,
-    \bool_if:NT \g_@@_upright_integral_bool
-      { upint }
+    \bool_if:NTF \g_@@_review_bool
+      { \exp_not:N \keys_set_exclude_groups:nnn { sjtu } { sensitive } }
+      { \exp_not:N \keys_set:nn { sjtu } }
   }
+%</thesis>
 %    \end{macrocode}
 %
-% 追加全局选项。
-%    \begin{macrocode}
-\clist_put_right:Nx \@classoptionslist
-  {
-    a4paper ,
-    \tl_if_eq:NNT \g_@@_lang_tl \c_@@_lang_de_tl
-      { german, ngerman } ,
-    \bool_if:NT \g_@@_integral_limits_bool
-      { intlimits } ,
-    \g_@@_math_font_options_clist
-  }
-%    \end{macrocode}
 %
-% 设置传入 \pkg{ctex} 文档类的选项。
-%    \begin{macrocode}
-\clist_put_right:Nx \g_@@_options_to_ctex_class_clist
-  {
-    zihao      = \g_@@_zihao_tl ,
-    \fp_if_nan:nF { \g_@@_line_spread_fp }
-      { linespread = \fp_use:N \g_@@_line_spread_fp } ,
-    \bool_if:NTF \g_@@_twoside_bool
-      { twoside   } { oneside     } ,
-%<!article>    \bool_if:NTF \g_@@_openright_bool
-%<!article>      { openright } { openany     } ,
-%<!thesis>    \bool_if:NTF \g_@@_titlepage_bool
-%<!thesis>      { titlepage } { notitlepage } ,
-    \bool_if:NTF \g_@@_draft_bool
-      { draft     } { final       }
-  }
-%    \end{macrocode}
-%
 % \subsection{载入宏包、文档类}
 %
 % 将选项传入 \pkg{ctex} 文档类。
@@ -2149,24 +2178,6 @@
 %
 % 传入各宏包选项。
 %    \begin{macrocode}
-\clist_set:Nx \g_@@_options_to_packages_clist
-  {
-    { no-math           } { fontspec     } ,
-    { list = off        } { bicaption    } ,
-    { warnings-off =
-      {
-        mathtools-overbracket,
-        mathtools-colon
-      }
-    }                     { unicode-math } ,
-    { amsmath, thmmarks } { ntheorem     } ,
-%<!article>    { chapter           } { algorithm    } ,
-%<!article>    { algochapter       } { algorithm2e  } ,
-    {
-      \bool_if:NTF \g_@@_integral_limits_bool
-        { displaylimits } { nolimits }
-    }                     { cmupint      }
-  }
 \clist_map_inline:Nn \g_@@_options_to_packages_clist
   { \PassOptionsToPackage #1 }
 %    \end{macrocode}
@@ -2185,8 +2196,7 @@
 %    \begin{macrocode}
 \RequirePackage
   {
-%<thesis>    xtemplate,
-%<thesis>    array,
+    array,
     mathtools,
     geometry,
     fancyhdr,
@@ -2200,315 +2210,41 @@
   }
 %    \end{macrocode}
 %
-% \subsection{内部定义}
+% \subsection{文档格式}
 %
-% \subsubsection{内部函数}
+% \subsubsection{字号行距}
 %
-% \begin{macro}[int]{\cs_gset:cpo,\tl_const:Nv,
-% \clist_use:NV,\clist_use:cv,
-% \exp_args:NNnv,\exp_last_unbraced:ce,
-% \regex_match:neTF}
-% \LaTeX3{} 函数变体。
+% \begin{macro}[int]{\SJTU at orig@normalsize}
+% 保存原始 \tn{normalsize} 字号大小。
 %    \begin{macrocode}
-\cs_generate_variant:Nn \cs_gset:Npn { cpo }
-\cs_generate_variant:Nn \tl_const:Nn { Nv }
-\cs_generate_variant:Nn \clist_use:Nn { NV, cv }
-\exp_args_generate:n { Nnv }
-\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
-\prg_generate_conditional_variant:Nnn \regex_match:nn { ne } { T, TF }
+\normalsize
+\cs_set_protected:Npe \SJTU at orig@normalsize
+  { \exp_not:N \fontsize { \f at size } { \f at baselineskip } \exp_not:N \selectfont }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\@@_engine_case:nn}
-% 2 个参数依次为 \pdfTeX 和 \XeTeX/\LuaTeX。
-%    \begin{macrocode}
-\cs_new:Npx \@@_engine_case:nn #1#2
-  {
-    \bool_lazy_or:nnTF
-      { \sys_if_engine_xetex_p:  }
-      { \sys_if_engine_luatex_p: }
-      {#2}
-      { \sys_if_engine_pdftex:T {#1} }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_engine_case:nnn}
-% 3 个参数依次为 \pdfTeX、 \XeTeX 和 \LuaTeX。
-%    \begin{macrocode}
-\cs_new:Npx \@@_engine_case:nnn #1#2#3
-  {
-    \sys_if_engine_xetex:TF
-      {#2}
-      {
-        \sys_if_engine_luatex:TF
-          {#3}
-          { \sys_if_engine_pdftex:T {#1} }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_unicode_engine_case:nn}
-% 2 个参数依次为 \XeTeX 和 \LuaTeX。
-%    \begin{macrocode}
-\cs_new:Npx \@@_unicode_engine_case:nn #1#2
-  {
-    \sys_if_engine_xetex:TF
-      {#1}
-      { \sys_if_engine_luatex:T {#2} }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_unicode_char:n}
-%    \begin{macrocode}
-\@@_engine_case:nn
-  {
-    \cs_new:Npn \@@_unicode_char:n #1
-      {
-        \exp_not:N \Unicode
-          { \int_div_truncate:nn {#1} { 256 } }
-          { \int_mod:nn          {#1} { 256 } }
-      }
-  }
-  { \cs_new:Npn \@@_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_preto_cmd:Nn,\@@_appto_cmd:Nn}
-% 补丁工具,来自 \pkg{ctexpatch} 宏包,在宏的原本定义前后增加钩子。
-%    \begin{macrocode}
-%<*!thesis>
-\cs_new_protected:Npn \@@_preto_cmd:Nn #1#2
-  {
-    \ctex_preto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-\cs_new_protected:Npn \@@_appto_cmd:Nn #1#2
-  {
-    \ctex_appto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-%</!thesis>
-%    \end{macrocode}
-% \end{macro}
-%
-% \changes{v2.0.2}{2023/03/31}{区分 \texttt{dim} 与 \texttt{skip} 类型变量。}
-% \begin{macro}[int]{\@@_dim_set_to_wd:Nn,\@@_skip_add_to_wd:Nn}
-% 操作长度变量的辅助函数。
-%    \begin{macrocode}
-%<*thesis>
-\cs_new:Npn \@@_dim_set_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l_@@_tmp_box {#2}
-    \dim_set:Nn #1 { \box_wd:N \l_@@_tmp_box }
-  }
-%</thesis>
-\cs_new:Npn \@@_skip_add_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l_@@_tmp_box {#2}
-    \skip_add:Nn #1 { \box_wd:N \l_@@_tmp_box }
-  }
-%<thesis>\cs_generate_variant:Nn \@@_dim_set_to_wd:Nn { Nv }
-\cs_generate_variant:Nn \@@_skip_add_to_wd:Nn { cv }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_cs_provide_eq:NN}
-%    \begin{macrocode}
-\cs_new:Npn \@@_cs_provide_eq:NN #1#2
-  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
-\cs_generate_variant:Nn \@@_cs_provide_eq:NN { cc }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_vspace:N,\@@_vspace:n,
-% \@@_vspace_r:N,\@@_vspace_r:n}
-% 类似 \LaTeXe{} 中的 \tn{vspace} 和 \tn{vspace*}。
-%    \begin{macrocode}
-%<*thesis>
-\cs_new_protected:Npn \@@_vspace:N #1
-  {
-    \skip_vertical:N #1
-    \skip_vertical:N \c_zero_skip
-  }
-\cs_new_protected:Npn \@@_vspace:n #1
-  {
-    \skip_set:Nn \l_@@_tmp_skip {#1}
-    \@@_vspace:N \l_@@_tmp_skip
-  }
-\cs_new_protected:Npn \@@_vspace_r:N #1
-  {
-    \dim_set_eq:NN \l_@@_tmp_dim \prevdepth
-    \hrule height \c_zero_dim
-    \nobreak
-    \skip_vertical:N #1
-    \skip_vertical:N \c_zero_skip
-    \dim_set_eq:NN \prevdepth \l_@@_tmp_dim
-  }
-\cs_new_protected:Npn \@@_vspace_r:n #1
-  {
-    \skip_set:Nn   \l_@@_tmp_skip {#1}
-    \@@_vspace_r:N \l_@@_tmp_skip
-  }
-%</thesis>
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_define_name:nn,\@@_define_name:nv,\@@_define_name:nnn,
-% \@@_define_name_from_clist:nnnn}
-% 定义默认名称的辅助函数。
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_define_name:nn #1#2
-  { \tl_const:cn { c_@@_name_ #1 _tl } {#2} }
-\cs_new_protected:Npn \@@_define_name:nnn #1#2#3
-  { \tl_const:cn { c_@@_name_ #2 _ #1 _tl } {#3} }
-%<*thesis>
-\cs_new_protected:Npn \@@_define_name_from_clist:nnnn #1#2#3#4
-  { \tl_const:cx { c_@@_name_ #2 _ #1 _tl } { \clist_item:nn {#4} {#3} } }
-\cs_generate_variant:Nn \@@_define_name:nn { nv }
-%</thesis>
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_define_symbol:nn}
-% 定义符号的辅助函数。
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_define_symbol:nn #1#2
-  { \tl_const:cx { c_@@_symbol_ #1 _tl } { \@@_unicode_char:n {#2} } }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_if_lang_valid:nTF}
-% 验证语言选项的函数。
-%    \begin{macrocode}
-%<*thesis>
-\cs_new_protected:Npn \@@_if_lang_valid:nTF #1
-  { \clist_if_in:NnTF \g_@@_lang_clist {#1} }
-\msg_new:nnn { sjtutex } { lang-validation }
-  { Invalid~ language~ argument~ `#1'! }
-%    \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{页面模板}
-%
-% 使用 \pkg{xtemplate} 构建页面模板,用于绘制标题页与版权页。
-%
-% 页面部件模板。
-%    \begin{macrocode}
-\DeclareObjectType { sjtu } { 0 }
-\DeclareTemplateInterface { sjtu } { component } { 0 }
-  {
-    format      : tokenlist = \c_empty_tl ,
-    content     : tokenlist = \c_empty_tl ,
-    bottom-skip : skip      = \c_zero_skip ,
-    align       : choice { left, right, center, normal } = center
-  }
-\DeclareTemplateCode { sjtu } { component } { 0 }
-  {
-    format      = \l_@@_component_format_tl ,
-    content     = \l_@@_component_content_tl ,
-    bottom-skip = \l_@@_component_bottom_skip ,
-    align       =
-      {
-        left    =
-          \cs_set_eq:NN \l_@@_component_align: \raggedright ,
-        right   =
-          \cs_set_eq:NN \l_@@_component_align: \raggedleft ,
-        center  =
-          \cs_set_eq:NN \l_@@_component_align: \centering ,
-        normal  =
-          \cs_set_eq:NN \l_@@_component_align: \prg_do_nothing:
-      }
-  }
-  {
-    \AssignTemplateKeys
-    \group_begin:
-      \l_@@_component_align:
-      \l_@@_component_format_tl
-      \l_@@_component_content_tl
-      \par
-    \group_end:
-    \@@_vspace:N \l_@@_component_bottom_skip
-  }
-%    \end{macrocode}
-%
-% 页面模板。
-%    \begin{macrocode}
-\DeclareTemplateInterface { sjtu } { page } { 0 }
-  {
-    bookmark      : boolean   = false ,
-    bookmark-text : tokenlist = \c_empty_tl ,
-    style         : tokenlist = empty ,
-    format        : tokenlist = \c_empty_tl ,
-    prefix        : tokenlist ,
-    components    : commalist ,
-    top-skip      : skip      = \c_zero_skip ,
-    bottom-skip   : skip      = \c_zero_skip
-  }
-\DeclareTemplateCode { sjtu } { page } { 0 }
-  {
-    bookmark      = \l_@@_page_bookmark_bool ,
-    bookmark-text = \l_@@_page_bookmark_text_tl ,
-    style         = \l_@@_page_style_tl ,
-    format        = \l_@@_page_format_tl ,
-    prefix        = \l_@@_page_prefix_tl ,
-    components    = \l_@@_page_components_clist ,
-    top-skip      = \l_@@_page_top_skip ,
-    bottom-skip   = \l_@@_page_bottom_skip
-  }
-  {
-    \AssignTemplateKeys
-    \bool_if:NTF \g_@@_openright_bool
-      { \cleardoublepage } { \clearpage }
-    \bool_if:NT \l_@@_page_bookmark_bool
-      { \@@_pdf_bookmark:nn { 0 } { \l_@@_page_bookmark_text_tl } }
-    \exp_args:No \thispagestyle { \l_@@_page_style_tl }
-%    \end{macrocode}
-% 移除页面顶部 \tn{vspace*} 的多余空白。
-% 见 \url{https://tex.stackexchange.com/questions/247513}。
-%    \begin{macrocode}
-    \@@_vspace_r:N \l_@@_page_top_skip
-    \@@_vspace:n { - \tex_parskip:D      }
-    \@@_vspace:n { - \tex_baselineskip:D }
-    \group_begin:
-      \l_@@_page_format_tl
-      \clist_map_inline:Nn \l_@@_page_components_clist
-        { \UseInstance { sjtu } { \l_@@_page_prefix_tl / ##1 } }
-    \group_end:
-    \@@_vspace:N \l_@@_page_bottom_skip
-    \clearpage
-  }
-%    \end{macrocode}
-%
-% 辅助函数。
-%    \begin{macrocode}
-\cs_new:Npn \@@_declare_component:nnn #1#2#3
-  { \DeclareInstance { sjtu } {#1/#2} { component } {#3} }
-\cs_new:Npn \@@_declare_page:nn #1#2
-  { \DeclareInstance { sjtu } {#1} { page } {#2} }
-%</thesis>
-%    \end{macrocode}
-%
-% \subsection{字号行距}
-%
 % \begin{macro}[int]{\@@_set_font_size:nnNn}
 % \begin{macro}{\normalsize}
 % 重定义 \tn{normalsize},设置正文的基线间距。
 %    \begin{macrocode}
+\msg_new:nnn { sjtutex } { baselineskip-invalid }
+  { Invalid~baselineskip~value~'#1'! \\ Using~default~value~instead. }
 \cs_new_protected:Npn \@@_set_font_size:nnNn #1#2#3#4
   { \cs_set_protected:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } }
-\tl_set:Nx \l_@@_font_size_tl
-  {
-    { \dim_to_decimal:n { \g_@@_font_size_dim     } }
-    { \dim_to_decimal:n { \g_@@_baseline_skip_dim } }
-  }
 \bool_if:NT \g_@@_fixed_baselineskip_bool
   {
-    \int_case:nn { \g_@@_font_size_int }
+    \dim_compare:nNnTF { \f at size pt } > { \g_@@_baseline_skip_dim }
       {
-        { 1 } {
+        \msg_warning:nne { sjtutex } { baselineskip-invalid }
+          { \dim_to_decimal:n { \g_@@_baseline_skip_dim } pt }
+      }
+      {
+        \tl_set:Ne \l_@@_font_size_tl
+          { { \f at size } { \dim_to_decimal:n { \g_@@_baseline_skip_dim } } }
+        \int_case:nn { \@ptsize }
+          {
+            { 0 }
+              {
                 \exp_after:wN \@@_set_font_size:nnNn \l_@@_font_size_tl
                   \normalsize
                   {
@@ -2519,10 +2255,23 @@
                     \let\@listi\@listI
                   }
               }
-        { 2 } {
+            { 1 }
+              {
                 \exp_after:wN \@@_set_font_size:nnNn \l_@@_font_size_tl
                   \normalsize
                   {
+                    \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+                    \abovedisplayshortskip \z@ \@plus3\p@
+                    \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+                    \belowdisplayskip \abovedisplayskip
+                    \let\@listi\@listI
+                  }
+              }
+            { 2 }
+              {
+                \exp_after:wN \@@_set_font_size:nnNn \l_@@_font_size_tl
+                  \normalsize
+                  {
                     \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
                     \abovedisplayshortskip \z@ \@plus3\p@
                     \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
@@ -2530,8 +2279,9 @@
                     \let\@listi\@listI
                   }
               }
+          }
+        \normalsize
       }
-    \normalsize
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2545,38 +2295,20 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{字体配置}
+% \subsubsection{字体配置}
 %
 % \begin{macro}[int]{\@@_fontset_error:nn}
 % 字库不可用时给出紧急错误信息,停止读取定义文件。
 %    \begin{macrocode}
+\msg_new:nnn { sjtutex } { font-unavailable }
+  { '#1-font~=~#2'~is~unavailable~in~current~mode. }
 \cs_new_protected:Npn \@@_fontset_error:nn #1#2
-  { \msg_error:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
-\msg_new:nnn { sjtutex } { font-unavailable }
-  { `#1-font~ =~ #2'~ is~ unavailable~ in~ current~ mode. }
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
+\cs_set_protected:Npn \ctex_fontset_error:n #1
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } { cjk } {#1} }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\@@_fontset_case:nn}
-% 2 个参数依次为 \pdfTeX 和 \XeTeX/\LuaTeX。
-%    \begin{macrocode}
-\cs_new_eq:NN \@@_fontset_case:nn \@@_engine_case:nn
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_fontset_case:nnn}
-% 3 个参数依次为 \pdfTeX(生成 PDF)、\pdfTeX(生成 DVI) 和
-% \XeTeX/\LuaTeX。
-%    \begin{macrocode}
-\cs_new:Npx \@@_fontset_case:nnn #1#2#3
-  {
-    \@@_engine_case:nn
-      { \sys_if_output_pdf:TF {#1} {#2} }
-      {#3}
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}[int]{\@@_declare_math_symbol:nnNn}
 %    \begin{macrocode}
 \cs_new_protected:Nn \@@_declare_math_symbol:nnNn
@@ -2644,9 +2376,14 @@
 % \begin{macro}[int]{\@@_load_font:nn,\@@_load_fontset:}
 % 如果字体配置文件不存在,则载入默认值,并给出警告。
 %    \begin{macrocode}
+\msg_new:nnn { sjtutex } { invalid-font }
+  {
+    Invalid~value~'#1-font~=~\tl_use:c { g_@@_ #1 _font_tl }'! \\
+    Using~'#2'~instead.
+  }
 \cs_new_protected:Npn \@@_load_font:nn #1#2
   {
-    \str_if_eq:eeF { \tl_use:c { g_@@_ #1 _font_tl } } { none }
+    \str_if_eq:vnF { g_@@_ #1 _font_tl } { none }
       {
         \file_if_exist:nF
           { sjtu- #1 -font- \tl_use:c { g_@@_ #1 _font_tl } .def }
@@ -2658,11 +2395,6 @@
           { sjtu- #1 -font- \tl_use:c { g_@@_ #1 _font_tl } .def }
       }
   }
-\msg_new:nnn { sjtutex } { invalid-font }
-  {
-    Invalid~ value~ `#1-font~ =~ \tl_use:c { g_@@_ #1 _font_tl }~ '! \\\\
-    Using~ `#2'~ instead.
-  }
 \cs_new_protected:Nn \@@_load_fontset:
   {
     \clist_map_inline:nn
@@ -2679,67 +2411,75 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsubsection{西文与数学字体}
+% \paragraph{西文与数学字体}
 %
 % \changes{v2.0.3}{2023/09/25}{新增 \opt{libertinus} 字体配置。}
 %    \begin{macrocode}
 %<*font&(math|text)>
-%<*stixtwo>
-\@@_fontset_case:nn
+%<*math&type1>
+%<*newtx|newpx>
+\tl_set_eq:NN \l_@@_save_encodingdefault_tl \encodingdefault
+\tl_set_eq:NN \l_@@_save_rmdefault_tl \rmdefault
+\tl_set_eq:NN \l_@@_save_sfdefault_tl \sfdefault
+\tl_set_eq:NN \l_@@_save_ttdefault_tl \ttdefault
+\tl_set:Nn \encodingdefault { OT1 }
+%<newtx>\tl_set:Nn \rmdefault { ntxtlf }
+%<newpx>\tl_set:Nn \rmdefault { zplTLF }
+\tl_set:Nn \qhv at scale { 0.94 }
+\tl_set:Nn \sfdefault { qhv }
+\tl_set:Nn \ttdefault { qcr }
+%<newtx>\RequirePackage { newtxmath }
+%<newpx>\RequirePackage { newpxmath }
+\tl_set_eq:NN \encodingdefault \l_@@_save_encodingdefault_tl
+\tl_set_eq:NN \rmdefault \l_@@_save_rmdefault_tl
+\tl_set_eq:NN \sfdefault \l_@@_save_sfdefault_tl
+\tl_set_eq:NN \ttdefault \l_@@_save_ttdefault_tl
+%</newtx|newpx>
+%<times>\PassOptionsToPackage { Symbol } { upgreek }
+%<lm|times>\RequirePackage { amssymb, upgreek }
+%<*lm>
+\SetSymbolFont { operators    } { normal } { OT1 } { lmr  } { m  } { n  }
+\SetSymbolFont { letters      } { normal } { OML } { lmm  } { m  } { it }
+\SetSymbolFont { symbols      } { normal } { OMS } { lmsy } { m  } { n  }
+\SetSymbolFont { largesymbols } { normal } { OMX } { lmex } { m  } { n  }
+\SetSymbolFont { operators    } { bold   } { OT1 } { lmr  } { bx } { n  }
+\SetSymbolFont { letters      } { bold   } { OML } { lmm  } { b  } { it }
+\SetSymbolFont { symbols      } { bold   } { OMS } { lmsy } { b  } { n  }
+\SetSymbolFont { largesymbols } { bold   } { OMX } { lmex } { m  } { n  }
+\SetMathAlphabet { \mathbf } { normal } { OT1 } { lmr  } { bx } { n  }
+\SetMathAlphabet { \mathsf } { normal } { OT1 } { lmss } { m  } { n  }
+\SetMathAlphabet { \mathit } { normal } { OT1 } { lmr  } { m  } { it }
+\SetMathAlphabet { \mathtt } { normal } { OT1 } { lmtt } { m  } { n  }
+\SetMathAlphabet { \mathbf } { bold   } { OT1 } { lmr  } { bx } { n  }
+\SetMathAlphabet { \mathsf } { bold   } { OT1 } { lmss } { bx } { n  }
+\SetMathAlphabet { \mathit } { bold   } { OT1 } { lmr  } { bx } { it }
+\SetMathAlphabet { \mathtt } { bold   } { OT1 } { lmtt } { m  } { n  }
+\@@_set_slanted_greek:
+%</lm>
+%<*times>
+\tl_set_eq:NN \l_@@_save_rmdefault_tl \rmdefault
+  \RequirePackage { mathptmx }
+\tl_set_eq:NN \rmdefault \l_@@_save_rmdefault_tl
+\tl_set:Nn \Hv at scale { 0.94 }
+\DeclareMathAlphabet { \mathsf } { OT1 } { phv } { m } { n }
+\DeclareMathAlphabet { \mathtt } { OT1 } { pcr } { m } { n }
+\SetMathAlphabet { \mathsf } { bold } { OT1 } { phv } { b } { n }
+\SetMathAlphabet { \mathtt } { bold } { OT1 } { pcr } { b } { n }
+\DeclareSymbolFont { SJTU at ptm } { OML } { ptmcm } { m } { it }
+\@@_declare_math_symbol:nnNn { \mathord } { SJTU at ptm } \upvarsigma { "26 }
+%</times>
+%<lm|times>\bool_if:NT \g_@@_upright_integral_bool
+%<lm|times>  { \RequirePackage { cmupint } }
+\@@_set_unimath_symbol:
+%</math&type1>
+%<*!(math&type1)>
+%<lm>\@@_if_engine_opentype:F
+%<*!lm>
+\@@_if_engine_opentype:TF
   {
 %<*math>
-    \DeclareSizeFunction { sub } { \sub at sfcnt \@font at info }
-    \PassOptionsToPackage { notext } { stix2 }
-    \RequirePackage { stix2 }
-    \clist_map_inline:nn
-      {
-        \upalpha      { "0B } ,
-        \upbeta       { "0C } ,
-        \upgamma      { "0D } ,
-        \updelta      { "0E } ,
-        \upepsilon    { "0F } ,
-        \upzeta       { "10 } ,
-        \upeta        { "11 } ,
-        \uptheta      { "12 } ,
-        \upiota       { "13 } ,
-        \upkappa      { "14 } ,
-        \uplambda     { "15 } ,
-        \upmu         { "16 } ,
-        \upnu         { "17 } ,
-        \upxi         { "18 } ,
-        \uppi         { "19 } ,
-        \uprho        { "1A } ,
-        \upsigma      { "1B } ,
-        \uptau        { "1C } ,
-        \upupsilon    { "1D } ,
-        \upphi        { "1E } ,
-        \upchi        { "1F } ,
-        \uppsi        { "20 } ,
-        \upomega      { "21 } ,
-        \upvarepsilon { "22 } ,
-        \upvartheta   { "23 } ,
-        \upvarpi      { "24 } ,
-        \upvarrho     { "25 } ,
-        \upvarsigma   { "26 } ,
-        \upvarphi     { "27 }
-      }
-      { \@@_declare_math_symbol:nnNn { \stix at lcgc } { operators } #1 }
-    \@@_set_slanted_greek:
-%</math>
-%<*text>
-    \tl_set:Nn \encodingdefault { T1 }
-    \DeclareEncodingSubset { TS1 } { ? } { 0 }
-    \UndeclareTextCommand { \textpertenthousand } { T1 }
-    \DeclareTextSymbolDefault { \textpertenthousand } { TS1 }
-    \tl_set:Nn \rmdefault { stix2 }
-    \tl_set:Nn \qhv at scale { 0.94 }
-    \tl_set:Nn \sfdefault { qhv }
-    \tl_set:Nn \ttdefault { qcr }
-%</text>
-  }
-  {
-%<*math>
     \RequirePackage { unicode-math }
+%<*stixtwo>
     \bool_if:NTF \g_@@_upright_integral_bool
       {
         \setmathfont { STIXTwoMath-Regular.otf }
@@ -2751,25 +2491,31 @@
         range        = { scr, bfscr },
         StylisticSet = 1
       ]
-%</math>
-%<math>    \setmathrm
-%<text>    \setmainfont
-      { STIXTwoText }
+%</stixtwo>
+%<*libertinus>
+    \bool_if:NTF \g_@@_upright_integral_bool
+      { \setmathfont { LibertinusMath-Regular.otf } }
+      {
+        \setmathfont { LibertinusMath-Regular.otf }
+          [ StylisticSet = 8 ]
+      }
+    \setmathfont { latinmodern-math.otf } [ range = \checkmark ]
+%</libertinus>
+%<cambria>    \setmathfont { Cambria~Math }
+%<*newcm>
+    \bool_if:NTF \g_@@_upright_integral_bool
+      {
+        \setmathfont { NewCMMath-Book.otf }
+          [ StylisticSet = 2 ]
+      }
+      { \setmathfont { NewCMMath-Book.otf } }
+    \setmathfont { NewCMMath-Book.otf }
       [
-        Extension      = .otf,
-        UprightFont    = *-Regular,
-        BoldFont       = *-Bold,
-        ItalicFont     = *-Italic,
-        BoldItalicFont = *-BoldItalic
+        range        = { scr, bfscr },
+        StylisticSet = 1
       ]
-%</stixtwo>
+%</newcm>
 %<*xits>
-\@@_fontset_case:nn
-%<math>  { \@@_fontset_error:nn { math } { xits } }
-%<text>  { \@@_fontset_error:nn { text } { xits } }
-  {
-%<*math>
-    \RequirePackage { unicode-math }
     \bool_if:NTF \g_@@_upright_integral_bool
       {
         \setmathfont { XITSMath-Regular }
@@ -2791,10 +2537,15 @@
         range        = { cal, bfcal },
         StylisticSet = 1
       ]
+%</xits>
 %</math>
+%<*newtx|newpx|stixtwo|xits>
 %<math>    \setmathrm
 %<text>    \setmainfont
-      { XITS }
+%<newtx>      { TeXGyreTermesX }
+%<newpx>      { TeXGyrePagellaX }
+%<stixtwo>      { STIXTwoText }
+%<xits>      { XITS }
       [
         Extension      = .otf,
         UprightFont    = *-Regular,
@@ -2802,49 +2553,6 @@
         ItalicFont     = *-Italic,
         BoldItalicFont = *-BoldItalic
       ]
-%</xits>
-%<*newtx|newpx>
-%<*math>
-\tl_set_eq:NN \l_@@_save_encodingdefault_tl \encodingdefault
-\tl_set_eq:NN \l_@@_save_rmdefault_tl \rmdefault
-\tl_set_eq:NN \l_@@_save_sfdefault_tl \sfdefault
-\tl_set_eq:NN \l_@@_save_ttdefault_tl \ttdefault
-\tl_set:Nn \encodingdefault { OT1 }
-%<newtx>\tl_set:Nn \rmdefault { ntxtlf }
-%<newpx>\tl_set:Nn \rmdefault { zplTLF }
-\tl_set:Nn \qhv at scale { 0.94 }
-\tl_set:Nn \sfdefault { qhv }
-\tl_set:Nn \ttdefault { qcr }
-%<newtx>\RequirePackage { newtxmath }
-%<newpx>\RequirePackage { newpxmath }
-\tl_set_eq:NN \encodingdefault \l_@@_save_encodingdefault_tl
-\tl_set_eq:NN \rmdefault \l_@@_save_rmdefault_tl
-\tl_set_eq:NN \sfdefault \l_@@_save_sfdefault_tl
-\tl_set_eq:NN \ttdefault \l_@@_save_ttdefault_tl
-\@@_set_unimath_symbol:
-%</math>
-%<*text>
-\@@_fontset_case:nn
-  {
-    \tl_set:Nn \encodingdefault { T1 }
-%<newtx>    \RequirePackage { newtxtext }
-%<newpx>    \RequirePackage { newpxtext }
-    \tl_set:Nn \ttdefault { qcr }
-  }
-  {
-    \setmainfont
-%<newtx>      { TeXGyreTermesX }
-%<newpx>      { TeXGyrePagellaX }
-      [
-        Extension       = .otf,
-        UprightFont     = *-Regular,
-        BoldFont        = *-Bold,
-        ItalicFont      = *-Italic,
-        BoldItalicFont  = *-BoldItalic
-      ]
-%</text>
-%</newtx|newpx>
-%<*text&(newtx|newpx)|stixtwo|xits>
 %<math>    \setmathsf
 %<text>    \setsansfont
       { texgyreheros }
@@ -2854,7 +2562,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
 %<math>    \setmathtt
 %<text>    \setmonofont
@@ -2867,68 +2575,13 @@
         BoldItalicFont = *-bolditalic,
         Ligatures      = CommonOff
       ]
-  }
-%</text&(newtx|newpx)|stixtwo|xits>
-%<*lm>
-%<*text>
-\@@_fontset_case:nn
-  {
-    \tl_set:Nn \encodingdefault { T1 }
-    \tl_set:Nn \rmdefault { lmr  }
-    \tl_set:Nn \sfdefault { lmss }
-    \tl_set:Nn \ttdefault { lmtt }
-  } { }
-%</text>
-%<*math>
-\RequirePackage { amssymb, upgreek }
-\SetSymbolFont { operators    } { normal } { OT1 } { lmr  } { m  } { n  }
-\SetSymbolFont { letters      } { normal } { OML } { lmm  } { m  } { it }
-\SetSymbolFont { symbols      } { normal } { OMS } { lmsy } { m  } { n  }
-\SetSymbolFont { largesymbols } { normal } { OMX } { lmex } { m  } { n  }
-\SetSymbolFont { operators    } { bold   } { OT1 } { lmr  } { bx } { n  }
-\SetSymbolFont { letters      } { bold   } { OML } { lmm  } { b  } { it }
-\SetSymbolFont { symbols      } { bold   } { OMS } { lmsy } { b  } { n  }
-\SetSymbolFont { largesymbols } { bold   } { OMX } { lmex } { m  } { n  }
-\SetMathAlphabet { \mathbf } { normal } { OT1 } { lmr  } { bx } { n  }
-\SetMathAlphabet { \mathsf } { normal } { OT1 } { lmss } { m  } { n  }
-\SetMathAlphabet { \mathit } { normal } { OT1 } { lmr  } { m  } { it }
-\SetMathAlphabet { \mathtt } { normal } { OT1 } { lmtt } { m  } { n  }
-\SetMathAlphabet { \mathbf } { bold   } { OT1 } { lmr  } { bx } { n  }
-\SetMathAlphabet { \mathsf } { bold   } { OT1 } { lmss } { bx } { n  }
-\SetMathAlphabet { \mathit } { bold   } { OT1 } { lmr  } { bx } { it }
-\SetMathAlphabet { \mathtt } { bold   } { OT1 } { lmtt } { m  } { n  }
-\bool_if:NT \g_@@_upright_integral_bool
-  { \RequirePackage { cmupint } }
-\@@_set_slanted_greek:
-\@@_set_unimath_symbol:
-%</math>
-%</lm>
+%</newtx|newpx|stixtwo|xits>
+%<*text&times>
+    \setmainfont { Times~New~Roman } [ Ligatures = Rare ]
+    \setsansfont { Arial } [ Scale = 0.94 ]
+    \setmonofont { Courier~New }
+%</text&times>
 %<*libertinus>
-\@@_fontset_case:nn
-  {
-%<*text>
-    \tl_set:Nn \encodingdefault { T1 }
-    \tl_set:Nn \rmdefault { LibertinusSerif-TLF }
-    \tl_set:Nn \sfdefault { LibertinusSans-TLF  }
-    \tl_set:Nn \ttdefault { lmtt                }
-%</text>
-%<*math>
-    \exp_args:No \PassOptionsToPackage
-      { \g_@@_math_font_options_clist } { libertinust1math }
-    \RequirePackage { libertinust1math }
-%</math>
-  }
-  {
-%<*math>
-    \RequirePackage { unicode-math }
-    \bool_if:NTF \g_@@_upright_integral_bool
-      { \setmathfont { LibertinusMath-Regular.otf } }
-      {
-        \setmathfont { LibertinusMath-Regular.otf }
-          [ StylisticSet = 8 ]
-      }
-    \setmathfont { latinmodern-math.otf } [ range = \checkmark ]
-%</math>
 %<math>    \setmathrm
 %<text>    \setmainfont
       { LibertinusSerif }
@@ -2958,61 +2611,20 @@
         SlantedFeatures     = { FakeSlant = 0.2 },
         BoldSlantedFeatures = { FakeSlant = 0.2 }
       ]
-  }
 %</libertinus>
-%<*times>
+%<*cambria>
 %<*math>
-\PassOptionsToPackage { Symbol } { upgreek }
-\RequirePackage { amssymb, upgreek }
-\tl_set_eq:NN \l_@@_save_rmdefault_tl \rmdefault
-  \RequirePackage { mathptmx }
-\tl_set_eq:NN \rmdefault \l_@@_save_rmdefault_tl
-\tl_set:Nn \Hv at scale { 0.94 }
-\DeclareMathAlphabet { \mathsf } { OT1 } { phv } { m } { n }
-\DeclareMathAlphabet { \mathtt } { OT1 } { pcr } { m } { n }
-\SetMathAlphabet { \mathsf } { bold } { OT1 } { phv } { b } { n }
-\SetMathAlphabet { \mathtt } { bold } { OT1 } { pcr } { b } { n }
-\DeclareSymbolFont { SJTU at ptm } { OML } { ptmcm } { m } { it }
-\@@_declare_math_symbol:nnNn { \mathord } { SJTU at ptm } \upvarsigma { "26 }
-\bool_if:NT \g_@@_upright_integral_bool
-  { \RequirePackage { cmupint } }
-\@@_set_unimath_symbol:
+    \setmathrm { Cambria }
+    \setmathsf { Calibri }
+    \setmathtt { Consolas } [ Scale = 0.95 ]
 %</math>
 %<*text>
-\@@_fontset_case:nn
-  {
-    \tl_set:Nn \encodingdefault { T1 }
-    \tl_set:Nn \rmdefault { ptm }
-    \tl_set:Nn \Hv at scale { 0.94 }
-    \tl_set:Nn \sfdefault { phv }
-    \tl_set:Nn \ttdefault { pcr }
-  }
-  {
-    \setmainfont { Times~New~Roman } [ Ligatures = Rare ]
-    \setsansfont { Arial } [ Scale = 0.94 ]
-    \setmonofont { Courier~New }
-  }
+    \setmainfont { Cambria }
+    \setsansfont { Calibri }
+    \setmonofont { Consolas } [ Scale = 0.95 ]
 %</text>
-%</times>
+%</cambria>
 %<*newcm>
-\@@_fontset_case:nn
-%<math>  { \@@_fontset_error:nn { math } { newcm } }
-%<text>  { \@@_fontset_error:nn { text } { newcm } }
-  {
-%<*math>
-    \RequirePackage { unicode-math }
-    \bool_if:NTF \g_@@_upright_integral_bool
-      {
-        \setmathfont { NewCMMath-Book.otf }
-          [ StylisticSet = 2 ]
-      }
-      { \setmathfont { NewCMMath-Book.otf } }
-    \setmathfont { NewCMMath-Book.otf }
-      [
-        range        = { scr, bfscr },
-        StylisticSet = 1
-      ]
-%</math>
 %<math>    \setmathrm
 %<text>    \setmainfont
       { NewCM10 }
@@ -3070,27 +2682,97 @@
         BoldSlantedFont     = *-Bold,
         BoldSlantedFeatures = { FakeSlant = 0.25 }
       ]
+%</newcm>
   }
-%</newcm>
-%<*cambria>
-\@@_fontset_case:nn
-%<math>  { \@@_fontset_error:nn { math } { cambria } }
-%<text>  { \@@_fontset_error:nn { text } { cambria } }
+%</!lm>
+%<*text&!otf>
   {
-%<*math>
-    \RequirePackage { unicode-math }
-    \setmathfont { Cambria~Math }
-    \setmathrm { Cambria }
-    \setmathsf { Calibri }
-    \setmathtt { Consolas } [ Scale = 0.95 ]
-%</math>
-%<*text>
-    \setmainfont { Cambria }
-    \setsansfont { Calibri }
-    \setmonofont { Consolas } [ Scale = 0.95 ]
-%</text>
+    \tl_set:Nn \encodingdefault { T1 }
+%<lm>    \tl_set:Nn \rmdefault { lmr  }
+%<lm>    \tl_set:Nn \sfdefault { lmss }
+%<libertinus>    \tl_set:Nn \rmdefault { LibertinusSerif-TLF }
+%<libertinus>    \tl_set:Nn \sfdefault { LibertinusSans-TLF  }
+%<lm|libertinus>    \tl_set:Nn \ttdefault { lmtt }
+%<newtx>    \PassOptionsToPackage { nohelv, nott } { newtxtext }
+%<newpx>    \PassOptionsToPackage { nohelv, nott } { newpxtext }
+%<newtx>    \RequirePackage { newtxtext }
+%<newpx>    \RequirePackage { newpxtext }
+%<*stixtwo>
+    \DeclareEncodingSubset { TS1 } { ? } { 0 }
+    \UndeclareTextCommand { \textpertenthousand } { T1 }
+    \DeclareTextSymbolDefault { \textpertenthousand } { TS1 }
+    \tl_set:Nn \rmdefault { stix2 }
+%</stixtwo>
+%<newtx|newpx|stixtwo>    \tl_set:Nn \qhv at scale { 0.94 }
+%<newtx|newpx|stixtwo>    \tl_set:Nn \sfdefault { qhv }
+%<newtx|newpx|stixtwo>    \tl_set:Nn \ttdefault { qcr }
+%<*times>
+    \tl_set:Nn \rmdefault { ptm }
+    \tl_set:Nn \Hv at scale { 0.94 }
+    \tl_set:Nn \sfdefault { phv }
+    \tl_set:Nn \ttdefault { pcr }
+%</times>
   }
-%</cambria>
+%</text&!otf>
+%<*text&otf>
+%<cambria>  { \@@_fontset_error:nn { text } { cambria } }
+%<newcm>  { \@@_fontset_error:nn { text } { newcm } }
+%<xits>  { \@@_fontset_error:nn { text } { xits } }
+%</text&otf>
+%<*math&!otf>
+  {
+%<*libertinus>
+    \exp_args:No \PassOptionsToPackage
+      { \g_@@_math_font_options_clist } { libertinust1math }
+    \RequirePackage { libertinust1math }
+%</libertinus>
+%<*stixtwo>
+    \DeclareSizeFunction { sub } { \sub at sfcnt \@font at info }
+    \PassOptionsToPackage { notext } { stix2 }
+    \RequirePackage { stix2 }
+    \clist_map_inline:nn
+      {
+        \upalpha      { "0B } ,
+        \upbeta       { "0C } ,
+        \upgamma      { "0D } ,
+        \updelta      { "0E } ,
+        \upepsilon    { "0F } ,
+        \upzeta       { "10 } ,
+        \upeta        { "11 } ,
+        \uptheta      { "12 } ,
+        \upiota       { "13 } ,
+        \upkappa      { "14 } ,
+        \uplambda     { "15 } ,
+        \upmu         { "16 } ,
+        \upnu         { "17 } ,
+        \upxi         { "18 } ,
+        \uppi         { "19 } ,
+        \uprho        { "1A } ,
+        \upsigma      { "1B } ,
+        \uptau        { "1C } ,
+        \upupsilon    { "1D } ,
+        \upphi        { "1E } ,
+        \upchi        { "1F } ,
+        \uppsi        { "20 } ,
+        \upomega      { "21 } ,
+        \upvarepsilon { "22 } ,
+        \upvartheta   { "23 } ,
+        \upvarpi      { "24 } ,
+        \upvarrho     { "25 } ,
+        \upvarsigma   { "26 } ,
+        \upvarphi     { "27 }
+      }
+      { \@@_declare_math_symbol:nnNn { \stix at lcgc } { operators } #1 }
+    \@@_set_slanted_greek:
+%</stixtwo>
+  }
+%</math&!otf>
+%<*math&otf>
+%<cambria>  { \@@_fontset_error:nn { math } { cambria } }
+%<newcm>  { \@@_fontset_error:nn { math } { newcm } }
+%<xits>  { \@@_fontset_error:nn { math } { xits } }
+%</math&otf>
+%</!(math&type1)>
 %</font&(math|text)>
 %    \end{macrocode}
 %
@@ -3115,123 +2797,190 @@
         \scpolint\npolint\pointint\sqint\intlarhk\intx
         \intcap\intcup\upint\lowint
       }
+    \clist_map_inline:nn
+      { amsfonts, amssymb, bm, upgreek }
+      { \@@_disable_package_load:n {#1} }
   }
 %    \end{macrocode}
 %
-% 若未使用 \pkg{unicode-math} 配置数学字体,则自动调用 \pkg{bm}。
+% 若未使用 \pkg{unicode-math} 配置数学字体,则自动调用 \pkg{bm},
+% 并在未定义 \tn{uppi} 和 \tn{checkmark} 时分别调用 \pkg{upgreek} 和 \pkg{amsfonts}。
 %    \begin{macrocode}
 \ctex_at_end_preamble:n
   {
-    \@ifpackageloaded { unicode-math }
-      { } { \RequirePackage { bm } }
+    \IfPackageLoadedF { unicode-math }
+      {
+        \RequirePackage { bm }
+        \cs_if_exist:NF \uppi
+          { \RequirePackage { upgreek  } }
+        \cs_if_exist:NF \checkmark
+          { \RequirePackage { amsfonts } }
+      }
   }
 %</class>
 %    \end{macrocode}
 %
-% \subsubsection{CJK 字体}
+% \paragraph{CJK 字体}
 %
+% \changes{v2.2}{2024/11/28}{新增 \opt{hanyi} 字体配置。}
 % 在字体未提供对应粗体的情况下,允许使用伪粗。
 %    \begin{macrocode}
 %<*font&cjk>
+\@@_if_engine_opentype:TF
+  {
+    \@@_if_main_lang_ja:TF
+      {
 %<*windows>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-windows-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-windows-zh.def } }
-%</und>
-%<*zh|ja>
-\@@_fontset_case:nn
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { windows }
-    \ctex_punct_set:n { windows }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-%<ja>  { \@@_fontset_error:nn { cjk } { windows } }
-  {
-%<*zh>
-    \setCJKmainfont { SimSun   }
-      [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
-    \setCJKsansfont { SimHei   } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { FangSong }
-%</zh>
-%<*ja>
-    \setCJKmainfont { MS~Mincho } [ AutoFakeBold = 3 ]
-    \setCJKsansfont { MS~Gothic } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { MS~Mincho }
-    \setCJKfamilyfont { jamin  } { MS~Mincho } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { jagoth } { MS~Gothic } [ AutoFakeBold = 3 ]
-%</ja>
+        \setCJKmainfont { MS~Mincho } [ AutoFakeBold = 3 ]
+        \setCJKsansfont { MS~Gothic } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { MS~Mincho }
+        \setCJKfamilyfont { jamin  } { MS~Mincho } [ AutoFakeBold = 3 ]
+        \setCJKfamilyfont { jagoth } { MS~Gothic } [ AutoFakeBold = 3 ]
+%</windows>
+%<*mac>
+        \setCJKmainfont { HiraMinProN  }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKsansfont { HiraKakuProN }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKmonofont { HiraMinProN-W3 }
+        \setCJKfamilyfont { jamin  } { HiraMinProN  }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKfamilyfont { jagoth } { HiraKakuProN }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+%</mac>
+%<*ubuntu>
+        \setCJKmainfont { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKsansfont { Noto~Sans~CJK~JP  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKmonofont { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKfamilyfont { jamin  } { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKfamilyfont { jagoth } { Noto~Sans~CJK~JP  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+%</ubuntu>
+%<*adobe>
+        \setCJKmainfont { KozMinPr6N }
+          [
+            UprightFont = *-Light ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKsansfont { KozGoPr6N  }
+          [
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { KozMinPr6N-Light }
+        \setCJKfamilyfont { jamin  } { KozMinPr6N }
+          [
+            UprightFont = *-Light ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKfamilyfont { jagoth } { KozGoPr6N  }
+          [
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+%</adobe>
+%<*fandol|hanyi>
+        \setCJKmainfont { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+%<fandol>            BoldFont    = *-Bold
+%<hanyi>            BoldFont    = *-Medium
+          ]
+        \setCJKsansfont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular
+          ]
+        \setCJKfamilyfont { jamin  } { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+%<fandol>            BoldFont    = *-Bold
+%<hanyi>            BoldFont    = *-Medium
+          ]
+        \setCJKfamilyfont { jagoth } { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+%</fandol|hanyi>
+%<*founder>
+        \setCJKmainfont { ipam.ttf } [ AutoFakeBold = 3 ]
+        \setCJKsansfont { ipag.ttf } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { ipag.ttf }
+        \setCJKfamilyfont { jamin  } { ipam.ttf } [ AutoFakeBold = 3 ]
+        \setCJKfamilyfont { jagoth } { ipag.ttf } [ AutoFakeBold = 3 ]
+%</founder>
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+%<*windows>
+      {
+        \setCJKmainfont { SimSun   }
+          [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
+        \setCJKsansfont { SimHei   } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { FangSong }
+      }
     \setCJKfamilyfont { zhsong } { SimSun   }
       [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
     \setCJKfamilyfont { zhhei  } { SimHei   } [ AutoFakeBold = 3 ]
     \setCJKfamilyfont { zhkai  } { KaiTi    }
     \setCJKfamilyfont { zhfs   } { FangSong }
-  }
-%</zh|ja>
 %</windows>
 %<*mac>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-mac-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-mac-zh.def } }
-%</und>
-%<*zh|ja>
-%<zh>\@@_fontset_case:nnn
-%<ja>\@@_fontset_case:nn
-  { \@@_fontset_error:nn { cjk } { mac } }
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { mac }
-    \ctex_punct_set:n { mac }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_family:nn   { \CJKsfdefault } { zhpf   }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhpf   }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-  {
-%<*zh>
-    \setCJKmainfont { Songti~SC  }
-      [
-        UprightFont    = *~Light ,
-        BoldFont       = *~Bold ,
-        ItalicFont     = Kaiti~SC~Regular ,
-        BoldItalicFont = Kaiti~SC~Bold
-      ]
-    \setCJKsansfont { Heiti~SC   }
-      [
-        UprightFont    = *~Medium ,
-        AutoFakeBold   = 3
-      ]
-    \setCJKmonofont { STFangsong }
-%</zh>
-%<*ja>
-    \setCJKmainfont { HiraMinProN  }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKsansfont { HiraKakuProN }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKmonofont { HiraMinProN-W3 }
-    \setCJKfamilyfont { jamin  } { HiraMinProN  }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKfamilyfont { jagoth } { HiraKakuProN }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-%</ja>
+      {
+        \setCJKmainfont { Songti~SC  }
+          [
+            UprightFont    = *~Light ,
+            BoldFont       = *~Bold ,
+            ItalicFont     = Kaiti~SC~Regular ,
+            BoldItalicFont = Kaiti~SC~Bold
+          ]
+        \setCJKsansfont { Heiti~SC   }
+          [
+            UprightFont    = *~Medium ,
+            AutoFakeBold   = 3
+          ]
+        \setCJKmonofont { STFangsong }
+      }
     \setCJKfamilyfont { zhsong } { Songti~SC  }
       [
         UprightFont    = *~Light ,
@@ -3249,75 +2998,27 @@
       [
         UprightFont    = *~Regular ,
         BoldFont       = *~Bold
-      ]
-  }
-%</zh|ja>
+        ]
 %</mac>
 %<*ubuntu>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-ubuntu-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-ubuntu-zh.def } }
-%</und>
-%<*zh|ja>
-%<zh>\@@_fontset_case:nnn
-%<ja>\@@_fontset_case:nn
-  { \@@_fontset_error:nn { cjk } { ubuntu } }
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhsong } { ubuntu }
-    \ctex_punct_set:n { ubuntu }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-  {
-%<*zh>
-    \setCJKmainfont { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold ,
-        ItalicFont  = AR~PL~KaitiM~GB
-      ]
-    \setCJKsansfont { Noto~Sans~CJK~SC  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKmonofont { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-%</zh>
-%<*ja>
-    \setCJKmainfont { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKsansfont { Noto~Sans~CJK~JP  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKmonofont { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { jamin  } { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { jagoth } { Noto~Sans~CJK~JP  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-%</ja>
+      {
+        \setCJKmainfont { Noto~Serif~CJK~SC }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold ,
+            ItalicFont  = AR~PL~KaitiM~GB
+          ]
+        \setCJKsansfont { Noto~Sans~CJK~SC  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKmonofont { Noto~Serif~CJK~SC }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+      }
     \setCJKfamilyfont { zhsong } { Noto~Serif~CJK~SC }
       [
         UprightFont = *~Light ,
@@ -3330,137 +3031,41 @@
         BoldFont    = *~Bold
       ]
     \setCJKfamilyfont { zhkai  } { AR~PL~KaitiM~GB   }
-  }
-%</zh|ja>
 %</ubuntu>
 %<*adobe>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-adobe-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-adobe-zh.def } }
-%</und>
-%<*zh|ja>
-%<zh>\@@_fontset_case:nnn
-%<ja>\@@_fontset_case:nn
-  { \@@_fontset_error:nn { cjk } { adobe } }
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { adobe }
-    \ctex_punct_set:n { adobe }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-  {
-%<*zh>
-    \setCJKmainfont { AdobeSongStd-Light       }
-      [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
-    \setCJKsansfont { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { AdobeFangsongStd-Regular }
-%</zh>
-%<*ja>
-    \setCJKmainfont { KozMinPr6N }
-      [
-        UprightFont = *-Light ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKsansfont { KozGoPr6N  }
-      [
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { KozMinPr6N-Light }
-    \setCJKfamilyfont { jamin  } { KozMinPr6N }
-      [
-        UprightFont = *-Light ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { jagoth } { KozGoPr6N  }
-      [
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-%</ja>
+      {
+        \setCJKmainfont { AdobeSongStd-Light       }
+          [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
+        \setCJKsansfont { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { AdobeFangsongStd-Regular }
+      }
     \setCJKfamilyfont { zhsong } { AdobeSongStd-Light       }
       [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
     \setCJKfamilyfont { zhhei  } { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
     \setCJKfamilyfont { zhfs   } { AdobeFangsongStd-Regular }
     \setCJKfamilyfont { zhkai  } { AdobeKaitiStd-Regular    }
-  }
-%</zh|ja>
 %</adobe>
 %<*fandol>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-fandol-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-fandol-zh.def } }
-%</und>
-%<*zh|ja>
-%<zh>\@@_fontset_case:nnn
-%<ja>\@@_fontset_case:nn
-  { \@@_fontset_error:nn { cjk } { fandol } }
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { fandol }
-    \ctex_punct_set:n { fandol }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-  {
-%<*zh>
-    \setCJKmainfont { FandolSong }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold ,
-        ItalicFont  = FandolKai-Regular
-      ]
-    \setCJKsansfont { FandolHei  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { FandolFang }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-%</zh>
-%<*ja>
-    \setCJKmainfont { HaranoAjiMincho }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKsansfont { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-    \setCJKfamilyfont { jamin  } { HaranoAjiMincho }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { jagoth } { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-%</ja>
+      {
+        \setCJKmainfont { FandolSong }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Bold ,
+            ItalicFont  = FandolKai-Regular
+          ]
+        \setCJKsansfont { FandolHei  }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { FandolFang }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular
+          ]
+      }
     \setCJKfamilyfont { zhsong } { FandolSong }
       [
         Extension   = .otf ,
@@ -3484,57 +3089,56 @@
         Extension   = .otf ,
         UprightFont = *-Regular
       ]
-  }
-%</zh|ja>
 %</fandol>
 %<*founder>
-%<*und>
-\tl_if_eq:NNTF \g_@@_lang_tl \c_@@_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-founder-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-founder-zh.def } }
-%</und>
-%<*zh|ja>
-\@@_fontset_case:nn
-%<*zh>
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { founder }
-    \ctex_punct_set:n { founder }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-%</zh>
-%<ja>  { \@@_fontset_error:nn { cjk } { founder } }
-  {
-%<*zh>
-    \setCJKmainfont { FZShuSong-Z01  }
-      [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
-    \setCJKsansfont { FZHei-B01      } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { FZFangSong-Z02 }
-%</zh>
-%<*ja>
-    \setCJKmainfont { ipam.ttf } [ AutoFakeBold = 3 ]
-    \setCJKsansfont { ipag.ttf } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { ipag.ttf }
-    \setCJKfamilyfont { jamin  } { ipam.ttf } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { jagoth } { ipag.ttf } [ AutoFakeBold = 3 ]
-%</ja>
+      {
+        \setCJKmainfont { FZShuSong-Z01  }
+          [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
+        \setCJKsansfont { FZHei-B01      } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { FZFangSong-Z02 }
+      }
     \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
       [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
     \setCJKfamilyfont { zhhei  } { FZHei-B01      } [ AutoFakeBold = 3 ]
     \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
     \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
+%</founder>
+%<*hanyi>
+      {
+        \setCJKmainfont { HYShuSongEr~S }
+          [ BoldFont = HYZhongSong~S, ItalicFont = HYKaiTi~S ]
+        \setCJKsansfont { HYZhongHei~S  } [ BoldFont = HYDaHei~S ]
+        \setCJKmonofont { HYFangSong~S  }
+      }
+    \setCJKfamilyfont { zhsong } { HYShuSongEr~S }
+      [ BoldFont = HYZhongSong~S ]
+    \setCJKfamilyfont { zhhei  } { HYZhongHei~S  }
+      [ BoldFont = HYDaHei~S     ]
+    \setCJKfamilyfont { zhkai  } { HYKaiTi~S     }
+    \setCJKfamilyfont { zhfs   } { HYFangSong~S  }
+%</hanyi>
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+%<!ubuntu>    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
   }
-%</zh|ja>
-%</founder>
-%<*!und>
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-%<!ubuntu>\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-%<ja>\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-%<ja>\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-%</!und>
+  {
+    \@@_if_main_lang_ja:TF
+%<windows>      { \@@_fontset_error:nn { cjk } { windows } }
+%<windows>      { \ctex_file_input:n { ctex-fontset-windows.def } }
+%<mac>      { \@@_fontset_error:nn { cjk } { mac } }
+%<mac>      { \ctex_file_input:n { ctex-fontset-mac.def } }
+%<ubuntu>      { \@@_fontset_error:nn { cjk } { ubuntu } }
+%<ubuntu>      { \ctex_file_input:n { ctex-fontset-ubuntu.def } }
+%<adobe>      { \@@_fontset_error:nn { cjk } { adobe } }
+%<adobe>      { \ctex_file_input:n { ctex-fontset-adobe.def } }
+%<fandol>      { \@@_fontset_error:nn { cjk } { fandol } }
+%<fandol>      { \ctex_file_input:n { ctex-fontset-fandol.def } }
+%<founder>      { \@@_fontset_error:nn { cjk } { founder } }
+%<founder>      { \ctex_file_input:n { ctex-fontset-founder.def } }
+%<hanyi>      { \@@_fontset_error:nn { cjk } { hanyi } }
+%<hanyi>      { \ctex_file_input:n { ctex-fontset-hanyi.def } }
+  }
 %</font&cjk>
 %    \end{macrocode}
 %
@@ -3550,18 +3154,43 @@
 %
 % 带圈数字使用 CJK 字体。
 %    \begin{macrocode}
-\@@_unicode_engine_case:nn
+\sys_if_engine_xetex:T
   {
     \xeCJK_declare_char_class:nn { CJK }
       { "24EA, "2460->"2473, "3251->"32BF, "25A1 }
   }
+\sys_if_engine_luatex:T
   {
     \ltjdefcharrange { 99 }
-      { "24EA, "2460-"2473, "3251-"32BF, "25A1 }
+      { "24EA, "2460- "2473, "3251- "32BF, "25A1 }
     \ltjsetparameter { jacharrange = { +99 } }
   }
 %    \end{macrocode}
 %
+% \begin{macro}[int]{\@@_unicode_char:n}
+% 由 Unicode 码位直接调用字符的辅助函数。
+%    \begin{macrocode}
+\sys_if_engine_pdftex:TF
+  {
+    \cs_new:Npn \@@_unicode_char:n #1
+      {
+        \exp_not:N \Unicode
+          { \int_div_truncate:nn {#1} { 256 } }
+          { \int_mod:nn          {#1} { 256 } }
+      }
+  }
+  { \cs_new:Npn \@@_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_symbol_const:nn}
+% 定义符号的辅助函数。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_symbol_const:nn #1#2
+  { \tl_const:ce { c_@@_symbol_ #1 _tl } { \@@_unicode_char:n {#2} } }
+%    \end{macrocode}
+% \end{macro}
+%
 % \changes{v2.0.2}{2023/04/01}{延迟载入字体配置,修复 \pkg{unicode-math}
 % 设置不生效的问题。}
 % 载入字体配置。
@@ -3569,7 +3198,7 @@
 \@@_load_fontset:
 %    \end{macrocode}
 %
-% \subsection{名称设置}
+% \subsubsection{名称选项}
 %
 % 定义 |sjtu/name| 键值类。
 %
@@ -3618,112 +3247,10 @@
     achv          .initial:n = { List~of~Research~Achievements },
 %</thesis>
   }
-%</class>
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-%<*scheme>
-%<*zh>
-\keys_set_known:nn { sjtu / name }
-  {
-    contents      = { 目 \protect \quad 录   } ,
-    listfigure    = { 插 \protect \quad 图   } ,
-    listtable     = { 表 \protect \quad 格   } ,
-    figure        = { 图                     } ,
-    table         = { 表                     } ,
-    abstract      = { 摘 \protect \quad 要   } ,
-    index         = { 索 \protect \quad 引   } ,
-    appendix      = { 附录                   } ,
-    proof         = { 证明                   } ,
-    bib           = { 参考文献               } ,
-    figure*       = { Figure                 } ,
-    table*        = { Table                  } ,
-    algorithm     = { 算法                   } ,
-    listalgorithm = { 算 \protect \quad 法   } ,
-    abbr          = { 缩略语对照表           } ,
-    nom           = { 符号对照表             } ,
-    ack           = { 致 \protect \quad 谢   } ,
-    resume        = { 个人简历               } ,
-    digest        = { 大摘要                 } ,
-    achv          = { 学术论文和科研成果目录 }
-  }
-%</zh>
-%    \end{macrocode}
+% \subsubsection{页面设置}
 %
-%    \begin{macrocode}
-%<*de>
-\keys_set_known:nn { sjtu / name }
-  {
-    contents      = { Inhaltsverzeichnis     } ,
-    listfigure    = { Abbildungsverzeichnis  } ,
-    listtable     = { Tabellenverzeichnis    } ,
-    figure        = { Abbildung              } ,
-    table         = { Tabelle                } ,
-    abstract      = { Zusammenfassung        } ,
-    index         = { Index                  } ,
-    appendix      = { Anhang                 } ,
-    proof         = { Beweis                 } ,
-    bib           = { Literaturverzeichnis   } ,
-    part          = { Teil                   } ,
-    chapter       = { Kapitel                } ,
-    figure*       = { Figure                 } ,
-    table*        = { Table                  } ,
-    algorithm     = { Algorithmus            } ,
-    listalgorithm = { Algorithmenverzeichnis } ,
-    abbr          = { Abkürzungsverzeichnis  } ,
-    nom           = { Symbolverzeichnis      } ,
-    ack           = { Danksagungen           } ,
-    resume        = { Lebenslauf             } ,
-    digest        = { Kurzfassung            } ,
-    achv          = { Forschungsleistungen   }
-  }
-%</de>
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%<*ja>
-\keys_set_known:nn { sjtu / name }
-  {
-    contents      = { 目 \protect \quad 次 } ,
-    listfigure    = { 図目次               } ,
-    listtable     = { 表目次               } ,
-    figure        = { 図                   } ,
-    table         = { 表                   } ,
-    abstract      = { 概 \protect \quad 要 } ,
-    index         = { 索 \protect \quad 引 } ,
-    appendix      = { 付録                 } ,
-    proof         = { 证明                 } ,
-    bib           = { 参考文献             } ,
-    figure*       = { Figure               } ,
-    table*        = { Table                } ,
-    algorithm     = { アルゴリズム         } ,
-    listalgorithm = { アルゴリズム目次     } ,
-    abbr          = { 略語表               } ,
-    nom           = { 記号表               } ,
-    ack           = { 謝 \protect \quad 辞 } ,
-    resume        = { 履歴書               } ,
-    digest        = { 要 \protect \quad 約 } ,
-    achv          = { 研究業績書           }
-  }
-%</ja>
-%</scheme>
-%    \end{macrocode}
-%
-% 载入名称配置。
-%    \begin{macrocode}
-%<*class>
-%<*thesis>
-\clist_map_inline:Nn \g_@@_lang_clist
-  { \file_input:n { sjtu-name-thesis- #1 .def } }
-\clist_map_inline:nn
-  { title_page, declaration, abstract }
-  { \@@_define_name:nv {#1} { c_@@_name_ #1 _ \g_@@_lang_tl _tl } }
-%</thesis>
-%<!thesis>\file_input:n { sjtu-name-generic- \g_@@_lang_tl .def }
-%    \end{macrocode}
-%
-% \subsection{页面设置}
-%
 % 利用 \pkg{geometry} 宏包设置页面边距以及页眉高度。
 %    \begin{macrocode}
 \geometry
@@ -3747,7 +3274,7 @@
 %</thesis>
 %    \end{macrocode}
 %
-% \subsection{页眉页脚}
+% \subsubsection{页眉页脚}
 %
 % \pkg{ctex} 宏包使用 \opt{heading} 选项后,会把页面格式设置为 |headings|。
 % 因此必须在 \pkg{ctex} 调用之后重新设置 \tn{pagestyle} 为 |fancy|。
@@ -3797,13 +3324,31 @@
 % \end{macro}
 %
 % \begin{macro}{style/page-number}
-% \begin{macro}[int]{\@@_page:n}
+% \begin{macro}[int]{\@@_page:nn}
 % 页脚页码格式。
 %    \begin{macrocode}
-\cs_new:Nn \@@_thepage: { \thepage }
+\tl_set:Nn \@@_the_page_tl { \thepage }
+\tl_new:N \@@_the_last_page_tl
+\msg_new:nnn { sjtutex } { require-pageslts }
+  {
+    Add~'\token_to_str:N \usepackage{pageslts}'~in~your~preamble \\
+    to~enable~the~page~number~of~the~last~page.
+  }
 \keys_define:nn { sjtu / style }
   {
-    page-number .cs_set:Np = \@@_page:n #1 ,
+    page-number    .code:n =
+      {
+        \regex_match:nnT { \#2 } { #1 }
+          {
+            \ctex_if_preamble:TF
+              { \RequirePackage { pageslts } }
+              {
+                \IfPackageLoadedF { pageslts }
+                  { \msg_warning:nn { sjtutex } { require-pageslts } }
+              }
+          }
+        \cs_set:Nn \@@_page:nn { #1 }
+      } ,
     page-number .initial:n = { {#1} }
   }
 %    \end{macrocode}
@@ -3814,15 +3359,10 @@
 %    \begin{macrocode}
 \tl_set:Nn \l_@@_header_tl
   {
-%<*thesis>
-    {
-      \@@_set_cjk_default_zh: \normalfont
-      \l_@@_info_subject_zh_tl
-    }
-%</thesis>
+%<thesis>    { \songti \l_@@_info_subject_zh_tl }
 %<*!thesis>
     \includegraphics [ height = 1.2 cm ]
-      { sjtu-vi-logo-small-red.pdf }
+      { sjtu-vi-logo-std-h-cor-red.pdf }
 %</!thesis>
   }
 %<thesis>\tl_set:Nn \l_@@_leftmark_tl  { \leftmark }
@@ -3832,7 +3372,7 @@
 %
 % 设置页眉页脚。
 %    \begin{macrocode}
-\bool_if:NTF \g_@@_twoside_bool
+\legacy_if:nTF { @twoside }
   {
     \fancyhead [ LO, RE ] { \l_@@_header_tl }
     \fancyhead [ LE ]     { \@@_nouppercase:V \l_@@_leftmark_tl  }
@@ -3842,7 +3382,8 @@
     \fancyhead [ L ] { \l_@@_header_tl }
     \fancyhead [ R ] { \@@_nouppercase:V \l_@@_rightmark_tl }
   }
-\fancyfoot [ C ] { \@@_page:n { \@@_thepage: } }
+\fancyfoot [ C ]
+  { \@@_page:nn { \@@_the_page_tl } { \@@_the_last_page_tl } }
 %    \end{macrocode}
 %
 % \begin{macro}{\headrule}
@@ -3849,7 +3390,7 @@
 % \cls{sjtuthesis} 的页眉线。
 %    \begin{macrocode}
 %<*thesis>
-\cs_set:Npn \headrule
+\tl_set:Nn \headrule
   {
     \hrule height 2.25 pt width \headwidth
     \skip_vertical:n {  0.75 pt }
@@ -3860,14 +3401,17 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \changes{v2.2}{2024/11/08}{更新 \cls{sjtureport} 和 \cls{sjtuarticle} 的
+% \texttt{plain} 页面样式。}
 % 重定义 |plain| 样式。
 %    \begin{macrocode}
 %<*!thesis>
-\bool_if:NTF \g_@@_twoside_bool
+\legacy_if:nTF { @twoside }
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ LE, RO ] { }
+        \fancyhead { }
+        \fancyhead [ LO, RE ] { \l_@@_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -3874,7 +3418,8 @@
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ R ] { }
+        \fancyhead { }
+        \fancyhead [ L ] { \l_@@_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -3892,7 +3437,7 @@
 \RenewDocumentCommand \cleardoublepage { }
   {
     \clearpage
-    \bool_if:NT \g_@@_twoside_bool
+    \legacy_if:nT { @twoside }
       {
         \int_if_odd:nF \c at page
           { \hbox:n { } \thispagestyle { empty } \newpage }
@@ -3901,7 +3446,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{页码设置}
+% \subsubsection{页码设置}
 %
 % 文档初始页码编码设置。
 %    \begin{macrocode}
@@ -3922,7 +3467,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{章节标题结构}
+% \subsubsection{章节标题}
 %
 % 设置章节标题样式。
 %    \begin{macrocode}
@@ -3974,7 +3519,7 @@
                   \CJKsffamily
   }
 %</thesis>
-%<!thesis>  { format = \normalsize \bfseries \CJKsffamily }
+%<!thesis>  { format = \SJTU at orig@normalsize \bfseries \CJKsffamily }
 \ctex_set:nn { subsubsection }
 %<*thesis>
   {
@@ -3983,7 +3528,7 @@
     format      = \zihao { -4 } \setbaselineskip { 16 bp } \normalfont
   }
 %</thesis>
-%<!thesis>  { format = \normalsize \normalfont }
+%<!thesis>  { format = \SJTU at orig@normalsize \normalfont }
 \ctex_set:n { secnumdepth = 3 }
 %    \end{macrocode}
 %
@@ -4012,32 +3557,9 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\SJTU at head,\@@_head_aux_s:nn,\@@_head_aux_s:nx,
-% \@@_pdf_bookmark:nn,\@@_phantom_section:}
-% 定义一个灵活的章节标题命令专门处理不同的需求。
+% \begin{macro}[int]{\@@_pdf_bookmark:nn,\@@_phantom_section:}
+% 在 \pkg{hyperref} 载入后才有意义。
 %    \begin{macrocode}
-\NewDocumentCommand \SJTU at head { s O{#3} m O{#2} }
-  {
-%<!article>    \CTEX at chapter@break
-    \IfBooleanTF {#1}
-      { \tl_if_empty:nF {#4} { \@@_pdf_bookmark:nn { 0 } {#4} } }
-      {
-        \@@_phantom_section:
-%<!article>        \addcontentsline { toc } { chapter } {#4}
-%<article>        \addcontentsline { toc } { section } {#4}
-      }
-    \cs_set_eq:NN \@@_orig_ctex_gettitle:n \CTEX at gettitle
-    \cs_set:Npn \CTEX at gettitle ##1 { \@@_orig_ctex_gettitle:n {#2} }
-%<!article>    \chapter* {#3}
-%<article>    \section* {#3}
-    \cs_set_eq:NN \CTEX at gettitle \@@_orig_ctex_gettitle:n
-    \@mkboth { \MakeUppercase {#2} } { \MakeUppercase {#2} }
-  }
-%<*thesis>
-\cs_new:Npn \@@_head_aux_s:nn #1#2
-  { \SJTU at head* [#1] {#2} }
-\cs_generate_variant:Nn \@@_head_aux_s:nn { nx }
-%</thesis>
 \cs_new_eq:NN \@@_pdf_bookmark:nn \use_none:nn
 \cs_new_eq:NN \@@_phantom_section: \prg_do_nothing:
 %</class>
@@ -4044,7 +3566,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{段落}
+% \subsubsection{段落}
 %
 % 设置全文首行缩进。
 %    \begin{macrocode}
@@ -4071,7 +3593,7 @@
 \setlist { nosep }
 %    \end{macrocode}
 %
-% \subsection{数学公式}
+% \subsubsection{数学公式}
 %
 % \changes{v2.1}{2023/11/30}{新增 \opt{style/equation-font} 选项。}
 % \begin{macro}{style/equation-font}
@@ -4080,8 +3602,7 @@
 \keys_define:nn { sjtu / style }
   {
     equation-font  .tl_set:N = \SJTU at style@equation at font ,
-%<thesis>    equation-font .initial:x = \exp_not:N \linespread { }
-%<thesis>                               \exp_not:N \zihao { \g_@@_zihao_tl }
+%<thesis>    equation-font .initial:n = \linespread { } \SJTU at orig@normalsize
 %<!thesis>    equation-font .initial:V = \c_empty_tl
   }
 %    \end{macrocode}
@@ -4115,7 +3636,7 @@
   }
 %    \end{macrocode}
 %
-% \subsection{数学环境}
+% \subsubsection{数学环境}
 %
 % 可以选用 \pkg{amsthm} 或 \pkg{ntheorem} 宏包控制数学环境样式,
 % 并提供对证明环境 \env{proof} 的支持。
@@ -4135,7 +3656,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{浮动体}
+% \subsubsection{浮动体}
 %
 % 下面这组命令使浮动对象的缺省值稍微宽松一点,从而防止幅度对象占据过多的
 % 文本页面,也可以防止在很大空白的浮动页上放置很小的图形。
@@ -4242,7 +3763,7 @@
         \@addtoreset {#4} {#5}
         \IfBooleanF {#1}
           {
-            \cs_gset:cpo { the #4 }
+            \exp_args:Nco \cs_gset:Npn { the #4 }
               { \cs:w the #5 \cs_end: #2 #3 {#4} }
           }
       }
@@ -4259,7 +3780,7 @@
 %</!article>
 %    \end{macrocode}
 %
-% \begin{macro}[int]{\l_@@_counter_without_chapter_clist}
+% \begin{variable}{\l_@@_counter_without_chapter_clist}
 % 大摘要中不需要随章编号的各计数器。
 %    \begin{macrocode}
 %<*thesis>
@@ -4267,24 +3788,16 @@
   { section, figure, table, equation }
 %</thesis>
 %    \end{macrocode}
-% \end{macro}
+% \end{variable}
 %
-% \subsection{脚注}
+% \subsubsection{脚注}
 %
-% \begin{macro}[int]{\@@_makefnmark_plain:,\@@_thefootnote_plain:,
-% \@@_thempfootnote_plain:}
-% 储存原始的脚注相关命令。
-%    \begin{macrocode}
-\cs_set_eq:NN \@@_makefnmark_plain: \@makefnmark
-\cs_set_eq:NN \@@_thefootnote_plain: \thefootnote
-\cs_set_eq:NN \@@_thempfootnote_plain: \thempfootnote
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_footnote_number:N}
+% \begin{macro}[int]{\@@_circled_number:N}
 % 通过 Unicode 码位调用带圈数字。
 %    \begin{macrocode}
-\cs_new:Npn \@@_footnote_number:N #1
+\msg_new:nnn { sjtutex } { circled-number-exceed }
+  { Circled~number~exceed~50! }
+\cs_new:Npn \@@_circled_number:N #1
   {
     \int_compare:nNnTF {#1} < { 21 }
       { \@@_unicode_char:n { \int_eval:n { "2460 - 1 + #1 } } }
@@ -4294,23 +3807,16 @@
           {
             \int_compare:nNnTF {#1} < { 51 }
               { \@@_unicode_char:n { \int_eval:n { "32B1 - 36 + #1 } } }
-              { \msg_warning:nn { sjtutex } { too-many-footnotes } }
+              {
+                \msg_warning:nn { sjtutex } { circled-number-exceed }
+                \int_to_arabic:n {#1}
+              }
           }
       }
   }
-\msg_new:nnn { sjtutex } { too-many-footnotes }
-  { Too~ many~ footnotes. }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\@@_makefnmark_circled:}
-% 重定义内部脚注文字命令,使用带圈数字编号时,脚注不使用上标。
-% 见 \url{https://www.zhihu.com/question/53030087}。
-%    \begin{macrocode}
-\cs_new:Nn \@@_makefnmark_circled: { \hbox:n { \@thefnmark } }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{style/fnmark-font}
 % 脚注编号字体。
 %    \begin{macrocode}
@@ -4319,8 +3825,7 @@
     fnmark-font           .choice: ,
     fnmark-font / haranoaji .code:n =
       {
-        \@@_engine_case:nn
-          { \tl_set_eq:NN \l_@@_style_fnmark_font_tl \c_empty_tl }
+        \@@_if_engine_opentype:TF
           {
             \tl_set:Nn \l_@@_style_fnmark_font_tl
               {
@@ -4332,6 +3837,7 @@
                   ]
               }
           }
+          { \tl_set_eq:NN \l_@@_style_fnmark_font_tl \c_empty_tl }
       } ,
     fnmark-font / unknown .tl_set:N = \l_@@_style_fnmark_font_tl ,
     fnmark-font          .initial:V = \c_empty_tl
@@ -4339,18 +3845,10 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\@@_thefootnote_circled:,\@@_thempfootnote_circled:}
-% 使用带圈数字编号脚注。
-%    \begin{macrocode}
-\cs_new:Nn \@@_thefootnote_circled:
-  { { \l_@@_style_fnmark_font_tl \@@_footnote_number:N \c at footnote } }
-\cs_new:Nn \@@_thempfootnote_circled:
-  { { \l_@@_style_fnmark_font_tl \@@_footnote_number:N \c at mpfootnote } }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{style/fnmark-style}
 % 脚注编号样式。
+% 重定义内部脚注文字命令,使用带圈数字编号时,脚注不使用上标。
+% 见 \url{https://www.zhihu.com/question/53030087}。
 %    \begin{macrocode}
 \keys_define:nn { sjtu / style }
   {
@@ -4357,15 +3855,21 @@
     fnmark-style           .choice: ,
     fnmark-style / plain   .code:n =
       {
-        \cs_set_eq:NN \@@_makefnmark: \@@_makefnmark_plain:
-        \cs_set_eq:NN \thefootnote \@@_thefootnote_plain:
-        \cs_set_eq:NN \thempfootnote \@@_thempfootnote_plain:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@textsuperscript { \normalfont \@thefnmark } } }
+        \tl_set:Nn \thefootnote
+          { \arabic { footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \itshape \alph { mpfootnote } } }
       } ,
     fnmark-style / circled .code:n =
       {
-        \cs_set_eq:NN \@@_makefnmark: \@@_makefnmark_circled:
-        \cs_set_eq:NN \thefootnote \@@_thefootnote_circled:
-        \cs_set_eq:NN \thempfootnote \@@_thempfootnote_circled:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@thefnmark } }
+        \tl_set:Nn \thefootnote
+          { { \l_@@_style_fnmark_font_tl \@@_circled_number:N \c at footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \l_@@_style_fnmark_font_tl \@@_circled_number:N \c at mpfootnote } }
       }
   }
 %</class>
@@ -4383,145 +3887,330 @@
 % 在导言末尾修改 \tn{@makefntext},支持使用 \pkg{footmisc} 修改脚注格式。
 %    \begin{macrocode}
 %<*class>
-\ctex_at_end_preamble:n {
-  \cs_set_eq:NN \@@_orig_make_fntext:n \@makefntext
-  \cs_set:Npn \@makefntext #1
-    {
-      \group_begin:
-        \cs_set_eq:NN \@makefnmark \@@_makefnmark:
-        \@@_orig_make_fntext:n {#1}
-      \group_end:
-    }
-}
+\ctex_at_end_preamble:n
+  {
+    \cs_set_eq:NN \SJTU at orig@makefntext \@makefntext
+    \cs_set:Npn \@makefntext #1
+      {
+        \group_begin:
+          \cs_set_eq:NN \@makefnmark \SJTU at makefnmark
+          \SJTU at orig@makefntext {#1}
+        \group_end:
+      }
+  }
 %    \end{macrocode}
 %
-% \subsection{信息录入}
+% \subsection{多语言支持}
 %
-% \changes{v2.0}{2022/12/17}{添加 \opt{display-date} 键。}
-% \changes{v2.0}{2022/12/23}{使用 \opt{assoc-supervisor} 键表示副导师,
-%                            使用 \opt{co-supervisor} 键表示联合导师。}
-% \changes{v2.0}{2022/12/23}{添加 \opt{subject} 键。}
-% \changes{v2.0}{2023/03/17}{使用语言代码前缀区别不同语种的 \opt{sjtu/info} 键。}
-% \begin{macro}[int]{\@@_info_keys_define:n}
-% 定义 \cls{sjtuthesis} 不同语种 |sjtu/info| 键值类的辅助函数。
+% \begin{variable}{\l_@@_lang_tl}
 %    \begin{macrocode}
-%<*thesis>
-\cs_new:Npn \@@_info_keys_define:n #1
+\tl_set_eq:NN \l_@@_lang_tl \g_@@_lang_tl
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+\msg_new:nnn { sjtutex } { lang-validation }
+  { Invalid~language~argument~'#1'! }
+\keys_define:nn { sjtu / private }
   {
-    \clist_map_inline:nn
-      {
-        title, display_title, subject, author, date,
-        supervisor, assoc_supervisor, department,
-        co_supervisor, major, degree
-      }
-      { \tl_new:c { l_@@_info_ ##1 _ #1 _tl } }
-    \clist_map_inline:nn
-      { keywords, fund }
-      { \clist_new:c { l_@@_info_ ##1 _ #1 _clist } }
-    \keys_define:nn { sjtu }
-      { info / #1 .meta:nn = { sjtu / info / #1 } {##1} }
-    \keys_define:nn { sjtu / info }
-      {        #1 .meta:nn = { sjtu / info / #1 } {##1} }
-    \keys_define:nn { sjtu / info / #1 }
-      {
-        title               .code:n =
-          {
-            \tl_set:cn { l_@@_info_title_ #1 _tl } {##1}
-            \tl_if_empty:cT { l_@@_info_display_title_ #1 _tl }
-              { \tl_set:cn { l_@@_info_display_title_ #1 _tl } {##1} }
-          } ,
-        display-title     .tl_set:c = l_@@_info_display_title_ #1 _tl ,
-        subject           .tl_set:c = l_@@_info_subject_ #1 _tl ,
-        keywords       .clist_set:c = l_@@_info_keywords_ #1 _clist ,
-        author            .tl_set:c = l_@@_info_author_ #1 _tl ,
-        id                 .meta:nn = { sjtu / info } { id = {##1} } ,
-        supervisor        .tl_set:c = l_@@_info_supervisor_ #1 _tl ,
-        assoc-supervisor  .tl_set:c = l_@@_info_assoc_supervisor_ #1 _tl ,
-        co-supervisor     .tl_set:c = l_@@_info_co_supervisor_ #1 _tl ,
-        degree            .tl_set:c = l_@@_info_degree_ #1 _tl ,
-        department        .tl_set:c = l_@@_info_department_ #1 _tl ,
-        major             .tl_set:c = l_@@_info_major_ #1 _tl ,
-        fund           .clist_set:c = l_@@_info_fund_ #1 _clist ,
-        date               .meta:nn = { sjtu / info } { date = {##1} } ,
-        display-date      .tl_set:c = l_@@_info_date_ #1 _tl ,
-      }
+    lang .choice: ,
+    lang .value_required:n = true ,
+    lang .groups:n = { lang } ,
+    lang / unknown .code:n =
+      { \msg_warning:nnn { sjtutex } { lang-validation } {#1} }
   }
 %    \end{macrocode}
+%
+% \begin{macro}[int]{\@@_select_language:n}
+% 选择局部语言。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_select_language:n
+  { \keys_set_groups:nnn { sjtu / private } { lang } }
+%    \end{macrocode}
 % \end{macro}
 %
-% \begin{variable}{\l_@@_info_id_zh_tl}
-% 单独处理学号。
+% 载入语言配置文件。
 %    \begin{macrocode}
-\tl_new:N \l_@@_info_id_zh_tl
-\keys_define:nn { sjtu / info }
-  { id   .tl_set:N = \l_@@_info_id_zh_tl }
+%<thesis>\clist_map_inline:Nn \g_@@_lang_clist
+%<thesis>  { \file_input:n { sjtu-lang- #1 .def } }
+%<!thesis>\file_input:n { sjtu-lang- \g_@@_lang_tl .def }
+\file_input:n { sjtu-scheme- \g_@@_lang_tl .def }
+%</class>
 %    \end{macrocode}
-% \end{variable}
 %
-% \begin{variable}{\l_@@_info_supervisors_clist}
-% 标题中需要显示的导师列表。
+% \begin{macro}[int]{\@@_set_cjk_default_zh:,\@@_set_cjk_default_ja:}
+% 设置 CJK 默认字体族的辅助命令。
 %    \begin{macrocode}
-\clist_set:Nn \l_@@_info_supervisors_clist { supervisor }
+%<*lang>
+%<*zh>
+\cs_new_protected:Nn \@@_set_cjk_default_zh:
+  {
+    \tl_set:Nn \CJKrmdefault { zhsong }
+    \tl_set:Nn \CJKsfdefault { zhhei  }
+    \tl_set:Nn \CJKttdefault { zhfs   }
+  }
+%</zh>
+%<*ja>
+\cs_new_protected:Nn \@@_set_cjk_default_ja:
+  {
+    \tl_set:Nn \CJKrmdefault { jamin  }
+    \tl_set:Nn \CJKsfdefault { jagoth }
+    \tl_set:Nn \CJKttdefault { jagoth }
+  }
+%</ja>
 %    \end{macrocode}
-% \end{variable}
+% \end{macro}
 %
-% 盲审模式下隐藏作者、导师姓名等信息。
 %    \begin{macrocode}
-\ctex_at_end_preamble:n
+\keys_define:nn { sjtu / private }
   {
-    \bool_if:NT \g_@@_review_bool
+%<zh>    lang / zh .code:n =
+%<en>    lang / en .code:n =
+%<de>    lang / de .code:n =
+%<ja>    lang / ja .code:n =
       {
-        \clist_map_inline:Nn \g_@@_lang_clist
-          {
-            \clist_map_inline:nn
-              { author, supervisor, assoc_supervisor, co_supervisor }
-              { \tl_clear:c { l_@@_info_ ##1 _ #1 _tl } }
-            \clist_clear:c { l_@@_info_fund_ #1 _clist }
-          }
-        \tl_clear:N \l_@@_info_id_zh_tl
-      }
+        \tl_set_eq:NN \l_@@_lang_tl \l_keys_value_tl
+%<zh>        \tl_set:Nn \languagename { chinese }
+%<en>        \tl_set:Nn \languagename { english }
+%<de>        \tl_set:Nn \languagename { ngerman }
+%<ja>        \tl_set:Nn \languagename { japanese }
+%<zh>        \@@_set_cjk_default_zh:
+%<ja>        \@@_set_cjk_default_ja:
+        \normalfont
+%<zh>        \ctex_set:n { autoindent = true }
+%<en|de>        \ctex_set:n { autoindent = 1.5 em }
+%<ja>        \ctex_set:n { autoindent = 1 }
+      } ,
+%<zh>    zh .meta:n = { lang = zh } ,
+%<zh>    zh .groups:n = { lang }
+%<en>    en .meta:n = { lang = en } ,
+%<en>    en .groups:n = { lang }
+%<de>    de .meta:n = { lang = de } ,
+%<de>    de .groups:n = { lang }
+%<ja>    ja .meta:n = { lang = ja } ,
+%<ja>    ja .groups:n = { lang }
   }
-%</thesis>
-%</class>
 %    \end{macrocode}
 %
+% \begin{macro}[int]{\@@_title_case_aux_zh:n,\@@_title_case_aux_en:n,
+% \@@_title_case_aux_de:n,\@@_title_case_aux_ja:n}
+% 设置标题大小写转换的辅助命令。
 %    \begin{macrocode}
-%<lang&thesis&zh>\@@_info_keys_define:n { zh }
-%<lang&thesis&en>\@@_info_keys_define:n { en }
-%<lang&thesis&de>\@@_info_keys_define:n { de }
-%<lang&thesis&ja>\@@_info_keys_define:n { ja }
+%<zh>\cs_set_eq:NN \@@_title_case_aux_zh:n \use:n
+%<en>\cs_set_eq:NN \@@_title_case_aux_en:n \MakeUppercase
+%<de>\cs_set_eq:NN \@@_title_case_aux_de:n \MakeUppercase
+%<ja>\cs_set_eq:NN \@@_title_case_aux_ja:n \use:n
 %    \end{macrocode}
+% \end{macro}
 %
-% \begin{variable}{\l_@@_info_subject_tl,\l_@@_info_keywords_clist}
+% 通用名称常量。
 %    \begin{macrocode}
-%<*class&!thesis>
-\tl_new:N \l_@@_info_subject_tl
-\clist_new:N \l_@@_info_keywords_clist
-\keys_define:nn { sjtu / info }
+\clist_map_inline:nn
   {
-    title             .tl_set:N = \@title ,
-    author            .tl_set:N = \@author ,
-    display-date      .tl_set:N = \@date ,
-    subject           .tl_set:N = \l_@@_info_subject_tl ,
-    keywords       .clist_set:N = \l_@@_info_keywords_clist ,
+%<zh>    { keywords } { 关键词          } ,
+%<en>    { keywords } { Key~words       } ,
+%<de>    { keywords } { Schlüsselwörter } ,
+%<ja>    { keywords } { キーワード      } ,
+%<zh|ja>    { info_sep } { : \null        } ,
+%<en|de>    { info_sep } { \hbox { :~ }    } ,
+%<zh>    { item_sep } { ,              }
+%<en|de>    { item_sep } { ,~              }
+%<ja>    { item_sep } { \quad           }
   }
-%</class&!thesis>
+%<zh>  { \@@_name_const:nnn { zh } #1 }
+%<en>  { \@@_name_const:nnn { en } #1 }
+%<de>  { \@@_name_const:nnn { de } #1 }
+%<ja>  { \@@_name_const:nnn { ja } #1 }
+%</lang>
 %    \end{macrocode}
-% \end{variable}
 %
-% \subsection{多语言支持}
+% 初始化语言名称。
+%    \begin{macrocode}
+%<*scheme>
+%<zh>\tl_set:Nn \languagename { chinese  }
+%<en>\tl_set:Nn \languagename { english  }
+%<de>\tl_set:Nn \languagename { ngerman  }
+%<ja>\tl_set:Nn \languagename { japanese }
+%    \end{macrocode}
 %
+% 设置名称选项。默认值为英文,只需修改其他语种。
+%    \begin{macrocode}
+%<*!en>
+\keys_set_known:nn { sjtu / name }
+  {
+%<*zh>
+    contents      = { 目 \protect \quad 录   } ,
+    listfigure    = { 插 \protect \quad 图   } ,
+    listtable     = { 表 \protect \quad 格   } ,
+    figure        = { 图                     } ,
+    table         = { 表                     } ,
+    abstract      = { 摘 \protect \quad 要   } ,
+    index         = { 索 \protect \quad 引   } ,
+    appendix      = { 附录                   } ,
+    proof         = { 证明                   } ,
+    bib           = { 参考文献               } ,
+    figure*       = { Figure                 } ,
+    table*        = { Table                  } ,
+    algorithm     = { 算法                   } ,
+    listalgorithm = { 算 \protect \quad 法   } ,
+    abbr          = { 缩略语对照表           } ,
+    nom           = { 符号对照表             } ,
+    ack           = { 致 \protect \quad 谢   } ,
+    resume        = { 个人简历               } ,
+    digest        = { 大摘要                 } ,
+    achv          = { 学术论文和科研成果目录 }
+%</zh>
+%<*de>
+    contents      = { Inhaltsverzeichnis     } ,
+    listfigure    = { Abbildungsverzeichnis  } ,
+    listtable     = { Tabellenverzeichnis    } ,
+    figure        = { Abbildung              } ,
+    table         = { Tabelle                } ,
+    abstract      = { Zusammenfassung        } ,
+    index         = { Index                  } ,
+    appendix      = { Anhang                 } ,
+    proof         = { Beweis                 } ,
+    bib           = { Literaturverzeichnis   } ,
+    part          = { Teil                   } ,
+    chapter       = { Kapitel                } ,
+    figure*       = { Figure                 } ,
+    table*        = { Table                  } ,
+    algorithm     = { Algorithmus            } ,
+    listalgorithm = { Algorithmenverzeichnis } ,
+    abbr          = { Abkürzungsverzeichnis  } ,
+    nom           = { Symbolverzeichnis      } ,
+    ack           = { Danksagungen           } ,
+    resume        = { Lebenslauf             } ,
+    digest        = { Kurzfassung            } ,
+    achv          = { Forschungsleistungen   }
+%</de>
+%<*ja>
+    contents      = { 目 \protect \quad 次 } ,
+    listfigure    = { 図目次               } ,
+    listtable     = { 表目次               } ,
+    figure        = { 図                   } ,
+    table         = { 表                   } ,
+    abstract      = { 概 \protect \quad 要 } ,
+    index         = { 索 \protect \quad 引 } ,
+    appendix      = { 付録                 } ,
+    proof         = { 证明                 } ,
+    bib           = { 参考文献             } ,
+    figure*       = { Figure               } ,
+    table*        = { Table                } ,
+    algorithm     = { アルゴリズム         } ,
+    listalgorithm = { アルゴリズム目次     } ,
+    abbr          = { 略語表               } ,
+    nom           = { 記号表               } ,
+    ack           = { 謝 \protect \quad 辞 } ,
+    resume        = { 履歴書               } ,
+    digest        = { 要 \protect \quad 約 } ,
+    achv          = { 研究業績書           }
+%</ja>
+  }
+%</!en>
+%</scheme>
+%    \end{macrocode}
+%
+% 学位论文名称常量。
+%    \begin{macrocode}
+%<*thesis-i18n>
+%<zh>\@@_symbol_const:nn { white_square } { "25A1 }
+%<zh>\@@_name_const_from_clist:nnnn { zh }
+%<en>\@@_name_const_from_clist:nnnn { en }
+%<de>\@@_name_const_from_clist:nnnn { de }
+%<ja>\@@_name_const_from_clist:nnnn { ja }
+  { degree_level } { \g_@@_thesis_type_int }
+%<zh>  { 学士, 硕士, 博士 }
+%<en>  { Bachelor, Master, Doctor }
+%<de>  { Bachelor, Master, Doktor }
+%<ja>  { 学士, 修士, 博士 }
+\clist_map_inline:nn
+  {
+%<*zh>
+    { univ             } { 上海交通大学           } ,
+    { address          } { 中国・上海             } ,
+    { thesis           } { 学位论文               } ,
+    { title_page       } { 题名页                 } ,
+    { declaration      } { 原创性声明及使用授权书 } ,
+    { orig_decl        } { 原创性声明             } ,
+    { auth_decl        } { 使用授权书             } ,
+    { decl_author      } { 学位论文作者           } ,
+    { decl_supervisor  } { 指导教师               } ,
+    { abstract         } { 摘 \protect \quad 要   }
+%</zh>
+%<*en>
+    { univ             } { Shanghai~ Jiao~ Tong~ University } ,
+    { address          } { Shanghai,~ P.R.~ China           } ,
+    { title_page       } { Title~ Page                      } ,
+    { declaration      } { Statutory~ Declaration           } ,
+    { abstract         } { Abstract                         }
+%</en>
+%<*de>
+    { univ             } { Shanghai~ Jiao~ Tong~ Universität } ,
+    { address          } { Shanghai,~ VR~ China              } ,
+    { title_page       } { Titelblatt                        } ,
+    { declaration      } { Eidesstattliche~ Erklärung        } ,
+    { abstract         } { Abstrakt                          }
+%</de>
+%<*ja>
+    { univ             } { 上海交通大学         } ,
+    { address          } { 中国・上海           } ,
+    { thesis           } { 学位請求論文         } ,
+    { title_page       } { 標題紙               } ,
+    { declaration      } { 誓約書・公表許諾書   } ,
+    { abstract         } { 要 \protect \quad 旨 }
+%</ja>
+  }
+%<zh>  { \@@_name_const:nnn { zh } #1 }
+%<en>  { \@@_name_const:nnn { en } #1 }
+%<de>  { \@@_name_const:nnn { de } #1 }
+%<ja>  { \@@_name_const:nnn { ja } #1 }
+\clist_map_inline:nn
+  {
+%<*zh>
+    { author           } { 姓名              } ,
+    { id               } { 学号              } ,
+    { supervisor       } { 导师              } ,
+    { assoc_supervisor } { 副导师            } ,
+    { co_supervisor    } { 联合导师          } ,
+    { department       } { 院系              } ,
+    { major            } { 学科 \, / \, 专业 } ,
+    { degree           } { 申请学位          }
+%</zh>
+%<*en>
+    { author           } { Author             } ,
+    { supervisor       } { Supervisor         } ,
+    { assoc_supervisor } { Assoc.\ Supervisor } ,
+    { co_supervisor    } { Co-supervisor      }
+%</en>
+%<*de>
+    { author           } { Autor/in         } ,
+    { supervisor       } { Betreuer/in      } ,
+    { assoc_supervisor } { Zweitbetreuer/in } ,
+    { co_supervisor    } { Co-Betreuer/in   }
+%</de>
+%<*ja>
+    { author           } { 氏名       } ,
+    { supervisor       } { 指導教員   } ,
+    { assoc_supervisor } { 副指導教員 } ,
+    { co_supervisor    } { 共同指導   }
+%</ja>
+  }
+%<zh>  { \@@_name_set:nnn { zh } #1 }
+%<en>  { \@@_name_set:nnn { en } #1 }
+%<de>  { \@@_name_set:nnn { de } #1 }
+%<ja>  { \@@_name_set:nnn { ja } #1 }
+%    \end{macrocode}
+%
 % \changes{v2.0.3}{2023/04/08}{更新学位论文初始英文主题。}
 % 初始化主题。
 %    \begin{macrocode}
-%<*lang>
-%<*thesis>
 %<zh>\keys_define:nn { sjtu / info / zh }
 %<en>\keys_define:nn { sjtu / info / en }
 %<de>\keys_define:nn { sjtu / info / de }
 %<ja>\keys_define:nn { sjtu / info / ja }
   {
-    subject          .initial:x =
+    subject          .initial:e =
       {
 %<*zh>
         \exp_not:V \c_@@_name_univ_zh_tl
@@ -4545,11 +4234,40 @@
 %</ja>
       }
   }
-%</thesis>
+%</thesis-i18n>
 %    \end{macrocode}
 %
 % 将形如 |yyyy-mm-dd| 或 |yyyy-mm| 的 ISO 日期格式字符串转化为日期表示。
 %
+% 日期常量。
+%    \begin{macrocode}
+%<*lang>
+%<*zh|ja>
+\clist_map_inline:nn
+  {
+    { year  } { 年 } ,
+    { month } { 月 } ,
+    { day   } { 日 }
+  }
+%<zh>  { \@@_name_const:nnn { zh } #1 }
+%<ja>  { \@@_name_const:nnn { ja } #1 }
+%</zh|ja>
+%<*en>
+\clist_const:Nn \c_@@_name_month_en_clist
+  {
+    January, February, March, April, May, June,
+    July, August, September, October, November, December
+  }
+%</en>
+%<*de>
+\clist_const:Nn \c_@@_name_month_de_clist
+  {
+    Januar, Februar, März, April, Mai, Juni,
+    Juli, August, September, Oktober, November, Dezember
+  }
+%</de>
+%    \end{macrocode}
+%
 % \begin{macro}[int]{\@@_date_aux_zh:nnn,\@@_date_aux_zh:w,
 % \@@_date_aux_short_zh:nn,\@@_date_aux_short_zh:w}
 % 中文日期。
@@ -4670,119 +4388,192 @@
 \cs_new:Npn \@@_date_aux_short_ja:w #1-#2 \q_stop
   { \@@_date_aux_short_ja:nn {#1} {#2} }
 %</ja>
+%</lang>
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[int]{\@@_set_language_zh:,\@@_set_language_en:,
-% \@@_set_language_de:,\@@_set_language_ja:,
-% \@@_set_cjk_default_zh:,\@@_set_cjk_default_ja:}
-% 设置语言格式辅助命令
+% \subsection{信息录入}
+%
+% \changes{v2.0}{2022/12/17}{添加 \opt{display-date} 键。}
+% \changes{v2.0}{2022/12/23}{使用 \opt{assoc-supervisor} 键表示副导师,
+%                            使用 \opt{co-supervisor} 键表示联合导师。}
+% \changes{v2.0}{2022/12/23}{添加 \opt{subject} 键。}
+% \changes{v2.0}{2023/03/17}{使用语言代码前缀区别不同语种的 \opt{sjtu/info} 键。}
+% \begin{macro}[int]{\@@_info_keys_define:n}
+% 定义 \cls{sjtuthesis} 不同语种 |sjtu/info| 键值类的辅助函数。
 %    \begin{macrocode}
-%<*zh>
-\cs_new:Nn \@@_set_cjk_default_zh:
+%<*class>
+%<*thesis>
+\msg_new:nnn { sjtutex } { key-already-defined }
+  { Key~'#1'~is~already~defined~and~redefination~is~being~ignored. }
+\msg_new:nnn { sjtutex } { key-invalid }
+  { Key~'#1'~is~invalid~and~ignored. }
+\msg_new:nnn { sjtutex } { key-needs-two-arguments }
+  { Key~'#1'~needs~two~arguments~otherwise~ignored. }
+\cs_new_protected:Npn \@@_info_keys_define:n #1
   {
-    \tl_set:Nn \CJKrmdefault { zhsong }
-    \tl_set:Nn \CJKsfdefault { zhhei  }
-    \tl_set:Nn \CJKttdefault { zhfs   }
+    \clist_map_inline:nn
+      {
+        title, display_title, subject, date, department, major,
+        author, supervisor, assoc_supervisor, co_supervisor, degree
+      }
+      { \tl_new:c { l_@@_info_ ##1 _ #1 _tl } }
+    \clist_map_inline:nn
+      { keywords, fund }
+      { \clist_new:c { l_@@_info_ ##1 _ #1 _clist } }
+    \bool_if:NTF \g_@@_review_bool
+      {
+        \seq_set_from_clist:cn { l_@@_info_show_ #1 _seq }
+          { author, id, supervisor, department, major, degree }
+      }
+      { \seq_new:c { l_@@_info_show_ #1 _seq } }
+    \keys_define:nn { sjtu }
+      { info / #1 .meta:nn = { sjtu / info / #1 } {##1} }
+    \keys_define:nn { sjtu / info }
+      {        #1 .meta:nn = { sjtu / info / #1 } {##1} }
+    \keys_define:nn { sjtu / info / #1 }
+      {
+        display-title       .code:n =
+          {
+            \tl_set:co { l_@@_info_display_title_ #1 _tl }
+              { \cs:w @@_title_case_aux_ #1 :n \cs_end: {##1} }
+          } ,
+        title               .code:n =
+          {
+            \tl_set:cn { l_@@_info_title_ #1 _tl } {##1}
+            \tl_if_empty:cT { l_@@_info_display_title_ #1 _tl }
+              { \keys_set:nn { sjtu / info / #1 } { display-title = {##1} } }
+          } ,
+        subject           .tl_set:c = { l_@@_info_subject_ #1 _tl } ,
+        keywords       .clist_set:c = { l_@@_info_keywords_ #1 _clist } ,
+        fund           .clist_set:c = { l_@@_info_fund_ #1 _clist } ,
+        fund              .groups:n = { sensitive } ,
+        date               .meta:nn = { sjtu / info } { date = {##1} } ,
+        display-date      .tl_set:c = { l_@@_info_date_ #1 _tl } ,
+        @show+              .code:n =
+          {
+            \seq_if_in:cnF { l_@@_info_show_ #1 _seq } {##1}
+              { \seq_put_right:cn { l_@@_info_show_ #1 _seq } {##1} }
+          } ,
+        @show+            .groups:n = { sensitive } ,
+        custom             .meta:nn = { sjtu / info / #1 / custom } {##1} ,
+        custom / unknown    .code:n =
+          {
+            \regex_match:nVTF { \A [a-z] [a-z0-9\-]* \Z } \l_keys_key_str
+              {
+                \keys_if_exist:neTF { sjtu / info / #1 } \l_keys_key_str
+                  {
+                    \msg_warning:nne { sjtutex } { key-already-defined }
+                      \l_keys_path_str
+                  }
+                  {
+                    \int_compare:nNnTF { \tl_count:n {##1} } = { 2 }
+                      {
+                        \tl_set_eq:NN \l_@@_tmp_tl \l_keys_key_str
+                        \tl_replace_all:Nnn \l_@@_tmp_tl { - } { _ }
+                        \tl_set:co { l_@@_name_ \l_@@_tmp_tl _ #1 _tl }
+                          { \use_i:nn  ##1 }
+                        \tl_set:co { l_@@_info_ \l_@@_tmp_tl _ #1 _tl }
+                          { \use_ii:nn ##1 }
+                        \exp_args:Ne \@@_setup:n
+                          { info / #1 / @show+ = \l_@@_tmp_tl }
+                      }
+                      {
+                        \msg_warning:nne { sjtutex } { key-needs-two-arguments }
+                          \l_keys_path_str
+                      }
+                  }
+              }
+              { \msg_warning:nne { sjtutex } { key-invalid } \l_keys_path_str }
+          }
+      }
+    \clist_map_inline:nn
+      {
+        author, supervisor, assoc-supervisor, co-supervisor,
+        department, major, degree
+      }
+      {
+        \tl_set:Nn \l_@@_tmp_tl {##1}
+        \tl_replace_all:Nnn \l_@@_tmp_tl { - } { _ }
+        \keys_define:ne { sjtu / info / #1 }
+          {
+            ##1 .code:n =
+              {
+                \exp_not:N \tl_set:cn
+                  { l_@@_info_ \l_@@_tmp_tl _ #1 _tl } {####1}
+                \exp_not:N \@@_setup:n
+                  { info / #1 / @show+ = \l_@@_tmp_tl }
+              }
+          }
+      }
+    \clist_map_inline:nn
+      { author, supervisor, assoc-supervisor, co-supervisor }
+      { \keys_define:nn { sjtu / info / #1 } { ##1 .groups:n = { sensitive } } }
   }
-\cs_new_protected:Nn \@@_set_language_zh:
-  {
-    \tl_set:Nn \languagename { chinese }
-    \ctex_set:n { autoindent = true }
-    \@@_set_cjk_default_zh:
-    \normalfont
-  }
-%</zh>
-%<*en|de>
-%<en>\cs_new_protected:Nn \@@_set_language_en:
-%<de>\cs_new_protected:Nn \@@_set_language_de:
-  {
-%<en>    \tl_set:Nn \languagename { english }
-%<de>    \tl_set:Nn \languagename { ngerman }
-    \ctex_set:n { autoindent = 1.5 em }
-    \normalfont
-  }
-%</en|de>
-%<*ja>
-\cs_new:Nn \@@_set_cjk_default_ja:
-  {
-    \tl_set:Nn \CJKrmdefault { jamin  }
-    \tl_set:Nn \CJKsfdefault { jagoth }
-    \tl_set:Nn \CJKttdefault { jagoth }
-  }
-\cs_new_protected:Nn \@@_set_language_ja:
-  {
-    \tl_set:Nn \languagename { japanese }
-    \ctex_set:n { autoindent = 1 }
-    \@@_set_cjk_default_ja:
-    \normalfont
-  }
-%</ja>
 %    \end{macrocode}
 % \end{macro}
 %
-% 标题页页面样式,页脚添加资助基金信息。
+% \begin{macro}{info/id}
+% \begin{variable}{\l_@@_info_id_zh_tl}
+% 单独处理学号。
 %    \begin{macrocode}
-%<*thesis>
-%<zh>\cs_new:Npn \ps at SJTU@fund at zh
-%<en>\cs_new:Npn \ps at SJTU@fund at en
-%<de>\cs_new:Npn \ps at SJTU@fund at de
-%<ja>\cs_new:Npn \ps at SJTU@fund at ja
+\tl_new:N \l_@@_info_id_zh_tl
+\keys_define:nn { sjtu / info }
   {
-    \ps at empty
-    \cs_set:Npn \@oddfoot
+    id   .code:n =
       {
-        \minipage [ t ] { \textwidth }
-          \centering \zihao { - 5 }
-%<zh>          \clist_use:Nn \l_@@_info_fund_zh_clist { \par }
-%<en>          \clist_use:Nn \l_@@_info_fund_en_clist { \par }
-%<de>          \clist_use:Nn \l_@@_info_fund_de_clist { \par }
-%<ja>          \clist_use:Nn \l_@@_info_fund_ja_clist { \par }
-        \endminipage
-      }
-    \cs_set_eq:NN \@evenfoot \@oddfoot
+        \tl_set:Nn \l_@@_info_id_zh_tl {#1}
+        \@@_setup:n { info / zh / @show+ = id }
+      } ,
+    id .groups:n = { sensitive }
   }
-%</thesis>
-%</lang>
 %    \end{macrocode}
+% \end{variable}
+% \end{macro}
 %
-% 初始化语言名称。
+% 定义 \cls{sjtuthesis} 中不同语种的信息键值类。
 %    \begin{macrocode}
-%<*scheme>
-%<zh>\tl_set:Nn \languagename { chinese  }
-%<en>\tl_set:Nn \languagename { english  }
-%<de>\tl_set:Nn \languagename { ngerman  }
-%<ja>\tl_set:Nn \languagename { japanese }
-%</scheme>
+\clist_map_inline:Nn \g_@@_lang_clist
+  { \@@_info_keys_define:n {#1} }
+%</thesis>
 %    \end{macrocode}
 %
-% 载入语言配置。
+% 定义 \cls{sjtureport} 和 \cls{sjtuarticle} 中的信息键值类。
+% \begin{variable}{\l_@@_info_subject_tl,\l_@@_info_keywords_clist}
 %    \begin{macrocode}
-%<*class>
-%<thesis>\clist_map_inline:Nn \g_@@_lang_clist
-%<thesis>  { \file_input:n { sjtu-lang-thesis- #1 .def } }
-%<!thesis>\file_input:n { sjtu-lang-generic- \g_@@_lang_tl .def }
-\file_input:n { sjtu-scheme- \g_@@_lang_tl .def }
+%<*!thesis>
+\tl_new:N \l_@@_info_subject_tl
+\clist_new:N \l_@@_info_keywords_clist
+\keys_define:nn { sjtu / info }
+  {
+    title             .tl_set:N = \@title ,
+    author            .tl_set:N = \@author ,
+    display-date      .tl_set:N = \@date ,
+    subject           .tl_set:N = \l_@@_info_subject_tl ,
+    keywords       .clist_set:N = \l_@@_info_keywords_clist ,
+  }
+%</!thesis>
 %    \end{macrocode}
+% \end{variable}
 %
 % \begin{macro}{info/date}
-% 初始化日期。
+% 日期。
 %    \begin{macrocode}
 \keys_define:nn { sjtu / info }
   {
     date    .code:n =
       {
-        \regex_match:neTF { \d+-\d+-\d+ } {#1}
+        \regex_match:nnTF { \A \d+ \- \d+ \- \d+ \Z } {#1}
           {
 %<*thesis>
             \clist_map_inline:Nn \g_@@_lang_clist
               {
-                \tl_set:cx { l_@@_info_date_ ##1 _tl }
+                \tl_set:ce { l_@@_info_date_ ##1 _tl }
                   { \exp_last_unbraced:ce { @@_date_aux_ ##1 :w } #1 \q_stop }
               }
 %</thesis>
 %<*!thesis>
-            \tl_set:Nx \@date
+            \tl_set:Ne \@date
               {
                 \exp_last_unbraced:ce
                   { @@_date_aux_ \g_@@_lang_tl :w } #1 \q_stop
@@ -4790,17 +4581,17 @@
 %</!thesis>
           }
           {
-            \regex_match:neT { \d+-\d+ } {#1}
+            \regex_match:nnT { \A \d+ \- \d+ \Z } {#1}
               {
 %<*thesis>
                 \clist_map_inline:Nn \g_@@_lang_clist
                   {
-                    \tl_set:cx { l_@@_info_date_ ##1 _tl }
+                    \tl_set:ce { l_@@_info_date_ ##1 _tl }
                       { \exp_last_unbraced:ce { @@_date_aux_short_ ##1 :w } #1 \q_stop }
                   }
 %</thesis>
 %<*!thesis>
-                \tl_set:Nx \@date
+                \tl_set:Ne \@date
                   {
                     \exp_last_unbraced:ce
                       { @@_date_aux_short_ \g_@@_lang_tl :w } #1 \q_stop
@@ -4809,7 +4600,7 @@
               }
           }
       } ,
-    date .initial:x =
+    date .initial:e =
       {
         \int_to_arabic:n { \c_sys_year_int  } -
         \int_to_arabic:n { \c_sys_month_int } -
@@ -4816,122 +4607,201 @@
         \int_to_arabic:n { \c_sys_day_int   }
       }
   }
-%<thesis>\tl_set:Nv \today { l_@@_info_date_ \g_@@_lang_tl _tl }
-%<!thesis>\tl_set:NV \today \@date
+%<thesis>\tl_set_eq:Nc \today { l_@@_info_date_ \g_@@_lang_tl _tl }
+%<!thesis>\tl_set_eq:NN \today \@date
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{标题页}
+% \subsection{特殊页面}
 %
-% \subsubsection{定义内部函数}
+% \subsubsection{页面模板}
 %
-% 汉字分散对齐的环境。
+% 使用 \pkg{lttemplates} 构建页面模板,用于绘制标题页与版权页。
+%
+% 页面元素模板。
 %    \begin{macrocode}
 %<*thesis>
-\@@_engine_case:nnn
+\NewTemplateType { sjtu / element } { 0 }
+\DeclareTemplateInterface { sjtu / element } { plain } { 0 }
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
-      {
-        \mode_leave_vertical:
-        \bool_set_false:N \l_@@_tmp_bool
-        \cs_set_eq:NN \SJTU at CJK@FTS at Symbol \CJKsymbol
-        \cs_set:Npn \CJKsymbol ##1
-          {
-            \bool_if:NTF \l_@@_tmp_bool
-              { \hfil \SJTU at CJK@FTS at Symbol { ##1 } }
-              {
-                \SJTU at CJK@FTS at Symbol { ##1 }
-                \bool_set_true:N \l_@@_tmp_bool
-              }
-          }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
-      }
-      { \egroup }
+    format      : tokenlist = \c_empty_tl ,
+    content     : tokenlist = \c_empty_tl ,
+    bottom-skip : skip      = \c_zero_skip ,
+    align       : choice { left, right, center, normal } = center
   }
+\DeclareTemplateCode { sjtu / element } { plain } { 0 }
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
+    format      = \l_@@_element_format_tl ,
+    content     = \l_@@_element_content_tl ,
+    bottom-skip = \l_@@_element_bottom_skip ,
+    align       =
       {
-        \mode_leave_vertical:
-        \cs_set:Npn \CJKglue
-          { \skip_horizontal:n { \c_zero_dim plus 1 filll } }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
+        left    =
+          \cs_set_eq:NN \l_@@_element_align: \raggedright ,
+        right   =
+          \cs_set_eq:NN \l_@@_element_align: \raggedleft ,
+        center  =
+          \cs_set_eq:NN \l_@@_element_align: \centering ,
+        normal  =
+          \cs_set_eq:NN \l_@@_element_align: \prg_do_nothing:
       }
-      { \egroup }
   }
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
-      {
-        \mode_leave_vertical:
-        \ltjsetparameter { kanjiskip = { \c_zero_dim plus 1 filll } }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
-      }
-      { \egroup }
+    \AssignTemplateKeys
+    \group_begin:
+      \l_@@_element_align:
+      \l_@@_element_format_tl
+      \l_@@_element_content_tl
+      \par
+    \group_end:
+    \skip_vertical:N \l_@@_element_bottom_skip
+    \skip_vertical:N \c_zero_skip
   }
 %    \end{macrocode}
 %
-% 汉字分散对齐的表格列说明符。
+% 页面模板。
 %    \begin{macrocode}
-\newcolumntype { \SJTU at CT@D } [ 1 ]
-  { > { \begin { SJTU at CJK@FTS } {#1} } c < { \end { SJTU at CJK@FTS } } }
+\NewTemplateType { sjtu / page } { 1 }
+\DeclareTemplateInterface { sjtu / page } { title } { 1 }
+  {
+    bookmark : tokenlist ,
+    style    : tokenlist = empty ,
+    format   : tokenlist = \linespread { } \selectfont ,
+    prefix   : tokenlist ,
+    elements : commalist
+  }
+\DeclareTemplateCode { sjtu / page } { title } { 1 }
+  {
+    bookmark = \l_@@_page_bookmark_tl ,
+    style    = \l_@@_page_style_tl ,
+    format   = \l_@@_page_format_tl ,
+    prefix   = \l_@@_page_prefix_tl ,
+    elements = \l_@@_page_elements_clist
+  }
+  {
+    \tl_set_eq:NN \l_@@_page_bookmark_tl \c_novalue_tl
+    \AssignTemplateKeys
+    \group_begin:
+      \@@_select_language:n {#1}
+      \clist_gset_eq:Nc \l_@@_info_fund_clist
+        { l_@@_info_fund_ \l_@@_lang_tl _clist }
+      \legacy_if:nTF { @openright }
+        { \cleardoublepage } { \clearpage }
+      \exp_args:No \tl_if_novalue:nF { \l_@@_page_bookmark_tl }
+        { \@@_pdf_bookmark:nn { 0 } { \l_@@_page_bookmark_tl } }
+      \exp_args:No \thispagestyle { \l_@@_page_style_tl }
+      \l_@@_page_format_tl
+      \clist_map_inline:Nn \l_@@_page_elements_clist
+        { \UseInstance { sjtu / element } { \l_@@_page_prefix_tl / ##1 } }
+    \group_end:
+    \clearpage
+  }
 %    \end{macrocode}
 %
+% 声明模板实例的辅助函数。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_element_instance:nnn #1#2#3
+  { \DeclareInstance { sjtu / element } {#1/#2} { plain } {#3} }
+\cs_new_protected:Npn \@@_declare_page_instance:nnn #1#2
+  { \DeclareInstance { sjtu / page } {#1} { title } {#2} }
+%    \end{macrocode}
+%
+% \subsubsection{标题页}
+%
+% \changes{v2.0}{2022/12/13}{启用新版封面。}
+% \changes{v2.0.2}{2023/04/01}{标题页日期底部增加空白。}
 % \changes{v2.1}{2023/11/30}{标题页信息栏改用表格实现。}
 % \changes{v2.1.4}{2024/08/14}{标题页信息栏允许手动换行。}
-% \begin{macro}[int]{\@@_title_page_info_i:nnn,\@@_title_page_info_i:nxx,
-% \@@_title_page_info_ii:n}
+% \changes{v2.1.5}{2024/11/06}{修复了 \pkg{array} 更新造成的标题页生成失败的问题。}
+%
+% \begin{variable}{\SJTU at CT@W at width}
+%    \begin{macrocode}
+\tl_set:Nn \SJTU at CT@W at width { 5 em }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[int]{\SJTU at CT@W,\SJTU at CT@R,\SJTU at CT@L}
+%    \begin{macrocode}
+\newcolumntype { \SJTU at CT@W } [ 1 ]
+  {
+    w {#1} { \SJTU at CT@W at width }
+    @{ \tl_use:c { c_@@_name_info_sep_ \l_@@_lang_tl _tl } }
+  }
+\newcolumntype { \SJTU at CT@R }
+  { r @{ \tl_use:c { c_@@_name_info_sep_ \l_@@_lang_tl _tl } } }
+\newcolumntype { \SJTU at CT@L }
+  { >{ \linespread { 0.75 } \normalfont } l }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_info_table_row:nn,\@@_info_table_row:vv,
+% \@@_title_page_info_table:n}
 % 信息输出。
 %    \begin{macrocode}
-\cs_new:Npn \@@_title_page_info_i:nnn #1#2#3
+\cs_new:Npn \@@_info_table_row:nn #1#2
   {
-    \clist_clear:N \l_@@_tmp_clist
-    \clist_map_inline:nn {#3}
+    \exp_not:n {#1}
+    &
+    \exp_not:N \hbox:n
       {
-        \clist_put_right:Nx \l_@@_tmp_clist
-          {
-            \exp_not:o { \cs:w c_@@_name_ ##1 _ #1 _tl \cs_end: }
-            &
-            \exp_not:N \hbox:n
-              {
-                \exp_not:N \tabular [ t ] { @{} l @{} }
-                  \exp_not:o { \cs:w l_@@_info_ ##1 _ #1 _tl \cs_end: }
-                \exp_not:N \endtabular
-              }
-          }
+        \exp_not:N \tabular [ t ] { @{} l @{} }
+          \exp_not:n {#2}
+        \exp_not:N \endtabular
       }
+  }
+\cs_generate_variant:Nn \@@_info_table_row:nn { vv }
+\cs_new_protected:Npn \@@_title_page_info_table:n #1
+  {
     \group_begin:
+      \clist_clear:N \l_@@_tmp_clist
+      \seq_map_inline:cn { l_@@_info_show_ \l_@@_lang_tl _seq }
+        {
+          \bool_lazy_all:nT
+            {
+              { \tl_if_exist_p:c { l_@@_name_ ##1 _ \l_@@_lang_tl _tl } }
+              { \tl_if_exist_p:c { l_@@_info_ ##1 _ \l_@@_lang_tl _tl } }
+            }
+            {
+              \clist_put_right:Ne \l_@@_tmp_clist
+                {
+                  \@@_info_table_row:vv
+                    { l_@@_name_ ##1 _ \l_@@_lang_tl _tl }
+                    { l_@@_info_ ##1 _ \l_@@_lang_tl _tl }
+                }
+            }
+        }
       \tl_set:Nn \arraystretch { 1 }
-      \tabular {#2}
+      \int_set_eq:NN \hbadness \c_max_int
+      \tabular {#1}
         \clist_use:Nn \l_@@_tmp_clist { \\ }
       \endtabular
     \group_end:
   }
-\cs_new:Npn \@@_title_page_info_ii:n #1
+%    \end{macrocode}
+% \end{macro}
+%
+% 标题页页面样式,页脚添加资助基金信息。
+%    \begin{macrocode}
+\cs_new:Npn \ps at SJTU@fund
   {
-    \tl_use:c { l_@@_info_department_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { c_@@_name_univ_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { c_@@_name_address_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { l_@@_info_date_ #1 _tl }
+    \ps at empty
+    \tl_set:Nn \@oddfoot
+      {
+        \hfil
+        \minipage [ t ] { \textwidth }
+          \centering \zihao { - 5 }
+          \clist_use:Nn \l_@@_info_fund_clist { \par }
+        \endminipage
+        \hfil
+      }
+    \tl_set_eq:NN \@evenfoot \@oddfoot
   }
-\cs_generate_variant:Nn \@@_title_page_info_i:nnn { nxx }
-%</thesis>
-%</class>
 %    \end{macrocode}
-% \end{macro}
 %
-% \subsubsection{构建标题页}
+% 构建标题页。
 %
-% \changes{v2.0}{2022/12/13}{启用新版封面。}
-% \changes{v2.0.2}{2023/04/01}{标题页日期底部增加空白。}
+% 样式 A 标题页元素实例。
 %    \begin{macrocode}
-%<*lang>
-%<*thesis>
-%<*zh>
 \clist_map_inline:nn
   {
     { logo    }
@@ -4939,175 +4809,184 @@
         content     =
           {
             \includegraphics [ width = 3 cm ]
-              { sjtu-vi-badge-red.pdf }
+              { sjtu-vi-badge-reg-red.pdf }
           }
-      },
+      } ,
     { subject }
       {
         format      = \zihao { -2 } \setbaselineskip { 30 bp } ,
-        content     = \l_@@_info_subject_zh_tl ,
+        content     = \tl_use:c { l_@@_info_subject_ \l_@@_lang_tl _tl } ,
         bottom-skip = \c_zero_dim plus 1 fill
-      },
+      } ,
     { title   }
       {
         format      = \zihao { 2 } \setbaselineskip { 36 bp } \bfseries ,
-        content     = \l_@@_info_display_title_zh_tl ,
+        content     = \tl_use:c { l_@@_info_display_title_ \l_@@_lang_tl _tl } ,
         bottom-skip = 30 bp plus 1 fill
-      },
+      } ,
     { info    }
       {
         format      = \zihao { 4 } \setbaselineskip { 30 bp } \heiti ,
-        content     =
-          {
-            \@@_title_page_info_i:nxx { zh }
-              {
-                \exp_not:N \SJTU at CT@D { 5 em }
-                @ { \exp_not:V \c_@@_name_info_sep_zh_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              {
-                author,
-                id,
-                \l_@@_info_supervisors_clist ,
-                department,
-                major,
-                \int_compare:nNnF { \g_@@_thesis_type_int } = { 1 }
-                  { degree }
-              }
-          } ,
+        content     = \@@_title_page_info_table:n
+                        { \SJTU at CT@W { s } \SJTU at CT@L } ,
         bottom-skip = 30 bp
-      },
+      } ,
     { date    }
       {
         format      = \zihao { 4 } \setbaselineskip { 30 bp } \bfseries ,
-        content     = \l_@@_info_date_zh_tl ,
+        content     = \tl_use:c { l_@@_info_date_ \l_@@_lang_tl _tl } ,
       }
   }
+  { \@@_declare_element_instance:nnn { title a } #1 }
+%    \end{macrocode}
+%
+% 样式 A 标题页实例。
+%    \begin{macrocode}
+\@@_declare_page_instance:nnn { title a }
   {
-    \@@_declare_component:nnn { title / zh } #1
+    bookmark = \tl_use:c { c_@@_name_title_page_ \g_@@_lang_tl _tl } ,
+    style    = SJTU at fund ,
+    prefix   = title a ,
+    elements = { logo, subject, title, info, date }
   }
-\@@_declare_page:nn { title / zh }
-  {
-    bookmark      = true ,
-    bookmark-text = \c_@@_name_title_page_tl ,
-    style         = SJTU at fund@zh ,
-    format        = \linespread { } \@@_set_language_zh: ,
-    prefix        = title / zh ,
-    components    = { logo, subject, title, info, date }
-  }
-%</zh>
-%<*en|de|ja>
+%    \end{macrocode}
+%
+% 样式 B 标题页元素实例。
+%    \begin{macrocode}
 \clist_map_inline:nn
   {
     { subject }
       {
         format      = \zihao { 4 } \setbaselineskip { 24 bp } \bfseries ,
-%<en>        content     = \l_@@_info_subject_en_tl ,
-%<de>        content     = \l_@@_info_subject_de_tl ,
-%<ja>        content     = \l_@@_info_subject_ja_tl ,
+        content     = \tl_use:c { l_@@_info_subject_ \l_@@_lang_tl _tl } ,
         bottom-skip = \c_zero_dim plus 1 fill
-      },
+      } ,
     { title   }
       {
         format      = \zihao { -2 } \setbaselineskip { 30 bp } \bfseries ,
-%<en>        content     = \MakeUppercase \l_@@_info_display_title_en_tl ,
-%<de>        content     = \MakeUppercase \l_@@_info_display_title_de_tl ,
-%<ja>        content     = \l_@@_info_display_title_ja_tl ,
+        content     = \tl_use:c { l_@@_info_display_title_ \l_@@_lang_tl _tl } ,
         bottom-skip = \c_zero_dim plus 1 fill
-      },
+      } ,
     { info    }
       {
         format      = \zihao { 3 } \setbaselineskip { 30 bp } \bfseries ,
-        content     =
-          {
-%<en>            \@@_title_page_info_i:nxx { en }
-%<de>            \@@_title_page_info_i:nxx { de }
-%<ja>            \@@_title_page_info_i:nxx { ja }
-              {
-%<en>                r @ { \exp_not:V \c_@@_name_info_sep_en_tl }
-%<de>                r @ { \exp_not:V \c_@@_name_info_sep_de_tl }
-%<ja>                r @ { \exp_not:V \c_@@_name_info_sep_ja_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              { author, \l_@@_info_supervisors_clist }
-          } ,
+        content     = \@@_title_page_info_table:n
+                        { \SJTU at CT@R \SJTU at CT@L } ,
         bottom-skip = 30 bp plus 1 fill
-      },
+      } ,
     { date    }
       {
         format      = \zihao { 3 } \setbaselineskip { 30 bp } ,
         content     =
-%<en>          { \@@_title_page_info_ii:n { en } } ,
-%<de>          { \@@_title_page_info_ii:n { de } } ,
-%<ja>          { \@@_title_page_info_ii:n { ja } } ,
-      },
+          {
+            \tl_use:c { l_@@_info_department_ \l_@@_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { c_@@_name_univ_ \l_@@_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { c_@@_name_address_ \l_@@_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { l_@@_info_date_ \l_@@_lang_tl _tl }
+          }
+      }
   }
+  { \@@_declare_element_instance:nnn { title b } #1 }
+%    \end{macrocode}
+%
+% 样式 B 标题页实例。
+%    \begin{macrocode}
+\@@_declare_page_instance:nnn { title b }
   {
-%<en>    \@@_declare_component:nnn { title / en } #1
-%<de>    \@@_declare_component:nnn { title / de } #1
-%<ja>    \@@_declare_component:nnn { title / ja } #1
+    prefix   = title b ,
+    style    = SJTU at fund ,
+    elements = { subject, title, info, date }
   }
-%<*en>
-\@@_declare_page:nn { title / en }
-  {
-    style       = SJTU at fund@en ,
-    format      = \linespread { } \@@_set_language_en: ,
-    prefix      = title / en ,
-    components  = { subject, title, info, date }
-  }
-%</en>
-%<*de>
-\@@_declare_page:nn { title / de }
-  {
-    style       = SJTU at fund@de ,
-    format      = \linespread { } \@@_set_language_de: ,
-    prefix      = title / de ,
-    components  = { subject, title, info, date }
-  }
-%</de>
-%<*ja>
-\@@_declare_page:nn { title / ja }
-  {
-    style       = SJTU at fund@ja ,
-    format      = \linespread { } \@@_set_language_ja: ,
-    prefix      = title / ja ,
-    components  = { subject, title, info, date }
-  }
-%</ja>
-%</en|de|ja>
+%    \end{macrocode}
+%
+% 载入学位论文语言配置文件。
+%    \begin{macrocode}
+\clist_map_inline:Nn \g_@@_lang_clist
+  { \file_input:n { sjtu-thesis- #1 .def } }
 %</thesis>
-%</lang>
+%</class>
 %    \end{macrocode}
 %
+% 中文标题页使用样式 A,其他语种使用样式 B。
+%    \begin{macrocode}
+%<*thesis-i18n>
+\DeclareInstanceCopy { sjtu / page }
+%<zh>  { title / zh } { title a }
+%<en>  { title / en } { title b }
+%<de>  { title / de } { title b }
+%<ja>  { title / ja } { title b }
+%</thesis-i18n>
+%    \end{macrocode}
+%
 % \begin{macro}{\maketitle}
-% 生成标题页,输出前先确定需要显示的导师列表。
+% 生成标题页。
 %    \begin{macrocode}
 %<*class>
 %<*thesis>
 \RenewDocumentCommand \maketitle { }
   {
-    \clist_map_inline:nn
-      { assoc_supervisor, co_supervisor }
-      {
-        \tl_if_empty:cF { l_@@_info_ ##1 _zh_tl }
-          { \clist_put_right:Nn \l_@@_info_supervisors_clist {##1} }
-      }
     \clist_map_inline:Nn \g_@@_lang_clist
-      { \UseInstance { sjtu } { title / ##1 } }
+      { \UseInstance { sjtu / page } { title / ##1 } { ##1 } }
   }
-%</thesis>
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{原创性声明及使用授权书}
+% \subsubsection{原创性声明及使用授权书}
 %
+% 声明及授权书文本。
 %    \begin{macrocode}
-%<*thesis>
+\tl_const:Nn \c_@@_orig_decl_text_zh_tl
+  {
+    本人郑重声明:所呈交的学位论文,是本人在导师的指导下,独立进行研究工
+    作所取得的成果。除文中已经注明引用的内容外,本论文不包含任何其他个人
+    或集体已经发表或撰写过的作品成果。对本文的研究做出重要贡献的个人和集
+    体,均已在文中以明确方式标明。本人完全知晓本声明的法律后果由本人承
+    担。
+  }
+\tl_const:Nn \c_@@_auth_decl_text_zh_tl
+  {
+    本人同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许
+    论文被查阅和借阅。 \par
+    \vskip 6 bp
+    \noindent
+    本学位论文属于: \par
+    { \c_@@_symbol_white_square_tl } \, \textbf { 公开论文 } \par
+    { \c_@@_symbol_white_square_tl } \, \textbf { 内部论文 },
+      保密 \, { \c_@@_symbol_white_square_tl } \, 1 \, 年 \, /
+           \, { \c_@@_symbol_white_square_tl } \, 2 \, 年 \, /
+           \, { \c_@@_symbol_white_square_tl } \, 3 \, 年,
+      过保密期后适用本授权书。 \par
+    { \c_@@_symbol_white_square_tl } \, \textbf { 秘密论文 },
+      保密 \, \underline { \hspace { 2 em } } \, 年(不超过~ 10~ 年),
+      过保密期后适用本授权书。 \par
+    { \c_@@_symbol_white_square_tl } \, \textbf { 机密论文 },
+      保密 \, \underline { \hspace { 2 em } } \, 年(不超过~ 20~ 年),
+      过保密期后适用本授权书。 \par
+    \hspace { 6 em }(请在以上方框内选择打“ \ensuremath { \checkmark } ”)
+  }
+%    \end{macrocode}
+%
+% 签名框。
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_signature_text_zh_tl
+  {
+    签名: \\
+    日期: \hspace { \stretch { 3 } } 年
+           \hspace { \stretch { 2 } } 月
+           \hspace { \stretch { 2 } } 日
+  }
 \cs_new_protected:Npn \@@_signature:N #1
   {
     \parbox [ t ] { 12 em }
       { #1 \c_@@_signature_text_zh_tl }
   }
+%    \end{macrocode}
+%
+% 声明及授权书元素实例。
+%    \begin{macrocode}
 \clist_map_inline:nn
   {
     { orig / title }
@@ -5176,56 +5055,165 @@
       }
   }
   {
-    \@@_declare_component:nnn { copyright } #1
+    \@@_declare_element_instance:nnn { copyright } #1
   }
-\@@_declare_page:nn { copyright }
+%    \end{macrocode}
+%
+% 声明及授权书模板实例。
+%    \begin{macrocode}
+\@@_declare_page_instance:nnn { copyright }
   {
-    bookmark      = true ,
-    bookmark-text = \c_@@_name_declaration_tl ,
-    format        = \linespread { } \@@_set_language_zh: ,
-    prefix        = copyright ,
-    components    =
+    bookmark = \tl_use:c { c_@@_name_declaration_ \g_@@_lang_tl _tl } ,
+    prefix   = copyright ,
+    elements =
       {
         orig / title, orig / text, orig / sign,
         auth / title, auth / text, auth / sign
       }
   }
+%    \end{macrocode}
+%
+% \begin{variable}{\l_@@_copyright_page_file_tl}
+%    \begin{macrocode}
+\tl_new:N \l_@@_copyright_page_file_tl
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+\keys_define:nn { sjtu / private / copyright }
+  {
+    file .tl_set:N = \l_@@_copyright_page_file_tl ,
+    file .value_required:n = true ,
+    filename .meta:n = { file = #1 }
+  }
+%    \end{macrocode}
+%
+% \changes{v2.0}{2022/12/20}{不再自动载入 \pkg{pdfpages} 宏包。}
+%    \begin{macrocode}
 \msg_new:nnn { sjtutex } { require-pdfpages }
   {
-    Add~"\token_to_str:N \usepackage{pdfpages}"~ in~ your~ preamble \\
-    before~ inserting~ pages~ of~ external~ PDF.
+    Add~'\token_to_str:N \usepackage{pdfpages}'~in~your~preamble \\
+    before~inserting~pages~of~external~PDF.
   }
 %    \end{macrocode}
 %
-% \changes{v2.0}{2022/12/20}{不再自动载入 \pkg{pdfpages} 宏包。}
 % \begin{macro}{\copyrightpage}
+% 生成声明及授权书。
 %    \begin{macrocode}
 \NewDocumentCommand \copyrightpage { O{ } }
   {
     \bool_if:NF \g_@@_review_bool
       {
-        \tl_if_blank:nTF {#1}
-          { \UseInstance { sjtu } { copyright } }
+        \group_begin:
+          \keys_set_known:nnN { sjtu / private / copyright }
+            {#1} \l_@@_tmp_tl
+          \tl_if_empty:NTF \l_@@_copyright_page_file_tl
+            { \UseInstance { sjtu / page } { copyright } { zh } }
+            {
+              \cs_if_exist:NTF \includepdf
+                {
+                  \legacy_if:nTF { @openright }
+                    { \cleardoublepage } { \clearpage }
+                  \@@_pdf_bookmark:nn { 0 } { \c_@@_name_declaration_tl }
+                  \tl_set_rescan:NnV \l_@@_tmp_tl { } \l_@@_tmp_tl
+                  \exp_args:NNo \includepdf [ \l_@@_tmp_tl ]
+                    { \l_@@_copyright_page_file_tl }
+                }
+                {
+                  \msg_warning:nn { sjtutex } { require-pdfpages }
+                  \UseInstance { sjtu / page } { copyright } { zh }
+                }
+            }
+        \group_end:
+      }
+  }
+%</thesis>
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{文档组成}
+%
+% \changes{v2.2}{2024/12/20}{内置文档命令与环境修改为使用键值对参数,废弃对应的带星号版本。}
+%
+% \subsubsection{统一接口}
+%
+% 定义文档组成部分的统一键值对接口。
+%
+% \begin{variable}{\l_@@_heading_numbering_bool,\l_@@_heading_in_toc_bool,
+% \l_@@_heading_title_tl,\l_@@_heading_marking_tl}
+%    \begin{macrocode}
+\bool_new:N \l_@@_heading_numbering_bool
+\bool_new:N \l_@@_heading_in_toc_bool
+\tl_new:N \l_@@_heading_title_tl
+\tl_new:N \l_@@_heading_marking_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% 默认 \tn{mainmatter} 之后的章节标题加入目录。
+%    \begin{macrocode}
+%<*thesis>
+\AddToHook { cmd / mainmatter / after }
+  { \bool_set_true:N \l_@@_heading_in_toc_bool }
+%</thesis>
+%    \end{macrocode}
+%
+% \begin{macro}{intoc,notintoc,title,marking}
+%    \begin{macrocode}
+\keys_define:nn { sjtu / private }
+  {
+    intoc    .value_forbidden:n = true,
+    intoc    .groups:n = { heading } ,
+    intoc    .code:n = { \bool_set_true:N  \l_@@_heading_in_toc_bool } ,
+    notintoc .value_forbidden:n = true,
+    notintoc .groups:n = { heading } ,
+    notintoc .code:n = { \bool_set_false:N \l_@@_heading_in_toc_bool } ,
+    title    .tl_set:N = \l_@@_heading_title_tl ,
+    title    .groups:n = { heading } ,
+    marking  .tl_set:N = \l_@@_heading_marking_tl ,
+    marking  .groups:n = { heading }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\SJTU at heading,\@@_heading:nn,\@@_heading:VV,
+% \@@_make_heading:n}
+% 定义一个灵活的章节标题命令专门处理不同的需求。
+%    \begin{macrocode}
+\NewDocumentCommand \SJTU at heading { O{#2} m }
+  {
+    \bool_if:nTF
+      { \l_@@_heading_numbering_bool && \l_@@_heading_in_toc_bool }
+%<!article>      { \chapter [#1] {#2} }
+%<article>      { \section [#1] {#2} }
+      {
+%<!article>        \CTEX at chapter@break
+        \bool_if:NTF \l_@@_heading_in_toc_bool
           {
-            \cs_if_exist:NTF \includepdf
-              {
-                \bool_if:NTF \g_@@_openright_bool
-                  { \cleardoublepage } { \clearpage }
-                \@@_pdf_bookmark:nn { 0 } { \c_@@_name_declaration_tl }
-                \includepdf {#1}
-              }
-              {
-                \msg_warning:nn { sjtutex } { require-pdfpages }
-                \UseInstance { sjtu } { copyright }
-              }
+            \@@_phantom_section:
+%<!article>            \addcontentsline { toc } { chapter } {#1}
+%<article>            \addcontentsline { toc } { section } {#1}
           }
+          { \@@_pdf_bookmark:nn { 0 } {#1} }
+%<!article>        \chapter* {#2}
+%<article>        \section* {#2}
+        \CTEX at gettitle {#1}
+        \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
       }
   }
-%</thesis>
+\cs_new_protected:Npn \@@_heading:nn #1#2
+  { \SJTU at heading [#1] {#2} }
+\cs_generate_variant:Nn \@@_heading:nn { VV }
+\cs_new_protected:Npn \@@_make_heading:n #1
+  {
+    \tl_set_eq:NN \l_@@_heading_marking_tl \c_novalue_tl
+    \keys_set_groups:nnn { sjtu / private } { heading } {#1}
+    \@@_heading:VV
+      \l_@@_heading_marking_tl \l_@@_heading_title_tl
+  }
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{摘要}
+% \subsubsection{摘要}
 %
 % \changes{v2.1}{2023/11/30}{新增 \opt{style/keywords-format} 选项。}
 % \begin{macro}{style/keywords-format}
@@ -5246,54 +5234,31 @@
 % \changes{v2.0}{2023/03/17}{\env{abstract} 环境新增指定语言的可选参数。}
 % \changes{v2.1}{2023/11/29}{\env{abstract} 环境添加目录条目,
 % \env{abstract*} 环境对应修改为不添加目录条目。}
-% \begin{macro}{abstract,abstract*}
+% \begin{macro}{abstract}
 % 学位论文摘要环境。
 %    \begin{macrocode}
 %<*thesis>
-\DeclareDocumentEnvironment { abstract  } { O{ zh } +b }
+\DeclareDocumentEnvironment { abstract } { O{ } }
   {
-    \@@_if_lang_valid:nTF {#1}
-      {
-        \use:c { @@_set_language_ #1 : }
-        \exp_args:Nv \SJTU at head { c_@@_name_abstract_ #1 _tl }
-        #2
-        \clist_if_empty:cF { l_@@_info_keywords_ #1 _clist }
-          {
-            \par \mode_leave_vertical: \par
-            \@@_keywords_format:n
-              {
-                \tl_use:c { c_@@_name_keywords_ #1 _tl }
-                \tl_use:c { c_@@_name_info_sep_ #1 _tl }
-              }
-            \clist_use:cv { l_@@_info_keywords_ #1 _clist }
-              { c_@@_name_item_sep_ #1 _tl }
-            \par
-          }
-      }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
-  } { }
-\DeclareDocumentEnvironment { abstract* } { O{ zh } +b }
+    \@@_select_language:n {#1}
+    \tl_set_eq:Nc \l_@@_heading_title_tl
+      { c_@@_name_abstract_ \l_@@_lang_tl _tl }
+    \@@_make_heading:n {#1}
+  }
   {
-    \@@_if_lang_valid:nTF {#1}
+    \clist_if_empty:cF { l_@@_info_keywords_ \l_@@_lang_tl _clist }
       {
-        \use:c { @@_set_language_ #1 : }
-        \exp_args:NNv \SJTU at head* { c_@@_name_abstract_ #1 _tl }
-        #2
-        \clist_if_empty:cF { l_@@_info_keywords_ #1 _clist }
+        \par \mode_leave_vertical: \par
+        \@@_keywords_format:n
           {
-            \par \mode_leave_vertical: \par
-            \@@_keywords_format:n
-              {
-                \tl_use:c { c_@@_name_keywords_ #1 _tl }
-                \tl_use:c { c_@@_name_info_sep_ #1 _tl }
-              }
-            \clist_use:cv { l_@@_info_keywords_ #1 _clist }
-              { c_@@_name_item_sep_ #1 _tl }
-            \par
+            \tl_use:c { c_@@_name_keywords_ \l_@@_lang_tl _tl }
+            \tl_use:c { c_@@_name_info_sep_ \l_@@_lang_tl _tl }
           }
+        \clist_use:cv { l_@@_info_keywords_ \l_@@_lang_tl _clist }
+          { c_@@_name_item_sep_ \l_@@_lang_tl _tl }
+        \par
       }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
-  } { }
+  }
 %</thesis>
 %    \end{macrocode}
 %
@@ -5300,13 +5265,13 @@
 % 修复通用模板摘要段首缩进。
 %    \begin{macrocode}
 %<*!thesis>
-\bool_if:NT \g_@@_titlepage_bool
-  { \@@_appto_cmd:Nn \abstract { \par } }
+\legacy_if:nT { @titlepage }
+  { \AddToHook { cmd / abstract / after } { \par } }
 %    \end{macrocode}
 %
 % 通用模板摘要后添加关键词。
 %    \begin{macrocode}
-\@@_preto_cmd:Nn \endabstract
+\AddToHook { env / abstract / end }
   {
     \clist_if_empty:NF \l_@@_info_keywords_clist
       {
@@ -5313,10 +5278,11 @@
         \par \mode_leave_vertical: \par
         \@@_keywords_format:n
           {
-            \c_@@_name_keywords_tl
-            \c_@@_name_info_sep_tl
+            \tl_use:c { c_@@_name_keywords_ \g_@@_lang_tl _tl }
+            \tl_use:c { c_@@_name_info_sep_ \g_@@_lang_tl _tl }
           }
-        \clist_use:NV \l_@@_info_keywords_clist \c_@@_name_item_sep_tl
+        \clist_use:Nv \l_@@_info_keywords_clist
+          { c_@@_name_item_sep_ \g_@@_lang_tl _tl }
         \par
       }
   }
@@ -5324,19 +5290,19 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{目录}
+% \subsubsection{目录列表}
 %
 % \changes{v2.1}{2023/11/29}{\tn{tableofcontents} 添加目录条目,
 % \tn{tableofcontents*} 对应修改为不添加目录条目。}
-% \begin{macro}{\tableofcontents,\tableofcontents*}
+% \begin{macro}{\tableofcontents}
 % 目录。
 %    \begin{macrocode}
-\DeclareDocumentCommand \tableofcontents { s }
+\DeclareDocumentCommand \tableofcontents { O{ } }
   {
-    \IfBooleanTF {#1}
-      { \SJTU at head* { \contentsname } }
-      { \SJTU at head  { \contentsname } }
-    \@starttoc { toc }
+    \group_begin:
+      \@@_make_heading:n { title = \contentsname, #1 }
+      \@starttoc { toc }
+    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
@@ -5366,15 +5332,15 @@
 % \changes{v2.0.1}{2023/03/31}{插图、表格和算法等索引不缩进。}
 % \changes{v2.0.1}{2023/03/31}{调整插图、表格和算法等索引编号宽度。}
 % \begin{macro}[int]{\SJTU at listof,\@@_new_list_of:Nnnn}
-% \begin{macro}{\listoffigures,\listoffigures*,\listoftables,\listoftables*}
+% \begin{macro}{\listoffigures,\listoftables}
 % 图表索引。
 %    \begin{macrocode}
-\NewDocumentCommand \SJTU at listof { m m s }
+\NewDocumentCommand \SJTU at listof { m m O{ } }
   {
-    \IfBooleanTF {#3}
-      { \SJTU at head* {#1} }
-      { \SJTU at head  {#1} }
-    \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_begin:
+      \@@_make_heading:n { title = #1, #3 }
+      \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_end:
   }
 \cs_new_protected:Npn \@@_new_list_of:Nnnn #1#2#3#4
   {
@@ -5394,38 +5360,30 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{预定义环境}
+% \subsubsection{预定义环境}
 %
-% \begin{macro}{abbreviation,abbreviation*}
+% \begin{macro}{abbreviation}
 % 缩略语对照表。
 %    \begin{macrocode}
 %<*thesis>
-\NewDocumentEnvironment { abbreviation  } { O{ \SJTU at abbrname } }
+\NewDocumentEnvironment { abbreviation } { O{ } }
   {
-    \chapter    {#1}
+    \bool_set_true:N \l_@@_heading_numbering_bool
+    \@@_make_heading:n { title = \SJTU at abbrname, #1 }
     \tl_clear:N \SJTU at style@float at font
   } { }
-\NewDocumentEnvironment { abbreviation* } { O{ \SJTU at abbrname } }
-  {
-    \SJTU at head* {#1}
-    \tl_clear:N \SJTU at style@float at font
-  } { }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{nomenclature,nomenclature*}
+% \begin{macro}{nomenclature}
 % 符号对照表。
 %    \begin{macrocode}
-\NewDocumentEnvironment { nomenclature  } { O{ \SJTU at nomname } }
+\NewDocumentEnvironment { nomenclature } { O{ } }
   {
-    \chapter    {#1}
+    \bool_set_true:N \l_@@_heading_numbering_bool
+    \@@_make_heading:n { title = \SJTU at nomname, #1 }
     \tl_clear:N \SJTU at style@float at font
   } { }
-\NewDocumentEnvironment { nomenclature* } { O{ \SJTU at nomname } }
-  {
-    \SJTU at head* {#1}
-    \tl_clear:N \SJTU at style@float at font
-  } { }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -5434,11 +5392,12 @@
 % \begin{macro}{acknowledgements}
 % 致谢,盲审模式下隐藏致谢。
 %    \begin{macrocode}
-\NewDocumentEnvironment { acknowledgements } { O{ \SJTU at ackname } +b }
+\NewDocumentEnvironment { acknowledgements } { O{ } +b }
   {
     \bool_if:NF \g_@@_review_bool
       {
-        \SJTU at head {#1}
+        \@@_select_language:n {#1}
+        \@@_make_heading:n { title = \SJTU at ackname, #1 }
         #2
       }
   } { }
@@ -5445,21 +5404,33 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \changes{v2.2}{2024/12/08}{移除 \env{bibliolist} 环境的使用限制,
+% 默认重置计数,新增 \opt{resume} 选项。}
 % \begin{macro}{achievements,bibliolist,bibliolist*}
 % 发表论文与学术成果。
 %    \begin{macrocode}
 \newcounter { SJTU at bib }
-\NewDocumentEnvironment { @bibliolist } { m }
+\bool_new:N \l_@@_bibliolist_resume_bool
+\keys_define:nn { sjtu / private / bibliolist }
   {
+    resume .value_forbidden:n = true,
+    resume .code:n =
+      { \bool_set_true:N \l_@@_bibliolist_resume_bool }
+  }
+\msg_new:nnn { sjtutex } { empty-environment }
+  { Empty~'#1'~environment. }
+\NewDocumentEnvironment { @bibliolist } { m m }
+  {
+    \keys_set:nn { sjtu / private / bibliolist } {#1}
     \cs_if_exist_use:N \bibfont
     \list
       {
-        \tl_if_blank:nTF {#1}
+        \tl_if_blank:nTF {#2}
           { \hfill }
           { \@biblabel { \arabic{ SJTU at bib } } }
       }
       {
-        \tl_if_blank:nTF {#1}
+        \tl_if_blank:nTF {#2}
           {
             \skip_if_exist:NTF \bibhang
               { \dim_set_eq:NN \leftmargin \bibhang }
@@ -5467,7 +5438,7 @@
             \dim_set:Nn \itemindent { - \leftmargin }
           }
           {
-            \@@_dim_set_to_wd:Nn \labelwidth { \@biblabel {#1} }
+            \@@_dim_set_to_wd:Nn \labelwidth { \@biblabel {#2} }
             \dim_set_eq:NN \leftmargin \labelwidth
             \dim_add:Nn    \leftmargin { \labelsep }
           }
@@ -5485,9 +5456,11 @@
               }
           }
         \@nmbrlisttrue
-        \tl_set:Nn  \@listctr    { SJTU at bib }
-        \cs_set:Npn \p at SJTU@bib  { }
-        \cs_set:Npn \theSJTU at bib { \arabic { SJTU at bib } }
+        \tl_set:Nn \@listctr { SJTU at bib }
+        \tl_clear:N \p at SJTU@bib
+        \bool_if:NF \l_@@_bibliolist_resume_bool
+          { \setcounter { SJTU at bib } { 0 } }
+        \tl_set:Nn \theSJTU at bib { \arabic { SJTU at bib } }
       }
       \sloppy
       \int_set:Nn \clubpenalty  { 4000 }
@@ -5496,51 +5469,33 @@
       \char_set_sfcode:nn { `\. } { 1000 }
   }
   {
-    \cs_set:Npn \@noitemerr
+    \tl_set:Nn \@noitemerr
       { \msg_warning:nnn { sjtutex } { empty-environment } { bibliolist } }
     \endlist
   }
-\msg_new:nnn { sjtutex } { empty-environment }
-  { Empty~ `#1'~ environment. }
-\bool_new:N \l_@@_achievements_bool
-\NewDocumentEnvironment { achievements } { O{ \SJTU at achvname } }
+\NewDocumentEnvironment { achievements } { O{ } }
   {
-    \SJTU at head {#1}
-    \setcounter { SJTU at bib } { 0 }
-    \bool_set_true:N \l_@@_achievements_bool
+    \@@_select_language:n {#1}
+    \@@_make_heading:n { title = \SJTU at achvname, #1 }
   } { }
-\NewDocumentEnvironment { bibliolist  } { m +b }
+\NewDocumentEnvironment { bibliolist  } { O{ } m +b }
   {
-    \bool_if:NF \l_@@_achievements_bool
-      {
-        \msg_error:nnnn { sjtutex } { environment-validation }
-          { bibliolist  } { achievements }
-      }
     \bool_if:NF \g_@@_review_bool
       {
-        \cs_set:Npn \@noitemerr { }
-        \begin { @bibliolist } {#1}
-        #2
+        \begin { @bibliolist } {#1} {#2}
+          #3
         \end { @bibliolist }
       }
   } { }
-\NewDocumentEnvironment { bibliolist* } { m +b }
+\NewDocumentEnvironment { bibliolist* } { O{ } m +b }
   {
-    \bool_if:NF \l_@@_achievements_bool
-      {
-        \msg_error:nnnn { sjtutex } { environment-validation }
-          { bibliolist* } { achievements }
-      }
     \bool_if:NT \g_@@_review_bool
       {
-        \cs_set:Npn \@noitemerr { }
-        \begin { @bibliolist } {#1}
-        #2
+        \begin { @bibliolist } {#1} {#2}
+          #3
         \end { @bibliolist }
       }
   } { }
-\msg_new:nnn { sjtutex } { environment-validation }
-  { `#1'~ is~ only~ valid~ in~ `#2'~ environment. }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -5547,11 +5502,12 @@
 % \begin{macro}{resume}
 % 简历。
 %    \begin{macrocode}
-\NewDocumentEnvironment { resume } { O{ \SJTU at resumename } +b }
+\NewDocumentEnvironment { resume } { O{ } +b }
   {
     \bool_if:NF \g_@@_review_bool
       {
-        \SJTU at head {#1}
+        \@@_select_language:n {#1}
+        \@@_make_heading:n { title = \SJTU at resumename, #1 }
         #2
       }
   } { }
@@ -5562,32 +5518,30 @@
 % \begin{macro}{digest}
 % 大摘要。
 %    \begin{macrocode}
-\NewDocumentEnvironment { digest } { O{ en } +b }
+\NewHook { sjtutex / digest }
+\NewDocumentEnvironment { digest } { O{ } +b }
   {
-    \@@_if_lang_valid:nTF {#1}
+    \AtEndDocument
       {
-        \AtEndDocument
-          {
-            \use:c { @@_set_language_ #1 : }
-            \bool_if:NTF \g_@@_openright_bool
-              { \cleardoublepage } { \clearpage }
-            \pagenumbering { roman }
-            \cs_gset:Nn \@@_thepage: { \arabic { page } }
-            \cs_gset_eq:NN \addcontentsline \use_none:nnn
-            \clist_map_inline:Nn \l_@@_counter_without_chapter_clist
-              {
-                \counterwithout {##1} { chapter }
-                \setcounter     {##1} { 0 }
-              }
-            \@@_head_aux_s:nx { \SJTU at digestname }
-              {
-                \exp_not:N \MakeUppercase
-                  { \exp_not:v { l_@@_info_title_ #1 _tl } }
-              }
-            #2
-          }
+        \group_begin:
+          \@@_select_language:n { en, #1 }
+          \legacy_if:nTF { @openright }
+            { \cleardoublepage } { \clearpage }
+          \pagenumbering { roman }
+          \tl_gset:Nn \@@_the_page_tl { \arabic { page } }
+          \UseHook { sjtutex / digest }
+          \cs_gset_eq:NN \addcontentsline \use_none:nnn
+          \clist_map_inline:Nn \l_@@_counter_without_chapter_clist
+            {
+              \counterwithout {##1} { chapter }
+              \setcounter     {##1} { 0 }
+            }
+          \tl_set_eq:Nc \l_@@_heading_title_tl
+            { l_@@_info_display_title_ \l_@@_lang_tl _tl }
+          \@@_make_heading:n { marking = \SJTU at digestname, #1, notintoc }
+          #2
+        \group_end:
       }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
   } { }
 %</thesis>
 %    \end{macrocode}
@@ -5597,8 +5551,10 @@
 %
 % \begin{macro}{\sjtusetup}
 % 用户设置接口。
+% 盲审模式下不会设置敏感信息。
 %    \begin{macrocode}
-\NewDocumentCommand \sjtusetup { } { \keys_set:nn { sjtu } }
+%<!thesis>\NewDocumentCommand \sjtusetup { } { \keys_set:nn { sjtu } }
+%<thesis>\NewDocumentCommand \sjtusetup { } { \@@_setup:n }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -5691,7 +5647,7 @@
         pdfdisplaydoctitle = true
       }
     \int_new:N \g_@@_bookmark_int
-    \cs_gset_protected:Npn \@@_pdf_bookmark:nn #1#2
+    \cs_set_protected:Npn \@@_pdf_bookmark:nn #1#2
       {
         \phantomsection
         \int_gincr:N \g_@@_bookmark_int
@@ -5698,13 +5654,16 @@
         \pdfbookmark [#1] {#2}
           { sjtubookmark. \int_use:N \g_@@_bookmark_int }
       }
-    \cs_gset_eq:NN \@@_phantom_section: \phantomsection
+    \cs_set_eq:NN \@@_phantom_section: \phantomsection
+    \DeclareExpandableDocumentCommand
+      { \@@_pdfstring_newline:w } { s o m } {#3}
     \pdfstringdefDisableCommands
       {
-        \cs_set_eq:NN \\       \prg_do_nothing:
-        \cs_set_eq:NN \quad    \c_empty_tl
-        \cs_set_eq:NN \qquad   \c_empty_tl
+        \cs_set_eq:NN \\       \@@_pdfstring_newline:w
         \cs_set_eq:NN \hspace  \use_none:n
+        \cs_set_eq:NN \zihao   \use_none:n
+        \tl_set_eq:NN \quad    \c_empty_tl
+        \tl_set_eq:NN \qquad   \c_empty_tl
       }
     \ctex_after_end_preamble:n
       {
@@ -5727,6 +5686,26 @@
   }
 %    \end{macrocode}
 %
+% \changes{v2.2}{2024/12/30}{使用 \pkg{pageslts} 宏包获取总页码。}
+% \subsubsection{\pkg{pageslts} 宏包}
+%
+%    \begin{macrocode}
+\ctex_at_end_package:nn { pageslts }
+  {
+%<thesis>    \pagenumbering { Alph }
+%<!thesis>    \pagenumbering { arabic }
+    \tl_set:Nn \@@_the_last_page_tl
+      { \lastpageref { pagesLTS.\pagesLTS at pnc } }
+%<*thesis>
+    \AddToHook { sjtutex / digest }
+      {
+        \tl_gset:Nn \@@_the_last_page_tl
+          { \lastpageref { pagesLTS.roman.local } }
+      }
+%</thesis>
+  }
+%    \end{macrocode}
+%
 % \subsubsection{\pkg{threeparttable} 宏包}
 %
 %    \begin{macrocode}
@@ -5739,6 +5718,7 @@
 %    \begin{macrocode}
 \ctex_at_end_package:nn { longtable }
   { \AtBeginEnvironment { longtable } { \SJTU at style@float at font } }
+%</class>
 %    \end{macrocode}
 %
 % \changes{v2.1.1}{2024/03/21}{预定义的数学环境声明移至导言区末尾,
@@ -5746,8 +5726,81 @@
 % \subsubsection{\pkg{amsthm} 宏包和 \pkg{ntheorem} 宏包}
 %
 % 预定义的数学环境,不包括证明环境 \env{proof}。
+%    \begin{macrocode}
+%<*scheme>
+\clist_map_inline:nn
+  {
+%<*zh>
+    { assumption  } { 假设        } ,
+    { axiom       } { 公理        } ,
+    { conjecture  } { 猜想        } ,
+    { corollary   } { 推论        } ,
+    { definition  } { 定义        } ,
+    { example     } { 例          } ,
+    { exercise    } { 练习        } ,
+    { lemma       } { 引理        } ,
+    { problem     } { 问题        } ,
+    { proposition } { 命题        } ,
+    { remark      } { 注          } ,
+    { solution    } { 解          } ,
+    { theorem     } { 定理        }
+%</zh>
+%<*en>
+    { assumption  } { Assumption  } ,
+    { axiom       } { Axiom       } ,
+    { conjecture  } { Conjecture  } ,
+    { corollary   } { Corollary   } ,
+    { definition  } { Definition  } ,
+    { example     } { Example     } ,
+    { exercise    } { Exercise    } ,
+    { lemma       } { Lemma       } ,
+    { problem     } { Problem     } ,
+    { proposition } { Proposition } ,
+    { remark      } { Remark      } ,
+    { solution    } { Solution    } ,
+    { theorem     } { Theorem     }
+%</en>
+%<*de>
+    { assumption  } { Annahme     } ,
+    { axiom       } { Axiom       } ,
+    { conjecture  } { Hypothese   } ,
+    { corollary   } { Korollar    } ,
+    { definition  } { Definition  } ,
+    { example     } { Beispiel    } ,
+    { exercise    } { Übung       } ,
+    { lemma       } { Lemma       } ,
+    { problem     } { Problem     } ,
+    { proposition } { Proposition } ,
+    { remark      } { Anmerkung   } ,
+    { solution    } { Lösung      } ,
+    { theorem     } { Theorem     }
+%</de>
+%<*ja>
+    { assumption  } { 仮定        } ,
+    { axiom       } { 公理        } ,
+    { conjecture  } { 予想        } ,
+    { corollary   } { 系          } ,
+    { definition  } { 定義        } ,
+    { example     } { 例          } ,
+    { exercise    } { 練習        } ,
+    { lemma       } { 補題        } ,
+    { problem     } { 問題        } ,
+    { proposition } { 命題        } ,
+    { remark      } { 注意        } ,
+    { solution    } { 解法        } ,
+    { theorem     } { 定理        }
+%</ja>
+  }
+%<zh>  { \@@_name_const:nnn { zh } #1 }
+%<en>  { \@@_name_const:nnn { en } #1 }
+%<de>  { \@@_name_const:nnn { de } #1 }
+%<ja>  { \@@_name_const:nnn { ja } #1 }
+%</scheme>
+%    \end{macrocode}
+%
 % 定义前会检测环境是否已经存在,避免覆盖用户的定义。
 %    \begin{macrocode}
+%<*class>
 \cs_new_protected:Nn \@@_new_theorems:
   {
     \clist_map_inline:nn
@@ -5757,19 +5810,20 @@
       }
       {
         \cs_if_exist:cF {##1}
-%<*!article>
           {
-            \exp_args:Nnv  \newtheorem  {##1} { c_@@_name_ ##1 _tl }
-              [ chapter ]
+            \exp_args:Nnv  \newtheorem  {##1}
+%<!article>              { c_@@_name_ ##1 _ \g_@@_lang_tl _tl } [ chapter ]
+%<article>              { c_@@_name_ ##1 _ \g_@@_lang_tl _tl }
           }
-%</!article>
-%<article>          { \exp_args:Nnv  \newtheorem  {##1} { c_@@_name_ ##1 _tl } }
       }
     \clist_map_inline:nn
       { remark, solution }
       {
         \cs_if_exist:cF {##1}
-          { \exp_args:NNnv \newtheorem* {##1} { c_@@_name_ ##1 _tl } }
+          {
+            \exp_args:NNnv \newtheorem* {##1}
+              { c_@@_name_ ##1 _ \g_@@_lang_tl _tl }
+          }
       }
   }
 %    \end{macrocode}
@@ -5781,7 +5835,7 @@
   {
     \cs_if_exist:NT \openbox
       {
-        \cs_new_eq:NN \@@_save_openbox: \openbox
+        \cs_new_eq:NN \SJTU at orig@openbox \openbox
         \cs_undefine:N \openbox
       }
   }
@@ -5788,8 +5842,8 @@
 \ctex_at_end_package:nn { amsthm }
   {
     \@@_cs_provide_eq:NN \QED \openbox
-    \cs_if_exist:NT \@@_save_openbox:
-      { \cs_set_eq:NN \openbox \@@_save_openbox: }
+    \cs_if_exist:NT \SJTU at orig@openbox
+      { \cs_set_eq:NN \openbox \SJTU at orig@openbox }
     \tl_set:Nn \qedsymbol { \ensuremath { \QED } }
     \RenewDocumentEnvironment { proof } { O{ \proofname } }
       {
@@ -5807,34 +5861,33 @@
     \newtheoremstyle { sjtu }
       { } { } { \SJTU at style@thm at body@font } { }
       { \SJTU at style@thm at header@font } { } { \ccwd } { }
+    \@@_disable_package_load:n { ntheorem }
+    \ctex_at_end_preamble:n
+      {
+        \theoremstyle { sjtu }
+        \@@_new_theorems:
+      }
   }
 %    \end{macrocode}
 %
-% 如果用户加载了 \pkg{amsthm} 或 \pkg{ntheorem} 宏包,
-% 则在导言区末尾应用预设的样式定义定理环境。
+% \pkg{ntheorem} 宏包。
 %    \begin{macrocode}
-\ctex_at_end_preamble:n
+\ctex_at_end_package:nn { ntheorem }
   {
-    \@ifpackageloaded { amsthm }
+    \@@_disable_package_load:n { amsthm }
+    \ctex_at_end_preamble:n
       {
-        \theoremstyle { sjtu }
+        \@@_cs_provide_eq:NN \QED \c_empty_tl
+        \theoremheaderfont { \SJTU at style@thm at header@font }
+        \theorembodyfont   { \SJTU at style@thm at body@font   }
+        \theoremseparator  { \enskip }
+        \theoremsymbol { \ensuremath { \QED } }
+        \qedsymbol     { \ensuremath { \QED } }
+        \cs_if_exist:NF \proof
+          { \newtheorem* { proof } { \proofname } }
+        \theoremsymbol { }
         \@@_new_theorems:
       }
-      {
-        \@ifpackageloaded { ntheorem }
-          {
-            \@@_cs_provide_eq:NN \QED \c_empty_tl
-            \theoremheaderfont { \SJTU at style@thm at header@font }
-            \theorembodyfont   { \SJTU at style@thm at body@font   }
-            \theoremseparator  { \enskip }
-            \theoremsymbol { \ensuremath { \QED } }
-            \qedsymbol     { \ensuremath { \QED } }
-            \cs_if_exist:NF \proof
-              { \newtheorem* { proof } { \proofname } }
-            \theoremsymbol { }
-            \@@_new_theorems:
-          } { }
-      }
   }
 %    \end{macrocode}
 %
@@ -5855,13 +5908,16 @@
         \exp_args:NV \contentsuse \thmt at envname { loe }
       }
     \cs_set:Npn \thmtlo at chaptervspacehack { }
-    \RenewDocumentCommand \listoftheorems { s O{ } }
+    \RenewDocumentCommand \listoftheorems { O{ } }
       {
         \group_begin:
-          \setlisttheoremstyle {#2}
-          \IfBooleanTF {#1}
-            { \SJTU at head* { \listtheoremname } }
-            { \SJTU at head  { \listtheoremname } }
+          \tl_set_eq:NN \l_@@_heading_marking_tl \c_novalue_tl
+          \keys_set_groups:nnnN { sjtu / private } { heading }
+            { title = \listtheoremname, #1 } \l_@@_tmp_tl
+          \tl_set_rescan:NnV \l_@@_tmp_tl { } \l_@@_tmp_tl
+          \@@_heading:VV
+            \l_@@_heading_marking_tl \l_@@_heading_title_tl
+          \exp_args:No \setlisttheoremstyle { \l_@@_tmp_tl }
           \cs_set:Npn \contentsline ##1
             { \use:c { thmt at contentsline@ ##1 } {##1} }
           \clist_map_inline:Nn \thmt at allenvs
@@ -5904,10 +5960,10 @@
 % \pkg{algorithm2e} 宏包。
 %    \begin{macrocode}
 %<!article>\ctex_at_begin_package:nn { algorithm2e }
-%<!article>  { \cs_set_eq:NN \@@_save_chapter:w \@chapter }
+%<!article>  { \cs_set_eq:NN \SJTU at orig@at at chapter \@chapter }
 \ctex_at_end_package:nn { algorithm2e }
   {
-%<!article>    \cs_set_eq:NN \@chapter \@@_save_chapter:w
+%<!article>    \cs_set_eq:NN \@chapter \SJTU at orig@at at chapter
     \SetAlgorithmName { \SJTU at algorithmname     }
                       { \SJTU at algorithmname     }
                       { \SJTU at listalgorithmname }
@@ -5976,270 +6032,9 @@
           }
       }
   }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
 %</class>
 %    \end{macrocode}
 %
-% \subsection{名称配置}
-%    \begin{macrocode}
-%<*name>
-%<*zh|ja>
-\clist_map_inline:nn
-  {
-    { year  } { 年 } ,
-    { month } { 月 } ,
-    { day   } { 日 }
-  }
-%<zh>  { \@@_define_name:nnn { zh } #1 }
-%<ja>  { \@@_define_name:nnn { ja } #1 }
-%</zh|ja>
-%<*en>
-\clist_const:Nn \c_@@_name_month_en_clist
-  {
-    January, February, March, April, May, June,
-    July, August, September, October, November, December
-  }
-%</en>
-%<*de>
-\clist_const:Nn \c_@@_name_month_de_clist
-  {
-    Januar, Februar, März, April, Mai, Juni,
-    Juli, August, September, Oktober, November, Dezember
-  }
-%</de>
-%<*thesis>
-%<*zh>
-\@@_define_symbol:nn { white_square } { "25A1 }
-\@@_define_name_from_clist:nnnn { zh }
-  { degree_level } { \g_@@_thesis_type_int }
-  { 学士, 硕士, 博士 }
-%</zh>
-%<*en>
-\@@_define_name_from_clist:nnnn { en }
-  { degree_level } { \g_@@_thesis_type_int }
-  { Bachelor, Master, Doctor }
-%</en>
-%<*de>
-\@@_define_name_from_clist:nnnn { de }
-  { degree_level } { \g_@@_thesis_type_int }
-  { Bachelor, Master, Doktor }
-%</de>
-%<*ja>
-\@@_define_name_from_clist:nnnn { ja }
-  { degree_level } { \g_@@_thesis_type_int }
-  { 学士, 修士, 博士 }
-%</ja>
-%</thesis>
-%<*zh>
-\clist_map_inline:nn
-  {
-%<*thesis>
-    { univ             } { 上海交通大学           } ,
-    { author           } { 姓名                   } ,
-    { id               } { 学号                   } ,
-    { supervisor       } { 导师                   } ,
-    { assoc_supervisor } { 副导师                 } ,
-    { department       } { 院系                   } ,
-    { co_supervisor    } { 联合导师               } ,
-    { major            } { 学科 / 专业            } ,
-    { degree           } { 申请学位               } ,
-    { thesis           } { 学位论文               } ,
-    { title_page       } { 题名页                 } ,
-    { declaration      } { 原创性声明及使用授权书 } ,
-    { orig_decl        } { 原创性声明             } ,
-    { auth_decl        } { 使用授权书             } ,
-    { decl_author      } { 学位论文作者           } ,
-    { decl_supervisor  } { 指导教师               } ,
-    { abstract         } { 摘 \protect \quad 要   } ,
-%</thesis>
-    { keywords         } { 关键词                 } ,
-    { info_sep         } { : \null               } ,
-    { item_sep         } { ,                     }
-  }
-%<thesis>  { \@@_define_name:nnn { zh } #1 }
-%<!thesis>  { \@@_define_name:nn #1 }
-%</zh>
-%<*en>
-\clist_map_inline:nn
-  {
-%<*thesis>
-    { univ             } { Shanghai~ Jiao~ Tong~ University } ,
-    { address          } { Shanghai,~ P.R.~ China           } ,
-    { author           } { Author                           } ,
-    { supervisor       } { Supervisor                       } ,
-    { assoc_supervisor } { Assoc.\ Supervisor               } ,
-    { co_supervisor    } { Co-supervisor                    } ,
-    { title_page       } { Title~ Page                      } ,
-    { declaration      } { Statutory~ Declaration           } ,
-    { abstract         } { Abstract                         } ,
-%</thesis>
-    { keywords         } { Key~words                        } ,
-    { info_sep         } { :~                               } ,
-    { item_sep         } { ,~                               }
-  }
-%<thesis>  { \@@_define_name:nnn { en } #1 }
-%<!thesis>  { \@@_define_name:nn #1 }
-%</en>
-%<*de>
-\clist_map_inline:nn
-  {
-%<*thesis>
-    { univ             } { Shanghai~ Jiao~ Tong~ Universität } ,
-    { address          } { Shanghai,~ VR~ China              } ,
-    { author           } { Autor/in                          } ,
-    { supervisor       } { Betreuer/in                       } ,
-    { assoc_supervisor } { Zweitbetreuer/in                  } ,
-    { co_supervisor    } { Co-Betreuer/in                    } ,
-    { title_page       } { Titelblatt                        } ,
-    { declaration      } { Eidesstattliche~ Erklärung        } ,
-    { abstract         } { Abstrakt                          } ,
-%</thesis>
-    { keywords         } { Schlüsselwörter                   } ,
-    { info_sep         } { :~                                } ,
-    { item_sep         } { ,~                                }
-  }
-%<thesis>  { \@@_define_name:nnn { de } #1 }
-%<!thesis>  { \@@_define_name:nn #1 }
-%</de>
-%<*ja>
-\clist_map_inline:nn
-  {
-%<*thesis>
-    { univ             } { 上海交通大学         } ,
-    { address          } { 中国・上海           } ,
-    { author           } { 氏名                 } ,
-    { supervisor       } { 指導教員             } ,
-    { assoc_supervisor } { 副指導教員           } ,
-    { co_supervisor    } { 共同指導             } ,
-    { thesis           } { 学位請求論文         } ,
-    { title_page       } { 標題紙               } ,
-    { declaration      } { 誓約書・公表許諾書   } ,
-    { abstract         } { 要 \protect \quad 旨 } ,
-%</thesis>
-    { keywords         } { キーワード           } ,
-    { info_sep         } { : \null             } ,
-    { item_sep         } { \quad                }
-  }
-%<thesis>  { \@@_define_name:nnn { ja } #1 }
-%<!thesis>  { \@@_define_name:nn #1 }
-%</ja>
-%<*thesis>
-%<*zh>
-\tl_const:Nn \c_@@_orig_decl_text_zh_tl
-  {
-    本人郑重声明:所呈交的学位论文,是本人在导师的指导下,独立进行研究工
-    作所取得的成果。除文中已经注明引用的内容外,本论文不包含任何其他个人
-    或集体已经发表或撰写过的作品成果。对本文的研究做出重要贡献的个人和集
-    体,均已在文中以明确方式标明。本人完全知晓本声明的法律后果由本人承
-    担。
-  }
-\tl_const:Nn \c_@@_auth_decl_text_zh_tl
-  {
-    本人同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许
-    论文被查阅和借阅。 \par
-    \vskip 6 bp
-    \noindent
-    本学位论文属于: \par
-    { \c_@@_symbol_white_square_tl } \textbf { 公开论文 } \par
-    { \c_@@_symbol_white_square_tl } \textbf { 内部论文 },
-      保密 { \c_@@_symbol_white_square_tl }~ 1~ 年 /
-           { \c_@@_symbol_white_square_tl }~ 2~ 年 /
-           { \c_@@_symbol_white_square_tl }~ 3~ 年,
-      过保密期后适用本授权书。 \par
-    { \c_@@_symbol_white_square_tl } \textbf { 秘密论文 },
-      保密 \underline { \hspace { 2 em } } 年(不超过~ 10~ 年),
-      过保密期后适用本授权书。 \par
-    { \c_@@_symbol_white_square_tl } \textbf { 机密论文 },
-      保密 \underline { \hspace { 2 em } } 年(不超过~ 20~ 年),
-      过保密期后适用本授权书。 \par
-    \hspace { 6 em }(请在以上方框内选择打“ \ensuremath { \checkmark } ”)
-  }
-\tl_const:Nn \c_@@_signature_text_zh_tl
-  {
-    签名: \\
-    日期: \hspace { \stretch { 3 } } 年
-           \hspace { \stretch { 2 } } 月
-           \hspace { \stretch { 2 } } 日
-  }
-%</zh>
-%</thesis>
-%</name>
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%<*scheme>
-\clist_map_inline:nn
-  {
-%<*zh>
-    { assumption  } { 假设        } ,
-    { axiom       } { 公理        } ,
-    { conjecture  } { 猜想        } ,
-    { corollary   } { 推论        } ,
-    { definition  } { 定义        } ,
-    { example     } { 例          } ,
-    { exercise    } { 练习        } ,
-    { lemma       } { 引理        } ,
-    { problem     } { 问题        } ,
-    { proposition } { 命题        } ,
-    { remark      } { 注          } ,
-    { solution    } { 解          } ,
-    { theorem     } { 定理        }
-%</zh>
-%<*en>
-    { assumption  } { Assumption  } ,
-    { axiom       } { Axiom       } ,
-    { conjecture  } { Conjecture  } ,
-    { corollary   } { Corollary   } ,
-    { definition  } { Definition  } ,
-    { example     } { Example     } ,
-    { exercise    } { Exercise    } ,
-    { lemma       } { Lemma       } ,
-    { problem     } { Problem     } ,
-    { proposition } { Proposition } ,
-    { remark      } { Remark      } ,
-    { solution    } { Solution    } ,
-    { theorem     } { Theorem     }
-%</en>
-%<*de>
-    { assumption  } { Annahme     } ,
-    { axiom       } { Axiom       } ,
-    { conjecture  } { Hypothese   } ,
-    { corollary   } { Korollar    } ,
-    { definition  } { Definition  } ,
-    { example     } { Beispiel    } ,
-    { exercise    } { Übung       } ,
-    { lemma       } { Lemma       } ,
-    { problem     } { Problem     } ,
-    { proposition } { Proposition } ,
-    { remark      } { Anmerkung   } ,
-    { solution    } { Lösung      } ,
-    { theorem     } { Theorem     }
-%</de>
-%<*ja>
-    { assumption  } { 仮定        } ,
-    { axiom       } { 公理        } ,
-    { conjecture  } { 予想        } ,
-    { corollary   } { 系          } ,
-    { definition  } { 定義        } ,
-    { example     } { 例          } ,
-    { exercise    } { 練習        } ,
-    { lemma       } { 補題        } ,
-    { problem     } { 問題        } ,
-    { proposition } { 命題        } ,
-    { remark      } { 注意        } ,
-    { solution    } { 解法        } ,
-    { theorem     } { 定理        }
-%</ja>
-  }
-  { \@@_define_name:nn #1 }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%</scheme>
-%    \end{macrocode}
-%
 % \end{implementation}
 %
 % \Finale

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,65 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-adobe-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,adobe,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Adobe CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-adobe-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { adobe } }
-  {
-    \setCJKmainfont { KozMinPr6N }
-      [
-        UprightFont = *-Light ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKsansfont { KozGoPr6N  }
-      [
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { KozMinPr6N-Light }
-    \setCJKfamilyfont { jamin  } { KozMinPr6N }
-      [
-        UprightFont = *-Light ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { jagoth } { KozGoPr6N  }
-      [
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { zhsong } { AdobeSongStd-Light       }
-      [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
-    \setCJKfamilyfont { zhhei  } { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhfs   } { AdobeFangsongStd-Regular }
-    \setCJKfamilyfont { zhkai  } { AdobeKaitiStd-Regular    }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-adobe-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,53 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-adobe-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,adobe,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Adobe CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-adobe-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nnn
-  { \__sjtu_fontset_error:nn { cjk } { adobe } }
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { adobe }
-    \ctex_punct_set:n { adobe }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { AdobeSongStd-Light       }
-      [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
-    \setCJKsansfont { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { AdobeFangsongStd-Regular }
-    \setCJKfamilyfont { zhsong } { AdobeSongStd-Light       }
-      [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
-    \setCJKfamilyfont { zhhei  } { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhfs   } { AdobeFangsongStd-Regular }
-    \setCJKfamilyfont { zhkai  } { AdobeKaitiStd-Regular    }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-adobe-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-adobe.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,adobe,und')
+%% sjtutex.dtx  (with options: `font,cjk,adobe')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,59 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Adobe CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-adobe.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-adobe-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-adobe-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { KozMinPr6N }
+          [
+            UprightFont = *-Light ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKsansfont { KozGoPr6N  }
+          [
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { KozMinPr6N-Light }
+        \setCJKfamilyfont { jamin  } { KozMinPr6N }
+          [
+            UprightFont = *-Light ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKfamilyfont { jagoth } { KozGoPr6N  }
+          [
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { AdobeSongStd-Light       }
+          [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
+        \setCJKsansfont { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { AdobeFangsongStd-Regular }
+      }
+    \setCJKfamilyfont { zhsong } { AdobeSongStd-Light       }
+      [ AutoFakeBold = 3 , ItalicFont = AdobeKaitiStd-Regular ]
+    \setCJKfamilyfont { zhhei  } { AdobeHeitiStd-Regular    } [ AutoFakeBold = 3 ]
+    \setCJKfamilyfont { zhfs   } { AdobeFangsongStd-Regular }
+    \setCJKfamilyfont { zhkai  } { AdobeKaitiStd-Regular    }
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { adobe } }
+      { \ctex_file_input:n { ctex-fontset-adobe.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-adobe.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,91 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-fandol-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,fandol,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Fandol CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-fandol-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { fandol } }
-  {
-    \setCJKmainfont { HaranoAjiMincho }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKsansfont { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-    \setCJKfamilyfont { jamin  } { HaranoAjiMincho }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { jagoth } { HaranoAjiGothic }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Medium ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { zhsong } { FandolSong }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold ,
-        ItalicFont  = FandolKai-Regular
-      ]
-    \setCJKfamilyfont { zhhei  } { FandolHei  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { zhfs   } { FandolFang }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-    \setCJKfamilyfont { zhkai  } { FandolKai  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-fandol-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,85 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-fandol-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,fandol,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Fandol CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-fandol-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nnn
-  { \__sjtu_fontset_error:nn { cjk } { fandol } }
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { fandol }
-    \ctex_punct_set:n { fandol }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { FandolSong }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold ,
-        ItalicFont  = FandolKai-Regular
-      ]
-    \setCJKsansfont { FandolHei  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold
-      ]
-    \setCJKmonofont { FandolFang }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-    \setCJKfamilyfont { zhsong } { FandolSong }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular ,
-        BoldFont    = *-Bold ,
-        ItalicFont  = FandolKai-Regular
-      ]
-    \setCJKfamilyfont { zhhei  } { FandolHei  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular,
-        BoldFont    = *-Bold
-      ]
-    \setCJKfamilyfont { zhfs   } { FandolFang }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-    \setCJKfamilyfont { zhkai  } { FandolKai  }
-      [
-        Extension   = .otf ,
-        UprightFont = *-Regular
-      ]
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-fandol-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-fandol.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,fandol,und')
+%% sjtutex.dtx  (with options: `font,cjk,fandol')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,98 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Fandol CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-fandol.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-fandol-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-fandol-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKsansfont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular
+          ]
+        \setCJKfamilyfont { jamin  } { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKfamilyfont { jagoth } { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { FandolSong }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Bold ,
+            ItalicFont  = FandolKai-Regular
+          ]
+        \setCJKsansfont { FandolHei  }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { FandolFang }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular
+          ]
+      }
+    \setCJKfamilyfont { zhsong } { FandolSong }
+      [
+        Extension   = .otf ,
+        UprightFont = *-Regular ,
+        BoldFont    = *-Bold ,
+        ItalicFont  = FandolKai-Regular
+      ]
+    \setCJKfamilyfont { zhhei  } { FandolHei  }
+      [
+        Extension   = .otf ,
+        UprightFont = *-Regular,
+        BoldFont    = *-Bold
+      ]
+    \setCJKfamilyfont { zhfs   } { FandolFang }
+      [
+        Extension   = .otf ,
+        UprightFont = *-Regular
+      ]
+    \setCJKfamilyfont { zhkai  } { FandolKai  }
+      [
+        Extension   = .otf ,
+        UprightFont = *-Regular
+      ]
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { fandol } }
+      { \ctex_file_input:n { ctex-fontset-fandol.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-fandol.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,49 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-founder-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,founder,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Founder CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-founder-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { founder } }
-  {
-    \setCJKmainfont { ipam.ttf } [ AutoFakeBold = 3 ]
-    \setCJKsansfont { ipag.ttf } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { ipag.ttf }
-    \setCJKfamilyfont { jamin  } { ipam.ttf } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { jagoth } { ipag.ttf } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
-      [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
-    \setCJKfamilyfont { zhhei  } { FZHei-B01      } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
-    \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-founder-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,52 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-founder-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,founder,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Founder CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-founder-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { founder }
-    \ctex_punct_set:n { founder }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { FZShuSong-Z01  }
-      [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
-    \setCJKsansfont { FZHei-B01      } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { FZFangSong-Z02 }
-    \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
-      [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
-    \setCJKfamilyfont { zhhei  } { FZHei-B01      } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
-    \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-founder-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-founder.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,founder,und')
+%% sjtutex.dtx  (with options: `font,cjk,founder')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,43 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Founder CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-founder.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-founder-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-founder-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { ipam.ttf } [ AutoFakeBold = 3 ]
+        \setCJKsansfont { ipag.ttf } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { ipag.ttf }
+        \setCJKfamilyfont { jamin  } { ipam.ttf } [ AutoFakeBold = 3 ]
+        \setCJKfamilyfont { jagoth } { ipag.ttf } [ AutoFakeBold = 3 ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { FZShuSong-Z01  }
+          [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
+        \setCJKsansfont { FZHei-B01      } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { FZFangSong-Z02 }
+      }
+    \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
+      [ AutoFakeBold = 3 , ItalicFont = FZKai-Z03 ]
+    \setCJKfamilyfont { zhhei  } { FZHei-B01      } [ AutoFakeBold = 3 ]
+    \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
+    \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { founder } }
+      { \ctex_file_input:n { ctex-fontset-founder.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-founder.def'.

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-hanyi.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-hanyi.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-hanyi.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,87 @@
+%%
+%% This is file `sjtu-cjk-font-hanyi.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `font,cjk,hanyi')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {Hanyi CJK fonts definition (SJTUTeX)}
+\ProvidesExplFile{sjtu-cjk-font-hanyi.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular ,
+            BoldFont    = *-Medium
+          ]
+        \setCJKsansfont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \setCJKmonofont { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Regular
+          ]
+        \setCJKfamilyfont { jamin  } { HaranoAjiMincho }
+          [
+            Extension   = .otf ,
+            BoldFont    = *-Medium
+          ]
+        \setCJKfamilyfont { jagoth } { HaranoAjiGothic }
+          [
+            Extension   = .otf ,
+            UprightFont = *-Medium ,
+            BoldFont    = *-Bold
+          ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { HYShuSongEr~S }
+          [ BoldFont = HYZhongSong~S, ItalicFont = HYKaiTi~S ]
+        \setCJKsansfont { HYZhongHei~S  } [ BoldFont = HYDaHei~S ]
+        \setCJKmonofont { HYFangSong~S  }
+      }
+    \setCJKfamilyfont { zhsong } { HYShuSongEr~S }
+      [ BoldFont = HYZhongSong~S ]
+    \setCJKfamilyfont { zhhei  } { HYZhongHei~S  }
+      [ BoldFont = HYDaHei~S     ]
+    \setCJKfamilyfont { zhkai  } { HYKaiTi~S     }
+    \setCJKfamilyfont { zhfs   } { HYFangSong~S  }
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { hanyi } }
+      { \ctex_file_input:n { ctex-fontset-hanyi.def } }
+  }
+\endinput
+%%
+%% End of file `sjtu-cjk-font-hanyi.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-hanyi.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,78 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-mac-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,mac,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {macOS CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-mac-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { mac } }
-  {
-    \setCJKmainfont { HiraMinProN  }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKsansfont { HiraKakuProN }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKmonofont { HiraMinProN-W3 }
-    \setCJKfamilyfont { jamin  } { HiraMinProN  }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKfamilyfont { jagoth } { HiraKakuProN }
-      [
-        UprightFont    = *-W3 ,
-        BoldFont       = *-W6
-      ]
-    \setCJKfamilyfont { zhsong } { Songti~SC  }
-      [
-        UprightFont    = *~Light ,
-        BoldFont       = *~Bold ,
-        ItalicFont     = Kaiti~SC~Regular ,
-        BoldItalicFont = Kaiti~SC~Bold
-      ]
-    \setCJKfamilyfont { zhhei  } { Heiti~SC   }
-      [
-        UprightFont    = *~Medium ,
-        AutoFakeBold   = 3
-      ]
-    \setCJKfamilyfont { zhfs   } { STFangsong }
-    \setCJKfamilyfont { zhkai  } { Kaiti~SC   }
-      [
-        UprightFont    = *~Regular ,
-        BoldFont       = *~Bold
-      ]
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-mac-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,76 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-mac-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,mac,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {macOS CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-mac-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nnn
-  { \__sjtu_fontset_error:nn { cjk } { mac } }
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { mac }
-    \ctex_punct_set:n { mac }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_family:nn   { \CJKsfdefault } { zhpf   }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhpf   }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { Songti~SC  }
-      [
-        UprightFont    = *~Light ,
-        BoldFont       = *~Bold ,
-        ItalicFont     = Kaiti~SC~Regular ,
-        BoldItalicFont = Kaiti~SC~Bold
-      ]
-    \setCJKsansfont { Heiti~SC   }
-      [
-        UprightFont    = *~Medium ,
-        AutoFakeBold   = 3
-      ]
-    \setCJKmonofont { STFangsong }
-    \setCJKfamilyfont { zhsong } { Songti~SC  }
-      [
-        UprightFont    = *~Light ,
-        BoldFont       = *~Bold ,
-        ItalicFont     = Kaiti~SC~Regular ,
-        BoldItalicFont = Kaiti~SC~Bold
-      ]
-    \setCJKfamilyfont { zhhei  } { Heiti~SC   }
-      [
-        UprightFont    = *~Medium ,
-        AutoFakeBold   = 3
-      ]
-    \setCJKfamilyfont { zhfs   } { STFangsong }
-    \setCJKfamilyfont { zhkai  } { Kaiti~SC   }
-      [
-        UprightFont    = *~Regular ,
-        BoldFont       = *~Bold
-      ]
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-mac-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-mac.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,mac,und')
+%% sjtutex.dtx  (with options: `font,cjk,mac')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,81 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {macOS CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-mac.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-mac-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-mac-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { HiraMinProN  }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKsansfont { HiraKakuProN }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKmonofont { HiraMinProN-W3 }
+        \setCJKfamilyfont { jamin  } { HiraMinProN  }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \setCJKfamilyfont { jagoth } { HiraKakuProN }
+          [
+            UprightFont    = *-W3 ,
+            BoldFont       = *-W6
+          ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { Songti~SC  }
+          [
+            UprightFont    = *~Light ,
+            BoldFont       = *~Bold ,
+            ItalicFont     = Kaiti~SC~Regular ,
+            BoldItalicFont = Kaiti~SC~Bold
+          ]
+        \setCJKsansfont { Heiti~SC   }
+          [
+            UprightFont    = *~Medium ,
+            AutoFakeBold   = 3
+          ]
+        \setCJKmonofont { STFangsong }
+      }
+    \setCJKfamilyfont { zhsong } { Songti~SC  }
+      [
+        UprightFont    = *~Light ,
+        BoldFont       = *~Bold ,
+        ItalicFont     = Kaiti~SC~Regular ,
+        BoldItalicFont = Kaiti~SC~Bold
+      ]
+    \setCJKfamilyfont { zhhei  } { Heiti~SC   }
+      [
+        UprightFont    = *~Medium ,
+        AutoFakeBold   = 3
+      ]
+    \setCJKfamilyfont { zhfs   } { STFangsong }
+    \setCJKfamilyfont { zhkai  } { Kaiti~SC   }
+      [
+        UprightFont    = *~Regular ,
+        BoldFont       = *~Bold
+        ]
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { mac } }
+      { \ctex_file_input:n { ctex-fontset-mac.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-mac.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,75 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-ubuntu-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,ubuntu,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Ubuntu CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-ubuntu-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { ubuntu } }
-  {
-    \setCJKmainfont { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKsansfont { Noto~Sans~CJK~JP  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKmonofont { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { jamin  } { Noto~Serif~CJK~JP }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { jagoth } { Noto~Sans~CJK~JP  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { zhsong } { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold ,
-        ItalicFont  = AR~PL~KaitiM~GB
-      ]
-    \setCJKfamilyfont { zhhei  } { Noto~Sans~CJK~SC  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { zhkai  } { AR~PL~KaitiM~GB   }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-ubuntu-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,71 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-ubuntu-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,ubuntu,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Ubuntu CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-ubuntu-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nnn
-  { \__sjtu_fontset_error:nn { cjk } { ubuntu } }
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhsong } { ubuntu }
-    \ctex_punct_set:n { ubuntu }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold ,
-        ItalicFont  = AR~PL~KaitiM~GB
-      ]
-    \setCJKsansfont { Noto~Sans~CJK~SC  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKmonofont { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { zhsong } { Noto~Serif~CJK~SC }
-      [
-        UprightFont = *~Light ,
-        BoldFont    = *~Bold ,
-        ItalicFont  = AR~PL~KaitiM~GB
-      ]
-    \setCJKfamilyfont { zhhei  } { Noto~Sans~CJK~SC  }
-      [
-        UprightFont = *~Medium ,
-        BoldFont    = *~Bold
-      ]
-    \setCJKfamilyfont { zhkai  } { AR~PL~KaitiM~GB   }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-ubuntu-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-ubuntu.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,ubuntu,und')
+%% sjtutex.dtx  (with options: `font,cjk,ubuntu')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,81 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Ubuntu CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-ubuntu.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-ubuntu-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-ubuntu-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKsansfont { Noto~Sans~CJK~JP  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKmonofont { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKfamilyfont { jamin  } { Noto~Serif~CJK~JP }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKfamilyfont { jagoth } { Noto~Sans~CJK~JP  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { Noto~Serif~CJK~SC }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold ,
+            ItalicFont  = AR~PL~KaitiM~GB
+          ]
+        \setCJKsansfont { Noto~Sans~CJK~SC  }
+          [
+            UprightFont = *~Medium ,
+            BoldFont    = *~Bold
+          ]
+        \setCJKmonofont { Noto~Serif~CJK~SC }
+          [
+            UprightFont = *~Light ,
+            BoldFont    = *~Bold
+          ]
+      }
+    \setCJKfamilyfont { zhsong } { Noto~Serif~CJK~SC }
+      [
+        UprightFont = *~Light ,
+        BoldFont    = *~Bold ,
+        ItalicFont  = AR~PL~KaitiM~GB
+      ]
+    \setCJKfamilyfont { zhhei  } { Noto~Sans~CJK~SC  }
+      [
+        UprightFont = *~Medium ,
+        BoldFont    = *~Bold
+      ]
+    \setCJKfamilyfont { zhkai  } { AR~PL~KaitiM~GB   }
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { ubuntu } }
+      { \ctex_file_input:n { ctex-fontset-ubuntu.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-ubuntu.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,49 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-windows-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,windows,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Windows CJK fonts definition for Japanese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-windows-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { cjk } { windows } }
-  {
-    \setCJKmainfont { MS~Mincho } [ AutoFakeBold = 3 ]
-    \setCJKsansfont { MS~Gothic } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { MS~Mincho }
-    \setCJKfamilyfont { jamin  } { MS~Mincho } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { jagoth } { MS~Gothic } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhsong } { SimSun   }
-      [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
-    \setCJKfamilyfont { zhhei  } { SimHei   } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhkai  } { KaiTi    }
-    \setCJKfamilyfont { zhfs   } { FangSong }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
-\NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-windows-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,52 +0,0 @@
-%%
-%% This is file `sjtu-cjk-font-windows-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `font,cjk,windows,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Windows CJK fonts definition for Chinese (SJTUTeX)}
-\ProvidesExplFile{sjtu-cjk-font-windows-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  {
-    \ctex_load_zhmap:nnnn { zhsong } { zhhei } { zhfs } { windows }
-    \ctex_punct_set:n { windows }
-    \ctex_punct_map_family:nn   { \CJKrmdefault } { zhsong }
-    \ctex_punct_map_bfseries:nn { \CJKrmdefault } { zhhei  }
-    \ctex_punct_map_itshape:nn  { \CJKrmdefault } { zhkai  }
-  }
-  {
-    \setCJKmainfont { SimSun   }
-      [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
-    \setCJKsansfont { SimHei   } [ AutoFakeBold = 3 ]
-    \setCJKmonofont { FangSong }
-    \setCJKfamilyfont { zhsong } { SimSun   }
-      [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
-    \setCJKfamilyfont { zhhei  } { SimHei   } [ AutoFakeBold = 3 ]
-    \setCJKfamilyfont { zhkai  } { KaiTi    }
-    \setCJKfamilyfont { zhfs   } { FangSong }
-  }
-\NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
-\NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
-\NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
-\NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
-\endinput
-%%
-%% End of file `sjtu-cjk-font-windows-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-cjk-font-windows.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,cjk,windows,und')
+%% sjtutex.dtx  (with options: `font,cjk,windows')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,13 +21,43 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Windows CJK fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-cjk-font-windows.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\tl_if_eq:NNTF \g__sjtu_lang_tl \c__sjtu_lang_ja_tl
-  { \ctex_file_input:n { sjtu-cjk-font-windows-ja.def } }
-  { \ctex_file_input:n { sjtu-cjk-font-windows-zh.def } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
+  {
+    \__sjtu_if_main_lang_ja:TF
+      {
+        \setCJKmainfont { MS~Mincho } [ AutoFakeBold = 3 ]
+        \setCJKsansfont { MS~Gothic } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { MS~Mincho }
+        \setCJKfamilyfont { jamin  } { MS~Mincho } [ AutoFakeBold = 3 ]
+        \setCJKfamilyfont { jagoth } { MS~Gothic } [ AutoFakeBold = 3 ]
+        \NewDocumentCommand \mincho   { } { \CJKfamily { jamin   } }
+        \NewDocumentCommand \gothic   { } { \CJKfamily { jagoth  } }
+      }
+      {
+        \setCJKmainfont { SimSun   }
+          [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
+        \setCJKsansfont { SimHei   } [ AutoFakeBold = 3 ]
+        \setCJKmonofont { FangSong }
+      }
+    \setCJKfamilyfont { zhsong } { SimSun   }
+      [ AutoFakeBold = 3 , ItalicFont = KaiTi ]
+    \setCJKfamilyfont { zhhei  } { SimHei   } [ AutoFakeBold = 3 ]
+    \setCJKfamilyfont { zhkai  } { KaiTi    }
+    \setCJKfamilyfont { zhfs   } { FangSong }
+    \NewDocumentCommand \songti   { } { \CJKfamily { zhsong  } }
+    \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei   } }
+    \NewDocumentCommand \fangsong { } { \CJKfamily { zhfs    } }
+    \NewDocumentCommand \kaishu   { } { \CJKfamily { zhkai   } }
+  }
+  {
+    \__sjtu_if_main_lang_ja:TF
+      { \__sjtu_fontset_error:nn { cjk } { windows } }
+      { \ctex_file_input:n { ctex-fontset-windows.def } }
+  }
 \endinput
 %%
 %% End of file `sjtu-cjk-font-windows.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-cambria.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-cambria.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-cambria.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,cambria')
+%% sjtutex.dtx  (with options: `font,math,otf,cambria')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,11 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Cambria math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-cambria.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { math } { cambria } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \RequirePackage { unicode-math }
     \setmathfont { Cambria~Math }
@@ -33,6 +33,7 @@
     \setmathsf { Calibri }
     \setmathtt { Consolas } [ Scale = 0.95 ]
   }
+  { \__sjtu_fontset_error:nn { math } { cambria } }
 \endinput
 %%
 %% End of file `sjtu-math-font-cambria.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-libertinus.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-libertinus.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-libertinus.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `font,math,libertinus')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,17 +21,12 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Libertinus math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-libertinus.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \exp_args:No \PassOptionsToPackage
-      { \g__sjtu_math_font_options_clist } { libertinust1math }
-    \RequirePackage { libertinust1math }
-  }
-  {
     \RequirePackage { unicode-math }
     \bool_if:NTF \g__sjtu_upright_integral_bool
       { \setmathfont { LibertinusMath-Regular.otf } }
@@ -67,6 +63,11 @@
         BoldSlantedFeatures = { FakeSlant = 0.2 }
       ]
   }
+  {
+    \exp_args:No \PassOptionsToPackage
+      { \g__sjtu_math_font_options_clist } { libertinust1math }
+    \RequirePackage { libertinust1math }
+  }
 \endinput
 %%
 %% End of file `sjtu-math-font-libertinus.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-lm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-lm.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-lm.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,lm')
+%% sjtutex.dtx  (with options: `font,math,type1,lm')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,10 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Latin Modern math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-lm.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
 \RequirePackage { amssymb, upgreek }
 \SetSymbolFont { operators    } { normal } { OT1 } { lmr  } { m  } { n  }
 \SetSymbolFont { letters      } { normal } { OML } { lmm  } { m  } { it }
@@ -41,9 +42,9 @@
 \SetMathAlphabet { \mathsf } { bold   } { OT1 } { lmss } { bx } { n  }
 \SetMathAlphabet { \mathit } { bold   } { OT1 } { lmr  } { bx } { it }
 \SetMathAlphabet { \mathtt } { bold   } { OT1 } { lmtt } { m  } { n  }
+\__sjtu_set_slanted_greek:
 \bool_if:NT \g__sjtu_upright_integral_bool
   { \RequirePackage { cmupint } }
-\__sjtu_set_slanted_greek:
 \__sjtu_set_unimath_symbol:
 \endinput
 %%

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newcm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newcm.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newcm.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,newcm')
+%% sjtutex.dtx  (with options: `font,math,otf,newcm')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,11 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New Computer Modern math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-newcm.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { math } { newcm } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \RequirePackage { unicode-math }
     \bool_if:NTF \g__sjtu_upright_integral_bool
@@ -94,6 +94,7 @@
         BoldSlantedFeatures = { FakeSlant = 0.25 }
       ]
   }
+  { \__sjtu_fontset_error:nn { math } { newcm } }
 \endinput
 %%
 %% End of file `sjtu-math-font-newcm.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newpx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newpx.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newpx.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,newpx')
+%% sjtutex.dtx  (with options: `font,math,type1,newpx')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,10 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New PX math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-newpx.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
 \tl_set_eq:NN \l__sjtu_save_encodingdefault_tl \encodingdefault
 \tl_set_eq:NN \l__sjtu_save_rmdefault_tl \rmdefault
 \tl_set_eq:NN \l__sjtu_save_sfdefault_tl \sfdefault

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newtx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newtx.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-newtx.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,newtx')
+%% sjtutex.dtx  (with options: `font,math,type1,newtx')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,10 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New TX math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-newtx.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
 \tl_set_eq:NN \l__sjtu_save_encodingdefault_tl \encodingdefault
 \tl_set_eq:NN \l__sjtu_save_rmdefault_tl \rmdefault
 \tl_set_eq:NN \l__sjtu_save_sfdefault_tl \sfdefault

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-stixtwo.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-stixtwo.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-stixtwo.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `font,math,stixtwo')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,51 +21,12 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {STIX Two math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-stixtwo.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \DeclareSizeFunction { sub } { \sub at sfcnt \@font at info }
-    \PassOptionsToPackage { notext } { stix2 }
-    \RequirePackage { stix2 }
-    \clist_map_inline:nn
-      {
-        \upalpha      { "0B } ,
-        \upbeta       { "0C } ,
-        \upgamma      { "0D } ,
-        \updelta      { "0E } ,
-        \upepsilon    { "0F } ,
-        \upzeta       { "10 } ,
-        \upeta        { "11 } ,
-        \uptheta      { "12 } ,
-        \upiota       { "13 } ,
-        \upkappa      { "14 } ,
-        \uplambda     { "15 } ,
-        \upmu         { "16 } ,
-        \upnu         { "17 } ,
-        \upxi         { "18 } ,
-        \uppi         { "19 } ,
-        \uprho        { "1A } ,
-        \upsigma      { "1B } ,
-        \uptau        { "1C } ,
-        \upupsilon    { "1D } ,
-        \upphi        { "1E } ,
-        \upchi        { "1F } ,
-        \uppsi        { "20 } ,
-        \upomega      { "21 } ,
-        \upvarepsilon { "22 } ,
-        \upvartheta   { "23 } ,
-        \upvarpi      { "24 } ,
-        \upvarrho     { "25 } ,
-        \upvarsigma   { "26 } ,
-        \upvarphi     { "27 }
-      }
-      { \__sjtu_declare_math_symbol:nnNn { \stix at lcgc } { operators } #1 }
-    \__sjtu_set_slanted_greek:
-  }
-  {
     \RequirePackage { unicode-math }
     \bool_if:NTF \g__sjtu_upright_integral_bool
       {
@@ -94,7 +56,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmathtt
       { texgyrecursor }
@@ -107,6 +69,45 @@
         Ligatures      = CommonOff
       ]
   }
+  {
+    \DeclareSizeFunction { sub } { \sub at sfcnt \@font at info }
+    \PassOptionsToPackage { notext } { stix2 }
+    \RequirePackage { stix2 }
+    \clist_map_inline:nn
+      {
+        \upalpha      { "0B } ,
+        \upbeta       { "0C } ,
+        \upgamma      { "0D } ,
+        \updelta      { "0E } ,
+        \upepsilon    { "0F } ,
+        \upzeta       { "10 } ,
+        \upeta        { "11 } ,
+        \uptheta      { "12 } ,
+        \upiota       { "13 } ,
+        \upkappa      { "14 } ,
+        \uplambda     { "15 } ,
+        \upmu         { "16 } ,
+        \upnu         { "17 } ,
+        \upxi         { "18 } ,
+        \uppi         { "19 } ,
+        \uprho        { "1A } ,
+        \upsigma      { "1B } ,
+        \uptau        { "1C } ,
+        \upupsilon    { "1D } ,
+        \upphi        { "1E } ,
+        \upchi        { "1F } ,
+        \uppsi        { "20 } ,
+        \upomega      { "21 } ,
+        \upvarepsilon { "22 } ,
+        \upvartheta   { "23 } ,
+        \upvarpi      { "24 } ,
+        \upvarrho     { "25 } ,
+        \upvarsigma   { "26 } ,
+        \upvarphi     { "27 }
+      }
+      { \__sjtu_declare_math_symbol:nnNn { \stix at lcgc } { operators } #1 }
+    \__sjtu_set_slanted_greek:
+  }
 \endinput
 %%
 %% End of file `sjtu-math-font-stixtwo.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-times.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-times.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-times.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,times')
+%% sjtutex.dtx  (with options: `font,math,type1,times')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,10 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Times math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-times.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
 \PassOptionsToPackage { Symbol } { upgreek }
 \RequirePackage { amssymb, upgreek }
 \tl_set_eq:NN \l__sjtu_save_rmdefault_tl \rmdefault

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-xits.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-xits.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-math-font-xits.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,math,xits')
+%% sjtutex.dtx  (with options: `font,math,otf,xits')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,11 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {XITS math fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-math-font-xits.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { math } { xits } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \RequirePackage { unicode-math }
     \bool_if:NTF \g__sjtu_upright_integral_bool
@@ -66,7 +66,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmathtt
       { texgyrecursor }
@@ -79,6 +79,7 @@
         Ligatures      = CommonOff
       ]
   }
+  { \__sjtu_fontset_error:nn { math } { xits } }
 \endinput
 %%
 %% End of file `sjtu-math-font-xits.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-cambria.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-cambria.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-cambria.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,cambria')
+%% sjtutex.dtx  (with options: `font,text,otf,cambria')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,17 +21,17 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Cambria text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-cambria.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { text } { cambria } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \setmainfont { Cambria }
     \setsansfont { Calibri }
     \setmonofont { Consolas } [ Scale = 0.95 ]
   }
+  { \__sjtu_fontset_error:nn { text } { cambria } }
 \endinput
 %%
 %% End of file `sjtu-text-font-cambria.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-libertinus.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-libertinus.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-libertinus.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `font,text,libertinus')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,18 +21,12 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Libertinus text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-libertinus.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \tl_set:Nn \encodingdefault { T1 }
-    \tl_set:Nn \rmdefault { LibertinusSerif-TLF }
-    \tl_set:Nn \sfdefault { LibertinusSans-TLF  }
-    \tl_set:Nn \ttdefault { lmtt                }
-  }
-  {
     \setmainfont
       { LibertinusSerif }
       [
@@ -60,6 +55,12 @@
         BoldSlantedFeatures = { FakeSlant = 0.2 }
       ]
   }
+  {
+    \tl_set:Nn \encodingdefault { T1 }
+    \tl_set:Nn \rmdefault { LibertinusSerif-TLF }
+    \tl_set:Nn \sfdefault { LibertinusSans-TLF  }
+    \tl_set:Nn \ttdefault { lmtt }
+  }
 \endinput
 %%
 %% End of file `sjtu-text-font-libertinus.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-lm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-lm.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-lm.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,lm')
+%% sjtutex.dtx  (with options: `font,text,type1,lm')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,17 +21,17 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Latin Modern text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-lm.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:F
   {
     \tl_set:Nn \encodingdefault { T1 }
     \tl_set:Nn \rmdefault { lmr  }
     \tl_set:Nn \sfdefault { lmss }
     \tl_set:Nn \ttdefault { lmtt }
-  } { }
+  }
 \endinput
 %%
 %% End of file `sjtu-text-font-lm.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newcm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newcm.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newcm.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,newcm')
+%% sjtutex.dtx  (with options: `font,text,otf,newcm')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,11 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New Computer Modern text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-newcm.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { text } { newcm } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \setmainfont
       { NewCM10 }
@@ -82,6 +82,7 @@
         BoldSlantedFeatures = { FakeSlant = 0.25 }
       ]
   }
+  { \__sjtu_fontset_error:nn { text } { newcm } }
 \endinput
 %%
 %% End of file `sjtu-text-font-newcm.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newpx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newpx.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newpx.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,newpx')
+%% sjtutex.dtx  (with options: `font,text,type1,newpx')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,25 +21,20 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New PX text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-newpx.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \tl_set:Nn \encodingdefault { T1 }
-    \RequirePackage { newpxtext }
-    \tl_set:Nn \ttdefault { qcr }
-  }
-  {
     \setmainfont
       { TeXGyrePagellaX }
       [
-        Extension       = .otf,
-        UprightFont     = *-Regular,
-        BoldFont        = *-Bold,
-        ItalicFont      = *-Italic,
-        BoldItalicFont  = *-BoldItalic
+        Extension      = .otf,
+        UprightFont    = *-Regular,
+        BoldFont       = *-Bold,
+        ItalicFont     = *-Italic,
+        BoldItalicFont = *-BoldItalic
       ]
     \setsansfont
       { texgyreheros }
@@ -48,7 +44,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmonofont
       { texgyrecursor }
@@ -61,6 +57,14 @@
         Ligatures      = CommonOff
       ]
   }
+  {
+    \tl_set:Nn \encodingdefault { T1 }
+    \PassOptionsToPackage { nohelv, nott } { newpxtext }
+    \RequirePackage { newpxtext }
+    \tl_set:Nn \qhv at scale { 0.94 }
+    \tl_set:Nn \sfdefault { qhv }
+    \tl_set:Nn \ttdefault { qcr }
+  }
 \endinput
 %%
 %% End of file `sjtu-text-font-newpx.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newtx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newtx.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-newtx.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,newtx')
+%% sjtutex.dtx  (with options: `font,text,type1,newtx')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,25 +21,20 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {New TX text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-newtx.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \tl_set:Nn \encodingdefault { T1 }
-    \RequirePackage { newtxtext }
-    \tl_set:Nn \ttdefault { qcr }
-  }
-  {
     \setmainfont
       { TeXGyreTermesX }
       [
-        Extension       = .otf,
-        UprightFont     = *-Regular,
-        BoldFont        = *-Bold,
-        ItalicFont      = *-Italic,
-        BoldItalicFont  = *-BoldItalic
+        Extension      = .otf,
+        UprightFont    = *-Regular,
+        BoldFont       = *-Bold,
+        ItalicFont     = *-Italic,
+        BoldItalicFont = *-BoldItalic
       ]
     \setsansfont
       { texgyreheros }
@@ -48,7 +44,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmonofont
       { texgyrecursor }
@@ -61,6 +57,14 @@
         Ligatures      = CommonOff
       ]
   }
+  {
+    \tl_set:Nn \encodingdefault { T1 }
+    \PassOptionsToPackage { nohelv, nott } { newtxtext }
+    \RequirePackage { newtxtext }
+    \tl_set:Nn \qhv at scale { 0.94 }
+    \tl_set:Nn \sfdefault { qhv }
+    \tl_set:Nn \ttdefault { qcr }
+  }
 \endinput
 %%
 %% End of file `sjtu-text-font-newtx.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-stixtwo.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-stixtwo.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-stixtwo.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `font,text,stixtwo')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,22 +21,12 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {STIX Two text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-stixtwo.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
-    \tl_set:Nn \encodingdefault { T1 }
-    \DeclareEncodingSubset { TS1 } { ? } { 0 }
-    \UndeclareTextCommand { \textpertenthousand } { T1 }
-    \DeclareTextSymbolDefault { \textpertenthousand } { TS1 }
-    \tl_set:Nn \rmdefault { stix2 }
-    \tl_set:Nn \qhv at scale { 0.94 }
-    \tl_set:Nn \sfdefault { qhv }
-    \tl_set:Nn \ttdefault { qcr }
-  }
-  {
     \setmainfont
       { STIXTwoText }
       [
@@ -53,7 +44,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmonofont
       { texgyrecursor }
@@ -66,6 +57,16 @@
         Ligatures      = CommonOff
       ]
   }
+  {
+    \tl_set:Nn \encodingdefault { T1 }
+    \DeclareEncodingSubset { TS1 } { ? } { 0 }
+    \UndeclareTextCommand { \textpertenthousand } { T1 }
+    \DeclareTextSymbolDefault { \textpertenthousand } { TS1 }
+    \tl_set:Nn \rmdefault { stix2 }
+    \tl_set:Nn \qhv at scale { 0.94 }
+    \tl_set:Nn \sfdefault { qhv }
+    \tl_set:Nn \ttdefault { qcr }
+  }
 \endinput
 %%
 %% End of file `sjtu-text-font-stixtwo.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-times.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-times.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-times.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,times')
+%% sjtutex.dtx  (with options: `font,text,type1,times')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,17 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Times text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-times.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
+    \setmainfont { Times~New~Roman } [ Ligatures = Rare ]
+    \setsansfont { Arial } [ Scale = 0.94 ]
+    \setmonofont { Courier~New }
+  }
+  {
     \tl_set:Nn \encodingdefault { T1 }
     \tl_set:Nn \rmdefault { ptm }
     \tl_set:Nn \Hv at scale { 0.94 }
@@ -32,11 +38,6 @@
     \tl_set:Nn \sfdefault { phv }
     \tl_set:Nn \ttdefault { pcr }
   }
-  {
-    \setmainfont { Times~New~Roman } [ Ligatures = Rare ]
-    \setsansfont { Arial } [ Scale = 0.94 ]
-    \setmonofont { Courier~New }
-  }
 \endinput
 %%
 %% End of file `sjtu-text-font-times.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-xits.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-xits.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/font/sjtu-text-font-xits.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -4,11 +4,12 @@
 %%
 %% The original source files were:
 %%
-%% sjtutex.dtx  (with options: `font,text,xits')
+%% sjtutex.dtx  (with options: `font,text,otf,xits')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,12 +21,11 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {XITS text fonts definition (SJTUTeX)}
 \ProvidesExplFile{sjtu-text-font-xits.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_fontset_case:nn
-  { \__sjtu_fontset_error:nn { text } { xits } }
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_if_engine_opentype:TF
   {
     \setmainfont
       { XITS }
@@ -44,7 +44,7 @@
         BoldFont       = *-bold,
         ItalicFont     = *-italic,
         BoldItalicFont = *-bolditalic,
-        Scale          = 0.94,
+        Scale          = 0.94
       ]
     \setmonofont
       { texgyrecursor }
@@ -57,6 +57,7 @@
         Ligatures      = CommonOff
       ]
   }
+  { \__sjtu_fontset_error:nn { text } { xits } }
 \endinput
 %%
 %% End of file `sjtu-text-font-xits.def'.

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-de.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-de.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,69 @@
+%%
+%% This is file `sjtu-lang-de.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `lang,de')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {German specific definition (SJTUTeX)}
+\ProvidesExplFile{sjtu-lang-de.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\keys_define:nn { sjtu / private }
+  {
+    lang / de .code:n =
+      {
+        \tl_set_eq:NN \l__sjtu_lang_tl \l_keys_value_tl
+        \tl_set:Nn \languagename { ngerman }
+        \normalfont
+        \ctex_set:n { autoindent = 1.5 em }
+      } ,
+    de .meta:n = { lang = de } ,
+    de .groups:n = { lang }
+  }
+\cs_set_eq:NN \__sjtu_title_case_aux_de:n \MakeUppercase
+\clist_map_inline:nn
+  {
+    { keywords } { Schlüsselwörter } ,
+    { info_sep } { \hbox { :~ }    } ,
+    { item_sep } { ,~              }
+  }
+  { \__sjtu_name_const:nnn { de } #1 }
+\clist_const:Nn \c__sjtu_name_month_de_clist
+  {
+    Januar, Februar, März, April, Mai, Juni,
+    Juli, August, September, Oktober, November, Dezember
+  }
+\cs_new:Npn \__sjtu_date_aux_de:nnn #1#2#3
+  {
+    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ~
+    {#3} ,~ \int_to_arabic:n {#1}
+  }
+\cs_new:Npn \__sjtu_date_aux_de:w #1-#2-#3 \q_stop
+  { \__sjtu_date_aux_de:nnn {#1} {#2} {#3} }
+\cs_new:Npn \__sjtu_date_aux_short_de:nn #1#2
+  {
+    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ,~
+    \int_to_arabic:n {#1}
+  }
+\cs_new:Npn \__sjtu_date_aux_short_de:w #1-#2 \q_stop
+  { \__sjtu_date_aux_short_de:nn {#1} {#2} }
+\endinput
+%%
+%% End of file `sjtu-lang-de.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-de.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-en.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-en.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-en.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,92 @@
+%%
+%% This is file `sjtu-lang-en.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `lang,en')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {English specific definition (SJTUTeX)}
+\ProvidesExplFile{sjtu-lang-en.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\keys_define:nn { sjtu / private }
+  {
+    lang / en .code:n =
+      {
+        \tl_set_eq:NN \l__sjtu_lang_tl \l_keys_value_tl
+        \tl_set:Nn \languagename { english }
+        \normalfont
+        \ctex_set:n { autoindent = 1.5 em }
+      } ,
+    en .meta:n = { lang = en } ,
+    en .groups:n = { lang }
+  }
+\cs_set_eq:NN \__sjtu_title_case_aux_en:n \MakeUppercase
+\clist_map_inline:nn
+  {
+    { keywords } { Key~words       } ,
+    { info_sep } { \hbox { :~ }    } ,
+    { item_sep } { ,~              }
+  }
+  { \__sjtu_name_const:nnn { en } #1 }
+\clist_const:Nn \c__sjtu_name_month_en_clist
+  {
+    January, February, March, April, May, June,
+    July, August, September, October, November, December
+  }
+\cs_new:Npn \__sjtu_ordinal_en:n #1
+  {
+    \int_to_arabic:n {#1}
+    \exp_not:N \textsuperscript
+      {
+        \int_case:nnF { \int_mod:nn {#1} { 100 } }
+          {
+            { 11 } { th }
+            { 12 } { th }
+            { 13 } { th }
+          }
+          {
+            \int_case:nnF { \int_mod:nn {#1} { 10 } }
+              {
+                { 1 } { st }
+                { 2 } { nd }
+                { 3 } { rd }
+              }
+              { th }
+          }
+      }
+  }
+\cs_new:Npn \__sjtu_date_aux_en:nnn #1#2#3
+  {
+    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ~
+    \__sjtu_ordinal_en:n {#3} ,~
+    \int_to_arabic:n {#1}
+  }
+\cs_new:Npn \__sjtu_date_aux_en:w #1-#2-#3 \q_stop
+  { \__sjtu_date_aux_en:nnn {#1} {#2} {#3} }
+\cs_new:Npn \__sjtu_date_aux_short_en:nn #1#2
+  {
+    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ,~
+    \int_to_arabic:n {#1}
+  }
+\cs_new:Npn \__sjtu_date_aux_short_en:w #1-#2 \q_stop
+  { \__sjtu_date_aux_short_en:nn {#1} {#2} }
+\endinput
+%%
+%% End of file `sjtu-lang-en.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-en.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-de.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-de.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,49 +0,0 @@
-%%
-%% This is file `sjtu-lang-generic-de.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,generic,de')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {German specific definition for generic (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-generic-de.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\cs_new:Npn \__sjtu_date_aux_de:nnn #1#2#3
-  {
-    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ~
-    {#3} ,~ \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_de:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_de:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_de:nn #1#2
-  {
-    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_short_de:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_de:nn {#1} {#2} }
-\cs_new_protected:Nn \__sjtu_set_language_de:
-  {
-    \tl_set:Nn \languagename { ngerman }
-    \ctex_set:n { autoindent = 1.5 em }
-    \normalfont
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-generic-de.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-en.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-en.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-en.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,72 +0,0 @@
-%%
-%% This is file `sjtu-lang-generic-en.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,generic,en')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {English specific definition for generic (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-generic-en.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\cs_new:Npn \__sjtu_ordinal_en:n #1
-  {
-    \int_to_arabic:n {#1}
-    \exp_not:N \textsuperscript
-      {
-        \int_case:nnF { \int_mod:nn {#1} { 100 } }
-          {
-            { 11 } { th }
-            { 12 } { th }
-            { 13 } { th }
-          }
-          {
-            \int_case:nnF { \int_mod:nn {#1} { 10 } }
-              {
-                { 1 } { st }
-                { 2 } { nd }
-                { 3 } { rd }
-              }
-              { th }
-          }
-      }
-  }
-\cs_new:Npn \__sjtu_date_aux_en:nnn #1#2#3
-  {
-    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ~
-    \__sjtu_ordinal_en:n {#3} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_en:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_en:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_en:nn #1#2
-  {
-    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_short_en:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_en:nn {#1} {#2} }
-\cs_new_protected:Nn \__sjtu_set_language_en:
-  {
-    \tl_set:Nn \languagename { english }
-    \ctex_set:n { autoindent = 1.5 em }
-    \normalfont
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-generic-en.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,57 +0,0 @@
-%%
-%% This is file `sjtu-lang-generic-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,generic,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Japanese specific definition for generic (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-generic-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\cs_new:Npn \__sjtu_date_aux_ja:nnn #1#2#3
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl } ~
-    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_ja_tl   }
-  }
-\cs_new:Npn \__sjtu_date_aux_ja:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_ja:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_ja:nn #1#2
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl }
-  }
-\cs_new:Npn \__sjtu_date_aux_short_ja:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_ja:nn {#1} {#2} }
-\cs_new:Nn \__sjtu_set_cjk_default_ja:
-  {
-    \tl_set:Nn \CJKrmdefault { jamin  }
-    \tl_set:Nn \CJKsfdefault { jagoth }
-    \tl_set:Nn \CJKttdefault { jagoth }
-  }
-\cs_new_protected:Nn \__sjtu_set_language_ja:
-  {
-    \tl_set:Nn \languagename { japanese }
-    \ctex_set:n { autoindent = 1 }
-    \__sjtu_set_cjk_default_ja:
-    \normalfont
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-generic-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-generic-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,57 +0,0 @@
-%%
-%% This is file `sjtu-lang-generic-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,generic,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Chinese specific definition for generic (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-generic-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\cs_new:Npn \__sjtu_date_aux_zh:nnn #1#2#3
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl } ~
-    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_zh_tl   }
-  }
-\cs_new:Npn \__sjtu_date_aux_zh:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_zh:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_zh:nn #1#2
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl }
-  }
-\cs_new:Npn \__sjtu_date_aux_short_zh:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_zh:nn {#1} {#2} }
-\cs_new:Nn \__sjtu_set_cjk_default_zh:
-  {
-    \tl_set:Nn \CJKrmdefault { zhsong }
-    \tl_set:Nn \CJKsfdefault { zhhei  }
-    \tl_set:Nn \CJKttdefault { zhfs   }
-  }
-\cs_new_protected:Nn \__sjtu_set_language_zh:
-  {
-    \tl_set:Nn \languagename { chinese }
-    \ctex_set:n { autoindent = true }
-    \__sjtu_set_cjk_default_zh:
-    \normalfont
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-generic-zh.def'.

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-ja.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,79 @@
+%%
+%% This is file `sjtu-lang-ja.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `lang,ja')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {Japanese specific definition (SJTUTeX)}
+\ProvidesExplFile{sjtu-lang-ja.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\cs_new_protected:Nn \__sjtu_set_cjk_default_ja:
+  {
+    \tl_set:Nn \CJKrmdefault { jamin  }
+    \tl_set:Nn \CJKsfdefault { jagoth }
+    \tl_set:Nn \CJKttdefault { jagoth }
+  }
+\keys_define:nn { sjtu / private }
+  {
+    lang / ja .code:n =
+      {
+        \tl_set_eq:NN \l__sjtu_lang_tl \l_keys_value_tl
+        \tl_set:Nn \languagename { japanese }
+        \__sjtu_set_cjk_default_ja:
+        \normalfont
+        \ctex_set:n { autoindent = 1 }
+      } ,
+    ja .meta:n = { lang = ja } ,
+    ja .groups:n = { lang }
+  }
+\cs_set_eq:NN \__sjtu_title_case_aux_ja:n \use:n
+\clist_map_inline:nn
+  {
+    { keywords } { キーワード      } ,
+    { info_sep } { : \null        } ,
+    { item_sep } { \quad           }
+  }
+  { \__sjtu_name_const:nnn { ja } #1 }
+\clist_map_inline:nn
+  {
+    { year  } { 年 } ,
+    { month } { 月 } ,
+    { day   } { 日 }
+  }
+  { \__sjtu_name_const:nnn { ja } #1 }
+\cs_new:Npn \__sjtu_date_aux_ja:nnn #1#2#3
+  {
+    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
+    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl } ~
+    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_ja_tl   }
+  }
+\cs_new:Npn \__sjtu_date_aux_ja:w #1-#2-#3 \q_stop
+  { \__sjtu_date_aux_ja:nnn {#1} {#2} {#3} }
+\cs_new:Npn \__sjtu_date_aux_short_ja:nn #1#2
+  {
+    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
+    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl }
+  }
+\cs_new:Npn \__sjtu_date_aux_short_ja:w #1-#2 \q_stop
+  { \__sjtu_date_aux_short_ja:nn {#1} {#2} }
+\endinput
+%%
+%% End of file `sjtu-lang-ja.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-ja.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-de.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-de.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,116 +0,0 @@
-%%
-%% This is file `sjtu-lang-thesis-de.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,thesis,de')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {German specific definition for thesis (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-thesis-de.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_info_keys_define:n { de }
-\keys_define:nn { sjtu / info / de }
-  {
-    subject          .initial:x =
-      {
-        Eine~ Dissertation~ Eingereicht~ an \exp_not:N \\
-        der~ { \exp_not:V \c__sjtu_name_univ_de_tl }~ für~
-        { \exp_not:V \c__sjtu_name_degree_level_de_tl } titel
-      }
-  }
-\cs_new:Npn \__sjtu_date_aux_de:nnn #1#2#3
-  {
-    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ~
-    {#3} ,~ \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_de:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_de:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_de:nn #1#2
-  {
-    \clist_item:Nn \c__sjtu_name_month_de_clist {#2} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_short_de:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_de:nn {#1} {#2} }
-\cs_new_protected:Nn \__sjtu_set_language_de:
-  {
-    \tl_set:Nn \languagename { ngerman }
-    \ctex_set:n { autoindent = 1.5 em }
-    \normalfont
-  }
-\cs_new:Npn \ps at SJTU@fund at de
-  {
-    \ps at empty
-    \cs_set:Npn \@oddfoot
-      {
-        \minipage [ t ] { \textwidth }
-          \centering \zihao { - 5 }
-          \clist_use:Nn \l__sjtu_info_fund_de_clist { \par }
-        \endminipage
-      }
-    \cs_set_eq:NN \@evenfoot \@oddfoot
-  }
-\clist_map_inline:nn
-  {
-    { subject }
-      {
-        format      = \zihao { 4 } \setbaselineskip { 24 bp } \bfseries ,
-        content     = \l__sjtu_info_subject_de_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { title   }
-      {
-        format      = \zihao { -2 } \setbaselineskip { 30 bp } \bfseries ,
-        content     = \MakeUppercase \l__sjtu_info_display_title_de_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { info    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } \bfseries ,
-        content     =
-          {
-            \__sjtu_title_page_info_i:nxx { de }
-              {
-                r @ { \exp_not:V \c__sjtu_name_info_sep_de_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              { author, \l__sjtu_info_supervisors_clist }
-          } ,
-        bottom-skip = 30 bp plus 1 fill
-      },
-    { date    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } ,
-        content     =
-          { \__sjtu_title_page_info_ii:n { de } } ,
-      },
-  }
-  {
-    \__sjtu_declare_component:nnn { title / de } #1
-  }
-\__sjtu_declare_page:nn { title / de }
-  {
-    style       = SJTU at fund@de ,
-    format      = \linespread { } \__sjtu_set_language_de: ,
-    prefix      = title / de ,
-    components  = { subject, title, info, date }
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-thesis-de.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-en.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-en.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-en.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,139 +0,0 @@
-%%
-%% This is file `sjtu-lang-thesis-en.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,thesis,en')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {English specific definition for thesis (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-thesis-en.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_info_keys_define:n { en }
-\keys_define:nn { sjtu / info / en }
-  {
-    subject          .initial:x =
-      {
-        A~ Dissertation~ Submitted~ to \exp_not:N \\
-        { \exp_not:V \c__sjtu_name_univ_en_tl }~ for~
-        the~ Degree~ of~ { \exp_not:V \c__sjtu_name_degree_level_en_tl }
-      }
-  }
-\cs_new:Npn \__sjtu_ordinal_en:n #1
-  {
-    \int_to_arabic:n {#1}
-    \exp_not:N \textsuperscript
-      {
-        \int_case:nnF { \int_mod:nn {#1} { 100 } }
-          {
-            { 11 } { th }
-            { 12 } { th }
-            { 13 } { th }
-          }
-          {
-            \int_case:nnF { \int_mod:nn {#1} { 10 } }
-              {
-                { 1 } { st }
-                { 2 } { nd }
-                { 3 } { rd }
-              }
-              { th }
-          }
-      }
-  }
-\cs_new:Npn \__sjtu_date_aux_en:nnn #1#2#3
-  {
-    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ~
-    \__sjtu_ordinal_en:n {#3} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_en:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_en:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_en:nn #1#2
-  {
-    \clist_item:Nn \c__sjtu_name_month_en_clist {#2} ,~
-    \int_to_arabic:n {#1}
-  }
-\cs_new:Npn \__sjtu_date_aux_short_en:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_en:nn {#1} {#2} }
-\cs_new_protected:Nn \__sjtu_set_language_en:
-  {
-    \tl_set:Nn \languagename { english }
-    \ctex_set:n { autoindent = 1.5 em }
-    \normalfont
-  }
-\cs_new:Npn \ps at SJTU@fund at en
-  {
-    \ps at empty
-    \cs_set:Npn \@oddfoot
-      {
-        \minipage [ t ] { \textwidth }
-          \centering \zihao { - 5 }
-          \clist_use:Nn \l__sjtu_info_fund_en_clist { \par }
-        \endminipage
-      }
-    \cs_set_eq:NN \@evenfoot \@oddfoot
-  }
-\clist_map_inline:nn
-  {
-    { subject }
-      {
-        format      = \zihao { 4 } \setbaselineskip { 24 bp } \bfseries ,
-        content     = \l__sjtu_info_subject_en_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { title   }
-      {
-        format      = \zihao { -2 } \setbaselineskip { 30 bp } \bfseries ,
-        content     = \MakeUppercase \l__sjtu_info_display_title_en_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { info    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } \bfseries ,
-        content     =
-          {
-            \__sjtu_title_page_info_i:nxx { en }
-              {
-                r @ { \exp_not:V \c__sjtu_name_info_sep_en_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              { author, \l__sjtu_info_supervisors_clist }
-          } ,
-        bottom-skip = 30 bp plus 1 fill
-      },
-    { date    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } ,
-        content     =
-          { \__sjtu_title_page_info_ii:n { en } } ,
-      },
-  }
-  {
-    \__sjtu_declare_component:nnn { title / en } #1
-  }
-\__sjtu_declare_page:nn { title / en }
-  {
-    style       = SJTU at fund@en ,
-    format      = \linespread { } \__sjtu_set_language_en: ,
-    prefix      = title / en ,
-    components  = { subject, title, info, date }
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-thesis-en.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,124 +0,0 @@
-%%
-%% This is file `sjtu-lang-thesis-ja.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,thesis,ja')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Japanese specific definition for thesis (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-thesis-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_info_keys_define:n { ja }
-\keys_define:nn { sjtu / info / ja }
-  {
-    subject          .initial:x =
-      {
-        \exp_not:V \c__sjtu_name_univ_ja_tl
-        \exp_not:V \c__sjtu_name_degree_level_ja_tl
-        \exp_not:V \c__sjtu_name_thesis_ja_tl
-      }
-  }
-\cs_new:Npn \__sjtu_date_aux_ja:nnn #1#2#3
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl } ~
-    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_ja_tl   }
-  }
-\cs_new:Npn \__sjtu_date_aux_ja:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_ja:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_ja:nn #1#2
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_ja_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_ja_tl }
-  }
-\cs_new:Npn \__sjtu_date_aux_short_ja:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_ja:nn {#1} {#2} }
-\cs_new:Nn \__sjtu_set_cjk_default_ja:
-  {
-    \tl_set:Nn \CJKrmdefault { jamin  }
-    \tl_set:Nn \CJKsfdefault { jagoth }
-    \tl_set:Nn \CJKttdefault { jagoth }
-  }
-\cs_new_protected:Nn \__sjtu_set_language_ja:
-  {
-    \tl_set:Nn \languagename { japanese }
-    \ctex_set:n { autoindent = 1 }
-    \__sjtu_set_cjk_default_ja:
-    \normalfont
-  }
-\cs_new:Npn \ps at SJTU@fund at ja
-  {
-    \ps at empty
-    \cs_set:Npn \@oddfoot
-      {
-        \minipage [ t ] { \textwidth }
-          \centering \zihao { - 5 }
-          \clist_use:Nn \l__sjtu_info_fund_ja_clist { \par }
-        \endminipage
-      }
-    \cs_set_eq:NN \@evenfoot \@oddfoot
-  }
-\clist_map_inline:nn
-  {
-    { subject }
-      {
-        format      = \zihao { 4 } \setbaselineskip { 24 bp } \bfseries ,
-        content     = \l__sjtu_info_subject_ja_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { title   }
-      {
-        format      = \zihao { -2 } \setbaselineskip { 30 bp } \bfseries ,
-        content     = \l__sjtu_info_display_title_ja_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { info    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } \bfseries ,
-        content     =
-          {
-            \__sjtu_title_page_info_i:nxx { ja }
-              {
-                r @ { \exp_not:V \c__sjtu_name_info_sep_ja_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              { author, \l__sjtu_info_supervisors_clist }
-          } ,
-        bottom-skip = 30 bp plus 1 fill
-      },
-    { date    }
-      {
-        format      = \zihao { 3 } \setbaselineskip { 30 bp } ,
-        content     =
-          { \__sjtu_title_page_info_ii:n { ja } } ,
-      },
-  }
-  {
-    \__sjtu_declare_component:nnn { title / ja } #1
-  }
-\__sjtu_declare_page:nn { title / ja }
-  {
-    style       = SJTU at fund@ja ,
-    format      = \linespread { } \__sjtu_set_language_ja: ,
-    prefix      = title / ja ,
-    components  = { subject, title, info, date }
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-thesis-ja.def'.

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-thesis-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -1,142 +0,0 @@
-%%
-%% This is file `sjtu-lang-thesis-zh.def',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% sjtutex.dtx  (with options: `lang,thesis,zh')
-%% 
-%%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
-%% 
-%%     This work may be distributed and/or modified under the
-%%     conditions of the LaTeX Project Public License, either
-%%     version 1.3c of this license or (at your option) any later
-%%     version. The latest version of this license is in:
-%% 
-%%       http://www.latex-project.org/lppl.txt
-%% 
-%%     and version 1.3 or later is part of all distributions of
-%%     LaTeX version 2005/12/01 or later.
-%% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
-  {Chinese specific definition for thesis (SJTUTeX)}
-\ProvidesExplFile{sjtu-lang-thesis-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\__sjtu_info_keys_define:n { zh }
-\keys_define:nn { sjtu / info / zh }
-  {
-    subject          .initial:x =
-      {
-        \exp_not:V \c__sjtu_name_univ_zh_tl
-        \exp_not:V \c__sjtu_name_degree_level_zh_tl
-        \exp_not:V \c__sjtu_name_thesis_zh_tl
-      }
-  }
-\cs_new:Npn \__sjtu_date_aux_zh:nnn #1#2#3
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl } ~
-    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_zh_tl   }
-  }
-\cs_new:Npn \__sjtu_date_aux_zh:w #1-#2-#3 \q_stop
-  { \__sjtu_date_aux_zh:nnn {#1} {#2} {#3} }
-\cs_new:Npn \__sjtu_date_aux_short_zh:nn #1#2
-  {
-    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
-    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl }
-  }
-\cs_new:Npn \__sjtu_date_aux_short_zh:w #1-#2 \q_stop
-  { \__sjtu_date_aux_short_zh:nn {#1} {#2} }
-\cs_new:Nn \__sjtu_set_cjk_default_zh:
-  {
-    \tl_set:Nn \CJKrmdefault { zhsong }
-    \tl_set:Nn \CJKsfdefault { zhhei  }
-    \tl_set:Nn \CJKttdefault { zhfs   }
-  }
-\cs_new_protected:Nn \__sjtu_set_language_zh:
-  {
-    \tl_set:Nn \languagename { chinese }
-    \ctex_set:n { autoindent = true }
-    \__sjtu_set_cjk_default_zh:
-    \normalfont
-  }
-\cs_new:Npn \ps at SJTU@fund at zh
-  {
-    \ps at empty
-    \cs_set:Npn \@oddfoot
-      {
-        \minipage [ t ] { \textwidth }
-          \centering \zihao { - 5 }
-          \clist_use:Nn \l__sjtu_info_fund_zh_clist { \par }
-        \endminipage
-      }
-    \cs_set_eq:NN \@evenfoot \@oddfoot
-  }
-\clist_map_inline:nn
-  {
-    { logo    }
-      {
-        content     =
-          {
-            \includegraphics [ width = 3 cm ]
-              { sjtu-vi-badge-red.pdf }
-          }
-      },
-    { subject }
-      {
-        format      = \zihao { -2 } \setbaselineskip { 30 bp } ,
-        content     = \l__sjtu_info_subject_zh_tl ,
-        bottom-skip = \c_zero_dim plus 1 fill
-      },
-    { title   }
-      {
-        format      = \zihao { 2 } \setbaselineskip { 36 bp } \bfseries ,
-        content     = \l__sjtu_info_display_title_zh_tl ,
-        bottom-skip = 30 bp plus 1 fill
-      },
-    { info    }
-      {
-        format      = \zihao { 4 } \setbaselineskip { 30 bp } \heiti ,
-        content     =
-          {
-            \__sjtu_title_page_info_i:nxx { zh }
-              {
-                \exp_not:N \SJTU at CT@D { 5 em }
-                @ { \exp_not:V \c__sjtu_name_info_sep_zh_tl }
-                > { \exp_not:N \setbaselineskip { 22.5 bp } \exp_not:N \normalfont } l
-              }
-              {
-                author,
-                id,
-                \l__sjtu_info_supervisors_clist ,
-                department,
-                major,
-                \int_compare:nNnF { \g__sjtu_thesis_type_int } = { 1 }
-                  { degree }
-              }
-          } ,
-        bottom-skip = 30 bp
-      },
-    { date    }
-      {
-        format      = \zihao { 4 } \setbaselineskip { 30 bp } \bfseries ,
-        content     = \l__sjtu_info_date_zh_tl ,
-      }
-  }
-  {
-    \__sjtu_declare_component:nnn { title / zh } #1
-  }
-\__sjtu_declare_page:nn { title / zh }
-  {
-    bookmark      = true ,
-    bookmark-text = \c__sjtu_name_title_page_tl ,
-    style         = SJTU at fund@zh ,
-    format        = \linespread { } \__sjtu_set_language_zh: ,
-    prefix        = title / zh ,
-    components    = { logo, subject, title, info, date }
-  }
-\endinput
-%%
-%% End of file `sjtu-lang-thesis-zh.def'.

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-zh.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,79 @@
+%%
+%% This is file `sjtu-lang-zh.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `lang,zh')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {Chinese specific definition (SJTUTeX)}
+\ProvidesExplFile{sjtu-lang-zh.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\cs_new_protected:Nn \__sjtu_set_cjk_default_zh:
+  {
+    \tl_set:Nn \CJKrmdefault { zhsong }
+    \tl_set:Nn \CJKsfdefault { zhhei  }
+    \tl_set:Nn \CJKttdefault { zhfs   }
+  }
+\keys_define:nn { sjtu / private }
+  {
+    lang / zh .code:n =
+      {
+        \tl_set_eq:NN \l__sjtu_lang_tl \l_keys_value_tl
+        \tl_set:Nn \languagename { chinese }
+        \__sjtu_set_cjk_default_zh:
+        \normalfont
+        \ctex_set:n { autoindent = true }
+      } ,
+    zh .meta:n = { lang = zh } ,
+    zh .groups:n = { lang }
+  }
+\cs_set_eq:NN \__sjtu_title_case_aux_zh:n \use:n
+\clist_map_inline:nn
+  {
+    { keywords } { 关键词          } ,
+    { info_sep } { : \null        } ,
+    { item_sep } { ,              }
+  }
+  { \__sjtu_name_const:nnn { zh } #1 }
+\clist_map_inline:nn
+  {
+    { year  } { 年 } ,
+    { month } { 月 } ,
+    { day   } { 日 }
+  }
+  { \__sjtu_name_const:nnn { zh } #1 }
+\cs_new:Npn \__sjtu_date_aux_zh:nnn #1#2#3
+  {
+    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
+    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl } ~
+    \int_to_arabic:n {#3} ~ { \exp_not:V \c__sjtu_name_day_zh_tl   }
+  }
+\cs_new:Npn \__sjtu_date_aux_zh:w #1-#2-#3 \q_stop
+  { \__sjtu_date_aux_zh:nnn {#1} {#2} {#3} }
+\cs_new:Npn \__sjtu_date_aux_short_zh:nn #1#2
+  {
+    \int_to_arabic:n {#1} ~ { \exp_not:V \c__sjtu_name_year_zh_tl  } ~
+    \int_to_arabic:n {#2} ~ { \exp_not:V \c__sjtu_name_month_zh_tl }
+  }
+\cs_new:Npn \__sjtu_date_aux_short_zh:w #1-#2 \q_stop
+  { \__sjtu_date_aux_short_zh:nn {#1} {#2} }
+\endinput
+%%
+%% End of file `sjtu-lang-zh.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/lang/sjtu-lang-zh.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-de.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-de.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `scheme,de')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,16 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {German scheme (SJTUTeX)}
 \ProvidesExplFile{sjtu-scheme-de.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\ctex_if_autoindent_touched:F
+  { \ctex_set:n { autoindent = 1.5 em } }
+\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
+\keys_set:nn { sjtu / style }
+  { fnmark-style = plain   }
+\tl_set:Nn \languagename { ngerman  }
 \keys_set_known:nn { sjtu / name }
   {
     contents      = { Inhaltsverzeichnis     } ,
@@ -49,12 +56,6 @@
     digest        = { Kurzfassung            } ,
     achv          = { Forschungsleistungen   }
   }
-\ctex_if_autoindent_touched:F
-  { \ctex_set:n { autoindent = 1.5 em } }
-\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
-\keys_set:nn { sjtu / style }
-  { fnmark-style = plain   }
-\tl_set:Nn \languagename { ngerman  }
 \clist_map_inline:nn
   {
     { assumption  } { Annahme     } ,
@@ -71,7 +72,7 @@
     { solution    } { Lösung      } ,
     { theorem     } { Theorem     }
   }
-  { \__sjtu_define_name:nn #1 }
+  { \__sjtu_name_const:nnn { de } #1 }
 \endinput
 %%
 %% End of file `sjtu-scheme-de.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-en.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-en.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-en.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `scheme,en')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,10 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {English scheme (SJTUTeX)}
 \ProvidesExplFile{sjtu-scheme-en.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
 \ctex_if_autoindent_touched:F
   { \ctex_set:n { autoindent = 1.5 em } }
 \ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
@@ -46,7 +47,7 @@
     { solution    } { Solution    } ,
     { theorem     } { Theorem     }
   }
-  { \__sjtu_define_name:nn #1 }
+  { \__sjtu_name_const:nnn { en } #1 }
 \endinput
 %%
 %% End of file `sjtu-scheme-en.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-ja.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `scheme,ja')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,20 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Japanese scheme (SJTUTeX)}
 \ProvidesExplFile{sjtu-scheme-ja.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\keys_set_known:nn { ctex / chapter }
+  { name = { 第 \space , \space 章 } }
+\ctex_if_autoindent_touched:F
+  { \ctex_set:n { autoindent = 1 } }
+\ctex_patch_cmd:Nnn \verse { -1.5em } { -2 \ccwd }
+\ctex_patch_cmd:Nnn \verse {  1.5em } {  2 \ccwd }
+\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
+\keys_set:nn { sjtu / style }
+  { fnmark-style = circled }
+\tl_set:Nn \languagename { japanese }
 \keys_set_known:nn { sjtu / name }
   {
     contents      = { 目 \protect \quad 次 } ,
@@ -47,16 +58,6 @@
     digest        = { 要 \protect \quad 約 } ,
     achv          = { 研究業績書           }
   }
-\keys_set_known:nn { ctex / chapter }
-  { name = { 第 \space , \space 章 } }
-\ctex_if_autoindent_touched:F
-  { \ctex_set:n { autoindent = 1 } }
-\ctex_patch_cmd:Nnn \verse { -1.5em } { -2 \ccwd }
-\ctex_patch_cmd:Nnn \verse {  1.5em } {  2 \ccwd }
-\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
-\keys_set:nn { sjtu / style }
-  { fnmark-style = circled }
-\tl_set:Nn \languagename { japanese }
 \clist_map_inline:nn
   {
     { assumption  } { 仮定        } ,
@@ -73,7 +74,7 @@
     { solution    } { 解法        } ,
     { theorem     } { 定理        }
   }
-  { \__sjtu_define_name:nn #1 }
+  { \__sjtu_name_const:nnn { ja } #1 }
 \endinput
 %%
 %% End of file `sjtu-scheme-ja.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-zh.def	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/scheme/sjtu-scheme-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `scheme,zh')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,10 +21,20 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Chinese scheme (SJTUTeX)}
 \ProvidesExplFile{sjtu-scheme-zh.def}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\keys_set_known:nn { ctex / chapter }
+  { name = { 第 \space , \space 章 } }
+\ctex_if_autoindent_touched:F
+  { \ctex_set:n { autoindent = true } }
+\ctex_patch_cmd:Nnn \verse { -1.5em } { -2 \ccwd }
+\ctex_patch_cmd:Nnn \verse {  1.5em } {  2 \ccwd }
+\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
+\keys_set:nn { sjtu / style }
+  { fnmark-style = circled }
+\tl_set:Nn \languagename { chinese  }
 \keys_set_known:nn { sjtu / name }
   {
     contents      = { 目 \protect \quad 录   } ,
@@ -47,16 +58,6 @@
     digest        = { 大摘要                 } ,
     achv          = { 学术论文和科研成果目录 }
   }
-\keys_set_known:nn { ctex / chapter }
-  { name = { 第 \space , \space 章 } }
-\ctex_if_autoindent_touched:F
-  { \ctex_set:n { autoindent = true } }
-\ctex_patch_cmd:Nnn \verse { -1.5em } { -2 \ccwd }
-\ctex_patch_cmd:Nnn \verse {  1.5em } {  2 \ccwd }
-\ctex_patch_cmd:Nnn \quotation { 1.5em } { \parindent }
-\keys_set:nn { sjtu / style }
-  { fnmark-style = circled }
-\tl_set:Nn \languagename { chinese  }
 \clist_map_inline:nn
   {
     { assumption  } { 假设        } ,
@@ -73,7 +74,7 @@
     { solution    } { 解          } ,
     { theorem     } { 定理        }
   }
-  { \__sjtu_define_name:nn #1 }
+  { \__sjtu_name_const:nnn { zh } #1 }
 \endinput
 %%
 %% End of file `sjtu-scheme-zh.def'.

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuarticle.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuarticle.cls	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuarticle.cls	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `class,article')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,30 +21,75 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+\NeedsTeXFormat{LaTeX2e}[2024-06-01]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
-\IfFormatAtLeastTF{2020/10/01}{}
+\IfFormatAtLeastTF{2024-06-01}{}
  {\PackageError{sjtutex}
    {Your LaTeX format is outdated!\MessageBreak\MessageBreak
-    Release `2020/10/01' or newer is required to\MessageBreak
+    Release '2024-06-01' or newer is required to\MessageBreak
     compile this document.\MessageBreak\MessageBreak
     Please update your TeX distribution}{}}
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Article document class for Shanghai Jiao Tong University (SJTUTeX)}
 \ProvidesExplClass{sjtuarticle}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\dim_new:N \l__sjtu_tmp_dim
-\skip_new:N \l__sjtu_tmp_skip
-\box_new:N \l__sjtu_tmp_box
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\msg_new:nnn { sjtutex } { unsupported-engine }
+  {
+    The~sjtutex~classes~does~NOT~support~'#1'~engine. \\\\
+    Please~set~your~typesetting~program~to~either~
+    'xelatex'~or~'lualatex'.
+  }
+\bool_lazy_any:nF
+  {
+    { \sys_if_engine_xetex_p:  }
+    { \sys_if_engine_luatex_p: }
+    { \sys_if_engine_pdftex_p: }
+  }
+  { \msg_fatal:nnV { sjtutex } { unsupported-engine } \c_sys_engine_str }
+\tl_new:N \l__sjtu_tmp_tl
+\clist_new:N \l__sjtu_tmp_clist
+\cs_generate_variant:Nn \clist_use:Nn { Nv, cv }
+\exp_args_generate:n { Nnv }
+\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
+\cs_new_protected:Npn \__sjtu_conditional_const:nn #1#2
+  {
+    \bool_if:nTF {#2}
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_i:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_true_bool
+      }
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_ii:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_false_bool
+      }
+  }
+\__sjtu_conditional_const:nn { engine_opentype }
+  {
+    \bool_lazy_or_p:nn
+      { \sys_if_engine_xetex_p:  }
+      { \sys_if_engine_luatex_p: }
+  }
+\msg_new:nnn { sjtutex } { package-disabled }
+  { The~loading~of~package~'#1'~is~disabled. }
+\cs_new_protected:Npn \__sjtu_disable_package_load:n #1
+  {
+    \disable at package@load {#1}
+      { \msg_warning:nnn { sjtutex } { package-disabled } {#1} }
+  }
+\cs_new_protected:Npn \__sjtu_cs_provide_eq:NN #1#2
+  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
+\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
+\cs_new_protected:Npn \__sjtu_name_set:nnn #1#2#3
+  { \tl_set:cn   { l__sjtu_name_ #2 _ #1 _tl } {#3} }
+\cs_new_protected:Npn \__sjtu_name_const:nnn #1#2#3
+  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
 \tl_new:N \g__sjtu_lang_tl
-\tl_const:Nn \c__sjtu_lang_de_tl { de }
-\tl_const:Nn \c__sjtu_lang_ja_tl { ja }
-\tl_new:N \g__sjtu_zihao_tl
-\int_new:N \g__sjtu_font_size_int
-\dim_new:N \g__sjtu_font_size_dim
 \dim_new:N \g__sjtu_baseline_skip_dim
 \bool_new:N \g__sjtu_fixed_baselineskip_bool
-\fp_new:N \g__sjtu_line_spread_fp
 \tl_new:N \g__sjtu_text_font_tl
 \tl_new:N \g__sjtu_math_font_tl
 \tl_new:N \g__sjtu_cjk_font_tl
@@ -52,22 +98,33 @@
 \bool_new:N \g__sjtu_integral_limits_bool
 \clist_new:N \g__sjtu_math_font_options_clist
 \clist_set:Nn \g__sjtu_options_to_ctex_class_clist
-  { a4paper, UTF8, scheme = plain, fontset = none }
-\clist_new:N \g__sjtu_options_to_packages_clist
-\bool_new:N \g__sjtu_twoside_bool
-\bool_set_false:N \g__sjtu_twoside_bool
-\bool_new:N \g__sjtu_titlepage_bool
-\bool_set_false:N \g__sjtu_titlepage_bool
-\bool_new:N \g__sjtu_draft_bool
-\cs_new_protected:Npn \__sjtu_deprecated_option:n
-  { \msg_warning:nnn { sjtutex } { deprecated-option } }
+  {
+    UTF8,
+    linespread = 1.3,
+    scheme = plain,
+    fontset = none
+  }
+\clist_set:Nn \g__sjtu_options_to_packages_clist
+  {
+    { no-math           } { fontspec     } ,
+    { list = off        } { bicaption    } ,
+    { warnings-off =
+      {
+        mathtools-overbracket,
+        mathtools-colon
+      }
+    }                     { unicode-math } ,
+    { amsmath, thmmarks } { ntheorem     }
+  }
+\msg_new:nnn { sjtutex } { deprecated-option }
+  { Option~'\l_keys_key_str'~is~deprecated! \\ #1 }
 \cs_new_protected:Npn \__sjtu_set_deprecated_option:n #1
   {
-    \__sjtu_deprecated_option:n { Option~ `#1'~ is~ set. }
+    \msg_warning:nnn { sjtutex } { deprecated-option } { Option~'#1'~is~set. }
     \keys_set:nn { sjtu / option } {#1}
   }
-\msg_new:nnn { sjtutex } { deprecated-option }
-  { Option~ `\l_keys_key_tl'~ is~ deprecated. \\ #1 }
+\msg_new:nnn { sjtutex } { unsupported-option }
+  { Option~'\l_keys_key_str'~is~not~supported! \\ Will~be~ignored. }
 \keys_define:nn { sjtu / option }
   {
     lang .choice: ,
@@ -78,24 +135,6 @@
         \tl_gset_eq:NN \g__sjtu_lang_tl \l_keys_choice_tl
       } ,
     lang .initial:n = { zh } ,
-    zihao .choice: ,
-    zihao .value_required:n = true ,
-    zihao /  5 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 1 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 10.5 bp }
-      } ,
-    zihao / -4 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 2 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 12   bp }
-      } ,
-    zihao .initial:n = {  5 } ,
-    linespread .fp_gset:N = \g__sjtu_line_spread_fp ,
-    linespread .initial:n = { \c_nan_fp } ,
-    linespread .value_required:n = true ,
     baselineskip .choice: ,
     baselineskip .value_required:n = true ,
     baselineskip / false   .code:n =
@@ -110,7 +149,10 @@
     text-font .initial:n = { newtx } ,
     math-font .tl_gset:N = \g__sjtu_math_font_tl ,
     cjk-font  .tl_gset:N = \g__sjtu_cjk_font_tl ,
-    fontset .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    fontset    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    nofonts    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = none } } ,
+    adobefonts .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = adobe } } ,
+    winfonts   .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = windows } } ,
     math-style .choice: ,
     math-style .value_required:n = true,
     math-style / TeX .code:n =
@@ -144,91 +186,51 @@
       { \bool_gset_false:N \g__sjtu_integral_limits_bool } ,
     integral-limits / true  .code:n =
       { \bool_gset_true:N  \g__sjtu_integral_limits_bool } ,
-    oneside .value_forbidden:n = true,
-    twoside .value_forbidden:n = true,
-    oneside .code:n =
-      { \bool_gset_false:N \g__sjtu_twoside_bool } ,
-    twoside .code:n =
-      { \bool_gset_true:N  \g__sjtu_twoside_bool } ,
-    titlepage   .value_forbidden:n = true,
-    notitlepage .value_forbidden:n = true,
-    titlepage   .code:n =
-      { \bool_gset_true:N  \g__sjtu_titlepage_bool } ,
-    notitlepage .code:n =
-      { \bool_gset_false:N \g__sjtu_titlepage_bool } ,
-    draft .value_forbidden:n = true,
-    final .value_forbidden:n = true,
-    draft .code:n =
-      { \bool_gset_true:N  \g__sjtu_draft_bool } ,
-    final .code:n =
-      { \bool_gset_false:N \g__sjtu_draft_bool } ,
-    unknown .code:n = { \msg_error:nn { sjtutex } { unknown-option } }
+    unknown .code:n =
+      { \clist_gput_right:No \g__sjtu_options_to_ctex_class_clist { \CurrentOption } }
   }
-\msg_new:nnn { sjtutex } { unknown-option }
-  { Class~ option~ "\l_keys_key_tl"~ is~ unknown. }
-\cs_if_exist:NTF \ProcessKeyOptions
-  { \ProcessKeyOptions [ sjtu / option ] }
+\clist_map_inline:nn
+  { GBK, scheme, cap, nocap }
   {
-    \RequirePackage { l3keys2e }
-    \ProcessKeysOptions { sjtu / option }
+    \keys_define:nn { sjtu / option }
+      {
+        #1 .code:n =
+          { \msg_warning:nn { sjtutex } { unsupported-option } }
+      }
   }
-\bool_if:NF \g__sjtu_fixed_baselineskip_bool
+\ProcessKeyOptions [ sjtu / option ]
+\__sjtu_conditional_const:nn { main_lang_de }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { de } }
+\__sjtu_conditional_const:nn { main_lang_ja }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { ja } }
+\bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { slantedGreek } }
+\bool_if:NT \g__sjtu_upright_integral_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { upint } }
+\clist_put_left:Nn \@classoptionslist { a4paper }
+\__sjtu_if_main_lang_de:T
+  { \clist_put_right:Nn \@classoptionslist { german, ngerman } }
+\bool_if:NTF \g__sjtu_integral_limits_bool
   {
-    \fp_if_nan:nT { \g__sjtu_line_spread_fp }
-      { \fp_set:Nn \g__sjtu_line_spread_fp { 1.3 } }
+    \clist_put_right:Nn \@classoptionslist { intlimits }
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { displaylimits } { cmupint } }
   }
-\clist_set:Nx \g__sjtu_math_font_options_clist
   {
-    \bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
-      { slantedGreek } ,
-    \bool_if:NT \g__sjtu_upright_integral_bool
-      { upint }
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { nolimits      } { cmupint } }
   }
-\clist_put_right:Nx \@classoptionslist
-  {
-    a4paper ,
-    \tl_if_eq:NNT \g__sjtu_lang_tl \c__sjtu_lang_de_tl
-      { german, ngerman } ,
-    \bool_if:NT \g__sjtu_integral_limits_bool
-      { intlimits } ,
-    \g__sjtu_math_font_options_clist
-  }
-\clist_put_right:Nx \g__sjtu_options_to_ctex_class_clist
-  {
-    zihao      = \g__sjtu_zihao_tl ,
-    \fp_if_nan:nF { \g__sjtu_line_spread_fp }
-      { linespread = \fp_use:N \g__sjtu_line_spread_fp } ,
-    \bool_if:NTF \g__sjtu_twoside_bool
-      { twoside   } { oneside     } ,
-    \bool_if:NTF \g__sjtu_titlepage_bool
-      { titlepage } { notitlepage } ,
-    \bool_if:NTF \g__sjtu_draft_bool
-      { draft     } { final       }
-  }
+\clist_concat:NNN \@classoptionslist
+  \@classoptionslist \g__sjtu_math_font_options_clist
 \exp_args:No \PassOptionsToClass
   { \g__sjtu_options_to_ctex_class_clist }
   { ctexart }
-\clist_set:Nx \g__sjtu_options_to_packages_clist
-  {
-    { no-math           } { fontspec     } ,
-    { list = off        } { bicaption    } ,
-    { warnings-off =
-      {
-        mathtools-overbracket,
-        mathtools-colon
-      }
-    }                     { unicode-math } ,
-    { amsmath, thmmarks } { ntheorem     } ,
-    {
-      \bool_if:NTF \g__sjtu_integral_limits_bool
-        { displaylimits } { nolimits }
-    }                     { cmupint      }
-  }
 \clist_map_inline:Nn \g__sjtu_options_to_packages_clist
   { \PassOptionsToPackage #1 }
 \LoadClass { ctexart }
 \RequirePackage
   {
+    array,
     mathtools,
     geometry,
     fancyhdr,
@@ -240,83 +242,27 @@
     graphicx,
     enumitem
   }
-\cs_generate_variant:Nn \cs_gset:Npn { cpo }
-\cs_generate_variant:Nn \tl_const:Nn { Nv }
-\cs_generate_variant:Nn \clist_use:Nn { NV, cv }
-\exp_args_generate:n { Nnv }
-\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
-\prg_generate_conditional_variant:Nnn \regex_match:nn { ne } { T, TF }
-\cs_new:Npx \__sjtu_engine_case:nn #1#2
-  {
-    \bool_lazy_or:nnTF
-      { \sys_if_engine_xetex_p:  }
-      { \sys_if_engine_luatex_p: }
-      {#2}
-      { \sys_if_engine_pdftex:T {#1} }
-  }
-\cs_new:Npx \__sjtu_engine_case:nnn #1#2#3
-  {
-    \sys_if_engine_xetex:TF
-      {#2}
-      {
-        \sys_if_engine_luatex:TF
-          {#3}
-          { \sys_if_engine_pdftex:T {#1} }
-      }
-  }
-\cs_new:Npx \__sjtu_unicode_engine_case:nn #1#2
-  {
-    \sys_if_engine_xetex:TF
-      {#1}
-      { \sys_if_engine_luatex:T {#2} }
-  }
-\__sjtu_engine_case:nn
-  {
-    \cs_new:Npn \__sjtu_unicode_char:n #1
-      {
-        \exp_not:N \Unicode
-          { \int_div_truncate:nn {#1} { 256 } }
-          { \int_mod:nn          {#1} { 256 } }
-      }
-  }
-  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
-\cs_new_protected:Npn \__sjtu_preto_cmd:Nn #1#2
-  {
-    \ctex_preto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-\cs_new_protected:Npn \__sjtu_appto_cmd:Nn #1#2
-  {
-    \ctex_appto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-\cs_new:Npn \__sjtu_skip_add_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l__sjtu_tmp_box {#2}
-    \skip_add:Nn #1 { \box_wd:N \l__sjtu_tmp_box }
-  }
-\cs_generate_variant:Nn \__sjtu_skip_add_to_wd:Nn { cv }
-\cs_new:Npn \__sjtu_cs_provide_eq:NN #1#2
-  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
-\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
-\cs_new_protected:Npn \__sjtu_define_name:nn #1#2
-  { \tl_const:cn { c__sjtu_name_ #1 _tl } {#2} }
-\cs_new_protected:Npn \__sjtu_define_name:nnn #1#2#3
-  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
-\cs_new_protected:Npn \__sjtu_define_symbol:nn #1#2
-  { \tl_const:cx { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
+\normalsize
+\cs_set_protected:Npe \SJTU at orig@normalsize
+  { \exp_not:N \fontsize { \f at size } { \f at baselineskip } \exp_not:N \selectfont }
+\msg_new:nnn { sjtutex } { baselineskip-invalid }
+  { Invalid~baselineskip~value~'#1'! \\ Using~default~value~instead. }
 \cs_new_protected:Npn \__sjtu_set_font_size:nnNn #1#2#3#4
   { \cs_set_protected:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } }
-\tl_set:Nx \l__sjtu_font_size_tl
-  {
-    { \dim_to_decimal:n { \g__sjtu_font_size_dim     } }
-    { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } }
-  }
 \bool_if:NT \g__sjtu_fixed_baselineskip_bool
   {
-    \int_case:nn { \g__sjtu_font_size_int }
+    \dim_compare:nNnTF { \f at size pt } > { \g__sjtu_baseline_skip_dim }
       {
-        { 1 } {
+        \msg_warning:nne { sjtutex } { baselineskip-invalid }
+          { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } pt }
+      }
+      {
+        \tl_set:Ne \l__sjtu_font_size_tl
+          { { \f at size } { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } } }
+        \int_case:nn { \@ptsize }
+          {
+            { 0 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
@@ -327,10 +273,23 @@
                     \let\@listi\@listI
                   }
               }
-        { 2 } {
+            { 1 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
+                    \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+                    \abovedisplayshortskip \z@ \@plus3\p@
+                    \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+                    \belowdisplayskip \abovedisplayskip
+                    \let\@listi\@listI
+                  }
+              }
+            { 2 }
+              {
+                \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
+                  \normalsize
+                  {
                     \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
                     \abovedisplayshortskip \z@ \@plus3\p@
                     \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
@@ -338,22 +297,18 @@
                     \let\@listi\@listI
                   }
               }
+          }
+        \normalsize
       }
-    \normalsize
   }
 \NewDocumentCommand \setbaselineskip { m }
   { \fontsize { \f at size } {#1} \selectfont }
+\msg_new:nnn { sjtutex } { font-unavailable }
+  { '#1-font~=~#2'~is~unavailable~in~current~mode. }
 \cs_new_protected:Npn \__sjtu_fontset_error:nn #1#2
-  { \msg_error:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
-\msg_new:nnn { sjtutex } { font-unavailable }
-  { `#1-font~ =~ #2'~ is~ unavailable~ in~ current~ mode. }
-\cs_new_eq:NN \__sjtu_fontset_case:nn \__sjtu_engine_case:nn
-\cs_new:Npx \__sjtu_fontset_case:nnn #1#2#3
-  {
-    \__sjtu_engine_case:nn
-      { \sys_if_output_pdf:TF {#1} {#2} }
-      {#3}
-  }
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
+\cs_set_protected:Npn \ctex_fontset_error:n #1
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } { cjk } {#1} }
 \cs_new_protected:Nn \__sjtu_declare_math_symbol:nnNn
   {
     \cs_undefine:N #3
@@ -395,9 +350,14 @@
           { \tl_gset:Nn \g__sjtu_cjk_font_tl { fandol } }
       }
   }
+\msg_new:nnn { sjtutex } { invalid-font }
+  {
+    Invalid~value~'#1-font~=~\tl_use:c { g__sjtu_ #1 _font_tl }'! \\
+    Using~'#2'~instead.
+  }
 \cs_new_protected:Npn \__sjtu_load_font:nn #1#2
   {
-    \str_if_eq:eeF { \tl_use:c { g__sjtu_ #1 _font_tl } } { none }
+    \str_if_eq:vnF { g__sjtu_ #1 _font_tl } { none }
       {
         \file_if_exist:nF
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
@@ -409,11 +369,6 @@
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
       }
   }
-\msg_new:nnn { sjtutex } { invalid-font }
-  {
-    Invalid~ value~ `#1-font~ =~ \tl_use:c { g__sjtu_ #1 _font_tl }~ '! \\\\
-    Using~ `#2'~ instead.
-  }
 \cs_new_protected:Nn \__sjtu_load_fontset:
   {
     \clist_map_inline:nn
@@ -444,25 +399,47 @@
         \scpolint\npolint\pointint\sqint\intlarhk\intx
         \intcap\intcup\upint\lowint
       }
+    \clist_map_inline:nn
+      { amsfonts, amssymb, bm, upgreek }
+      { \__sjtu_disable_package_load:n {#1} }
   }
 \ctex_at_end_preamble:n
   {
-    \@ifpackageloaded { unicode-math }
-      { } { \RequirePackage { bm } }
+    \IfPackageLoadedF { unicode-math }
+      {
+        \RequirePackage { bm }
+        \cs_if_exist:NF \uppi
+          { \RequirePackage { upgreek  } }
+        \cs_if_exist:NF \checkmark
+          { \RequirePackage { amsfonts } }
+      }
   }
 \NewDocumentCommand \CJKrmfamily { } { \CJKfamily { \CJKrmdefault } }
 \NewDocumentCommand \CJKsffamily { } { \CJKfamily { \CJKsfdefault } }
 \NewDocumentCommand \CJKttfamily { } { \CJKfamily { \CJKttdefault } }
-\__sjtu_unicode_engine_case:nn
+\sys_if_engine_xetex:T
   {
     \xeCJK_declare_char_class:nn { CJK }
       { "24EA, "2460->"2473, "3251->"32BF, "25A1 }
   }
+\sys_if_engine_luatex:T
   {
     \ltjdefcharrange { 99 }
-      { "24EA, "2460-"2473, "3251-"32BF, "25A1 }
+      { "24EA, "2460- "2473, "3251- "32BF, "25A1 }
     \ltjsetparameter { jacharrange = { +99 } }
   }
+\sys_if_engine_pdftex:TF
+  {
+    \cs_new:Npn \__sjtu_unicode_char:n #1
+      {
+        \exp_not:N \Unicode
+          { \int_div_truncate:nn {#1} { 256 } }
+          { \int_mod:nn          {#1} { 256 } }
+      }
+  }
+  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
+\cs_new_protected:Npn \__sjtu_symbol_const:nn #1#2
+  { \tl_const:ce { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
 \__sjtu_load_fontset:
 \keys_define:nn { sjtu / name }
   {
@@ -486,7 +463,6 @@
     listalgorithm  .tl_set:N = \SJTU at listalgorithmname ,
     listalgorithm .initial:n = { List~of~Algorithms } ,
   }
-\file_input:n { sjtu-name-generic- \g__sjtu_lang_tl .def }
 \geometry
   {
     top           = 3.5 cm,
@@ -519,20 +495,38 @@
     header-uppercase      .initial:n = { false }
   }
 \cs_generate_variant:Nn \__sjtu_nouppercase:n { V }
-\cs_new:Nn \__sjtu_thepage: { \thepage }
+\tl_set:Nn \__sjtu_the_page_tl { \thepage }
+\tl_new:N \__sjtu_the_last_page_tl
+\msg_new:nnn { sjtutex } { require-pageslts }
+  {
+    Add~'\token_to_str:N \usepackage{pageslts}'~in~your~preamble \\
+    to~enable~the~page~number~of~the~last~page.
+  }
 \keys_define:nn { sjtu / style }
   {
-    page-number .cs_set:Np = \__sjtu_page:n #1 ,
+    page-number    .code:n =
+      {
+        \regex_match:nnT { \#2 } { #1 }
+          {
+            \ctex_if_preamble:TF
+              { \RequirePackage { pageslts } }
+              {
+                \IfPackageLoadedF { pageslts }
+                  { \msg_warning:nn { sjtutex } { require-pageslts } }
+              }
+          }
+        \cs_set:Nn \__sjtu_page:nn { #1 }
+      } ,
     page-number .initial:n = { {#1} }
   }
 \tl_set:Nn \l__sjtu_header_tl
   {
     \includegraphics [ height = 1.2 cm ]
-      { sjtu-vi-logo-small-red.pdf }
+      { sjtu-vi-logo-std-h-cor-red.pdf }
   }
 \tl_set:Nn \l__sjtu_leftmark_tl  { \l__sjtu_info_subject_tl }
 \tl_set:Nn \l__sjtu_rightmark_tl { \leftmark }
-\bool_if:NTF \g__sjtu_twoside_bool
+\legacy_if:nTF { @twoside }
   {
     \fancyhead [ LO, RE ] { \l__sjtu_header_tl }
     \fancyhead [ LE ]     { \__sjtu_nouppercase:V \l__sjtu_leftmark_tl  }
@@ -542,12 +536,14 @@
     \fancyhead [ L ] { \l__sjtu_header_tl }
     \fancyhead [ R ] { \__sjtu_nouppercase:V \l__sjtu_rightmark_tl }
   }
-\fancyfoot [ C ] { \__sjtu_page:n { \__sjtu_thepage: } }
-\bool_if:NTF \g__sjtu_twoside_bool
+\fancyfoot [ C ]
+  { \__sjtu_page:nn { \__sjtu_the_page_tl } { \__sjtu_the_last_page_tl } }
+\legacy_if:nTF { @twoside }
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ LE, RO ] { }
+        \fancyhead { }
+        \fancyhead [ LO, RE ] { \l__sjtu_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -554,7 +550,8 @@
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ R ] { }
+        \fancyhead { }
+        \fancyhead [ L ] { \l__sjtu_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -562,7 +559,7 @@
 \RenewDocumentCommand \cleardoublepage { }
   {
     \clearpage
-    \bool_if:NT \g__sjtu_twoside_bool
+    \legacy_if:nT { @twoside }
       {
         \int_if_odd:nF \c at page
           { \hbox:n { } \thispagestyle { empty } \newpage }
@@ -571,9 +568,9 @@
 \ctex_set:nn { section }
   { format = \large \bfseries \CJKsffamily }
 \ctex_set:nn { subsection }
-  { format = \normalsize \bfseries \CJKsffamily }
+  { format = \SJTU at orig@normalsize \bfseries \CJKsffamily }
 \ctex_set:nn { subsubsection }
-  { format = \normalsize \normalfont }
+  { format = \SJTU at orig@normalsize \normalfont }
 \ctex_set:n { secnumdepth = 3 }
 \keys_define:nn { sjtu / style }
   {
@@ -592,20 +589,6 @@
     indent-first   .default:n = { true } ,
     indent-first   .initial:n = { true }
   }
-\NewDocumentCommand \SJTU at head { s O{#3} m O{#2} }
-  {
-    \IfBooleanTF {#1}
-      { \tl_if_empty:nF {#4} { \__sjtu_pdf_bookmark:nn { 0 } {#4} } }
-      {
-        \__sjtu_phantom_section:
-        \addcontentsline { toc } { section } {#4}
-      }
-    \cs_set_eq:NN \__sjtu_orig_ctex_gettitle:n \CTEX at gettitle
-    \cs_set:Npn \CTEX at gettitle ##1 { \__sjtu_orig_ctex_gettitle:n {#2} }
-    \section* {#3}
-    \cs_set_eq:NN \CTEX at gettitle \__sjtu_orig_ctex_gettitle:n
-    \@mkboth { \MakeUppercase {#2} } { \MakeUppercase {#2} }
-  }
 \cs_new_eq:NN \__sjtu_pdf_bookmark:nn \use_none:nn
 \cs_new_eq:NN \__sjtu_phantom_section: \prg_do_nothing:
 \setlist { nosep }
@@ -703,15 +686,14 @@
         \@addtoreset {#4} {#5}
         \IfBooleanF {#1}
           {
-            \cs_gset:cpo { the #4 }
+            \exp_args:Nco \cs_gset:Npn { the #4 }
               { \cs:w the #5 \cs_end: #2 #3 {#4} }
           }
       }
   }
-\cs_set_eq:NN \__sjtu_makefnmark_plain: \@makefnmark
-\cs_set_eq:NN \__sjtu_thefootnote_plain: \thefootnote
-\cs_set_eq:NN \__sjtu_thempfootnote_plain: \thempfootnote
-\cs_new:Npn \__sjtu_footnote_number:N #1
+\msg_new:nnn { sjtutex } { circled-number-exceed }
+  { Circled~number~exceed~50! }
+\cs_new:Npn \__sjtu_circled_number:N #1
   {
     \int_compare:nNnTF {#1} < { 21 }
       { \__sjtu_unicode_char:n { \int_eval:n { "2460 - 1 + #1 } } }
@@ -721,20 +703,19 @@
           {
             \int_compare:nNnTF {#1} < { 51 }
               { \__sjtu_unicode_char:n { \int_eval:n { "32B1 - 36 + #1 } } }
-              { \msg_warning:nn { sjtutex } { too-many-footnotes } }
+              {
+                \msg_warning:nn { sjtutex } { circled-number-exceed }
+                \int_to_arabic:n {#1}
+              }
           }
       }
   }
-\msg_new:nnn { sjtutex } { too-many-footnotes }
-  { Too~ many~ footnotes. }
-\cs_new:Nn \__sjtu_makefnmark_circled: { \hbox:n { \@thefnmark } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-font           .choice: ,
     fnmark-font / haranoaji .code:n =
       {
-        \__sjtu_engine_case:nn
-          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
+        \__sjtu_if_engine_opentype:TF
           {
             \tl_set:Nn \l__sjtu_style_fnmark_font_tl
               {
@@ -746,40 +727,59 @@
                   ]
               }
           }
+          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
       } ,
     fnmark-font / unknown .tl_set:N = \l__sjtu_style_fnmark_font_tl ,
     fnmark-font          .initial:V = \c_empty_tl
   }
-\cs_new:Nn \__sjtu_thefootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at footnote } }
-\cs_new:Nn \__sjtu_thempfootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at mpfootnote } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-style           .choice: ,
     fnmark-style / plain   .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_plain:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_plain:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_plain:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@textsuperscript { \normalfont \@thefnmark } } }
+        \tl_set:Nn \thefootnote
+          { \arabic { footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \itshape \alph { mpfootnote } } }
       } ,
     fnmark-style / circled .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_circled:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_circled:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_circled:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@thefnmark } }
+        \tl_set:Nn \thefootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at mpfootnote } }
       }
   }
-\ctex_at_end_preamble:n {
-  \cs_set_eq:NN \__sjtu_orig_make_fntext:n \@makefntext
-  \cs_set:Npn \@makefntext #1
-    {
-      \group_begin:
-        \cs_set_eq:NN \@makefnmark \__sjtu_makefnmark:
-        \__sjtu_orig_make_fntext:n {#1}
-      \group_end:
-    }
-}
+\ctex_at_end_preamble:n
+  {
+    \cs_set_eq:NN \SJTU at orig@makefntext \@makefntext
+    \cs_set:Npn \@makefntext #1
+      {
+        \group_begin:
+          \cs_set_eq:NN \@makefnmark \SJTU at makefnmark
+          \SJTU at orig@makefntext {#1}
+        \group_end:
+      }
+  }
+\tl_set_eq:NN \l__sjtu_lang_tl \g__sjtu_lang_tl
+\msg_new:nnn { sjtutex } { lang-validation }
+  { Invalid~language~argument~'#1'! }
+\keys_define:nn { sjtu / private }
+  {
+    lang .choice: ,
+    lang .value_required:n = true ,
+    lang .groups:n = { lang } ,
+    lang / unknown .code:n =
+      { \msg_warning:nnn { sjtutex } { lang-validation } {#1} }
+  }
+\cs_new_protected:Npn \__sjtu_select_language:n
+  { \keys_set_groups:nnn { sjtu / private } { lang } }
+\file_input:n { sjtu-lang- \g__sjtu_lang_tl .def }
+\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
 \tl_new:N \l__sjtu_info_subject_tl
 \clist_new:N \l__sjtu_info_keywords_clist
 \keys_define:nn { sjtu / info }
@@ -790,15 +790,13 @@
     subject           .tl_set:N = \l__sjtu_info_subject_tl ,
     keywords       .clist_set:N = \l__sjtu_info_keywords_clist ,
   }
-\file_input:n { sjtu-lang-generic- \g__sjtu_lang_tl .def }
-\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
 \keys_define:nn { sjtu / info }
   {
     date    .code:n =
       {
-        \regex_match:neTF { \d+-\d+-\d+ } {#1}
+        \regex_match:nnTF { \A \d+ \- \d+ \- \d+ \Z } {#1}
           {
-            \tl_set:Nx \@date
+            \tl_set:Ne \@date
               {
                 \exp_last_unbraced:ce
                   { __sjtu_date_aux_ \g__sjtu_lang_tl :w } #1 \q_stop
@@ -805,9 +803,9 @@
               }
           }
           {
-            \regex_match:neT { \d+-\d+ } {#1}
+            \regex_match:nnT { \A \d+ \- \d+ \Z } {#1}
               {
-                \tl_set:Nx \@date
+                \tl_set:Ne \@date
                   {
                     \exp_last_unbraced:ce
                       { __sjtu_date_aux_short_ \g__sjtu_lang_tl :w } #1 \q_stop
@@ -815,7 +813,7 @@
               }
           }
       } ,
-    date .initial:x =
+    date .initial:e =
       {
         \int_to_arabic:n { \c_sys_year_int  } -
         \int_to_arabic:n { \c_sys_month_int } -
@@ -822,7 +820,51 @@
         \int_to_arabic:n { \c_sys_day_int   }
       }
   }
-\tl_set:NV \today \@date
+\tl_set_eq:NN \today \@date
+\bool_new:N \l__sjtu_heading_numbering_bool
+\bool_new:N \l__sjtu_heading_in_toc_bool
+\tl_new:N \l__sjtu_heading_title_tl
+\tl_new:N \l__sjtu_heading_marking_tl
+\keys_define:nn { sjtu / private }
+  {
+    intoc    .value_forbidden:n = true,
+    intoc    .groups:n = { heading } ,
+    intoc    .code:n = { \bool_set_true:N  \l__sjtu_heading_in_toc_bool } ,
+    notintoc .value_forbidden:n = true,
+    notintoc .groups:n = { heading } ,
+    notintoc .code:n = { \bool_set_false:N \l__sjtu_heading_in_toc_bool } ,
+    title    .tl_set:N = \l__sjtu_heading_title_tl ,
+    title    .groups:n = { heading } ,
+    marking  .tl_set:N = \l__sjtu_heading_marking_tl ,
+    marking  .groups:n = { heading }
+  }
+\NewDocumentCommand \SJTU at heading { O{#2} m }
+  {
+    \bool_if:nTF
+      { \l__sjtu_heading_numbering_bool && \l__sjtu_heading_in_toc_bool }
+      { \section [#1] {#2} }
+      {
+        \bool_if:NTF \l__sjtu_heading_in_toc_bool
+          {
+            \__sjtu_phantom_section:
+            \addcontentsline { toc } { section } {#1}
+          }
+          { \__sjtu_pdf_bookmark:nn { 0 } {#1} }
+        \section* {#2}
+        \CTEX at gettitle {#1}
+        \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
+      }
+  }
+\cs_new_protected:Npn \__sjtu_heading:nn #1#2
+  { \SJTU at heading [#1] {#2} }
+\cs_generate_variant:Nn \__sjtu_heading:nn { VV }
+\cs_new_protected:Npn \__sjtu_make_heading:n #1
+  {
+    \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+    \keys_set_groups:nnn { sjtu / private } { heading } {#1}
+    \__sjtu_heading:VV
+      \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+  }
 \keys_define:nn { sjtu / style }
   {
     keywords-format       .choice: ,
@@ -832,9 +874,9 @@
       { \cs_set:Nn \__sjtu_keywords_format:n { \@hangfrom { \bfseries ##1 } } } ,
     keywords-format      .initial:n = { plain }
   }
-\bool_if:NT \g__sjtu_titlepage_bool
-  { \__sjtu_appto_cmd:Nn \abstract { \par } }
-\__sjtu_preto_cmd:Nn \endabstract
+\legacy_if:nT { @titlepage }
+  { \AddToHook { cmd / abstract / after } { \par } }
+\AddToHook { env / abstract / end }
   {
     \clist_if_empty:NF \l__sjtu_info_keywords_clist
       {
@@ -841,19 +883,20 @@
         \par \mode_leave_vertical: \par
         \__sjtu_keywords_format:n
           {
-            \c__sjtu_name_keywords_tl
-            \c__sjtu_name_info_sep_tl
+            \tl_use:c { c__sjtu_name_keywords_ \g__sjtu_lang_tl _tl }
+            \tl_use:c { c__sjtu_name_info_sep_ \g__sjtu_lang_tl _tl }
           }
-        \clist_use:NV \l__sjtu_info_keywords_clist \c__sjtu_name_item_sep_tl
+        \clist_use:Nv \l__sjtu_info_keywords_clist
+          { c__sjtu_name_item_sep_ \g__sjtu_lang_tl _tl }
         \par
       }
   }
-\DeclareDocumentCommand \tableofcontents { s }
+\DeclareDocumentCommand \tableofcontents { O{ } }
   {
-    \IfBooleanTF {#1}
-      { \SJTU at head* { \contentsname } }
-      { \SJTU at head  { \contentsname } }
-    \@starttoc { toc }
+    \group_begin:
+      \__sjtu_make_heading:n { title = \contentsname, #1 }
+      \@starttoc { toc }
+    \group_end:
   }
 \tl_set:Nn \SJTU at leaders { \titlerule* [ 4bp ] { . } }
 \contentsmargin [ 2.55 em ] { 0 pt }
@@ -869,12 +912,12 @@
   [ 4 em ] { }
   { \contentspush { \thecontentslabel \enskip } } { }
   { \SJTU at leaders \thecontentspage }
-\NewDocumentCommand \SJTU at listof { m m s }
+\NewDocumentCommand \SJTU at listof { m m O{ } }
   {
-    \IfBooleanTF {#3}
-      { \SJTU at head* {#1} }
-      { \SJTU at head  {#1} }
-    \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_begin:
+      \__sjtu_make_heading:n { title = #1, #3 }
+      \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_end:
   }
 \cs_new_protected:Npn \__sjtu_new_list_of:Nnnn #1#2#3#4
   {
@@ -916,7 +959,7 @@
         pdfdisplaydoctitle = true
       }
     \int_new:N \g__sjtu_bookmark_int
-    \cs_gset_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
+    \cs_set_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
       {
         \phantomsection
         \int_gincr:N \g__sjtu_bookmark_int
@@ -923,13 +966,16 @@
         \pdfbookmark [#1] {#2}
           { sjtubookmark. \int_use:N \g__sjtu_bookmark_int }
       }
-    \cs_gset_eq:NN \__sjtu_phantom_section: \phantomsection
+    \cs_set_eq:NN \__sjtu_phantom_section: \phantomsection
+    \DeclareExpandableDocumentCommand
+      { \__sjtu_pdfstring_newline:w } { s o m } {#3}
     \pdfstringdefDisableCommands
       {
-        \cs_set_eq:NN \\       \prg_do_nothing:
-        \cs_set_eq:NN \quad    \c_empty_tl
-        \cs_set_eq:NN \qquad   \c_empty_tl
+        \cs_set_eq:NN \\       \__sjtu_pdfstring_newline:w
         \cs_set_eq:NN \hspace  \use_none:n
+        \cs_set_eq:NN \zihao   \use_none:n
+        \tl_set_eq:NN \quad    \c_empty_tl
+        \tl_set_eq:NN \qquad   \c_empty_tl
       }
     \ctex_after_end_preamble:n
       {
@@ -942,6 +988,12 @@
           }
       }
   }
+\ctex_at_end_package:nn { pageslts }
+  {
+    \pagenumbering { arabic }
+    \tl_set:Nn \__sjtu_the_last_page_tl
+      { \lastpageref { pagesLTS.\pagesLTS at pnc } }
+  }
 \ctex_at_end_package:nn { threeparttable }
   { \tl_put_right:Nn \TPTnoteSettings { \footnotesize } }
 \ctex_at_end_package:nn { longtable }
@@ -955,13 +1007,19 @@
       }
       {
         \cs_if_exist:cF {##1}
-          { \exp_args:Nnv  \newtheorem  {##1} { c__sjtu_name_ ##1 _tl } }
+          {
+            \exp_args:Nnv  \newtheorem  {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl }
+          }
       }
     \clist_map_inline:nn
       { remark, solution }
       {
         \cs_if_exist:cF {##1}
-          { \exp_args:NNnv \newtheorem* {##1} { c__sjtu_name_ ##1 _tl } }
+          {
+            \exp_args:NNnv \newtheorem* {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl }
+          }
       }
   }
 \ctex_at_begin_package:nn { amsthm }
@@ -968,7 +1026,7 @@
   {
     \cs_if_exist:NT \openbox
       {
-        \cs_new_eq:NN \__sjtu_save_openbox: \openbox
+        \cs_new_eq:NN \SJTU at orig@openbox \openbox
         \cs_undefine:N \openbox
       }
   }
@@ -975,8 +1033,8 @@
 \ctex_at_end_package:nn { amsthm }
   {
     \__sjtu_cs_provide_eq:NN \QED \openbox
-    \cs_if_exist:NT \__sjtu_save_openbox:
-      { \cs_set_eq:NN \openbox \__sjtu_save_openbox: }
+    \cs_if_exist:NT \SJTU at orig@openbox
+      { \cs_set_eq:NN \openbox \SJTU at orig@openbox }
     \tl_set:Nn \qedsymbol { \ensuremath { \QED } }
     \RenewDocumentEnvironment { proof } { O{ \proofname } }
       {
@@ -994,28 +1052,28 @@
     \newtheoremstyle { sjtu }
       { } { } { \SJTU at style@thm at body@font } { }
       { \SJTU at style@thm at header@font } { } { \ccwd } { }
-  }
-\ctex_at_end_preamble:n
-  {
-    \@ifpackageloaded { amsthm }
+    \__sjtu_disable_package_load:n { ntheorem }
+    \ctex_at_end_preamble:n
       {
         \theoremstyle { sjtu }
         \__sjtu_new_theorems:
       }
+  }
+\ctex_at_end_package:nn { ntheorem }
+  {
+    \__sjtu_disable_package_load:n { amsthm }
+    \ctex_at_end_preamble:n
       {
-        \@ifpackageloaded { ntheorem }
-          {
-            \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
-            \theoremheaderfont { \SJTU at style@thm at header@font }
-            \theorembodyfont   { \SJTU at style@thm at body@font   }
-            \theoremseparator  { \enskip }
-            \theoremsymbol { \ensuremath { \QED } }
-            \qedsymbol     { \ensuremath { \QED } }
-            \cs_if_exist:NF \proof
-              { \newtheorem* { proof } { \proofname } }
-            \theoremsymbol { }
-            \__sjtu_new_theorems:
-          } { }
+        \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
+        \theoremheaderfont { \SJTU at style@thm at header@font }
+        \theorembodyfont   { \SJTU at style@thm at body@font   }
+        \theoremseparator  { \enskip }
+        \theoremsymbol { \ensuremath { \QED } }
+        \qedsymbol     { \ensuremath { \QED } }
+        \cs_if_exist:NF \proof
+          { \newtheorem* { proof } { \proofname } }
+        \theoremsymbol { }
+        \__sjtu_new_theorems:
       }
   }
 \ctex_at_end_package:nn { thmtools }
@@ -1030,13 +1088,16 @@
         \exp_args:NV \contentsuse \thmt at envname { loe }
       }
     \cs_set:Npn \thmtlo at chaptervspacehack { }
-    \RenewDocumentCommand \listoftheorems { s O{ } }
+    \RenewDocumentCommand \listoftheorems { O{ } }
       {
         \group_begin:
-          \setlisttheoremstyle {#2}
-          \IfBooleanTF {#1}
-            { \SJTU at head* { \listtheoremname } }
-            { \SJTU at head  { \listtheoremname } }
+          \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+          \keys_set_groups:nnnN { sjtu / private } { heading }
+            { title = \listtheoremname, #1 } \l__sjtu_tmp_tl
+          \tl_set_rescan:NnV \l__sjtu_tmp_tl { } \l__sjtu_tmp_tl
+          \__sjtu_heading:VV
+            \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+          \exp_args:No \setlisttheoremstyle { \l__sjtu_tmp_tl }
           \cs_set:Npn \contentsline ##1
             { \use:c { thmt at contentsline@ ##1 } {##1} }
           \clist_map_inline:Nn \thmt at allenvs

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/sjtureport.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/sjtureport.cls	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/sjtureport.cls	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `class,report')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,30 +21,75 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+\NeedsTeXFormat{LaTeX2e}[2024-06-01]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
-\IfFormatAtLeastTF{2020/10/01}{}
+\IfFormatAtLeastTF{2024-06-01}{}
  {\PackageError{sjtutex}
    {Your LaTeX format is outdated!\MessageBreak\MessageBreak
-    Release `2020/10/01' or newer is required to\MessageBreak
+    Release '2024-06-01' or newer is required to\MessageBreak
     compile this document.\MessageBreak\MessageBreak
     Please update your TeX distribution}{}}
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Report document class for Shanghai Jiao Tong University (SJTUTeX)}
 \ProvidesExplClass{sjtureport}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\dim_new:N \l__sjtu_tmp_dim
-\skip_new:N \l__sjtu_tmp_skip
-\box_new:N \l__sjtu_tmp_box
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\msg_new:nnn { sjtutex } { unsupported-engine }
+  {
+    The~sjtutex~classes~does~NOT~support~'#1'~engine. \\\\
+    Please~set~your~typesetting~program~to~either~
+    'xelatex'~or~'lualatex'.
+  }
+\bool_lazy_any:nF
+  {
+    { \sys_if_engine_xetex_p:  }
+    { \sys_if_engine_luatex_p: }
+    { \sys_if_engine_pdftex_p: }
+  }
+  { \msg_fatal:nnV { sjtutex } { unsupported-engine } \c_sys_engine_str }
+\tl_new:N \l__sjtu_tmp_tl
+\clist_new:N \l__sjtu_tmp_clist
+\cs_generate_variant:Nn \clist_use:Nn { Nv, cv }
+\exp_args_generate:n { Nnv }
+\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
+\cs_new_protected:Npn \__sjtu_conditional_const:nn #1#2
+  {
+    \bool_if:nTF {#2}
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_i:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_true_bool
+      }
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_ii:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_false_bool
+      }
+  }
+\__sjtu_conditional_const:nn { engine_opentype }
+  {
+    \bool_lazy_or_p:nn
+      { \sys_if_engine_xetex_p:  }
+      { \sys_if_engine_luatex_p: }
+  }
+\msg_new:nnn { sjtutex } { package-disabled }
+  { The~loading~of~package~'#1'~is~disabled. }
+\cs_new_protected:Npn \__sjtu_disable_package_load:n #1
+  {
+    \disable at package@load {#1}
+      { \msg_warning:nnn { sjtutex } { package-disabled } {#1} }
+  }
+\cs_new_protected:Npn \__sjtu_cs_provide_eq:NN #1#2
+  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
+\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
+\cs_new_protected:Npn \__sjtu_name_set:nnn #1#2#3
+  { \tl_set:cn   { l__sjtu_name_ #2 _ #1 _tl } {#3} }
+\cs_new_protected:Npn \__sjtu_name_const:nnn #1#2#3
+  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
 \tl_new:N \g__sjtu_lang_tl
-\tl_const:Nn \c__sjtu_lang_de_tl { de }
-\tl_const:Nn \c__sjtu_lang_ja_tl { ja }
-\tl_new:N \g__sjtu_zihao_tl
-\int_new:N \g__sjtu_font_size_int
-\dim_new:N \g__sjtu_font_size_dim
 \dim_new:N \g__sjtu_baseline_skip_dim
 \bool_new:N \g__sjtu_fixed_baselineskip_bool
-\fp_new:N \g__sjtu_line_spread_fp
 \tl_new:N \g__sjtu_text_font_tl
 \tl_new:N \g__sjtu_math_font_tl
 \tl_new:N \g__sjtu_cjk_font_tl
@@ -52,24 +98,36 @@
 \bool_new:N \g__sjtu_integral_limits_bool
 \clist_new:N \g__sjtu_math_font_options_clist
 \clist_set:Nn \g__sjtu_options_to_ctex_class_clist
-  { a4paper, UTF8, scheme = plain, fontset = none }
-\clist_new:N \g__sjtu_options_to_packages_clist
-\bool_new:N \g__sjtu_twoside_bool
-\bool_set_false:N \g__sjtu_twoside_bool
-\bool_new:N \g__sjtu_openright_bool
-\bool_set_false:N \g__sjtu_openright_bool
-\bool_new:N \g__sjtu_titlepage_bool
-\bool_set_true:N \g__sjtu_titlepage_bool
-\bool_new:N \g__sjtu_draft_bool
-\cs_new_protected:Npn \__sjtu_deprecated_option:n
-  { \msg_warning:nnn { sjtutex } { deprecated-option } }
+  {
+    UTF8,
+    zihao = -4,
+    linespread = 1.3,
+    scheme = plain,
+    fontset = none
+  }
+\clist_set:Nn \g__sjtu_options_to_packages_clist
+  {
+    { no-math           } { fontspec     } ,
+    { list = off        } { bicaption    } ,
+    { warnings-off =
+      {
+        mathtools-overbracket,
+        mathtools-colon
+      }
+    }                     { unicode-math } ,
+    { chapter           } { algorithm    } ,
+    { algochapter       } { algorithm2e  } ,
+    { amsmath, thmmarks } { ntheorem     }
+  }
+\msg_new:nnn { sjtutex } { deprecated-option }
+  { Option~'\l_keys_key_str'~is~deprecated! \\ #1 }
 \cs_new_protected:Npn \__sjtu_set_deprecated_option:n #1
   {
-    \__sjtu_deprecated_option:n { Option~ `#1'~ is~ set. }
+    \msg_warning:nnn { sjtutex } { deprecated-option } { Option~'#1'~is~set. }
     \keys_set:nn { sjtu / option } {#1}
   }
-\msg_new:nnn { sjtutex } { deprecated-option }
-  { Option~ `\l_keys_key_tl'~ is~ deprecated. \\ #1 }
+\msg_new:nnn { sjtutex } { unsupported-option }
+  { Option~'\l_keys_key_str'~is~not~supported! \\ Will~be~ignored. }
 \keys_define:nn { sjtu / option }
   {
     lang .choice: ,
@@ -80,24 +138,6 @@
         \tl_gset_eq:NN \g__sjtu_lang_tl \l_keys_choice_tl
       } ,
     lang .initial:n = { zh } ,
-    zihao .choice: ,
-    zihao .value_required:n = true ,
-    zihao /  5 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 1 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 10.5 bp }
-      } ,
-    zihao / -4 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 2 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 12   bp }
-      } ,
-    zihao .initial:n = { -4 } ,
-    linespread .fp_gset:N = \g__sjtu_line_spread_fp ,
-    linespread .initial:n = { \c_nan_fp } ,
-    linespread .value_required:n = true ,
     baselineskip .choice: ,
     baselineskip .value_required:n = true ,
     baselineskip / false   .code:n =
@@ -112,7 +152,10 @@
     text-font .initial:n = { newtx } ,
     math-font .tl_gset:N = \g__sjtu_math_font_tl ,
     cjk-font  .tl_gset:N = \g__sjtu_cjk_font_tl ,
-    fontset .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    fontset    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    nofonts    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = none } } ,
+    adobefonts .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = adobe } } ,
+    winfonts   .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = windows } } ,
     math-style .choice: ,
     math-style .value_required:n = true,
     math-style / TeX .code:n =
@@ -146,101 +189,51 @@
       { \bool_gset_false:N \g__sjtu_integral_limits_bool } ,
     integral-limits / true  .code:n =
       { \bool_gset_true:N  \g__sjtu_integral_limits_bool } ,
-    oneside .value_forbidden:n = true,
-    twoside .value_forbidden:n = true,
-    oneside .code:n =
-      { \bool_gset_false:N \g__sjtu_twoside_bool } ,
-    twoside .code:n =
-      { \bool_gset_true:N  \g__sjtu_twoside_bool } ,
-    openany   .value_forbidden:n = true,
-    openright .value_forbidden:n = true,
-    openany   .code:n =
-      { \bool_gset_false:N \g__sjtu_openright_bool } ,
-    openright .code:n =
-      { \bool_gset_true:N  \g__sjtu_openright_bool } ,
-    titlepage   .value_forbidden:n = true,
-    notitlepage .value_forbidden:n = true,
-    titlepage   .code:n =
-      { \bool_gset_true:N  \g__sjtu_titlepage_bool } ,
-    notitlepage .code:n =
-      { \bool_gset_false:N \g__sjtu_titlepage_bool } ,
-    draft .value_forbidden:n = true,
-    final .value_forbidden:n = true,
-    draft .code:n =
-      { \bool_gset_true:N  \g__sjtu_draft_bool } ,
-    final .code:n =
-      { \bool_gset_false:N \g__sjtu_draft_bool } ,
-    unknown .code:n = { \msg_error:nn { sjtutex } { unknown-option } }
+    unknown .code:n =
+      { \clist_gput_right:No \g__sjtu_options_to_ctex_class_clist { \CurrentOption } }
   }
-\msg_new:nnn { sjtutex } { unknown-option }
-  { Class~ option~ "\l_keys_key_tl"~ is~ unknown. }
-\cs_if_exist:NTF \ProcessKeyOptions
-  { \ProcessKeyOptions [ sjtu / option ] }
+\clist_map_inline:nn
+  { GBK, scheme, cap, nocap }
   {
-    \RequirePackage { l3keys2e }
-    \ProcessKeysOptions { sjtu / option }
+    \keys_define:nn { sjtu / option }
+      {
+        #1 .code:n =
+          { \msg_warning:nn { sjtutex } { unsupported-option } }
+      }
   }
-\bool_if:NF \g__sjtu_fixed_baselineskip_bool
+\ProcessKeyOptions [ sjtu / option ]
+\__sjtu_conditional_const:nn { main_lang_de }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { de } }
+\__sjtu_conditional_const:nn { main_lang_ja }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { ja } }
+\bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { slantedGreek } }
+\bool_if:NT \g__sjtu_upright_integral_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { upint } }
+\clist_put_left:Nn \@classoptionslist { a4paper }
+\__sjtu_if_main_lang_de:T
+  { \clist_put_right:Nn \@classoptionslist { german, ngerman } }
+\bool_if:NTF \g__sjtu_integral_limits_bool
   {
-    \fp_if_nan:nT { \g__sjtu_line_spread_fp }
-      { \fp_set:Nn \g__sjtu_line_spread_fp { 1.3 } }
+    \clist_put_right:Nn \@classoptionslist { intlimits }
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { displaylimits } { cmupint } }
   }
-\clist_set:Nx \g__sjtu_math_font_options_clist
   {
-    \bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
-      { slantedGreek } ,
-    \bool_if:NT \g__sjtu_upright_integral_bool
-      { upint }
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { nolimits      } { cmupint } }
   }
-\clist_put_right:Nx \@classoptionslist
-  {
-    a4paper ,
-    \tl_if_eq:NNT \g__sjtu_lang_tl \c__sjtu_lang_de_tl
-      { german, ngerman } ,
-    \bool_if:NT \g__sjtu_integral_limits_bool
-      { intlimits } ,
-    \g__sjtu_math_font_options_clist
-  }
-\clist_put_right:Nx \g__sjtu_options_to_ctex_class_clist
-  {
-    zihao      = \g__sjtu_zihao_tl ,
-    \fp_if_nan:nF { \g__sjtu_line_spread_fp }
-      { linespread = \fp_use:N \g__sjtu_line_spread_fp } ,
-    \bool_if:NTF \g__sjtu_twoside_bool
-      { twoside   } { oneside     } ,
-    \bool_if:NTF \g__sjtu_openright_bool
-      { openright } { openany     } ,
-    \bool_if:NTF \g__sjtu_titlepage_bool
-      { titlepage } { notitlepage } ,
-    \bool_if:NTF \g__sjtu_draft_bool
-      { draft     } { final       }
-  }
+\clist_concat:NNN \@classoptionslist
+  \@classoptionslist \g__sjtu_math_font_options_clist
 \exp_args:No \PassOptionsToClass
   { \g__sjtu_options_to_ctex_class_clist }
   { ctexrep }
-\clist_set:Nx \g__sjtu_options_to_packages_clist
-  {
-    { no-math           } { fontspec     } ,
-    { list = off        } { bicaption    } ,
-    { warnings-off =
-      {
-        mathtools-overbracket,
-        mathtools-colon
-      }
-    }                     { unicode-math } ,
-    { amsmath, thmmarks } { ntheorem     } ,
-    { chapter           } { algorithm    } ,
-    { algochapter       } { algorithm2e  } ,
-    {
-      \bool_if:NTF \g__sjtu_integral_limits_bool
-        { displaylimits } { nolimits }
-    }                     { cmupint      }
-  }
 \clist_map_inline:Nn \g__sjtu_options_to_packages_clist
   { \PassOptionsToPackage #1 }
 \LoadClass { ctexrep }
 \RequirePackage
   {
+    array,
     mathtools,
     geometry,
     fancyhdr,
@@ -252,83 +245,27 @@
     graphicx,
     enumitem
   }
-\cs_generate_variant:Nn \cs_gset:Npn { cpo }
-\cs_generate_variant:Nn \tl_const:Nn { Nv }
-\cs_generate_variant:Nn \clist_use:Nn { NV, cv }
-\exp_args_generate:n { Nnv }
-\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
-\prg_generate_conditional_variant:Nnn \regex_match:nn { ne } { T, TF }
-\cs_new:Npx \__sjtu_engine_case:nn #1#2
-  {
-    \bool_lazy_or:nnTF
-      { \sys_if_engine_xetex_p:  }
-      { \sys_if_engine_luatex_p: }
-      {#2}
-      { \sys_if_engine_pdftex:T {#1} }
-  }
-\cs_new:Npx \__sjtu_engine_case:nnn #1#2#3
-  {
-    \sys_if_engine_xetex:TF
-      {#2}
-      {
-        \sys_if_engine_luatex:TF
-          {#3}
-          { \sys_if_engine_pdftex:T {#1} }
-      }
-  }
-\cs_new:Npx \__sjtu_unicode_engine_case:nn #1#2
-  {
-    \sys_if_engine_xetex:TF
-      {#1}
-      { \sys_if_engine_luatex:T {#2} }
-  }
-\__sjtu_engine_case:nn
-  {
-    \cs_new:Npn \__sjtu_unicode_char:n #1
-      {
-        \exp_not:N \Unicode
-          { \int_div_truncate:nn {#1} { 256 } }
-          { \int_mod:nn          {#1} { 256 } }
-      }
-  }
-  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
-\cs_new_protected:Npn \__sjtu_preto_cmd:Nn #1#2
-  {
-    \ctex_preto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-\cs_new_protected:Npn \__sjtu_appto_cmd:Nn #1#2
-  {
-    \ctex_appto_cmd:NnnTF #1 { } {#2}
-      { } { \ctex_patch_failure:N #1 }
-  }
-\cs_new:Npn \__sjtu_skip_add_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l__sjtu_tmp_box {#2}
-    \skip_add:Nn #1 { \box_wd:N \l__sjtu_tmp_box }
-  }
-\cs_generate_variant:Nn \__sjtu_skip_add_to_wd:Nn { cv }
-\cs_new:Npn \__sjtu_cs_provide_eq:NN #1#2
-  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
-\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
-\cs_new_protected:Npn \__sjtu_define_name:nn #1#2
-  { \tl_const:cn { c__sjtu_name_ #1 _tl } {#2} }
-\cs_new_protected:Npn \__sjtu_define_name:nnn #1#2#3
-  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
-\cs_new_protected:Npn \__sjtu_define_symbol:nn #1#2
-  { \tl_const:cx { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
+\normalsize
+\cs_set_protected:Npe \SJTU at orig@normalsize
+  { \exp_not:N \fontsize { \f at size } { \f at baselineskip } \exp_not:N \selectfont }
+\msg_new:nnn { sjtutex } { baselineskip-invalid }
+  { Invalid~baselineskip~value~'#1'! \\ Using~default~value~instead. }
 \cs_new_protected:Npn \__sjtu_set_font_size:nnNn #1#2#3#4
   { \cs_set_protected:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } }
-\tl_set:Nx \l__sjtu_font_size_tl
-  {
-    { \dim_to_decimal:n { \g__sjtu_font_size_dim     } }
-    { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } }
-  }
 \bool_if:NT \g__sjtu_fixed_baselineskip_bool
   {
-    \int_case:nn { \g__sjtu_font_size_int }
+    \dim_compare:nNnTF { \f at size pt } > { \g__sjtu_baseline_skip_dim }
       {
-        { 1 } {
+        \msg_warning:nne { sjtutex } { baselineskip-invalid }
+          { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } pt }
+      }
+      {
+        \tl_set:Ne \l__sjtu_font_size_tl
+          { { \f at size } { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } } }
+        \int_case:nn { \@ptsize }
+          {
+            { 0 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
@@ -339,10 +276,23 @@
                     \let\@listi\@listI
                   }
               }
-        { 2 } {
+            { 1 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
+                    \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+                    \abovedisplayshortskip \z@ \@plus3\p@
+                    \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+                    \belowdisplayskip \abovedisplayskip
+                    \let\@listi\@listI
+                  }
+              }
+            { 2 }
+              {
+                \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
+                  \normalsize
+                  {
                     \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
                     \abovedisplayshortskip \z@ \@plus3\p@
                     \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
@@ -350,22 +300,18 @@
                     \let\@listi\@listI
                   }
               }
+          }
+        \normalsize
       }
-    \normalsize
   }
 \NewDocumentCommand \setbaselineskip { m }
   { \fontsize { \f at size } {#1} \selectfont }
+\msg_new:nnn { sjtutex } { font-unavailable }
+  { '#1-font~=~#2'~is~unavailable~in~current~mode. }
 \cs_new_protected:Npn \__sjtu_fontset_error:nn #1#2
-  { \msg_error:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
-\msg_new:nnn { sjtutex } { font-unavailable }
-  { `#1-font~ =~ #2'~ is~ unavailable~ in~ current~ mode. }
-\cs_new_eq:NN \__sjtu_fontset_case:nn \__sjtu_engine_case:nn
-\cs_new:Npx \__sjtu_fontset_case:nnn #1#2#3
-  {
-    \__sjtu_engine_case:nn
-      { \sys_if_output_pdf:TF {#1} {#2} }
-      {#3}
-  }
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
+\cs_set_protected:Npn \ctex_fontset_error:n #1
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } { cjk } {#1} }
 \cs_new_protected:Nn \__sjtu_declare_math_symbol:nnNn
   {
     \cs_undefine:N #3
@@ -407,9 +353,14 @@
           { \tl_gset:Nn \g__sjtu_cjk_font_tl { fandol } }
       }
   }
+\msg_new:nnn { sjtutex } { invalid-font }
+  {
+    Invalid~value~'#1-font~=~\tl_use:c { g__sjtu_ #1 _font_tl }'! \\
+    Using~'#2'~instead.
+  }
 \cs_new_protected:Npn \__sjtu_load_font:nn #1#2
   {
-    \str_if_eq:eeF { \tl_use:c { g__sjtu_ #1 _font_tl } } { none }
+    \str_if_eq:vnF { g__sjtu_ #1 _font_tl } { none }
       {
         \file_if_exist:nF
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
@@ -421,11 +372,6 @@
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
       }
   }
-\msg_new:nnn { sjtutex } { invalid-font }
-  {
-    Invalid~ value~ `#1-font~ =~ \tl_use:c { g__sjtu_ #1 _font_tl }~ '! \\\\
-    Using~ `#2'~ instead.
-  }
 \cs_new_protected:Nn \__sjtu_load_fontset:
   {
     \clist_map_inline:nn
@@ -456,25 +402,47 @@
         \scpolint\npolint\pointint\sqint\intlarhk\intx
         \intcap\intcup\upint\lowint
       }
+    \clist_map_inline:nn
+      { amsfonts, amssymb, bm, upgreek }
+      { \__sjtu_disable_package_load:n {#1} }
   }
 \ctex_at_end_preamble:n
   {
-    \@ifpackageloaded { unicode-math }
-      { } { \RequirePackage { bm } }
+    \IfPackageLoadedF { unicode-math }
+      {
+        \RequirePackage { bm }
+        \cs_if_exist:NF \uppi
+          { \RequirePackage { upgreek  } }
+        \cs_if_exist:NF \checkmark
+          { \RequirePackage { amsfonts } }
+      }
   }
 \NewDocumentCommand \CJKrmfamily { } { \CJKfamily { \CJKrmdefault } }
 \NewDocumentCommand \CJKsffamily { } { \CJKfamily { \CJKsfdefault } }
 \NewDocumentCommand \CJKttfamily { } { \CJKfamily { \CJKttdefault } }
-\__sjtu_unicode_engine_case:nn
+\sys_if_engine_xetex:T
   {
     \xeCJK_declare_char_class:nn { CJK }
       { "24EA, "2460->"2473, "3251->"32BF, "25A1 }
   }
+\sys_if_engine_luatex:T
   {
     \ltjdefcharrange { 99 }
-      { "24EA, "2460-"2473, "3251-"32BF, "25A1 }
+      { "24EA, "2460- "2473, "3251- "32BF, "25A1 }
     \ltjsetparameter { jacharrange = { +99 } }
   }
+\sys_if_engine_pdftex:TF
+  {
+    \cs_new:Npn \__sjtu_unicode_char:n #1
+      {
+        \exp_not:N \Unicode
+          { \int_div_truncate:nn {#1} { 256 } }
+          { \int_mod:nn          {#1} { 256 } }
+      }
+  }
+  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
+\cs_new_protected:Npn \__sjtu_symbol_const:nn #1#2
+  { \tl_const:ce { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
 \__sjtu_load_fontset:
 \keys_define:nn { sjtu / name }
   {
@@ -499,7 +467,6 @@
     listalgorithm  .tl_set:N = \SJTU at listalgorithmname ,
     listalgorithm .initial:n = { List~of~Algorithms } ,
   }
-\file_input:n { sjtu-name-generic- \g__sjtu_lang_tl .def }
 \geometry
   {
     top           = 3.5 cm,
@@ -532,20 +499,38 @@
     header-uppercase      .initial:n = { false }
   }
 \cs_generate_variant:Nn \__sjtu_nouppercase:n { V }
-\cs_new:Nn \__sjtu_thepage: { \thepage }
+\tl_set:Nn \__sjtu_the_page_tl { \thepage }
+\tl_new:N \__sjtu_the_last_page_tl
+\msg_new:nnn { sjtutex } { require-pageslts }
+  {
+    Add~'\token_to_str:N \usepackage{pageslts}'~in~your~preamble \\
+    to~enable~the~page~number~of~the~last~page.
+  }
 \keys_define:nn { sjtu / style }
   {
-    page-number .cs_set:Np = \__sjtu_page:n #1 ,
+    page-number    .code:n =
+      {
+        \regex_match:nnT { \#2 } { #1 }
+          {
+            \ctex_if_preamble:TF
+              { \RequirePackage { pageslts } }
+              {
+                \IfPackageLoadedF { pageslts }
+                  { \msg_warning:nn { sjtutex } { require-pageslts } }
+              }
+          }
+        \cs_set:Nn \__sjtu_page:nn { #1 }
+      } ,
     page-number .initial:n = { {#1} }
   }
 \tl_set:Nn \l__sjtu_header_tl
   {
     \includegraphics [ height = 1.2 cm ]
-      { sjtu-vi-logo-small-red.pdf }
+      { sjtu-vi-logo-std-h-cor-red.pdf }
   }
 \tl_set:Nn \l__sjtu_leftmark_tl  { \l__sjtu_info_subject_tl }
 \tl_set:Nn \l__sjtu_rightmark_tl { \leftmark }
-\bool_if:NTF \g__sjtu_twoside_bool
+\legacy_if:nTF { @twoside }
   {
     \fancyhead [ LO, RE ] { \l__sjtu_header_tl }
     \fancyhead [ LE ]     { \__sjtu_nouppercase:V \l__sjtu_leftmark_tl  }
@@ -555,12 +540,14 @@
     \fancyhead [ L ] { \l__sjtu_header_tl }
     \fancyhead [ R ] { \__sjtu_nouppercase:V \l__sjtu_rightmark_tl }
   }
-\fancyfoot [ C ] { \__sjtu_page:n { \__sjtu_thepage: } }
-\bool_if:NTF \g__sjtu_twoside_bool
+\fancyfoot [ C ]
+  { \__sjtu_page:nn { \__sjtu_the_page_tl } { \__sjtu_the_last_page_tl } }
+\legacy_if:nTF { @twoside }
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ LE, RO ] { }
+        \fancyhead { }
+        \fancyhead [ LO, RE ] { \l__sjtu_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -567,7 +554,8 @@
   {
     \fancypagestyle { plain }
       {
-        \fancyhead [ R ] { }
+        \fancyhead { }
+        \fancyhead [ L ] { \l__sjtu_header_tl }
         \tl_set:Nn \headrulewidth { 0 pt }
       }
   }
@@ -575,7 +563,7 @@
 \RenewDocumentCommand \cleardoublepage { }
   {
     \clearpage
-    \bool_if:NT \g__sjtu_twoside_bool
+    \legacy_if:nT { @twoside }
       {
         \int_if_odd:nF \c at page
           { \hbox:n { } \thispagestyle { empty } \newpage }
@@ -597,9 +585,9 @@
 \ctex_set:nn { section }
   { format = \large \bfseries \CJKsffamily }
 \ctex_set:nn { subsection }
-  { format = \normalsize \bfseries \CJKsffamily }
+  { format = \SJTU at orig@normalsize \bfseries \CJKsffamily }
 \ctex_set:nn { subsubsection }
-  { format = \normalsize \normalfont }
+  { format = \SJTU at orig@normalsize \normalfont }
 \ctex_set:n { secnumdepth = 3 }
 \keys_define:nn { sjtu / style }
   {
@@ -618,21 +606,6 @@
     indent-first   .default:n = { true } ,
     indent-first   .initial:n = { true }
   }
-\NewDocumentCommand \SJTU at head { s O{#3} m O{#2} }
-  {
-    \CTEX at chapter@break
-    \IfBooleanTF {#1}
-      { \tl_if_empty:nF {#4} { \__sjtu_pdf_bookmark:nn { 0 } {#4} } }
-      {
-        \__sjtu_phantom_section:
-        \addcontentsline { toc } { chapter } {#4}
-      }
-    \cs_set_eq:NN \__sjtu_orig_ctex_gettitle:n \CTEX at gettitle
-    \cs_set:Npn \CTEX at gettitle ##1 { \__sjtu_orig_ctex_gettitle:n {#2} }
-    \chapter* {#3}
-    \cs_set_eq:NN \CTEX at gettitle \__sjtu_orig_ctex_gettitle:n
-    \@mkboth { \MakeUppercase {#2} } { \MakeUppercase {#2} }
-  }
 \cs_new_eq:NN \__sjtu_pdf_bookmark:nn \use_none:nn
 \cs_new_eq:NN \__sjtu_phantom_section: \prg_do_nothing:
 \setlist { nosep }
@@ -730,7 +703,7 @@
         \@addtoreset {#4} {#5}
         \IfBooleanF {#1}
           {
-            \cs_gset:cpo { the #4 }
+            \exp_args:Nco \cs_gset:Npn { the #4 }
               { \cs:w the #5 \cs_end: #2 #3 {#4} }
           }
       }
@@ -738,10 +711,9 @@
 \SJTU at counterwithin { figure } { chapter }
 \SJTU at counterwithin { table  } { chapter }
 \SJTU at counterwithin [ \SJTU at style@eq at num@sep ] { equation } { chapter }
-\cs_set_eq:NN \__sjtu_makefnmark_plain: \@makefnmark
-\cs_set_eq:NN \__sjtu_thefootnote_plain: \thefootnote
-\cs_set_eq:NN \__sjtu_thempfootnote_plain: \thempfootnote
-\cs_new:Npn \__sjtu_footnote_number:N #1
+\msg_new:nnn { sjtutex } { circled-number-exceed }
+  { Circled~number~exceed~50! }
+\cs_new:Npn \__sjtu_circled_number:N #1
   {
     \int_compare:nNnTF {#1} < { 21 }
       { \__sjtu_unicode_char:n { \int_eval:n { "2460 - 1 + #1 } } }
@@ -751,20 +723,19 @@
           {
             \int_compare:nNnTF {#1} < { 51 }
               { \__sjtu_unicode_char:n { \int_eval:n { "32B1 - 36 + #1 } } }
-              { \msg_warning:nn { sjtutex } { too-many-footnotes } }
+              {
+                \msg_warning:nn { sjtutex } { circled-number-exceed }
+                \int_to_arabic:n {#1}
+              }
           }
       }
   }
-\msg_new:nnn { sjtutex } { too-many-footnotes }
-  { Too~ many~ footnotes. }
-\cs_new:Nn \__sjtu_makefnmark_circled: { \hbox:n { \@thefnmark } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-font           .choice: ,
     fnmark-font / haranoaji .code:n =
       {
-        \__sjtu_engine_case:nn
-          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
+        \__sjtu_if_engine_opentype:TF
           {
             \tl_set:Nn \l__sjtu_style_fnmark_font_tl
               {
@@ -776,40 +747,59 @@
                   ]
               }
           }
+          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
       } ,
     fnmark-font / unknown .tl_set:N = \l__sjtu_style_fnmark_font_tl ,
     fnmark-font          .initial:V = \c_empty_tl
   }
-\cs_new:Nn \__sjtu_thefootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at footnote } }
-\cs_new:Nn \__sjtu_thempfootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at mpfootnote } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-style           .choice: ,
     fnmark-style / plain   .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_plain:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_plain:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_plain:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@textsuperscript { \normalfont \@thefnmark } } }
+        \tl_set:Nn \thefootnote
+          { \arabic { footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \itshape \alph { mpfootnote } } }
       } ,
     fnmark-style / circled .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_circled:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_circled:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_circled:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@thefnmark } }
+        \tl_set:Nn \thefootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at mpfootnote } }
       }
   }
-\ctex_at_end_preamble:n {
-  \cs_set_eq:NN \__sjtu_orig_make_fntext:n \@makefntext
-  \cs_set:Npn \@makefntext #1
-    {
-      \group_begin:
-        \cs_set_eq:NN \@makefnmark \__sjtu_makefnmark:
-        \__sjtu_orig_make_fntext:n {#1}
-      \group_end:
-    }
-}
+\ctex_at_end_preamble:n
+  {
+    \cs_set_eq:NN \SJTU at orig@makefntext \@makefntext
+    \cs_set:Npn \@makefntext #1
+      {
+        \group_begin:
+          \cs_set_eq:NN \@makefnmark \SJTU at makefnmark
+          \SJTU at orig@makefntext {#1}
+        \group_end:
+      }
+  }
+\tl_set_eq:NN \l__sjtu_lang_tl \g__sjtu_lang_tl
+\msg_new:nnn { sjtutex } { lang-validation }
+  { Invalid~language~argument~'#1'! }
+\keys_define:nn { sjtu / private }
+  {
+    lang .choice: ,
+    lang .value_required:n = true ,
+    lang .groups:n = { lang } ,
+    lang / unknown .code:n =
+      { \msg_warning:nnn { sjtutex } { lang-validation } {#1} }
+  }
+\cs_new_protected:Npn \__sjtu_select_language:n
+  { \keys_set_groups:nnn { sjtu / private } { lang } }
+\file_input:n { sjtu-lang- \g__sjtu_lang_tl .def }
+\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
 \tl_new:N \l__sjtu_info_subject_tl
 \clist_new:N \l__sjtu_info_keywords_clist
 \keys_define:nn { sjtu / info }
@@ -820,15 +810,13 @@
     subject           .tl_set:N = \l__sjtu_info_subject_tl ,
     keywords       .clist_set:N = \l__sjtu_info_keywords_clist ,
   }
-\file_input:n { sjtu-lang-generic- \g__sjtu_lang_tl .def }
-\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
 \keys_define:nn { sjtu / info }
   {
     date    .code:n =
       {
-        \regex_match:neTF { \d+-\d+-\d+ } {#1}
+        \regex_match:nnTF { \A \d+ \- \d+ \- \d+ \Z } {#1}
           {
-            \tl_set:Nx \@date
+            \tl_set:Ne \@date
               {
                 \exp_last_unbraced:ce
                   { __sjtu_date_aux_ \g__sjtu_lang_tl :w } #1 \q_stop
@@ -835,9 +823,9 @@
               }
           }
           {
-            \regex_match:neT { \d+-\d+ } {#1}
+            \regex_match:nnT { \A \d+ \- \d+ \Z } {#1}
               {
-                \tl_set:Nx \@date
+                \tl_set:Ne \@date
                   {
                     \exp_last_unbraced:ce
                       { __sjtu_date_aux_short_ \g__sjtu_lang_tl :w } #1 \q_stop
@@ -845,7 +833,7 @@
               }
           }
       } ,
-    date .initial:x =
+    date .initial:e =
       {
         \int_to_arabic:n { \c_sys_year_int  } -
         \int_to_arabic:n { \c_sys_month_int } -
@@ -852,7 +840,52 @@
         \int_to_arabic:n { \c_sys_day_int   }
       }
   }
-\tl_set:NV \today \@date
+\tl_set_eq:NN \today \@date
+\bool_new:N \l__sjtu_heading_numbering_bool
+\bool_new:N \l__sjtu_heading_in_toc_bool
+\tl_new:N \l__sjtu_heading_title_tl
+\tl_new:N \l__sjtu_heading_marking_tl
+\keys_define:nn { sjtu / private }
+  {
+    intoc    .value_forbidden:n = true,
+    intoc    .groups:n = { heading } ,
+    intoc    .code:n = { \bool_set_true:N  \l__sjtu_heading_in_toc_bool } ,
+    notintoc .value_forbidden:n = true,
+    notintoc .groups:n = { heading } ,
+    notintoc .code:n = { \bool_set_false:N \l__sjtu_heading_in_toc_bool } ,
+    title    .tl_set:N = \l__sjtu_heading_title_tl ,
+    title    .groups:n = { heading } ,
+    marking  .tl_set:N = \l__sjtu_heading_marking_tl ,
+    marking  .groups:n = { heading }
+  }
+\NewDocumentCommand \SJTU at heading { O{#2} m }
+  {
+    \bool_if:nTF
+      { \l__sjtu_heading_numbering_bool && \l__sjtu_heading_in_toc_bool }
+      { \chapter [#1] {#2} }
+      {
+        \CTEX at chapter@break
+        \bool_if:NTF \l__sjtu_heading_in_toc_bool
+          {
+            \__sjtu_phantom_section:
+            \addcontentsline { toc } { chapter } {#1}
+          }
+          { \__sjtu_pdf_bookmark:nn { 0 } {#1} }
+        \chapter* {#2}
+        \CTEX at gettitle {#1}
+        \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
+      }
+  }
+\cs_new_protected:Npn \__sjtu_heading:nn #1#2
+  { \SJTU at heading [#1] {#2} }
+\cs_generate_variant:Nn \__sjtu_heading:nn { VV }
+\cs_new_protected:Npn \__sjtu_make_heading:n #1
+  {
+    \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+    \keys_set_groups:nnn { sjtu / private } { heading } {#1}
+    \__sjtu_heading:VV
+      \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+  }
 \keys_define:nn { sjtu / style }
   {
     keywords-format       .choice: ,
@@ -862,9 +895,9 @@
       { \cs_set:Nn \__sjtu_keywords_format:n { \@hangfrom { \bfseries ##1 } } } ,
     keywords-format      .initial:n = { plain }
   }
-\bool_if:NT \g__sjtu_titlepage_bool
-  { \__sjtu_appto_cmd:Nn \abstract { \par } }
-\__sjtu_preto_cmd:Nn \endabstract
+\legacy_if:nT { @titlepage }
+  { \AddToHook { cmd / abstract / after } { \par } }
+\AddToHook { env / abstract / end }
   {
     \clist_if_empty:NF \l__sjtu_info_keywords_clist
       {
@@ -871,19 +904,20 @@
         \par \mode_leave_vertical: \par
         \__sjtu_keywords_format:n
           {
-            \c__sjtu_name_keywords_tl
-            \c__sjtu_name_info_sep_tl
+            \tl_use:c { c__sjtu_name_keywords_ \g__sjtu_lang_tl _tl }
+            \tl_use:c { c__sjtu_name_info_sep_ \g__sjtu_lang_tl _tl }
           }
-        \clist_use:NV \l__sjtu_info_keywords_clist \c__sjtu_name_item_sep_tl
+        \clist_use:Nv \l__sjtu_info_keywords_clist
+          { c__sjtu_name_item_sep_ \g__sjtu_lang_tl _tl }
         \par
       }
   }
-\DeclareDocumentCommand \tableofcontents { s }
+\DeclareDocumentCommand \tableofcontents { O{ } }
   {
-    \IfBooleanTF {#1}
-      { \SJTU at head* { \contentsname } }
-      { \SJTU at head  { \contentsname } }
-    \@starttoc { toc }
+    \group_begin:
+      \__sjtu_make_heading:n { title = \contentsname, #1 }
+      \@starttoc { toc }
+    \group_end:
   }
 \tl_set:Nn \SJTU at leaders { \titlerule* [ 4bp ] { . } }
 \contentsmargin [ 2.55 em ] { 0 pt }
@@ -899,12 +933,12 @@
   [ 4 em ] { }
   { \contentspush { \thecontentslabel \enskip } } { }
   { \SJTU at leaders \thecontentspage }
-\NewDocumentCommand \SJTU at listof { m m s }
+\NewDocumentCommand \SJTU at listof { m m O{ } }
   {
-    \IfBooleanTF {#3}
-      { \SJTU at head* {#1} }
-      { \SJTU at head  {#1} }
-    \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_begin:
+      \__sjtu_make_heading:n { title = #1, #3 }
+      \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_end:
   }
 \cs_new_protected:Npn \__sjtu_new_list_of:Nnnn #1#2#3#4
   {
@@ -946,7 +980,7 @@
         pdfdisplaydoctitle = true
       }
     \int_new:N \g__sjtu_bookmark_int
-    \cs_gset_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
+    \cs_set_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
       {
         \phantomsection
         \int_gincr:N \g__sjtu_bookmark_int
@@ -953,13 +987,16 @@
         \pdfbookmark [#1] {#2}
           { sjtubookmark. \int_use:N \g__sjtu_bookmark_int }
       }
-    \cs_gset_eq:NN \__sjtu_phantom_section: \phantomsection
+    \cs_set_eq:NN \__sjtu_phantom_section: \phantomsection
+    \DeclareExpandableDocumentCommand
+      { \__sjtu_pdfstring_newline:w } { s o m } {#3}
     \pdfstringdefDisableCommands
       {
-        \cs_set_eq:NN \\       \prg_do_nothing:
-        \cs_set_eq:NN \quad    \c_empty_tl
-        \cs_set_eq:NN \qquad   \c_empty_tl
+        \cs_set_eq:NN \\       \__sjtu_pdfstring_newline:w
         \cs_set_eq:NN \hspace  \use_none:n
+        \cs_set_eq:NN \zihao   \use_none:n
+        \tl_set_eq:NN \quad    \c_empty_tl
+        \tl_set_eq:NN \qquad   \c_empty_tl
       }
     \ctex_after_end_preamble:n
       {
@@ -972,6 +1009,12 @@
           }
       }
   }
+\ctex_at_end_package:nn { pageslts }
+  {
+    \pagenumbering { arabic }
+    \tl_set:Nn \__sjtu_the_last_page_tl
+      { \lastpageref { pagesLTS.\pagesLTS at pnc } }
+  }
 \ctex_at_end_package:nn { threeparttable }
   { \tl_put_right:Nn \TPTnoteSettings { \footnotesize } }
 \ctex_at_end_package:nn { longtable }
@@ -986,8 +1029,8 @@
       {
         \cs_if_exist:cF {##1}
           {
-            \exp_args:Nnv  \newtheorem  {##1} { c__sjtu_name_ ##1 _tl }
-              [ chapter ]
+            \exp_args:Nnv  \newtheorem  {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl } [ chapter ]
           }
       }
     \clist_map_inline:nn
@@ -994,7 +1037,10 @@
       { remark, solution }
       {
         \cs_if_exist:cF {##1}
-          { \exp_args:NNnv \newtheorem* {##1} { c__sjtu_name_ ##1 _tl } }
+          {
+            \exp_args:NNnv \newtheorem* {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl }
+          }
       }
   }
 \ctex_at_begin_package:nn { amsthm }
@@ -1001,7 +1047,7 @@
   {
     \cs_if_exist:NT \openbox
       {
-        \cs_new_eq:NN \__sjtu_save_openbox: \openbox
+        \cs_new_eq:NN \SJTU at orig@openbox \openbox
         \cs_undefine:N \openbox
       }
   }
@@ -1008,8 +1054,8 @@
 \ctex_at_end_package:nn { amsthm }
   {
     \__sjtu_cs_provide_eq:NN \QED \openbox
-    \cs_if_exist:NT \__sjtu_save_openbox:
-      { \cs_set_eq:NN \openbox \__sjtu_save_openbox: }
+    \cs_if_exist:NT \SJTU at orig@openbox
+      { \cs_set_eq:NN \openbox \SJTU at orig@openbox }
     \tl_set:Nn \qedsymbol { \ensuremath { \QED } }
     \RenewDocumentEnvironment { proof } { O{ \proofname } }
       {
@@ -1027,28 +1073,28 @@
     \newtheoremstyle { sjtu }
       { } { } { \SJTU at style@thm at body@font } { }
       { \SJTU at style@thm at header@font } { } { \ccwd } { }
-  }
-\ctex_at_end_preamble:n
-  {
-    \@ifpackageloaded { amsthm }
+    \__sjtu_disable_package_load:n { ntheorem }
+    \ctex_at_end_preamble:n
       {
         \theoremstyle { sjtu }
         \__sjtu_new_theorems:
       }
+  }
+\ctex_at_end_package:nn { ntheorem }
+  {
+    \__sjtu_disable_package_load:n { amsthm }
+    \ctex_at_end_preamble:n
       {
-        \@ifpackageloaded { ntheorem }
-          {
-            \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
-            \theoremheaderfont { \SJTU at style@thm at header@font }
-            \theorembodyfont   { \SJTU at style@thm at body@font   }
-            \theoremseparator  { \enskip }
-            \theoremsymbol { \ensuremath { \QED } }
-            \qedsymbol     { \ensuremath { \QED } }
-            \cs_if_exist:NF \proof
-              { \newtheorem* { proof } { \proofname } }
-            \theoremsymbol { }
-            \__sjtu_new_theorems:
-          } { }
+        \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
+        \theoremheaderfont { \SJTU at style@thm at header@font }
+        \theorembodyfont   { \SJTU at style@thm at body@font   }
+        \theoremseparator  { \enskip }
+        \theoremsymbol { \ensuremath { \QED } }
+        \qedsymbol     { \ensuremath { \QED } }
+        \cs_if_exist:NF \proof
+          { \newtheorem* { proof } { \proofname } }
+        \theoremsymbol { }
+        \__sjtu_new_theorems:
       }
   }
 \ctex_at_end_package:nn { thmtools }
@@ -1063,13 +1109,16 @@
         \exp_args:NV \contentsuse \thmt at envname { loe }
       }
     \cs_set:Npn \thmtlo at chaptervspacehack { }
-    \RenewDocumentCommand \listoftheorems { s O{ } }
+    \RenewDocumentCommand \listoftheorems { O{ } }
       {
         \group_begin:
-          \setlisttheoremstyle {#2}
-          \IfBooleanTF {#1}
-            { \SJTU at head* { \listtheoremname } }
-            { \SJTU at head  { \listtheoremname } }
+          \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+          \keys_set_groups:nnnN { sjtu / private } { heading }
+            { title = \listtheoremname, #1 } \l__sjtu_tmp_tl
+          \tl_set_rescan:NnV \l__sjtu_tmp_tl { } \l__sjtu_tmp_tl
+          \__sjtu_heading:VV
+            \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+          \exp_args:No \setlisttheoremstyle { \l__sjtu_tmp_tl }
           \cs_set:Npn \contentsline ##1
             { \use:c { thmt at contentsline@ ##1 } {##1} }
           \clist_map_inline:Nn \thmt at allenvs
@@ -1101,10 +1150,10 @@
       { \fname at algorithm } { \listalgorithmname }
   }
 \ctex_at_begin_package:nn { algorithm2e }
-  { \cs_set_eq:NN \__sjtu_save_chapter:w \@chapter }
+  { \cs_set_eq:NN \SJTU at orig@at at chapter \@chapter }
 \ctex_at_end_package:nn { algorithm2e }
   {
-    \cs_set_eq:NN \@chapter \__sjtu_save_chapter:w
+    \cs_set_eq:NN \@chapter \SJTU at orig@at at chapter
     \SetAlgorithmName { \SJTU at algorithmname     }
                       { \SJTU at algorithmname     }
                       { \SJTU at listalgorithmname }

Modified: trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuthesis.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuthesis.cls	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/sjtuthesis.cls	2025-02-12 21:06:30 UTC (rev 73925)
@@ -7,8 +7,9 @@
 %% sjtutex.dtx  (with options: `class,thesis')
 %% 
 %%     Copyright (C) SJTUG
-%%       2018--2024 Weijian Wu   <alexarawu at outlook.com>
-%%       2022--2024 Zilong Li    <logcreative at outlook.com>
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
 %% 
 %%     This work may be distributed and/or modified under the
 %%     conditions of the LaTeX Project Public License, either
@@ -20,34 +21,86 @@
 %%     and version 1.3 or later is part of all distributions of
 %%     LaTeX version 2005/12/01 or later.
 %% 
-\NeedsTeXFormat{LaTeX2e}[2020/10/01]
+\NeedsTeXFormat{LaTeX2e}[2024-06-01]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
-\IfFormatAtLeastTF{2020/10/01}{}
+\IfFormatAtLeastTF{2024-06-01}{}
  {\PackageError{sjtutex}
    {Your LaTeX format is outdated!\MessageBreak\MessageBreak
-    Release `2020/10/01' or newer is required to\MessageBreak
+    Release '2024-06-01' or newer is required to\MessageBreak
     compile this document.\MessageBreak\MessageBreak
     Please update your TeX distribution}{}}
-\GetIdInfo$Id: sjtutex.dtx 879eea9 2024-11-06 19:54:03 +0800 Alexara Wu <alexarawu at outlook.com> $
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
   {Thesis document class for Shanghai Jiao Tong University (SJTUTeX)}
 \ProvidesExplClass{sjtuthesis}
-  {\ExplFileDate}{2.1.5}{\ExplFileDescription}
-\bool_new:N \l__sjtu_tmp_bool
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\msg_new:nnn { sjtutex } { unsupported-engine }
+  {
+    The~sjtutex~classes~does~NOT~support~'#1'~engine. \\\\
+    Please~set~your~typesetting~program~to~either~
+    'xelatex'~or~'lualatex'.
+  }
+\bool_lazy_any:nF
+  {
+    { \sys_if_engine_xetex_p:  }
+    { \sys_if_engine_luatex_p: }
+    { \sys_if_engine_pdftex_p: }
+  }
+  { \msg_fatal:nnV { sjtutex } { unsupported-engine } \c_sys_engine_str }
+\tl_new:N \l__sjtu_tmp_tl
 \clist_new:N \l__sjtu_tmp_clist
-\dim_new:N \l__sjtu_tmp_dim
-\skip_new:N \l__sjtu_tmp_skip
 \box_new:N \l__sjtu_tmp_box
+\cs_generate_variant:Nn \clist_use:Nn { Nv, cv }
+\exp_args_generate:n { Nnv }
+\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
+\cs_new_protected:Npn \__sjtu_conditional_const:nn #1#2
+  {
+    \bool_if:nTF {#2}
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_i:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_true_bool
+      }
+      {
+        \cs_new_eq:cN { __sjtu_if_ #1 :T  } \use_none:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :F  } \use:n
+        \cs_new_eq:cN { __sjtu_if_ #1 :TF } \use_ii:nn
+        \cs_new_eq:cN { __sjtu_if_ #1 _p: } \c_false_bool
+      }
+  }
+\__sjtu_conditional_const:nn { engine_opentype }
+  {
+    \bool_lazy_or_p:nn
+      { \sys_if_engine_xetex_p:  }
+      { \sys_if_engine_luatex_p: }
+  }
+\msg_new:nnn { sjtutex } { package-disabled }
+  { The~loading~of~package~'#1'~is~disabled. }
+\cs_new_protected:Npn \__sjtu_disable_package_load:n #1
+  {
+    \disable at package@load {#1}
+      { \msg_warning:nnn { sjtutex } { package-disabled } {#1} }
+  }
+\cs_new:Npn \__sjtu_dim_set_to_wd:Nn #1#2
+  {
+    \hbox_set:Nn \l__sjtu_tmp_box {#2}
+    \dim_set:Nn #1 { \box_wd:N \l__sjtu_tmp_box }
+  }
+\cs_generate_variant:Nn \__sjtu_dim_set_to_wd:Nn { Nv }
+\cs_new_protected:Npn \__sjtu_cs_provide_eq:NN #1#2
+  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
+\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
+\cs_new_protected:Npn \__sjtu_name_set:nnn #1#2#3
+  { \tl_set:cn   { l__sjtu_name_ #2 _ #1 _tl } {#3} }
+\cs_new_protected:Npn \__sjtu_name_const:nnn #1#2#3
+  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
+\cs_new_protected:Npn \__sjtu_name_const_from_clist:nnnn #1#2#3#4
+  { \tl_const:ce { c__sjtu_name_ #2 _ #1 _tl } { \clist_item:nn {#4} {#3} } }
 \int_new:N \g__sjtu_thesis_type_int
 \tl_new:N \g__sjtu_lang_tl
 \clist_set:Nn \g__sjtu_lang_clist { zh, en }
-\tl_const:Nn \c__sjtu_lang_de_tl { de }
-\tl_const:Nn \c__sjtu_lang_ja_tl { ja }
-\tl_new:N \g__sjtu_zihao_tl
-\int_new:N \g__sjtu_font_size_int
-\dim_new:N \g__sjtu_font_size_dim
 \dim_new:N \g__sjtu_baseline_skip_dim
 \bool_new:N \g__sjtu_fixed_baselineskip_bool
-\fp_new:N \g__sjtu_line_spread_fp
 \tl_new:N \g__sjtu_text_font_tl
 \tl_new:N \g__sjtu_math_font_tl
 \tl_new:N \g__sjtu_cjk_font_tl
@@ -57,22 +110,35 @@
 \clist_new:N \g__sjtu_math_font_options_clist
 \bool_new:N \g__sjtu_review_bool
 \clist_set:Nn \g__sjtu_options_to_ctex_class_clist
-  { a4paper, UTF8, scheme = plain, fontset = none }
-\clist_new:N \g__sjtu_options_to_packages_clist
-\bool_new:N \g__sjtu_twoside_bool
-\bool_set_true:N \g__sjtu_twoside_bool
-\bool_new:N \g__sjtu_openright_bool
-\bool_set_true:N \g__sjtu_openright_bool
-\bool_new:N \g__sjtu_draft_bool
-\cs_new_protected:Npn \__sjtu_deprecated_option:n
-  { \msg_warning:nnn { sjtutex } { deprecated-option } }
+  {
+    UTF8,
+    zihao = -4,
+    scheme = plain,
+    fontset = none
+  }
+\clist_set:Nn \g__sjtu_options_to_packages_clist
+  {
+    { no-math           } { fontspec     } ,
+    { list = off        } { bicaption    } ,
+    { warnings-off =
+      {
+        mathtools-overbracket,
+        mathtools-colon
+      }
+    }                     { unicode-math } ,
+    { chapter           } { algorithm    } ,
+    { algochapter       } { algorithm2e  } ,
+    { amsmath, thmmarks } { ntheorem     }
+  }
+\msg_new:nnn { sjtutex } { deprecated-option }
+  { Option~'\l_keys_key_str'~is~deprecated! \\ #1 }
 \cs_new_protected:Npn \__sjtu_set_deprecated_option:n #1
   {
-    \__sjtu_deprecated_option:n { Option~ `#1'~ is~ set. }
+    \msg_warning:nnn { sjtutex } { deprecated-option } { Option~'#1'~is~set. }
     \keys_set:nn { sjtu / option } {#1}
   }
-\msg_new:nnn { sjtutex } { deprecated-option }
-  { Option~ `\l_keys_key_tl'~ is~ deprecated. \\ #1 }
+\msg_new:nnn { sjtutex } { unsupported-option }
+  { Option~'\l_keys_key_str'~is~not~supported! \\ Will~be~ignored. }
 \keys_define:nn { sjtu / option }
   {
     type .choice: ,
@@ -91,24 +157,6 @@
           { \clist_gput_right:Nn \g__sjtu_lang_clist {#1} }
       } ,
     lang .initial:n = { zh } ,
-    zihao .choice: ,
-    zihao .value_required:n = true ,
-    zihao /  5 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 1 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 10.5 bp }
-      } ,
-    zihao / -4 .code:n =
-      {
-        \tl_gset:Nn  \g__sjtu_zihao_tl {#1}
-        \int_gset:Nn \g__sjtu_font_size_int { 2 }
-        \dim_gset:Nn \g__sjtu_font_size_dim { 12   bp }
-      } ,
-    zihao .initial:n = { -4 } ,
-    linespread .fp_gset:N = \g__sjtu_line_spread_fp ,
-    linespread .initial:n = { \c_nan_fp } ,
-    linespread .value_required:n = true ,
     baselineskip .choice: ,
     baselineskip .value_required:n = true ,
     baselineskip / false   .code:n =
@@ -123,7 +171,10 @@
     text-font .initial:n = { newtx } ,
     math-font .tl_gset:N = \g__sjtu_math_font_tl ,
     cjk-font  .tl_gset:N = \g__sjtu_cjk_font_tl ,
-    fontset .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    fontset    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = #1 } } ,
+    nofonts    .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = none } } ,
+    adobefonts .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = adobe } } ,
+    winfonts   .code:n = { \__sjtu_set_deprecated_option:n { cjk-font = windows } } ,
     math-style .choice: ,
     math-style .value_required:n = true,
     math-style / TeX .code:n =
@@ -157,91 +208,58 @@
       { \bool_gset_false:N \g__sjtu_integral_limits_bool } ,
     integral-limits / true  .code:n =
       { \bool_gset_true:N  \g__sjtu_integral_limits_bool } ,
-    oneside .value_forbidden:n = true,
-    twoside .value_forbidden:n = true,
-    oneside .code:n =
-      { \bool_gset_false:N \g__sjtu_twoside_bool } ,
-    twoside .code:n =
-      { \bool_gset_true:N  \g__sjtu_twoside_bool } ,
-    openany   .value_forbidden:n = true,
-    openright .value_forbidden:n = true,
-    openany   .code:n =
-      { \bool_gset_false:N \g__sjtu_openright_bool } ,
-    openright .code:n =
-      { \bool_gset_true:N  \g__sjtu_openright_bool } ,
-    draft .value_forbidden:n = true,
-    final .value_forbidden:n = true,
-    draft .code:n =
-      { \bool_gset_true:N  \g__sjtu_draft_bool } ,
-    final .code:n =
-      { \bool_gset_false:N \g__sjtu_draft_bool } ,
     review .bool_gset:N = \g__sjtu_review_bool ,
     review .initial:n = false ,
-    unknown .code:n = { \msg_error:nn { sjtutex } { unknown-option } }
+    unknown .code:n =
+      { \clist_gput_right:No \g__sjtu_options_to_ctex_class_clist { \CurrentOption } }
   }
-\msg_new:nnn { sjtutex } { unknown-option }
-  { Class~ option~ "\l_keys_key_tl"~ is~ unknown. }
-\cs_if_exist:NTF \ProcessKeyOptions
-  { \ProcessKeyOptions [ sjtu / option ] }
+\clist_map_inline:nn
+  { GBK, scheme, cap, nocap }
   {
-    \RequirePackage { l3keys2e }
-    \ProcessKeysOptions { sjtu / option }
+    \keys_define:nn { sjtu / option }
+      {
+        #1 .code:n =
+          { \msg_warning:nn { sjtutex } { unsupported-option } }
+      }
   }
-\clist_set:Nx \g__sjtu_math_font_options_clist
+\ProcessKeyOptions [ sjtu / option ]
+\__sjtu_conditional_const:nn { main_lang_de }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { de } }
+\__sjtu_conditional_const:nn { main_lang_ja }
+  { \str_if_eq_p:Vn \g__sjtu_lang_tl { ja } }
+\bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { slantedGreek } }
+\bool_if:NT \g__sjtu_upright_integral_bool
+  { \clist_put_right:Nn \g__sjtu_math_font_options_clist { upint } }
+\clist_put_left:Nn \@classoptionslist { a4paper }
+\__sjtu_if_main_lang_de:T
+  { \clist_put_right:Nn \@classoptionslist { german, ngerman } }
+\bool_if:NTF \g__sjtu_integral_limits_bool
   {
-    \bool_if:NT \g__sjtu_slanted_uppercase_greek_bool
-      { slantedGreek } ,
-    \bool_if:NT \g__sjtu_upright_integral_bool
-      { upint }
+    \clist_put_right:Nn \@classoptionslist { intlimits }
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { displaylimits } { cmupint } }
   }
-\clist_put_right:Nx \@classoptionslist
   {
-    a4paper ,
-    \tl_if_eq:NNT \g__sjtu_lang_tl \c__sjtu_lang_de_tl
-      { german, ngerman } ,
-    \bool_if:NT \g__sjtu_integral_limits_bool
-      { intlimits } ,
-    \g__sjtu_math_font_options_clist
+    \clist_put_right:Nn \g__sjtu_options_to_packages_clist
+      { { nolimits      } { cmupint } }
   }
-\clist_put_right:Nx \g__sjtu_options_to_ctex_class_clist
+\clist_concat:NNN \@classoptionslist
+  \@classoptionslist \g__sjtu_math_font_options_clist
+\cs_set_protected:Npe \__sjtu_setup:n
   {
-    zihao      = \g__sjtu_zihao_tl ,
-    \fp_if_nan:nF { \g__sjtu_line_spread_fp }
-      { linespread = \fp_use:N \g__sjtu_line_spread_fp } ,
-    \bool_if:NTF \g__sjtu_twoside_bool
-      { twoside   } { oneside     } ,
-    \bool_if:NTF \g__sjtu_openright_bool
-      { openright } { openany     } ,
-    \bool_if:NTF \g__sjtu_draft_bool
-      { draft     } { final       }
+    \bool_if:NTF \g__sjtu_review_bool
+      { \exp_not:N \keys_set_exclude_groups:nnn { sjtu } { sensitive } }
+      { \exp_not:N \keys_set:nn { sjtu } }
   }
 \exp_args:No \PassOptionsToClass
   { \g__sjtu_options_to_ctex_class_clist }
   { ctexbook }
-\clist_set:Nx \g__sjtu_options_to_packages_clist
-  {
-    { no-math           } { fontspec     } ,
-    { list = off        } { bicaption    } ,
-    { warnings-off =
-      {
-        mathtools-overbracket,
-        mathtools-colon
-      }
-    }                     { unicode-math } ,
-    { amsmath, thmmarks } { ntheorem     } ,
-    { chapter           } { algorithm    } ,
-    { algochapter       } { algorithm2e  } ,
-    {
-      \bool_if:NTF \g__sjtu_integral_limits_bool
-        { displaylimits } { nolimits }
-    }                     { cmupint      }
-  }
 \clist_map_inline:Nn \g__sjtu_options_to_packages_clist
   { \PassOptionsToPackage #1 }
 \LoadClass { ctexbook }
 \RequirePackage
   {
-    xtemplate,
     array,
     mathtools,
     geometry,
@@ -254,189 +272,27 @@
     graphicx,
     enumitem
   }
-\cs_generate_variant:Nn \cs_gset:Npn { cpo }
-\cs_generate_variant:Nn \tl_const:Nn { Nv }
-\cs_generate_variant:Nn \clist_use:Nn { NV, cv }
-\exp_args_generate:n { Nnv }
-\cs_generate_variant:Nn \exp_last_unbraced:Ne { ce }
-\prg_generate_conditional_variant:Nnn \regex_match:nn { ne } { T, TF }
-\cs_new:Npx \__sjtu_engine_case:nn #1#2
-  {
-    \bool_lazy_or:nnTF
-      { \sys_if_engine_xetex_p:  }
-      { \sys_if_engine_luatex_p: }
-      {#2}
-      { \sys_if_engine_pdftex:T {#1} }
-  }
-\cs_new:Npx \__sjtu_engine_case:nnn #1#2#3
-  {
-    \sys_if_engine_xetex:TF
-      {#2}
-      {
-        \sys_if_engine_luatex:TF
-          {#3}
-          { \sys_if_engine_pdftex:T {#1} }
-      }
-  }
-\cs_new:Npx \__sjtu_unicode_engine_case:nn #1#2
-  {
-    \sys_if_engine_xetex:TF
-      {#1}
-      { \sys_if_engine_luatex:T {#2} }
-  }
-\__sjtu_engine_case:nn
-  {
-    \cs_new:Npn \__sjtu_unicode_char:n #1
-      {
-        \exp_not:N \Unicode
-          { \int_div_truncate:nn {#1} { 256 } }
-          { \int_mod:nn          {#1} { 256 } }
-      }
-  }
-  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
-\cs_new:Npn \__sjtu_dim_set_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l__sjtu_tmp_box {#2}
-    \dim_set:Nn #1 { \box_wd:N \l__sjtu_tmp_box }
-  }
-\cs_new:Npn \__sjtu_skip_add_to_wd:Nn #1#2
-  {
-    \hbox_set:Nn \l__sjtu_tmp_box {#2}
-    \skip_add:Nn #1 { \box_wd:N \l__sjtu_tmp_box }
-  }
-\cs_generate_variant:Nn \__sjtu_dim_set_to_wd:Nn { Nv }
-\cs_generate_variant:Nn \__sjtu_skip_add_to_wd:Nn { cv }
-\cs_new:Npn \__sjtu_cs_provide_eq:NN #1#2
-  { \cs_if_exist:NF #1 { \cs_set_eq:NN #1 #2 } }
-\cs_generate_variant:Nn \__sjtu_cs_provide_eq:NN { cc }
-\cs_new_protected:Npn \__sjtu_vspace:N #1
-  {
-    \skip_vertical:N #1
-    \skip_vertical:N \c_zero_skip
-  }
-\cs_new_protected:Npn \__sjtu_vspace:n #1
-  {
-    \skip_set:Nn \l__sjtu_tmp_skip {#1}
-    \__sjtu_vspace:N \l__sjtu_tmp_skip
-  }
-\cs_new_protected:Npn \__sjtu_vspace_r:N #1
-  {
-    \dim_set_eq:NN \l__sjtu_tmp_dim \prevdepth
-    \hrule height \c_zero_dim
-    \nobreak
-    \skip_vertical:N #1
-    \skip_vertical:N \c_zero_skip
-    \dim_set_eq:NN \prevdepth \l__sjtu_tmp_dim
-  }
-\cs_new_protected:Npn \__sjtu_vspace_r:n #1
-  {
-    \skip_set:Nn   \l__sjtu_tmp_skip {#1}
-    \__sjtu_vspace_r:N \l__sjtu_tmp_skip
-  }
-\cs_new_protected:Npn \__sjtu_define_name:nn #1#2
-  { \tl_const:cn { c__sjtu_name_ #1 _tl } {#2} }
-\cs_new_protected:Npn \__sjtu_define_name:nnn #1#2#3
-  { \tl_const:cn { c__sjtu_name_ #2 _ #1 _tl } {#3} }
-\cs_new_protected:Npn \__sjtu_define_name_from_clist:nnnn #1#2#3#4
-  { \tl_const:cx { c__sjtu_name_ #2 _ #1 _tl } { \clist_item:nn {#4} {#3} } }
-\cs_generate_variant:Nn \__sjtu_define_name:nn { nv }
-\cs_new_protected:Npn \__sjtu_define_symbol:nn #1#2
-  { \tl_const:cx { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
-\cs_new_protected:Npn \__sjtu_if_lang_valid:nTF #1
-  { \clist_if_in:NnTF \g__sjtu_lang_clist {#1} }
-\msg_new:nnn { sjtutex } { lang-validation }
-  { Invalid~ language~ argument~ `#1'! }
-\DeclareObjectType { sjtu } { 0 }
-\DeclareTemplateInterface { sjtu } { component } { 0 }
-  {
-    format      : tokenlist = \c_empty_tl ,
-    content     : tokenlist = \c_empty_tl ,
-    bottom-skip : skip      = \c_zero_skip ,
-    align       : choice { left, right, center, normal } = center
-  }
-\DeclareTemplateCode { sjtu } { component } { 0 }
-  {
-    format      = \l__sjtu_component_format_tl ,
-    content     = \l__sjtu_component_content_tl ,
-    bottom-skip = \l__sjtu_component_bottom_skip ,
-    align       =
-      {
-        left    =
-          \cs_set_eq:NN \l__sjtu_component_align: \raggedright ,
-        right   =
-          \cs_set_eq:NN \l__sjtu_component_align: \raggedleft ,
-        center  =
-          \cs_set_eq:NN \l__sjtu_component_align: \centering ,
-        normal  =
-          \cs_set_eq:NN \l__sjtu_component_align: \prg_do_nothing:
-      }
-  }
-  {
-    \AssignTemplateKeys
-    \group_begin:
-      \l__sjtu_component_align:
-      \l__sjtu_component_format_tl
-      \l__sjtu_component_content_tl
-      \par
-    \group_end:
-    \__sjtu_vspace:N \l__sjtu_component_bottom_skip
-  }
-\DeclareTemplateInterface { sjtu } { page } { 0 }
-  {
-    bookmark      : boolean   = false ,
-    bookmark-text : tokenlist = \c_empty_tl ,
-    style         : tokenlist = empty ,
-    format        : tokenlist = \c_empty_tl ,
-    prefix        : tokenlist ,
-    components    : commalist ,
-    top-skip      : skip      = \c_zero_skip ,
-    bottom-skip   : skip      = \c_zero_skip
-  }
-\DeclareTemplateCode { sjtu } { page } { 0 }
-  {
-    bookmark      = \l__sjtu_page_bookmark_bool ,
-    bookmark-text = \l__sjtu_page_bookmark_text_tl ,
-    style         = \l__sjtu_page_style_tl ,
-    format        = \l__sjtu_page_format_tl ,
-    prefix        = \l__sjtu_page_prefix_tl ,
-    components    = \l__sjtu_page_components_clist ,
-    top-skip      = \l__sjtu_page_top_skip ,
-    bottom-skip   = \l__sjtu_page_bottom_skip
-  }
-  {
-    \AssignTemplateKeys
-    \bool_if:NTF \g__sjtu_openright_bool
-      { \cleardoublepage } { \clearpage }
-    \bool_if:NT \l__sjtu_page_bookmark_bool
-      { \__sjtu_pdf_bookmark:nn { 0 } { \l__sjtu_page_bookmark_text_tl } }
-    \exp_args:No \thispagestyle { \l__sjtu_page_style_tl }
-    \__sjtu_vspace_r:N \l__sjtu_page_top_skip
-    \__sjtu_vspace:n { - \tex_parskip:D      }
-    \__sjtu_vspace:n { - \tex_baselineskip:D }
-    \group_begin:
-      \l__sjtu_page_format_tl
-      \clist_map_inline:Nn \l__sjtu_page_components_clist
-        { \UseInstance { sjtu } { \l__sjtu_page_prefix_tl / ##1 } }
-    \group_end:
-    \__sjtu_vspace:N \l__sjtu_page_bottom_skip
-    \clearpage
-  }
-\cs_new:Npn \__sjtu_declare_component:nnn #1#2#3
-  { \DeclareInstance { sjtu } {#1/#2} { component } {#3} }
-\cs_new:Npn \__sjtu_declare_page:nn #1#2
-  { \DeclareInstance { sjtu } {#1} { page } {#2} }
+\normalsize
+\cs_set_protected:Npe \SJTU at orig@normalsize
+  { \exp_not:N \fontsize { \f at size } { \f at baselineskip } \exp_not:N \selectfont }
+\msg_new:nnn { sjtutex } { baselineskip-invalid }
+  { Invalid~baselineskip~value~'#1'! \\ Using~default~value~instead. }
 \cs_new_protected:Npn \__sjtu_set_font_size:nnNn #1#2#3#4
   { \cs_set_protected:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } }
-\tl_set:Nx \l__sjtu_font_size_tl
-  {
-    { \dim_to_decimal:n { \g__sjtu_font_size_dim     } }
-    { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } }
-  }
 \bool_if:NT \g__sjtu_fixed_baselineskip_bool
   {
-    \int_case:nn { \g__sjtu_font_size_int }
+    \dim_compare:nNnTF { \f at size pt } > { \g__sjtu_baseline_skip_dim }
       {
-        { 1 } {
+        \msg_warning:nne { sjtutex } { baselineskip-invalid }
+          { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } pt }
+      }
+      {
+        \tl_set:Ne \l__sjtu_font_size_tl
+          { { \f at size } { \dim_to_decimal:n { \g__sjtu_baseline_skip_dim } } }
+        \int_case:nn { \@ptsize }
+          {
+            { 0 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
@@ -447,10 +303,23 @@
                     \let\@listi\@listI
                   }
               }
-        { 2 } {
+            { 1 }
+              {
                 \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
                   \normalsize
                   {
+                    \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+                    \abovedisplayshortskip \z@ \@plus3\p@
+                    \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+                    \belowdisplayskip \abovedisplayskip
+                    \let\@listi\@listI
+                  }
+              }
+            { 2 }
+              {
+                \exp_after:wN \__sjtu_set_font_size:nnNn \l__sjtu_font_size_tl
+                  \normalsize
+                  {
                     \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
                     \abovedisplayshortskip \z@ \@plus3\p@
                     \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
@@ -458,22 +327,18 @@
                     \let\@listi\@listI
                   }
               }
+          }
+        \normalsize
       }
-    \normalsize
   }
 \NewDocumentCommand \setbaselineskip { m }
   { \fontsize { \f at size } {#1} \selectfont }
+\msg_new:nnn { sjtutex } { font-unavailable }
+  { '#1-font~=~#2'~is~unavailable~in~current~mode. }
 \cs_new_protected:Npn \__sjtu_fontset_error:nn #1#2
-  { \msg_error:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
-\msg_new:nnn { sjtutex } { font-unavailable }
-  { `#1-font~ =~ #2'~ is~ unavailable~ in~ current~ mode. }
-\cs_new_eq:NN \__sjtu_fontset_case:nn \__sjtu_engine_case:nn
-\cs_new:Npx \__sjtu_fontset_case:nnn #1#2#3
-  {
-    \__sjtu_engine_case:nn
-      { \sys_if_output_pdf:TF {#1} {#2} }
-      {#3}
-  }
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } {#1} {#2} }
+\cs_set_protected:Npn \ctex_fontset_error:n #1
+  { \msg_critical:nnnn { sjtutex } { font-unavailable } { cjk } {#1} }
 \cs_new_protected:Nn \__sjtu_declare_math_symbol:nnNn
   {
     \cs_undefine:N #3
@@ -515,9 +380,14 @@
           { \tl_gset:Nn \g__sjtu_cjk_font_tl { fandol } }
       }
   }
+\msg_new:nnn { sjtutex } { invalid-font }
+  {
+    Invalid~value~'#1-font~=~\tl_use:c { g__sjtu_ #1 _font_tl }'! \\
+    Using~'#2'~instead.
+  }
 \cs_new_protected:Npn \__sjtu_load_font:nn #1#2
   {
-    \str_if_eq:eeF { \tl_use:c { g__sjtu_ #1 _font_tl } } { none }
+    \str_if_eq:vnF { g__sjtu_ #1 _font_tl } { none }
       {
         \file_if_exist:nF
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
@@ -529,11 +399,6 @@
           { sjtu- #1 -font- \tl_use:c { g__sjtu_ #1 _font_tl } .def }
       }
   }
-\msg_new:nnn { sjtutex } { invalid-font }
-  {
-    Invalid~ value~ `#1-font~ =~ \tl_use:c { g__sjtu_ #1 _font_tl }~ '! \\\\
-    Using~ `#2'~ instead.
-  }
 \cs_new_protected:Nn \__sjtu_load_fontset:
   {
     \clist_map_inline:nn
@@ -564,25 +429,47 @@
         \scpolint\npolint\pointint\sqint\intlarhk\intx
         \intcap\intcup\upint\lowint
       }
+    \clist_map_inline:nn
+      { amsfonts, amssymb, bm, upgreek }
+      { \__sjtu_disable_package_load:n {#1} }
   }
 \ctex_at_end_preamble:n
   {
-    \@ifpackageloaded { unicode-math }
-      { } { \RequirePackage { bm } }
+    \IfPackageLoadedF { unicode-math }
+      {
+        \RequirePackage { bm }
+        \cs_if_exist:NF \uppi
+          { \RequirePackage { upgreek  } }
+        \cs_if_exist:NF \checkmark
+          { \RequirePackage { amsfonts } }
+      }
   }
 \NewDocumentCommand \CJKrmfamily { } { \CJKfamily { \CJKrmdefault } }
 \NewDocumentCommand \CJKsffamily { } { \CJKfamily { \CJKsfdefault } }
 \NewDocumentCommand \CJKttfamily { } { \CJKfamily { \CJKttdefault } }
-\__sjtu_unicode_engine_case:nn
+\sys_if_engine_xetex:T
   {
     \xeCJK_declare_char_class:nn { CJK }
       { "24EA, "2460->"2473, "3251->"32BF, "25A1 }
   }
+\sys_if_engine_luatex:T
   {
     \ltjdefcharrange { 99 }
-      { "24EA, "2460-"2473, "3251-"32BF, "25A1 }
+      { "24EA, "2460- "2473, "3251- "32BF, "25A1 }
     \ltjsetparameter { jacharrange = { +99 } }
   }
+\sys_if_engine_pdftex:TF
+  {
+    \cs_new:Npn \__sjtu_unicode_char:n #1
+      {
+        \exp_not:N \Unicode
+          { \int_div_truncate:nn {#1} { 256 } }
+          { \int_mod:nn          {#1} { 256 } }
+      }
+  }
+  { \cs_new:Npn \__sjtu_unicode_char:n #1 { \tex_Uchar:D #1 \scan_stop: } }
+\cs_new_protected:Npn \__sjtu_symbol_const:nn #1#2
+  { \tl_const:ce { c__sjtu_symbol_ #1 _tl } { \__sjtu_unicode_char:n {#2} } }
 \__sjtu_load_fontset:
 \keys_define:nn { sjtu / name }
   {
@@ -618,11 +505,6 @@
     achv           .tl_set:N = \SJTU at achvname ,
     achv          .initial:n = { List~of~Research~Achievements },
   }
-\clist_map_inline:Nn \g__sjtu_lang_clist
-  { \file_input:n { sjtu-name-thesis- #1 .def } }
-\clist_map_inline:nn
-  { title_page, declaration, abstract }
-  { \__sjtu_define_name:nv {#1} { c__sjtu_name_ #1 _ \g__sjtu_lang_tl _tl } }
 \geometry
   {
     top           = 3.5 cm,
@@ -657,22 +539,37 @@
     header-uppercase      .initial:n = { false }
   }
 \cs_generate_variant:Nn \__sjtu_nouppercase:n { V }
-\cs_new:Nn \__sjtu_thepage: { \thepage }
+\tl_set:Nn \__sjtu_the_page_tl { \thepage }
+\tl_new:N \__sjtu_the_last_page_tl
+\msg_new:nnn { sjtutex } { require-pageslts }
+  {
+    Add~'\token_to_str:N \usepackage{pageslts}'~in~your~preamble \\
+    to~enable~the~page~number~of~the~last~page.
+  }
 \keys_define:nn { sjtu / style }
   {
-    page-number .cs_set:Np = \__sjtu_page:n #1 ,
+    page-number    .code:n =
+      {
+        \regex_match:nnT { \#2 } { #1 }
+          {
+            \ctex_if_preamble:TF
+              { \RequirePackage { pageslts } }
+              {
+                \IfPackageLoadedF { pageslts }
+                  { \msg_warning:nn { sjtutex } { require-pageslts } }
+              }
+          }
+        \cs_set:Nn \__sjtu_page:nn { #1 }
+      } ,
     page-number .initial:n = { {#1} }
   }
 \tl_set:Nn \l__sjtu_header_tl
   {
-    {
-      \__sjtu_set_cjk_default_zh: \normalfont
-      \l__sjtu_info_subject_zh_tl
-    }
+    { \songti \l__sjtu_info_subject_zh_tl }
   }
 \tl_set:Nn \l__sjtu_leftmark_tl  { \leftmark }
 \tl_set:Nn \l__sjtu_rightmark_tl { \leftmark }
-\bool_if:NTF \g__sjtu_twoside_bool
+\legacy_if:nTF { @twoside }
   {
     \fancyhead [ LO, RE ] { \l__sjtu_header_tl }
     \fancyhead [ LE ]     { \__sjtu_nouppercase:V \l__sjtu_leftmark_tl  }
@@ -682,8 +579,9 @@
     \fancyhead [ L ] { \l__sjtu_header_tl }
     \fancyhead [ R ] { \__sjtu_nouppercase:V \l__sjtu_rightmark_tl }
   }
-\fancyfoot [ C ] { \__sjtu_page:n { \__sjtu_thepage: } }
-\cs_set:Npn \headrule
+\fancyfoot [ C ]
+  { \__sjtu_page:nn { \__sjtu_the_page_tl } { \__sjtu_the_last_page_tl } }
+\tl_set:Nn \headrule
   {
     \hrule height 2.25 pt width \headwidth
     \skip_vertical:n {  0.75 pt }
@@ -694,7 +592,7 @@
 \RenewDocumentCommand \cleardoublepage { }
   {
     \clearpage
-    \bool_if:NT \g__sjtu_twoside_bool
+    \legacy_if:nT { @twoside }
       {
         \int_if_odd:nF \c at page
           { \hbox:n { } \thispagestyle { empty } \newpage }
@@ -759,24 +657,6 @@
     indent-first   .default:n = { true } ,
     indent-first   .initial:n = { true }
   }
-\NewDocumentCommand \SJTU at head { s O{#3} m O{#2} }
-  {
-    \CTEX at chapter@break
-    \IfBooleanTF {#1}
-      { \tl_if_empty:nF {#4} { \__sjtu_pdf_bookmark:nn { 0 } {#4} } }
-      {
-        \__sjtu_phantom_section:
-        \addcontentsline { toc } { chapter } {#4}
-      }
-    \cs_set_eq:NN \__sjtu_orig_ctex_gettitle:n \CTEX at gettitle
-    \cs_set:Npn \CTEX at gettitle ##1 { \__sjtu_orig_ctex_gettitle:n {#2} }
-    \chapter* {#3}
-    \cs_set_eq:NN \CTEX at gettitle \__sjtu_orig_ctex_gettitle:n
-    \@mkboth { \MakeUppercase {#2} } { \MakeUppercase {#2} }
-  }
-\cs_new:Npn \__sjtu_head_aux_s:nn #1#2
-  { \SJTU at head* [#1] {#2} }
-\cs_generate_variant:Nn \__sjtu_head_aux_s:nn { nx }
 \cs_new_eq:NN \__sjtu_pdf_bookmark:nn \use_none:nn
 \cs_new_eq:NN \__sjtu_phantom_section: \prg_do_nothing:
 \setlist { nosep }
@@ -783,8 +663,7 @@
 \keys_define:nn { sjtu / style }
   {
     equation-font  .tl_set:N = \SJTU at style@equation at font ,
-    equation-font .initial:x = \exp_not:N \linespread { }
-                               \exp_not:N \zihao { \g__sjtu_zihao_tl }
+    equation-font .initial:n = \linespread { } \SJTU at orig@normalsize
   }
 \clist_map_inline:nn
   {
@@ -878,7 +757,7 @@
         \@addtoreset {#4} {#5}
         \IfBooleanF {#1}
           {
-            \cs_gset:cpo { the #4 }
+            \exp_args:Nco \cs_gset:Npn { the #4 }
               { \cs:w the #5 \cs_end: #2 #3 {#4} }
           }
       }
@@ -888,10 +767,9 @@
 \SJTU at counterwithin [ \SJTU at style@eq at num@sep ] { equation } { chapter }
 \clist_set:Nn \l__sjtu_counter_without_chapter_clist
   { section, figure, table, equation }
-\cs_set_eq:NN \__sjtu_makefnmark_plain: \@makefnmark
-\cs_set_eq:NN \__sjtu_thefootnote_plain: \thefootnote
-\cs_set_eq:NN \__sjtu_thempfootnote_plain: \thempfootnote
-\cs_new:Npn \__sjtu_footnote_number:N #1
+\msg_new:nnn { sjtutex } { circled-number-exceed }
+  { Circled~number~exceed~50! }
+\cs_new:Npn \__sjtu_circled_number:N #1
   {
     \int_compare:nNnTF {#1} < { 21 }
       { \__sjtu_unicode_char:n { \int_eval:n { "2460 - 1 + #1 } } }
@@ -901,20 +779,19 @@
           {
             \int_compare:nNnTF {#1} < { 51 }
               { \__sjtu_unicode_char:n { \int_eval:n { "32B1 - 36 + #1 } } }
-              { \msg_warning:nn { sjtutex } { too-many-footnotes } }
+              {
+                \msg_warning:nn { sjtutex } { circled-number-exceed }
+                \int_to_arabic:n {#1}
+              }
           }
       }
   }
-\msg_new:nnn { sjtutex } { too-many-footnotes }
-  { Too~ many~ footnotes. }
-\cs_new:Nn \__sjtu_makefnmark_circled: { \hbox:n { \@thefnmark } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-font           .choice: ,
     fnmark-font / haranoaji .code:n =
       {
-        \__sjtu_engine_case:nn
-          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
+        \__sjtu_if_engine_opentype:TF
           {
             \tl_set:Nn \l__sjtu_style_fnmark_font_tl
               {
@@ -926,52 +803,83 @@
                   ]
               }
           }
+          { \tl_set_eq:NN \l__sjtu_style_fnmark_font_tl \c_empty_tl }
       } ,
     fnmark-font / unknown .tl_set:N = \l__sjtu_style_fnmark_font_tl ,
     fnmark-font          .initial:V = \c_empty_tl
   }
-\cs_new:Nn \__sjtu_thefootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at footnote } }
-\cs_new:Nn \__sjtu_thempfootnote_circled:
-  { { \l__sjtu_style_fnmark_font_tl \__sjtu_footnote_number:N \c at mpfootnote } }
 \keys_define:nn { sjtu / style }
   {
     fnmark-style           .choice: ,
     fnmark-style / plain   .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_plain:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_plain:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_plain:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@textsuperscript { \normalfont \@thefnmark } } }
+        \tl_set:Nn \thefootnote
+          { \arabic { footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \itshape \alph { mpfootnote } } }
       } ,
     fnmark-style / circled .code:n =
       {
-        \cs_set_eq:NN \__sjtu_makefnmark: \__sjtu_makefnmark_circled:
-        \cs_set_eq:NN \thefootnote \__sjtu_thefootnote_circled:
-        \cs_set_eq:NN \thempfootnote \__sjtu_thempfootnote_circled:
+        \cs_set:Npn \SJTU at makefnmark
+          { \hbox:n { \@thefnmark } }
+        \tl_set:Nn \thefootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at footnote } }
+        \tl_set:Nn \thempfootnote
+          { { \l__sjtu_style_fnmark_font_tl \__sjtu_circled_number:N \c at mpfootnote } }
       }
   }
-\ctex_at_end_preamble:n {
-  \cs_set_eq:NN \__sjtu_orig_make_fntext:n \@makefntext
-  \cs_set:Npn \@makefntext #1
-    {
-      \group_begin:
-        \cs_set_eq:NN \@makefnmark \__sjtu_makefnmark:
-        \__sjtu_orig_make_fntext:n {#1}
-      \group_end:
-    }
-}
-\cs_new:Npn \__sjtu_info_keys_define:n #1
+\ctex_at_end_preamble:n
   {
+    \cs_set_eq:NN \SJTU at orig@makefntext \@makefntext
+    \cs_set:Npn \@makefntext #1
+      {
+        \group_begin:
+          \cs_set_eq:NN \@makefnmark \SJTU at makefnmark
+          \SJTU at orig@makefntext {#1}
+        \group_end:
+      }
+  }
+\tl_set_eq:NN \l__sjtu_lang_tl \g__sjtu_lang_tl
+\msg_new:nnn { sjtutex } { lang-validation }
+  { Invalid~language~argument~'#1'! }
+\keys_define:nn { sjtu / private }
+  {
+    lang .choice: ,
+    lang .value_required:n = true ,
+    lang .groups:n = { lang } ,
+    lang / unknown .code:n =
+      { \msg_warning:nnn { sjtutex } { lang-validation } {#1} }
+  }
+\cs_new_protected:Npn \__sjtu_select_language:n
+  { \keys_set_groups:nnn { sjtu / private } { lang } }
+\clist_map_inline:Nn \g__sjtu_lang_clist
+  { \file_input:n { sjtu-lang- #1 .def } }
+\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
+\msg_new:nnn { sjtutex } { key-already-defined }
+  { Key~'#1'~is~already~defined~and~redefination~is~being~ignored. }
+\msg_new:nnn { sjtutex } { key-invalid }
+  { Key~'#1'~is~invalid~and~ignored. }
+\msg_new:nnn { sjtutex } { key-needs-two-arguments }
+  { Key~'#1'~needs~two~arguments~otherwise~ignored. }
+\cs_new_protected:Npn \__sjtu_info_keys_define:n #1
+  {
     \clist_map_inline:nn
       {
-        title, display_title, subject, author, date,
-        supervisor, assoc_supervisor, department,
-        co_supervisor, major, degree
+        title, display_title, subject, date, department, major,
+        author, supervisor, assoc_supervisor, co_supervisor, degree
       }
       { \tl_new:c { l__sjtu_info_ ##1 _ #1 _tl } }
     \clist_map_inline:nn
       { keywords, fund }
       { \clist_new:c { l__sjtu_info_ ##1 _ #1 _clist } }
+    \bool_if:NTF \g__sjtu_review_bool
+      {
+        \seq_set_from_clist:cn { l__sjtu_info_show_ #1 _seq }
+          { author, id, supervisor, department, major, degree }
+      }
+      { \seq_new:c { l__sjtu_info_show_ #1 _seq } }
     \keys_define:nn { sjtu }
       { info / #1 .meta:nn = { sjtu / info / #1 } {##1} }
     \keys_define:nn { sjtu / info }
@@ -978,73 +886,119 @@
       {        #1 .meta:nn = { sjtu / info / #1 } {##1} }
     \keys_define:nn { sjtu / info / #1 }
       {
+        display-title       .code:n =
+          {
+            \tl_set:co { l__sjtu_info_display_title_ #1 _tl }
+              { \cs:w __sjtu_title_case_aux_ #1 :n \cs_end: {##1} }
+          } ,
         title               .code:n =
           {
             \tl_set:cn { l__sjtu_info_title_ #1 _tl } {##1}
             \tl_if_empty:cT { l__sjtu_info_display_title_ #1 _tl }
-              { \tl_set:cn { l__sjtu_info_display_title_ #1 _tl } {##1} }
+              { \keys_set:nn { sjtu / info / #1 } { display-title = {##1} } }
           } ,
-        display-title     .tl_set:c = l__sjtu_info_display_title_ #1 _tl ,
-        subject           .tl_set:c = l__sjtu_info_subject_ #1 _tl ,
-        keywords       .clist_set:c = l__sjtu_info_keywords_ #1 _clist ,
-        author            .tl_set:c = l__sjtu_info_author_ #1 _tl ,
-        id                 .meta:nn = { sjtu / info } { id = {##1} } ,
-        supervisor        .tl_set:c = l__sjtu_info_supervisor_ #1 _tl ,
-        assoc-supervisor  .tl_set:c = l__sjtu_info_assoc_supervisor_ #1 _tl ,
-        co-supervisor     .tl_set:c = l__sjtu_info_co_supervisor_ #1 _tl ,
-        degree            .tl_set:c = l__sjtu_info_degree_ #1 _tl ,
-        department        .tl_set:c = l__sjtu_info_department_ #1 _tl ,
-        major             .tl_set:c = l__sjtu_info_major_ #1 _tl ,
-        fund           .clist_set:c = l__sjtu_info_fund_ #1 _clist ,
+        subject           .tl_set:c = { l__sjtu_info_subject_ #1 _tl } ,
+        keywords       .clist_set:c = { l__sjtu_info_keywords_ #1 _clist } ,
+        fund           .clist_set:c = { l__sjtu_info_fund_ #1 _clist } ,
+        fund              .groups:n = { sensitive } ,
         date               .meta:nn = { sjtu / info } { date = {##1} } ,
-        display-date      .tl_set:c = l__sjtu_info_date_ #1 _tl ,
+        display-date      .tl_set:c = { l__sjtu_info_date_ #1 _tl } ,
+        @show+              .code:n =
+          {
+            \seq_if_in:cnF { l__sjtu_info_show_ #1 _seq } {##1}
+              { \seq_put_right:cn { l__sjtu_info_show_ #1 _seq } {##1} }
+          } ,
+        @show+            .groups:n = { sensitive } ,
+        custom             .meta:nn = { sjtu / info / #1 / custom } {##1} ,
+        custom / unknown    .code:n =
+          {
+            \regex_match:nVTF { \A [a-z] [a-z0-9\-]* \Z } \l_keys_key_str
+              {
+                \keys_if_exist:neTF { sjtu / info / #1 } \l_keys_key_str
+                  {
+                    \msg_warning:nne { sjtutex } { key-already-defined }
+                      \l_keys_path_str
+                  }
+                  {
+                    \int_compare:nNnTF { \tl_count:n {##1} } = { 2 }
+                      {
+                        \tl_set_eq:NN \l__sjtu_tmp_tl \l_keys_key_str
+                        \tl_replace_all:Nnn \l__sjtu_tmp_tl { - } { _ }
+                        \tl_set:co { l__sjtu_name_ \l__sjtu_tmp_tl _ #1 _tl }
+                          { \use_i:nn  ##1 }
+                        \tl_set:co { l__sjtu_info_ \l__sjtu_tmp_tl _ #1 _tl }
+                          { \use_ii:nn ##1 }
+                        \exp_args:Ne \__sjtu_setup:n
+                          { info / #1 / @show+ = \l__sjtu_tmp_tl }
+                      }
+                      {
+                        \msg_warning:nne { sjtutex } { key-needs-two-arguments }
+                          \l_keys_path_str
+                      }
+                  }
+              }
+              { \msg_warning:nne { sjtutex } { key-invalid } \l_keys_path_str }
+          }
       }
+    \clist_map_inline:nn
+      {
+        author, supervisor, assoc-supervisor, co-supervisor,
+        department, major, degree
+      }
+      {
+        \tl_set:Nn \l__sjtu_tmp_tl {##1}
+        \tl_replace_all:Nnn \l__sjtu_tmp_tl { - } { _ }
+        \keys_define:ne { sjtu / info / #1 }
+          {
+            ##1 .code:n =
+              {
+                \exp_not:N \tl_set:cn
+                  { l__sjtu_info_ \l__sjtu_tmp_tl _ #1 _tl } {####1}
+                \exp_not:N \__sjtu_setup:n
+                  { info / #1 / @show+ = \l__sjtu_tmp_tl }
+              }
+          }
+      }
+    \clist_map_inline:nn
+      { author, supervisor, assoc-supervisor, co-supervisor }
+      { \keys_define:nn { sjtu / info / #1 } { ##1 .groups:n = { sensitive } } }
   }
 \tl_new:N \l__sjtu_info_id_zh_tl
 \keys_define:nn { sjtu / info }
-  { id   .tl_set:N = \l__sjtu_info_id_zh_tl }
-\clist_set:Nn \l__sjtu_info_supervisors_clist { supervisor }
-\ctex_at_end_preamble:n
   {
-    \bool_if:NT \g__sjtu_review_bool
+    id   .code:n =
       {
-        \clist_map_inline:Nn \g__sjtu_lang_clist
-          {
-            \clist_map_inline:nn
-              { author, supervisor, assoc_supervisor, co_supervisor }
-              { \tl_clear:c { l__sjtu_info_ ##1 _ #1 _tl } }
-            \clist_clear:c { l__sjtu_info_fund_ #1 _clist }
-          }
-        \tl_clear:N \l__sjtu_info_id_zh_tl
-      }
+        \tl_set:Nn \l__sjtu_info_id_zh_tl {#1}
+        \__sjtu_setup:n { info / zh / @show+ = id }
+      } ,
+    id .groups:n = { sensitive }
   }
 \clist_map_inline:Nn \g__sjtu_lang_clist
-  { \file_input:n { sjtu-lang-thesis- #1 .def } }
-\file_input:n { sjtu-scheme- \g__sjtu_lang_tl .def }
+  { \__sjtu_info_keys_define:n {#1} }
 \keys_define:nn { sjtu / info }
   {
     date    .code:n =
       {
-        \regex_match:neTF { \d+-\d+-\d+ } {#1}
+        \regex_match:nnTF { \A \d+ \- \d+ \- \d+ \Z } {#1}
           {
             \clist_map_inline:Nn \g__sjtu_lang_clist
               {
-                \tl_set:cx { l__sjtu_info_date_ ##1 _tl }
+                \tl_set:ce { l__sjtu_info_date_ ##1 _tl }
                   { \exp_last_unbraced:ce { __sjtu_date_aux_ ##1 :w } #1 \q_stop }
               }
           }
           {
-            \regex_match:neT { \d+-\d+ } {#1}
+            \regex_match:nnT { \A \d+ \- \d+ \Z } {#1}
               {
                 \clist_map_inline:Nn \g__sjtu_lang_clist
                   {
-                    \tl_set:cx { l__sjtu_info_date_ ##1 _tl }
+                    \tl_set:ce { l__sjtu_info_date_ ##1 _tl }
                       { \exp_last_unbraced:ce { __sjtu_date_aux_short_ ##1 :w } #1 \q_stop }
                   }
               }
           }
       } ,
-    date .initial:x =
+    date .initial:e =
       {
         \int_to_arabic:n { \c_sys_year_int  } -
         \int_to_arabic:n { \c_sys_month_int } -
@@ -1051,97 +1005,274 @@
         \int_to_arabic:n { \c_sys_day_int   }
       }
   }
-\tl_set:Nv \today { l__sjtu_info_date_ \g__sjtu_lang_tl _tl }
-\__sjtu_engine_case:nnn
+\tl_set_eq:Nc \today { l__sjtu_info_date_ \g__sjtu_lang_tl _tl }
+\NewTemplateType { sjtu / element } { 0 }
+\DeclareTemplateInterface { sjtu / element } { plain } { 0 }
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
+    format      : tokenlist = \c_empty_tl ,
+    content     : tokenlist = \c_empty_tl ,
+    bottom-skip : skip      = \c_zero_skip ,
+    align       : choice { left, right, center, normal } = center
+  }
+\DeclareTemplateCode { sjtu / element } { plain } { 0 }
+  {
+    format      = \l__sjtu_element_format_tl ,
+    content     = \l__sjtu_element_content_tl ,
+    bottom-skip = \l__sjtu_element_bottom_skip ,
+    align       =
       {
-        \mode_leave_vertical:
-        \bool_set_false:N \l__sjtu_tmp_bool
-        \cs_set_eq:NN \SJTU at CJK@FTS at Symbol \CJKsymbol
-        \cs_set:Npn \CJKsymbol ##1
-          {
-            \bool_if:NTF \l__sjtu_tmp_bool
-              { \hfil \SJTU at CJK@FTS at Symbol { ##1 } }
-              {
-                \SJTU at CJK@FTS at Symbol { ##1 }
-                \bool_set_true:N \l__sjtu_tmp_bool
-              }
-          }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
+        left    =
+          \cs_set_eq:NN \l__sjtu_element_align: \raggedright ,
+        right   =
+          \cs_set_eq:NN \l__sjtu_element_align: \raggedleft ,
+        center  =
+          \cs_set_eq:NN \l__sjtu_element_align: \centering ,
+        normal  =
+          \cs_set_eq:NN \l__sjtu_element_align: \prg_do_nothing:
       }
-      { \egroup }
   }
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
+    \AssignTemplateKeys
+    \group_begin:
+      \l__sjtu_element_align:
+      \l__sjtu_element_format_tl
+      \l__sjtu_element_content_tl
+      \par
+    \group_end:
+    \skip_vertical:N \l__sjtu_element_bottom_skip
+    \skip_vertical:N \c_zero_skip
+  }
+\NewTemplateType { sjtu / page } { 1 }
+\DeclareTemplateInterface { sjtu / page } { title } { 1 }
+  {
+    bookmark : tokenlist ,
+    style    : tokenlist = empty ,
+    format   : tokenlist = \linespread { } \selectfont ,
+    prefix   : tokenlist ,
+    elements : commalist
+  }
+\DeclareTemplateCode { sjtu / page } { title } { 1 }
+  {
+    bookmark = \l__sjtu_page_bookmark_tl ,
+    style    = \l__sjtu_page_style_tl ,
+    format   = \l__sjtu_page_format_tl ,
+    prefix   = \l__sjtu_page_prefix_tl ,
+    elements = \l__sjtu_page_elements_clist
+  }
+  {
+    \tl_set_eq:NN \l__sjtu_page_bookmark_tl \c_novalue_tl
+    \AssignTemplateKeys
+    \group_begin:
+      \__sjtu_select_language:n {#1}
+      \clist_gset_eq:Nc \l__sjtu_info_fund_clist
+        { l__sjtu_info_fund_ \l__sjtu_lang_tl _clist }
+      \legacy_if:nTF { @openright }
+        { \cleardoublepage } { \clearpage }
+      \exp_args:No \tl_if_novalue:nF { \l__sjtu_page_bookmark_tl }
+        { \__sjtu_pdf_bookmark:nn { 0 } { \l__sjtu_page_bookmark_tl } }
+      \exp_args:No \thispagestyle { \l__sjtu_page_style_tl }
+      \l__sjtu_page_format_tl
+      \clist_map_inline:Nn \l__sjtu_page_elements_clist
+        { \UseInstance { sjtu / element } { \l__sjtu_page_prefix_tl / ##1 } }
+    \group_end:
+    \clearpage
+  }
+\cs_new_protected:Npn \__sjtu_declare_element_instance:nnn #1#2#3
+  { \DeclareInstance { sjtu / element } {#1/#2} { plain } {#3} }
+\cs_new_protected:Npn \__sjtu_declare_page_instance:nnn #1#2
+  { \DeclareInstance { sjtu / page } {#1} { title } {#2} }
+\tl_set:Nn \SJTU at CT@W at width { 5 em }
+\newcolumntype { \SJTU at CT@W } [ 1 ]
+  {
+    w {#1} { \SJTU at CT@W at width }
+    @{ \tl_use:c { c__sjtu_name_info_sep_ \l__sjtu_lang_tl _tl } }
+  }
+\newcolumntype { \SJTU at CT@R }
+  { r @{ \tl_use:c { c__sjtu_name_info_sep_ \l__sjtu_lang_tl _tl } } }
+\newcolumntype { \SJTU at CT@L }
+  { >{ \linespread { 0.75 } \normalfont } l }
+\cs_new:Npn \__sjtu_info_table_row:nn #1#2
+  {
+    \exp_not:n {#1}
+    &
+    \exp_not:N \hbox:n
       {
-        \mode_leave_vertical:
-        \cs_set:Npn \CJKglue
-          { \skip_horizontal:n { \c_zero_dim plus 1 filll } }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
+        \exp_not:N \tabular [ t ] { @{} l @{} }
+          \exp_not:n {#2}
+        \exp_not:N \endtabular
       }
-      { \egroup }
   }
+\cs_generate_variant:Nn \__sjtu_info_table_row:nn { vv }
+\cs_new_protected:Npn \__sjtu_title_page_info_table:n #1
   {
-    \NewDocumentEnvironment { SJTU at CJK@FTS } { m }
+    \group_begin:
+      \clist_clear:N \l__sjtu_tmp_clist
+      \seq_map_inline:cn { l__sjtu_info_show_ \l__sjtu_lang_tl _seq }
+        {
+          \bool_lazy_all:nT
+            {
+              { \tl_if_exist_p:c { l__sjtu_name_ ##1 _ \l__sjtu_lang_tl _tl } }
+              { \tl_if_exist_p:c { l__sjtu_info_ ##1 _ \l__sjtu_lang_tl _tl } }
+            }
+            {
+              \clist_put_right:Ne \l__sjtu_tmp_clist
+                {
+                  \__sjtu_info_table_row:vv
+                    { l__sjtu_name_ ##1 _ \l__sjtu_lang_tl _tl }
+                    { l__sjtu_info_ ##1 _ \l__sjtu_lang_tl _tl }
+                }
+            }
+        }
+      \tl_set:Nn \arraystretch { 1 }
+      \int_set_eq:NN \hbadness \c_max_int
+      \tabular {#1}
+        \clist_use:Nn \l__sjtu_tmp_clist { \\ }
+      \endtabular
+    \group_end:
+  }
+\cs_new:Npn \ps at SJTU@fund
+  {
+    \ps at empty
+    \tl_set:Nn \@oddfoot
       {
-        \mode_leave_vertical:
-        \ltjsetparameter { kanjiskip = { \c_zero_dim plus 1 filll } }
-        \use:e { \exp_not:N \tex_hbox:D to \dim_eval:n {#1} }
-        \bgroup \ignorespaces
+        \hfil
+        \minipage [ t ] { \textwidth }
+          \centering \zihao { - 5 }
+          \clist_use:Nn \l__sjtu_info_fund_clist { \par }
+        \endminipage
+        \hfil
       }
-      { \egroup }
+    \tl_set_eq:NN \@evenfoot \@oddfoot
   }
-\newcolumntype { \SJTU at CT@D } [ 1 ]
-  { > { \begin { SJTU at CJK@FTS } {#1} } c < { \end { SJTU at CJK@FTS } } }
-\cs_new:Npn \__sjtu_title_page_info_i:nnn #1#2#3
+\clist_map_inline:nn
   {
-    \clist_clear:N \l__sjtu_tmp_clist
-    \clist_map_inline:nn {#3}
+    { logo    }
       {
-        \clist_put_right:Nx \l__sjtu_tmp_clist
+        content     =
           {
-            \exp_not:o { \cs:w c__sjtu_name_ ##1 _ #1 _tl \cs_end: }
-            &
-            \exp_not:N \hbox:n
-              {
-                \exp_not:N \tabular [ t ] { @{} l @{} }
-                  \exp_not:o { \cs:w l__sjtu_info_ ##1 _ #1 _tl \cs_end: }
-                \exp_not:N \endtabular
-              }
+            \includegraphics [ width = 3 cm ]
+              { sjtu-vi-badge-reg-red.pdf }
           }
+      } ,
+    { subject }
+      {
+        format      = \zihao { -2 } \setbaselineskip { 30 bp } ,
+        content     = \tl_use:c { l__sjtu_info_subject_ \l__sjtu_lang_tl _tl } ,
+        bottom-skip = \c_zero_dim plus 1 fill
+      } ,
+    { title   }
+      {
+        format      = \zihao { 2 } \setbaselineskip { 36 bp } \bfseries ,
+        content     = \tl_use:c { l__sjtu_info_display_title_ \l__sjtu_lang_tl _tl } ,
+        bottom-skip = 30 bp plus 1 fill
+      } ,
+    { info    }
+      {
+        format      = \zihao { 4 } \setbaselineskip { 30 bp } \heiti ,
+        content     = \__sjtu_title_page_info_table:n
+                        { \SJTU at CT@W { s } \SJTU at CT@L } ,
+        bottom-skip = 30 bp
+      } ,
+    { date    }
+      {
+        format      = \zihao { 4 } \setbaselineskip { 30 bp } \bfseries ,
+        content     = \tl_use:c { l__sjtu_info_date_ \l__sjtu_lang_tl _tl } ,
       }
-    \group_begin:
-      \tl_set:Nn \arraystretch { 1 }
-      \tabular {#2}
-        \clist_use:Nn \l__sjtu_tmp_clist { \\ }
-      \endtabular
-    \group_end:
   }
-\cs_new:Npn \__sjtu_title_page_info_ii:n #1
+  { \__sjtu_declare_element_instance:nnn { title a } #1 }
+\__sjtu_declare_page_instance:nnn { title a }
   {
-    \tl_use:c { l__sjtu_info_department_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { c__sjtu_name_univ_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { c__sjtu_name_address_ #1 _tl }
-    \skip_vertical:N \c_zero_skip
-    \tl_use:c { l__sjtu_info_date_ #1 _tl }
+    bookmark = \tl_use:c { c__sjtu_name_title_page_ \g__sjtu_lang_tl _tl } ,
+    style    = SJTU at fund ,
+    prefix   = title a ,
+    elements = { logo, subject, title, info, date }
   }
-\cs_generate_variant:Nn \__sjtu_title_page_info_i:nnn { nxx }
-\RenewDocumentCommand \maketitle { }
+\clist_map_inline:nn
   {
-    \clist_map_inline:nn
-      { assoc_supervisor, co_supervisor }
+    { subject }
       {
-        \tl_if_empty:cF { l__sjtu_info_ ##1 _zh_tl }
-          { \clist_put_right:Nn \l__sjtu_info_supervisors_clist {##1} }
+        format      = \zihao { 4 } \setbaselineskip { 24 bp } \bfseries ,
+        content     = \tl_use:c { l__sjtu_info_subject_ \l__sjtu_lang_tl _tl } ,
+        bottom-skip = \c_zero_dim plus 1 fill
+      } ,
+    { title   }
+      {
+        format      = \zihao { -2 } \setbaselineskip { 30 bp } \bfseries ,
+        content     = \tl_use:c { l__sjtu_info_display_title_ \l__sjtu_lang_tl _tl } ,
+        bottom-skip = \c_zero_dim plus 1 fill
+      } ,
+    { info    }
+      {
+        format      = \zihao { 3 } \setbaselineskip { 30 bp } \bfseries ,
+        content     = \__sjtu_title_page_info_table:n
+                        { \SJTU at CT@R \SJTU at CT@L } ,
+        bottom-skip = 30 bp plus 1 fill
+      } ,
+    { date    }
+      {
+        format      = \zihao { 3 } \setbaselineskip { 30 bp } ,
+        content     =
+          {
+            \tl_use:c { l__sjtu_info_department_ \l__sjtu_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { c__sjtu_name_univ_ \l__sjtu_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { c__sjtu_name_address_ \l__sjtu_lang_tl _tl }
+            \skip_vertical:N \c_zero_skip
+            \tl_use:c { l__sjtu_info_date_ \l__sjtu_lang_tl _tl }
+          }
       }
+  }
+  { \__sjtu_declare_element_instance:nnn { title b } #1 }
+\__sjtu_declare_page_instance:nnn { title b }
+  {
+    prefix   = title b ,
+    style    = SJTU at fund ,
+    elements = { subject, title, info, date }
+  }
+\clist_map_inline:Nn \g__sjtu_lang_clist
+  { \file_input:n { sjtu-thesis- #1 .def } }
+\RenewDocumentCommand \maketitle { }
+  {
     \clist_map_inline:Nn \g__sjtu_lang_clist
-      { \UseInstance { sjtu } { title / ##1 } }
+      { \UseInstance { sjtu / page } { title / ##1 } { ##1 } }
   }
+\tl_const:Nn \c__sjtu_orig_decl_text_zh_tl
+  {
+    本人郑重声明:所呈交的学位论文,是本人在导师的指导下,独立进行研究工
+    作所取得的成果。除文中已经注明引用的内容外,本论文不包含任何其他个人
+    或集体已经发表或撰写过的作品成果。对本文的研究做出重要贡献的个人和集
+    体,均已在文中以明确方式标明。本人完全知晓本声明的法律后果由本人承
+    担。
+  }
+\tl_const:Nn \c__sjtu_auth_decl_text_zh_tl
+  {
+    本人同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许
+    论文被查阅和借阅。 \par
+    \vskip 6 bp
+    \noindent
+    本学位论文属于: \par
+    { \c__sjtu_symbol_white_square_tl } \, \textbf { 公开论文 } \par
+    { \c__sjtu_symbol_white_square_tl } \, \textbf { 内部论文 },
+      保密 \, { \c__sjtu_symbol_white_square_tl } \, 1 \, 年 \, /
+           \, { \c__sjtu_symbol_white_square_tl } \, 2 \, 年 \, /
+           \, { \c__sjtu_symbol_white_square_tl } \, 3 \, 年,
+      过保密期后适用本授权书。 \par
+    { \c__sjtu_symbol_white_square_tl } \, \textbf { 秘密论文 },
+      保密 \, \underline { \hspace { 2 em } } \, 年(不超过~ 10~ 年),
+      过保密期后适用本授权书。 \par
+    { \c__sjtu_symbol_white_square_tl } \, \textbf { 机密论文 },
+      保密 \, \underline { \hspace { 2 em } } \, 年(不超过~ 20~ 年),
+      过保密期后适用本授权书。 \par
+    \hspace { 6 em }(请在以上方框内选择打“ \ensuremath { \checkmark } ”)
+  }
+\tl_const:Nn \c__sjtu_signature_text_zh_tl
+  {
+    签名: \\
+    日期: \hspace { \stretch { 3 } } 年
+           \hspace { \stretch { 2 } } 月
+           \hspace { \stretch { 2 } } 日
+  }
 \cs_new_protected:Npn \__sjtu_signature:N #1
   {
     \parbox [ t ] { 12 em }
@@ -1215,46 +1346,104 @@
       }
   }
   {
-    \__sjtu_declare_component:nnn { copyright } #1
+    \__sjtu_declare_element_instance:nnn { copyright } #1
   }
-\__sjtu_declare_page:nn { copyright }
+\__sjtu_declare_page_instance:nnn { copyright }
   {
-    bookmark      = true ,
-    bookmark-text = \c__sjtu_name_declaration_tl ,
-    format        = \linespread { } \__sjtu_set_language_zh: ,
-    prefix        = copyright ,
-    components    =
+    bookmark = \tl_use:c { c__sjtu_name_declaration_ \g__sjtu_lang_tl _tl } ,
+    prefix   = copyright ,
+    elements =
       {
         orig / title, orig / text, orig / sign,
         auth / title, auth / text, auth / sign
       }
   }
+\tl_new:N \l__sjtu_copyright_page_file_tl
+\keys_define:nn { sjtu / private / copyright }
+  {
+    file .tl_set:N = \l__sjtu_copyright_page_file_tl ,
+    file .value_required:n = true ,
+    filename .meta:n = { file = #1 }
+  }
 \msg_new:nnn { sjtutex } { require-pdfpages }
   {
-    Add~"\token_to_str:N \usepackage{pdfpages}"~ in~ your~ preamble \\
-    before~ inserting~ pages~ of~ external~ PDF.
+    Add~'\token_to_str:N \usepackage{pdfpages}'~in~your~preamble \\
+    before~inserting~pages~of~external~PDF.
   }
 \NewDocumentCommand \copyrightpage { O{ } }
   {
     \bool_if:NF \g__sjtu_review_bool
       {
-        \tl_if_blank:nTF {#1}
-          { \UseInstance { sjtu } { copyright } }
+        \group_begin:
+          \keys_set_known:nnN { sjtu / private / copyright }
+            {#1} \l__sjtu_tmp_tl
+          \tl_if_empty:NTF \l__sjtu_copyright_page_file_tl
+            { \UseInstance { sjtu / page } { copyright } { zh } }
+            {
+              \cs_if_exist:NTF \includepdf
+                {
+                  \legacy_if:nTF { @openright }
+                    { \cleardoublepage } { \clearpage }
+                  \__sjtu_pdf_bookmark:nn { 0 } { \c__sjtu_name_declaration_tl }
+                  \tl_set_rescan:NnV \l__sjtu_tmp_tl { } \l__sjtu_tmp_tl
+                  \exp_args:NNo \includepdf [ \l__sjtu_tmp_tl ]
+                    { \l__sjtu_copyright_page_file_tl }
+                }
+                {
+                  \msg_warning:nn { sjtutex } { require-pdfpages }
+                  \UseInstance { sjtu / page } { copyright } { zh }
+                }
+            }
+        \group_end:
+      }
+  }
+\bool_new:N \l__sjtu_heading_numbering_bool
+\bool_new:N \l__sjtu_heading_in_toc_bool
+\tl_new:N \l__sjtu_heading_title_tl
+\tl_new:N \l__sjtu_heading_marking_tl
+\AddToHook { cmd / mainmatter / after }
+  { \bool_set_true:N \l__sjtu_heading_in_toc_bool }
+\keys_define:nn { sjtu / private }
+  {
+    intoc    .value_forbidden:n = true,
+    intoc    .groups:n = { heading } ,
+    intoc    .code:n = { \bool_set_true:N  \l__sjtu_heading_in_toc_bool } ,
+    notintoc .value_forbidden:n = true,
+    notintoc .groups:n = { heading } ,
+    notintoc .code:n = { \bool_set_false:N \l__sjtu_heading_in_toc_bool } ,
+    title    .tl_set:N = \l__sjtu_heading_title_tl ,
+    title    .groups:n = { heading } ,
+    marking  .tl_set:N = \l__sjtu_heading_marking_tl ,
+    marking  .groups:n = { heading }
+  }
+\NewDocumentCommand \SJTU at heading { O{#2} m }
+  {
+    \bool_if:nTF
+      { \l__sjtu_heading_numbering_bool && \l__sjtu_heading_in_toc_bool }
+      { \chapter [#1] {#2} }
+      {
+        \CTEX at chapter@break
+        \bool_if:NTF \l__sjtu_heading_in_toc_bool
           {
-            \cs_if_exist:NTF \includepdf
-              {
-                \bool_if:NTF \g__sjtu_openright_bool
-                  { \cleardoublepage } { \clearpage }
-                \__sjtu_pdf_bookmark:nn { 0 } { \c__sjtu_name_declaration_tl }
-                \includepdf {#1}
-              }
-              {
-                \msg_warning:nn { sjtutex } { require-pdfpages }
-                \UseInstance { sjtu } { copyright }
-              }
+            \__sjtu_phantom_section:
+            \addcontentsline { toc } { chapter } {#1}
           }
+          { \__sjtu_pdf_bookmark:nn { 0 } {#1} }
+        \chapter* {#2}
+        \CTEX at gettitle {#1}
+        \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
       }
   }
+\cs_new_protected:Npn \__sjtu_heading:nn #1#2
+  { \SJTU at heading [#1] {#2} }
+\cs_generate_variant:Nn \__sjtu_heading:nn { VV }
+\cs_new_protected:Npn \__sjtu_make_heading:n #1
+  {
+    \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+    \keys_set_groups:nnn { sjtu / private } { heading } {#1}
+    \__sjtu_heading:VV
+      \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+  }
 \keys_define:nn { sjtu / style }
   {
     keywords-format       .choice: ,
@@ -1264,56 +1453,33 @@
       { \cs_set:Nn \__sjtu_keywords_format:n { \@hangfrom { \bfseries ##1 } } } ,
     keywords-format      .initial:n = { plain }
   }
-\DeclareDocumentEnvironment { abstract  } { O{ zh } +b }
+\DeclareDocumentEnvironment { abstract } { O{ } }
   {
-    \__sjtu_if_lang_valid:nTF {#1}
-      {
-        \use:c { __sjtu_set_language_ #1 : }
-        \exp_args:Nv \SJTU at head { c__sjtu_name_abstract_ #1 _tl }
-        #2
-        \clist_if_empty:cF { l__sjtu_info_keywords_ #1 _clist }
-          {
-            \par \mode_leave_vertical: \par
-            \__sjtu_keywords_format:n
-              {
-                \tl_use:c { c__sjtu_name_keywords_ #1 _tl }
-                \tl_use:c { c__sjtu_name_info_sep_ #1 _tl }
-              }
-            \clist_use:cv { l__sjtu_info_keywords_ #1 _clist }
-              { c__sjtu_name_item_sep_ #1 _tl }
-            \par
-          }
-      }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
-  } { }
-\DeclareDocumentEnvironment { abstract* } { O{ zh } +b }
+    \__sjtu_select_language:n {#1}
+    \tl_set_eq:Nc \l__sjtu_heading_title_tl
+      { c__sjtu_name_abstract_ \l__sjtu_lang_tl _tl }
+    \__sjtu_make_heading:n {#1}
+  }
   {
-    \__sjtu_if_lang_valid:nTF {#1}
+    \clist_if_empty:cF { l__sjtu_info_keywords_ \l__sjtu_lang_tl _clist }
       {
-        \use:c { __sjtu_set_language_ #1 : }
-        \exp_args:NNv \SJTU at head* { c__sjtu_name_abstract_ #1 _tl }
-        #2
-        \clist_if_empty:cF { l__sjtu_info_keywords_ #1 _clist }
+        \par \mode_leave_vertical: \par
+        \__sjtu_keywords_format:n
           {
-            \par \mode_leave_vertical: \par
-            \__sjtu_keywords_format:n
-              {
-                \tl_use:c { c__sjtu_name_keywords_ #1 _tl }
-                \tl_use:c { c__sjtu_name_info_sep_ #1 _tl }
-              }
-            \clist_use:cv { l__sjtu_info_keywords_ #1 _clist }
-              { c__sjtu_name_item_sep_ #1 _tl }
-            \par
+            \tl_use:c { c__sjtu_name_keywords_ \l__sjtu_lang_tl _tl }
+            \tl_use:c { c__sjtu_name_info_sep_ \l__sjtu_lang_tl _tl }
           }
+        \clist_use:cv { l__sjtu_info_keywords_ \l__sjtu_lang_tl _clist }
+          { c__sjtu_name_item_sep_ \l__sjtu_lang_tl _tl }
+        \par
       }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
-  } { }
-\DeclareDocumentCommand \tableofcontents { s }
+  }
+\DeclareDocumentCommand \tableofcontents { O{ } }
   {
-    \IfBooleanTF {#1}
-      { \SJTU at head* { \contentsname } }
-      { \SJTU at head  { \contentsname } }
-    \@starttoc { toc }
+    \group_begin:
+      \__sjtu_make_heading:n { title = \contentsname, #1 }
+      \@starttoc { toc }
+    \group_end:
   }
 \tl_set:Nn \SJTU at leaders { \titlerule* [ 4bp ] { . } }
 \contentsmargin [ 2.55 em ] { 0 pt }
@@ -1329,12 +1495,12 @@
   [ 4 em ] { }
   { \contentspush { \thecontentslabel \enskip } } { }
   { \SJTU at leaders \thecontentspage }
-\NewDocumentCommand \SJTU at listof { m m s }
+\NewDocumentCommand \SJTU at listof { m m O{ } }
   {
-    \IfBooleanTF {#3}
-      { \SJTU at head* {#1} }
-      { \SJTU at head  {#1} }
-    \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_begin:
+      \__sjtu_make_heading:n { title = #1, #3 }
+      \exp_args:Nv \@starttoc { ext@ #2 }
+    \group_end:
   }
 \cs_new_protected:Npn \__sjtu_new_list_of:Nnnn #1#2#3#4
   {
@@ -1350,46 +1516,49 @@
   { \figurename } { \listfigurename }
 \__sjtu_new_list_of:Nnnn \listoftables  { table  }
   { \tablename  } { \listtablename  }
-\NewDocumentEnvironment { abbreviation  } { O{ \SJTU at abbrname } }
+\NewDocumentEnvironment { abbreviation } { O{ } }
   {
-    \chapter    {#1}
+    \bool_set_true:N \l__sjtu_heading_numbering_bool
+    \__sjtu_make_heading:n { title = \SJTU at abbrname, #1 }
     \tl_clear:N \SJTU at style@float at font
   } { }
-\NewDocumentEnvironment { abbreviation* } { O{ \SJTU at abbrname } }
+\NewDocumentEnvironment { nomenclature } { O{ } }
   {
-    \SJTU at head* {#1}
+    \bool_set_true:N \l__sjtu_heading_numbering_bool
+    \__sjtu_make_heading:n { title = \SJTU at nomname, #1 }
     \tl_clear:N \SJTU at style@float at font
   } { }
-\NewDocumentEnvironment { nomenclature  } { O{ \SJTU at nomname } }
+\NewDocumentEnvironment { acknowledgements } { O{ } +b }
   {
-    \chapter    {#1}
-    \tl_clear:N \SJTU at style@float at font
-  } { }
-\NewDocumentEnvironment { nomenclature* } { O{ \SJTU at nomname } }
-  {
-    \SJTU at head* {#1}
-    \tl_clear:N \SJTU at style@float at font
-  } { }
-\NewDocumentEnvironment { acknowledgements } { O{ \SJTU at ackname } +b }
-  {
     \bool_if:NF \g__sjtu_review_bool
       {
-        \SJTU at head {#1}
+        \__sjtu_select_language:n {#1}
+        \__sjtu_make_heading:n { title = \SJTU at ackname, #1 }
         #2
       }
   } { }
 \newcounter { SJTU at bib }
-\NewDocumentEnvironment { @bibliolist } { m }
+\bool_new:N \l__sjtu_bibliolist_resume_bool
+\keys_define:nn { sjtu / private / bibliolist }
   {
+    resume .value_forbidden:n = true,
+    resume .code:n =
+      { \bool_set_true:N \l__sjtu_bibliolist_resume_bool }
+  }
+\msg_new:nnn { sjtutex } { empty-environment }
+  { Empty~'#1'~environment. }
+\NewDocumentEnvironment { @bibliolist } { m m }
+  {
+    \keys_set:nn { sjtu / private / bibliolist } {#1}
     \cs_if_exist_use:N \bibfont
     \list
       {
-        \tl_if_blank:nTF {#1}
+        \tl_if_blank:nTF {#2}
           { \hfill }
           { \@biblabel { \arabic{ SJTU at bib } } }
       }
       {
-        \tl_if_blank:nTF {#1}
+        \tl_if_blank:nTF {#2}
           {
             \skip_if_exist:NTF \bibhang
               { \dim_set_eq:NN \leftmargin \bibhang }
@@ -1397,7 +1566,7 @@
             \dim_set:Nn \itemindent { - \leftmargin }
           }
           {
-            \__sjtu_dim_set_to_wd:Nn \labelwidth { \@biblabel {#1} }
+            \__sjtu_dim_set_to_wd:Nn \labelwidth { \@biblabel {#2} }
             \dim_set_eq:NN \leftmargin \labelwidth
             \dim_add:Nn    \leftmargin { \labelsep }
           }
@@ -1415,9 +1584,11 @@
               }
           }
         \@nmbrlisttrue
-        \tl_set:Nn  \@listctr    { SJTU at bib }
-        \cs_set:Npn \p at SJTU@bib  { }
-        \cs_set:Npn \theSJTU at bib { \arabic { SJTU at bib } }
+        \tl_set:Nn \@listctr { SJTU at bib }
+        \tl_clear:N \p at SJTU@bib
+        \bool_if:NF \l__sjtu_bibliolist_resume_bool
+          { \setcounter { SJTU at bib } { 0 } }
+        \tl_set:Nn \theSJTU at bib { \arabic { SJTU at bib } }
       }
       \sloppy
       \int_set:Nn \clubpenalty  { 4000 }
@@ -1426,87 +1597,68 @@
       \char_set_sfcode:nn { `\. } { 1000 }
   }
   {
-    \cs_set:Npn \@noitemerr
+    \tl_set:Nn \@noitemerr
       { \msg_warning:nnn { sjtutex } { empty-environment } { bibliolist } }
     \endlist
   }
-\msg_new:nnn { sjtutex } { empty-environment }
-  { Empty~ `#1'~ environment. }
-\bool_new:N \l__sjtu_achievements_bool
-\NewDocumentEnvironment { achievements } { O{ \SJTU at achvname } }
+\NewDocumentEnvironment { achievements } { O{ } }
   {
-    \SJTU at head {#1}
-    \setcounter { SJTU at bib } { 0 }
-    \bool_set_true:N \l__sjtu_achievements_bool
+    \__sjtu_select_language:n {#1}
+    \__sjtu_make_heading:n { title = \SJTU at achvname, #1 }
   } { }
-\NewDocumentEnvironment { bibliolist  } { m +b }
+\NewDocumentEnvironment { bibliolist  } { O{ } m +b }
   {
-    \bool_if:NF \l__sjtu_achievements_bool
-      {
-        \msg_error:nnnn { sjtutex } { environment-validation }
-          { bibliolist  } { achievements }
-      }
     \bool_if:NF \g__sjtu_review_bool
       {
-        \cs_set:Npn \@noitemerr { }
-        \begin { @bibliolist } {#1}
-        #2
+        \begin { @bibliolist } {#1} {#2}
+          #3
         \end { @bibliolist }
       }
   } { }
-\NewDocumentEnvironment { bibliolist* } { m +b }
+\NewDocumentEnvironment { bibliolist* } { O{ } m +b }
   {
-    \bool_if:NF \l__sjtu_achievements_bool
-      {
-        \msg_error:nnnn { sjtutex } { environment-validation }
-          { bibliolist* } { achievements }
-      }
     \bool_if:NT \g__sjtu_review_bool
       {
-        \cs_set:Npn \@noitemerr { }
-        \begin { @bibliolist } {#1}
-        #2
+        \begin { @bibliolist } {#1} {#2}
+          #3
         \end { @bibliolist }
       }
   } { }
-\msg_new:nnn { sjtutex } { environment-validation }
-  { `#1'~ is~ only~ valid~ in~ `#2'~ environment. }
-\NewDocumentEnvironment { resume } { O{ \SJTU at resumename } +b }
+\NewDocumentEnvironment { resume } { O{ } +b }
   {
     \bool_if:NF \g__sjtu_review_bool
       {
-        \SJTU at head {#1}
+        \__sjtu_select_language:n {#1}
+        \__sjtu_make_heading:n { title = \SJTU at resumename, #1 }
         #2
       }
   } { }
-\NewDocumentEnvironment { digest } { O{ en } +b }
+\NewHook { sjtutex / digest }
+\NewDocumentEnvironment { digest } { O{ } +b }
   {
-    \__sjtu_if_lang_valid:nTF {#1}
+    \AtEndDocument
       {
-        \AtEndDocument
-          {
-            \use:c { __sjtu_set_language_ #1 : }
-            \bool_if:NTF \g__sjtu_openright_bool
-              { \cleardoublepage } { \clearpage }
-            \pagenumbering { roman }
-            \cs_gset:Nn \__sjtu_thepage: { \arabic { page } }
-            \cs_gset_eq:NN \addcontentsline \use_none:nnn
-            \clist_map_inline:Nn \l__sjtu_counter_without_chapter_clist
-              {
-                \counterwithout {##1} { chapter }
-                \setcounter     {##1} { 0 }
-              }
-            \__sjtu_head_aux_s:nx { \SJTU at digestname }
-              {
-                \exp_not:N \MakeUppercase
-                  { \exp_not:v { l__sjtu_info_title_ #1 _tl } }
-              }
-            #2
-          }
+        \group_begin:
+          \__sjtu_select_language:n { en, #1 }
+          \legacy_if:nTF { @openright }
+            { \cleardoublepage } { \clearpage }
+          \pagenumbering { roman }
+          \tl_gset:Nn \__sjtu_the_page_tl { \arabic { page } }
+          \UseHook { sjtutex / digest }
+          \cs_gset_eq:NN \addcontentsline \use_none:nnn
+          \clist_map_inline:Nn \l__sjtu_counter_without_chapter_clist
+            {
+              \counterwithout {##1} { chapter }
+              \setcounter     {##1} { 0 }
+            }
+          \tl_set_eq:Nc \l__sjtu_heading_title_tl
+            { l__sjtu_info_display_title_ \l__sjtu_lang_tl _tl }
+          \__sjtu_make_heading:n { marking = \SJTU at digestname, #1, notintoc }
+          #2
+        \group_end:
       }
-      { \msg_error:nnn { sjtutex } { lang-validation } {#1} }
   } { }
-\NewDocumentCommand \sjtusetup { } { \keys_set:nn { sjtu } }
+\NewDocumentCommand \sjtusetup { } { \__sjtu_setup:n }
 \keys_define:nn { sjtu }
   {
     style .meta:nn = { sjtu / style } {#1} ,
@@ -1565,7 +1717,7 @@
         pdfdisplaydoctitle = true
       }
     \int_new:N \g__sjtu_bookmark_int
-    \cs_gset_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
+    \cs_set_protected:Npn \__sjtu_pdf_bookmark:nn #1#2
       {
         \phantomsection
         \int_gincr:N \g__sjtu_bookmark_int
@@ -1572,13 +1724,16 @@
         \pdfbookmark [#1] {#2}
           { sjtubookmark. \int_use:N \g__sjtu_bookmark_int }
       }
-    \cs_gset_eq:NN \__sjtu_phantom_section: \phantomsection
+    \cs_set_eq:NN \__sjtu_phantom_section: \phantomsection
+    \DeclareExpandableDocumentCommand
+      { \__sjtu_pdfstring_newline:w } { s o m } {#3}
     \pdfstringdefDisableCommands
       {
-        \cs_set_eq:NN \\       \prg_do_nothing:
-        \cs_set_eq:NN \quad    \c_empty_tl
-        \cs_set_eq:NN \qquad   \c_empty_tl
+        \cs_set_eq:NN \\       \__sjtu_pdfstring_newline:w
         \cs_set_eq:NN \hspace  \use_none:n
+        \cs_set_eq:NN \zihao   \use_none:n
+        \tl_set_eq:NN \quad    \c_empty_tl
+        \tl_set_eq:NN \qquad   \c_empty_tl
       }
     \ctex_after_end_preamble:n
       {
@@ -1591,6 +1746,17 @@
           }
       }
   }
+\ctex_at_end_package:nn { pageslts }
+  {
+    \pagenumbering { Alph }
+    \tl_set:Nn \__sjtu_the_last_page_tl
+      { \lastpageref { pagesLTS.\pagesLTS at pnc } }
+    \AddToHook { sjtutex / digest }
+      {
+        \tl_gset:Nn \__sjtu_the_last_page_tl
+          { \lastpageref { pagesLTS.roman.local } }
+      }
+  }
 \ctex_at_end_package:nn { threeparttable }
   { \tl_put_right:Nn \TPTnoteSettings { \footnotesize } }
 \ctex_at_end_package:nn { longtable }
@@ -1605,8 +1771,8 @@
       {
         \cs_if_exist:cF {##1}
           {
-            \exp_args:Nnv  \newtheorem  {##1} { c__sjtu_name_ ##1 _tl }
-              [ chapter ]
+            \exp_args:Nnv  \newtheorem  {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl } [ chapter ]
           }
       }
     \clist_map_inline:nn
@@ -1613,7 +1779,10 @@
       { remark, solution }
       {
         \cs_if_exist:cF {##1}
-          { \exp_args:NNnv \newtheorem* {##1} { c__sjtu_name_ ##1 _tl } }
+          {
+            \exp_args:NNnv \newtheorem* {##1}
+              { c__sjtu_name_ ##1 _ \g__sjtu_lang_tl _tl }
+          }
       }
   }
 \ctex_at_begin_package:nn { amsthm }
@@ -1620,7 +1789,7 @@
   {
     \cs_if_exist:NT \openbox
       {
-        \cs_new_eq:NN \__sjtu_save_openbox: \openbox
+        \cs_new_eq:NN \SJTU at orig@openbox \openbox
         \cs_undefine:N \openbox
       }
   }
@@ -1627,8 +1796,8 @@
 \ctex_at_end_package:nn { amsthm }
   {
     \__sjtu_cs_provide_eq:NN \QED \openbox
-    \cs_if_exist:NT \__sjtu_save_openbox:
-      { \cs_set_eq:NN \openbox \__sjtu_save_openbox: }
+    \cs_if_exist:NT \SJTU at orig@openbox
+      { \cs_set_eq:NN \openbox \SJTU at orig@openbox }
     \tl_set:Nn \qedsymbol { \ensuremath { \QED } }
     \RenewDocumentEnvironment { proof } { O{ \proofname } }
       {
@@ -1646,28 +1815,28 @@
     \newtheoremstyle { sjtu }
       { } { } { \SJTU at style@thm at body@font } { }
       { \SJTU at style@thm at header@font } { } { \ccwd } { }
-  }
-\ctex_at_end_preamble:n
-  {
-    \@ifpackageloaded { amsthm }
+    \__sjtu_disable_package_load:n { ntheorem }
+    \ctex_at_end_preamble:n
       {
         \theoremstyle { sjtu }
         \__sjtu_new_theorems:
       }
+  }
+\ctex_at_end_package:nn { ntheorem }
+  {
+    \__sjtu_disable_package_load:n { amsthm }
+    \ctex_at_end_preamble:n
       {
-        \@ifpackageloaded { ntheorem }
-          {
-            \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
-            \theoremheaderfont { \SJTU at style@thm at header@font }
-            \theorembodyfont   { \SJTU at style@thm at body@font   }
-            \theoremseparator  { \enskip }
-            \theoremsymbol { \ensuremath { \QED } }
-            \qedsymbol     { \ensuremath { \QED } }
-            \cs_if_exist:NF \proof
-              { \newtheorem* { proof } { \proofname } }
-            \theoremsymbol { }
-            \__sjtu_new_theorems:
-          } { }
+        \__sjtu_cs_provide_eq:NN \QED \c_empty_tl
+        \theoremheaderfont { \SJTU at style@thm at header@font }
+        \theorembodyfont   { \SJTU at style@thm at body@font   }
+        \theoremseparator  { \enskip }
+        \theoremsymbol { \ensuremath { \QED } }
+        \qedsymbol     { \ensuremath { \QED } }
+        \cs_if_exist:NF \proof
+          { \newtheorem* { proof } { \proofname } }
+        \theoremsymbol { }
+        \__sjtu_new_theorems:
       }
   }
 \ctex_at_end_package:nn { thmtools }
@@ -1682,13 +1851,16 @@
         \exp_args:NV \contentsuse \thmt at envname { loe }
       }
     \cs_set:Npn \thmtlo at chaptervspacehack { }
-    \RenewDocumentCommand \listoftheorems { s O{ } }
+    \RenewDocumentCommand \listoftheorems { O{ } }
       {
         \group_begin:
-          \setlisttheoremstyle {#2}
-          \IfBooleanTF {#1}
-            { \SJTU at head* { \listtheoremname } }
-            { \SJTU at head  { \listtheoremname } }
+          \tl_set_eq:NN \l__sjtu_heading_marking_tl \c_novalue_tl
+          \keys_set_groups:nnnN { sjtu / private } { heading }
+            { title = \listtheoremname, #1 } \l__sjtu_tmp_tl
+          \tl_set_rescan:NnV \l__sjtu_tmp_tl { } \l__sjtu_tmp_tl
+          \__sjtu_heading:VV
+            \l__sjtu_heading_marking_tl \l__sjtu_heading_title_tl
+          \exp_args:No \setlisttheoremstyle { \l__sjtu_tmp_tl }
           \cs_set:Npn \contentsline ##1
             { \use:c { thmt at contentsline@ ##1 } {##1} }
           \clist_map_inline:Nn \thmt at allenvs
@@ -1721,10 +1893,10 @@
       { \fname at algorithm } { \listalgorithmname }
   }
 \ctex_at_begin_package:nn { algorithm2e }
-  { \cs_set_eq:NN \__sjtu_save_chapter:w \@chapter }
+  { \cs_set_eq:NN \SJTU at orig@at at chapter \@chapter }
 \ctex_at_end_package:nn { algorithm2e }
   {
-    \cs_set_eq:NN \@chapter \__sjtu_save_chapter:w
+    \cs_set_eq:NN \@chapter \SJTU at orig@at at chapter
     \SetAlgorithmName { \SJTU at algorithmname     }
                       { \SJTU at algorithmname     }
                       { \SJTU at listalgorithmname }

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-de.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-de.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,61 @@
+%%
+%% This is file `sjtu-thesis-de.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `thesis-i18n,de')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {German config for thesis (SJTUTeX)}
+\ProvidesExplFile{sjtu-thesis-de.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_name_const_from_clist:nnnn { de }
+  { degree_level } { \g__sjtu_thesis_type_int }
+  { Bachelor, Master, Doktor }
+\clist_map_inline:nn
+  {
+    { univ             } { Shanghai~ Jiao~ Tong~ Universität } ,
+    { address          } { Shanghai,~ VR~ China              } ,
+    { title_page       } { Titelblatt                        } ,
+    { declaration      } { Eidesstattliche~ Erklärung        } ,
+    { abstract         } { Abstrakt                          }
+  }
+  { \__sjtu_name_const:nnn { de } #1 }
+\clist_map_inline:nn
+  {
+    { author           } { Autor/in         } ,
+    { supervisor       } { Betreuer/in      } ,
+    { assoc_supervisor } { Zweitbetreuer/in } ,
+    { co_supervisor    } { Co-Betreuer/in   }
+  }
+  { \__sjtu_name_set:nnn { de } #1 }
+\keys_define:nn { sjtu / info / de }
+  {
+    subject          .initial:e =
+      {
+        Eine~ Dissertation~ Eingereicht~ an \exp_not:N \\
+        der~ { \exp_not:V \c__sjtu_name_univ_de_tl }~ für~
+        { \exp_not:V \c__sjtu_name_degree_level_de_tl } titel
+      }
+  }
+\DeclareInstanceCopy { sjtu / page }
+  { title / de } { title b }
+\endinput
+%%
+%% End of file `sjtu-thesis-de.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-de.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-en.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-en.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-en.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,61 @@
+%%
+%% This is file `sjtu-thesis-en.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `thesis-i18n,en')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {English config for thesis (SJTUTeX)}
+\ProvidesExplFile{sjtu-thesis-en.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_name_const_from_clist:nnnn { en }
+  { degree_level } { \g__sjtu_thesis_type_int }
+  { Bachelor, Master, Doctor }
+\clist_map_inline:nn
+  {
+    { univ             } { Shanghai~ Jiao~ Tong~ University } ,
+    { address          } { Shanghai,~ P.R.~ China           } ,
+    { title_page       } { Title~ Page                      } ,
+    { declaration      } { Statutory~ Declaration           } ,
+    { abstract         } { Abstract                         }
+  }
+  { \__sjtu_name_const:nnn { en } #1 }
+\clist_map_inline:nn
+  {
+    { author           } { Author             } ,
+    { supervisor       } { Supervisor         } ,
+    { assoc_supervisor } { Assoc.\ Supervisor } ,
+    { co_supervisor    } { Co-supervisor      }
+  }
+  { \__sjtu_name_set:nnn { en } #1 }
+\keys_define:nn { sjtu / info / en }
+  {
+    subject          .initial:e =
+      {
+        A~ Dissertation~ Submitted~ to \exp_not:N \\
+        { \exp_not:V \c__sjtu_name_univ_en_tl }~ for~
+        the~ Degree~ of~ { \exp_not:V \c__sjtu_name_degree_level_en_tl }
+      }
+  }
+\DeclareInstanceCopy { sjtu / page }
+  { title / en } { title b }
+\endinput
+%%
+%% End of file `sjtu-thesis-en.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-en.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-ja.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-ja.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-ja.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,62 @@
+%%
+%% This is file `sjtu-thesis-ja.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `thesis-i18n,ja')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {Japanese config for thesis (SJTUTeX)}
+\ProvidesExplFile{sjtu-thesis-ja.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_name_const_from_clist:nnnn { ja }
+  { degree_level } { \g__sjtu_thesis_type_int }
+  { 学士, 修士, 博士 }
+\clist_map_inline:nn
+  {
+    { univ             } { 上海交通大学         } ,
+    { address          } { 中国・上海           } ,
+    { thesis           } { 学位請求論文         } ,
+    { title_page       } { 標題紙               } ,
+    { declaration      } { 誓約書・公表許諾書   } ,
+    { abstract         } { 要 \protect \quad 旨 }
+  }
+  { \__sjtu_name_const:nnn { ja } #1 }
+\clist_map_inline:nn
+  {
+    { author           } { 氏名       } ,
+    { supervisor       } { 指導教員   } ,
+    { assoc_supervisor } { 副指導教員 } ,
+    { co_supervisor    } { 共同指導   }
+  }
+  { \__sjtu_name_set:nnn { ja } #1 }
+\keys_define:nn { sjtu / info / ja }
+  {
+    subject          .initial:e =
+      {
+        \exp_not:V \c__sjtu_name_univ_ja_tl
+        \exp_not:V \c__sjtu_name_degree_level_ja_tl
+        \exp_not:V \c__sjtu_name_thesis_ja_tl
+      }
+  }
+\DeclareInstanceCopy { sjtu / page }
+  { title / ja } { title b }
+\endinput
+%%
+%% End of file `sjtu-thesis-ja.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-ja.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-zh.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-zh.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-zh.def	2025-02-12 21:06:30 UTC (rev 73925)
@@ -0,0 +1,71 @@
+%%
+%% This is file `sjtu-thesis-zh.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% sjtutex.dtx  (with options: `thesis-i18n,zh')
+%% 
+%%     Copyright (C) SJTUG
+%%       2018--2025 Weijian Wu   <alexarawu at outlook.com>
+%%       2022--2025 Zilong Li    <logcreative at outlook.com>
+%%       2024--2025 Boshi Yuan   <nemoyuan2008 at outlook.com>
+%% 
+%%     This work may be distributed and/or modified under the
+%%     conditions of the LaTeX Project Public License, either
+%%     version 1.3c of this license or (at your option) any later
+%%     version. The latest version of this license is in:
+%% 
+%%       http://www.latex-project.org/lppl.txt
+%% 
+%%     and version 1.3 or later is part of all distributions of
+%%     LaTeX version 2005/12/01 or later.
+%% 
+\GetIdInfo$Id: sjtutex.dtx d611a82 2025-02-12 23:33:21 +0800 Alexara Wu <alexarawu at outlook.com> $
+  {Chinese config for thesis (SJTUTeX)}
+\ProvidesExplFile{sjtu-thesis-zh.def}
+  {\ExplFileDate}{2.2}{\ExplFileDescription}
+\__sjtu_symbol_const:nn { white_square } { "25A1 }
+\__sjtu_name_const_from_clist:nnnn { zh }
+  { degree_level } { \g__sjtu_thesis_type_int }
+  { 学士, 硕士, 博士 }
+\clist_map_inline:nn
+  {
+    { univ             } { 上海交通大学           } ,
+    { address          } { 中国・上海             } ,
+    { thesis           } { 学位论文               } ,
+    { title_page       } { 题名页                 } ,
+    { declaration      } { 原创性声明及使用授权书 } ,
+    { orig_decl        } { 原创性声明             } ,
+    { auth_decl        } { 使用授权书             } ,
+    { decl_author      } { 学位论文作者           } ,
+    { decl_supervisor  } { 指导教师               } ,
+    { abstract         } { 摘 \protect \quad 要   }
+  }
+  { \__sjtu_name_const:nnn { zh } #1 }
+\clist_map_inline:nn
+  {
+    { author           } { 姓名              } ,
+    { id               } { 学号              } ,
+    { supervisor       } { 导师              } ,
+    { assoc_supervisor } { 副导师            } ,
+    { co_supervisor    } { 联合导师          } ,
+    { department       } { 院系              } ,
+    { major            } { 学科 \, / \, 专业 } ,
+    { degree           } { 申请学位          }
+  }
+  { \__sjtu_name_set:nnn { zh } #1 }
+\keys_define:nn { sjtu / info / zh }
+  {
+    subject          .initial:e =
+      {
+        \exp_not:V \c__sjtu_name_univ_zh_tl
+        \exp_not:V \c__sjtu_name_degree_level_zh_tl
+        \exp_not:V \c__sjtu_name_thesis_zh_tl
+      }
+  }
+\DeclareInstanceCopy { sjtu / page }
+  { title / zh } { title a }
+\endinput
+%%
+%% End of file `sjtu-thesis-zh.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/thesis/sjtu-thesis-zh.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-cor-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-red.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-reg-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-badge-small-red.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-cor-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-eng-h-reg-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-red.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-small-red.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-cor-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-c-reg-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-cor-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-h-reg-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-cor-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf
===================================================================
--- trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf	2025-02-12 21:06:08 UTC (rev 73924)
+++ trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf	2025-02-12 21:06:30 UTC (rev 73925)

Property changes on: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-logo-std-v-reg-red.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/tex/latex/sjtutex/vi/sjtu-vi-name-red.pdf
===================================================================
(Binary files differ)



More information about the tex-live-commits mailing list.