summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-12-24 22:30:14 +0000
committerKarl Berry <karl@freefriends.org>2020-12-24 22:30:14 +0000
commit545013b983311b51f74f326f502a16caccbec543 (patch)
treeedeb905c08efbcbcd2bbcbb6c9cfef36081b3a7b
parentaab6e713c8e75bf14c05f0f93ff1e98de9c19f2e (diff)
chinese-jfm (24dec20)
git-svn-id: svn://tug.org/texlive/trunk@57218 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/luatex/chinese-jfm/LICENSE21
-rw-r--r--Master/texmf-dist/doc/luatex/chinese-jfm/README.md57
-rw-r--r--Master/texmf-dist/tex/luatex/chinese-jfm/jfm-ja_JP.lua297
-rw-r--r--Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_CN.lua311
-rw-r--r--Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_TW.lua333
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check3
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds1
-rw-r--r--Master/tlpkg/tlpsrc/chinese-jfm.tlpsrc0
-rw-r--r--Master/tlpkg/tlpsrc/collection-luatex.tlpsrc1
9 files changed, 1023 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/luatex/chinese-jfm/LICENSE b/Master/texmf-dist/doc/luatex/chinese-jfm/LICENSE
new file mode 100644
index 00000000000..01171f681d0
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/chinese-jfm/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 ListLee
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Master/texmf-dist/doc/luatex/chinese-jfm/README.md b/Master/texmf-dist/doc/luatex/chinese-jfm/README.md
new file mode 100644
index 00000000000..e1056097059
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/chinese-jfm/README.md
@@ -0,0 +1,57 @@
+# 中文使用的 luatexja JFM 文件
+
+为中文编写的 luatexja JFM 文件,提供全角、半角、开明三种风格,适用于简繁中文及日文字体的横直排。
+
+## 使用方法
+
+luatexja 可以使用 `/` 来调用 JFM 特性,语法为 `JFM=<JFM name>/{<JFM features>}` 。受北川宏典先生的 [fork 版本](https://github.com/h-kitagawa/ChineseJFM/tree/combine)的影响,所有风格的 JFM 被整合进一个文件内,使用 JFM 特性调用。
+
+### 特性一览
+
+* `quanjiao`、`banjiao`、`kaiming`
+
+ 最基础的三种特性,即「全角」「半角」与「开明」。此三特性**必须**选择其中一种。
+
+* `vert`
+
+ 直排特性,在直排时必须使用。
+
+* `hwcl`
+
+ 半宽冒号特性,仅 zh_CN 拥有,必须在直排下使用。适用于部分竖排时冒号只占半宽的字体。
+
+* `prop`
+
+ 比例宽度特性,仅 ja_JP 拥有。适用于日文的比例假名字体。
+
+## 挤压顺序
+
+JFM 文件中同时增加了 `priority` 的设置,配合 luatexja-adjust 包,可以进行有优先顺序的标点挤压。挤压顺序如下:
+
+* 最优先挤压引号、括号前后与间隔号两边的空格;
+
+* 其次挤压顿号、逗号、冒号、分号后的空格;
+
+* 最后挤压句号、问号、叹号后的空格。
+
+* 如果进行上述挤压后,仍无法达到行长要求,最后才会进行字间字距调整。
+
+\**注:以上对标点空白的描述是针对于简体中文的。对于标点置中的繁体中文,以上调整顺序仍然适用。但此时除括号外,可调整的空白变为标点两边的空白。全宽标点无空白可调整的,不作调整。*
+
+以上挤压规则是针对于全角风格的标点调整。对于半角与开明这种标点风格,若以「挤压」理解,顺序仍相同,但直观性就有所欠缺。事实上,JFM 文件中的标点是沿袭铅字与 InDesign 的习惯,认为标点只占半宽,全宽标点是半宽标点加上半宽空格的结果。因此上述规则在半宽标点的前提下应描述为:
+
+* 最先给句号、问号、叹号插空;
+
+* 其次添加顿号、逗号、冒号、分号后空格;
+
+* 最后调整引号、括号前后与间隔号两边的空格;
+
+* 如果进行上述调整后,仍无法达到行长要求,最后才会进行字间字距调整。
+
+「加法式」的标点调整,更加直观,也更容易理解。
+
+## 修改说明
+
+* v1.0.0
+
+ 初次发布至 CTAN。
diff --git a/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-ja_JP.lua b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-ja_JP.lua
new file mode 100644
index 00000000000..5be752863c1
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-ja_JP.lua
@@ -0,0 +1,297 @@
+-- Chinese JFM for Japanese fonts (ja_JP)
+-- v1.0.0
+
+local is_vt, is_qj, is_bj, is_km, is_prop
+
+if luatexja.jfont.jfm_feature then
+ is_vt = luatexja.jfont.jfm_feature.vert
+ is_qj = luatexja.jfont.jfm_feature.quanjiao
+ is_bj = luatexja.jfont.jfm_feature.banjiao
+ is_km = luatexja.jfont.jfm_feature.kaiming
+ is_prop = luatexja.jfont.jfm_feature.prop
+end
+
+if
+ not ((is_qj and not (is_bj or is_km)) or (is_bj and not (is_qj or is_km)) or
+ (is_km and not (is_qj or is_bj)))
+ then
+ tex.error(
+ 'You must specify ONLY ONE feature among "quanjiao", "banjiao" and ' ..
+ '"kaiming"'
+ )
+end
+
+local function aki(wd, pr, km)
+ -- 插入空白量
+ local p = pr or 0
+ return km and
+ (is_bj and {0, wd, 0, priority = {p, -p}} or
+ {wd, 0, wd, priority = {p, -p}}) or
+ (is_qj and {wd, 0, wd, priority = {p, -p}} or
+ {0, wd, 0, priority = {p, -p}})
+end
+
+luatexja.jfont.define_jfm {
+ version = 3,
+ dir = is_vt and 'tate' or 'yoko',
+ zw = 1,
+ zh = 1,
+ kanjiskip = {0.0, 0.25, 0},
+ xkanjiskip = {0.25, 0.25, 0.125},
+ [0] = {
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = is_prop and 'prop' or 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ },
+ round_threshold = 0.01
+ },
+ [1] = {
+ -- 开括号
+ chars = {
+ '‘',
+ '“',
+ '〈',
+ '《',
+ '「',
+ '『',
+ '【',
+ '〔',
+ '〖',
+ '〘',
+ '〝',
+ '(',
+ '[',
+ '{',
+ '⦅'
+ },
+ align = 'right',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ }
+ },
+ [2] = {
+ -- 闭括号
+ chars = {
+ '’',
+ '”',
+ '〉',
+ '》',
+ '」',
+ '』',
+ '】',
+ '〕',
+ '〗',
+ '〙',
+ '〞',
+ '〟',
+ ')',
+ ']',
+ '}',
+ '⦆'
+ },
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5, -1),
+ [1] = aki(0.5, -1),
+ [22] = aki(0.5, -1),
+ [3] = aki(0.5, -1),
+ [5] = aki(0.5, -1),
+ [51] = aki(0.5, -1),
+ [52] = aki(0.5, -1)
+ }
+ },
+ [21] = {
+ -- 逗号、顿号
+ chars = {'、', ','},
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5),
+ [1] = aki(0.5),
+ [22] = aki(0.5),
+ [3] = aki(0.5),
+ [5] = aki(0.5),
+ [51] = aki(0.5),
+ [52] = aki(0.5)
+ }
+ },
+ [22] = {
+ -- 冒号、分号
+ chars = {':', ';'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25),
+ [1] = aki(0.5),
+ [2] = aki(0.25),
+ [21] = aki(0.25),
+ [22] = aki(0.5),
+ [3] = aki(0.5, -1),
+ [4] = aki(0.25),
+ [41] = aki(0.25),
+ [5] = aki(0.25)
+ }
+ },
+ [3] = {
+ -- 间隔号
+ chars = {'・', '·'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25, -1),
+ [1] = aki(0.5, -1),
+ [2] = aki(0.25, -1),
+ [21] = aki(0.25, -1),
+ [22] = aki(0.5, -1),
+ [3] = aki(0.5, -1),
+ [4] = aki(0.25, -1),
+ [41] = aki(0.25, -1),
+ [5] = aki(0.25, -1)
+ }
+ },
+ [4] = {
+ -- 句号
+ chars = {'。', '.'},
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5, 1, true),
+ [1] = aki(0.5, 1, true),
+ [22] = aki(0.5, 1, true),
+ [3] = aki(0.5, 1, true),
+ [5] = aki(0.5, 1, true),
+ [51] = aki(0.5, 1, true),
+ [52] = aki(0.5, 1, true)
+ }
+ },
+ [41] = {
+ -- 叹号、问号
+ chars = {'!', '?', '‼', '⁇', '⁈', '⁉'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ }
+ },
+ [5] = {
+ -- 一字线、省略号、波浪线
+ chars = {
+ '—', -- U+2014
+ '―', -- U+2015
+ '‥',
+ '…',
+ '〜', -- U+301C
+ '~' -- U+FF5E
+ },
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [51] = {
+ -- U+2E3A TWO-EM DASH
+ chars = {'⸺'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 2,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [52] = {
+ -- U+2E3B THREE-EM DASH
+ chars = {'⸻'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 3,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [22] = aki(0.25),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [6] = {
+ -- box end
+ chars = {'boxbdd', 'parbdd', 'glue'}
+ }
+}
diff --git a/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_CN.lua b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_CN.lua
new file mode 100644
index 00000000000..fc707eaab6f
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_CN.lua
@@ -0,0 +1,311 @@
+-- Chinese JFM for Simplified Chinese fonts (zh_CN)
+-- v1.0.0
+
+local is_vt, is_qj, is_bj, is_km, is_hwcl
+
+if luatexja.jfont.jfm_feature then
+ is_vt = luatexja.jfont.jfm_feature.vert
+ is_qj = luatexja.jfont.jfm_feature.quanjiao
+ is_bj = luatexja.jfont.jfm_feature.banjiao
+ is_km = luatexja.jfont.jfm_feature.kaiming
+ is_hwcl = luatexja.jfont.jfm_feature.hwcl
+end
+
+if is_hwcl then
+ if not is_vt then
+ tex.error('JFM feature "hwcl" can only be used in vertical mode')
+ end
+end
+
+if
+ not ((is_qj and not (is_bj or is_km)) or (is_bj and not (is_qj or is_km)) or
+ (is_km and not (is_qj or is_bj)))
+ then
+ tex.error(
+ 'You must specify ONLY ONE feature among "quanjiao", "banjiao" and ' ..
+ '"kaiming"'
+ )
+end
+
+local function aki(wd, pr, km)
+ -- 插入空白量
+ local p = pr or 0
+ return km and
+ (is_bj and {0, wd, 0, priority = {p, -p}} or
+ {wd, 0, wd, priority = {p, -p}}) or
+ (is_qj and {wd, 0, wd, priority = {p, -p}} or
+ {0, wd, 0, priority = {p, -p}})
+end
+
+luatexja.jfont.define_jfm {
+ version = 3,
+ dir = is_vt and 'tate' or 'yoko',
+ zw = 1,
+ zh = 1,
+ kanjiskip = {0.0, 0.25, 0},
+ xkanjiskip = {0.25, 0.25, 0.125},
+ [0] = {
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [3] = aki(0.25, -1)
+ },
+ round_threshold = 0.01
+ },
+ [1] = {
+ -- 开括号
+ chars = {
+ '‘',
+ '“',
+ '〈',
+ '《',
+ '「',
+ '『',
+ '【',
+ '〔',
+ '〖',
+ '〘',
+ '〝',
+ '(',
+ '[',
+ '{',
+ '⦅'
+ },
+ align = 'right',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [3] = aki(0.25, -1)
+ }
+ },
+ [2] = {
+ -- 闭括号
+ chars = {
+ '’',
+ '”',
+ '〉',
+ '》',
+ '」',
+ '』',
+ '】',
+ '〕',
+ '〗',
+ '〙',
+ '〞',
+ '〟',
+ ')',
+ ']',
+ '}',
+ '⦆'
+ },
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5, -1),
+ [1] = aki(0.5, -1),
+ [3] = aki(0.5, -1),
+ [5] = aki(0.5, -1),
+ [51] = aki(0.5, -1),
+ [52] = aki(0.5, -1)
+ }
+ },
+ [21] = {
+ -- 逗号、顿号
+ chars = {'、', ','},
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5),
+ [1] = aki(0.5),
+ [3] = aki(0.5),
+ [5] = aki(0.5),
+ [51] = aki(0.5),
+ [52] = aki(0.5)
+ }
+ },
+ [22] = {
+ -- 冒号、分号
+ chars = {':', ';'},
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = is_vt and (is_hwcl and 0.5 or 1) or 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = is_vt and (is_hwcl and aki(0.5) or {}) or aki(0.5),
+ [1] = is_vt and (is_hwcl and aki(0.5) or {}) or aki(0.5),
+ [3] = is_vt and (is_hwcl and aki(0.5) or aki(0.25, 1)) or aki(0.5),
+ [5] = is_vt and (is_hwcl and aki(0.5) or {}) or aki(0.5),
+ [51] = is_vt and (is_hwcl and aki(0.5) or {}) or aki(0.5),
+ [52] = is_vt and (is_hwcl and aki(0.5) or {}) or aki(0.5)
+ }
+ },
+ [3] = {
+ -- 间隔号
+ chars = {'・', '·'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25, -1),
+ [1] = aki(0.5, -1),
+ [2] = aki(0.25, -1),
+ [21] = aki(0.25, -1),
+ [22] = aki(0.25, -1),
+ [3] = aki(0.5, -1),
+ [4] = aki(0.25, -1),
+ [41] = aki(0.25, -1),
+ [42] = aki(0.25, -1),
+ [5] = aki(0.25, -1)
+ }
+ },
+ [4] = {
+ -- 句号
+ chars = {'。', '.'},
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5, 1, true),
+ [1] = aki(0.5, 1, true),
+ [3] = aki(0.5, 1, true),
+ [5] = aki(0.5, 1, true),
+ [51] = aki(0.5, 1, true),
+ [52] = aki(0.5, 1, true)
+ }
+ },
+ [41] = {
+ -- 叹号、问号
+ chars = {'!', '?'},
+ align = is_vt and 'middle' or 'left',
+ left = 0,
+ down = 0,
+ width = is_vt and 1 or 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = is_vt and {} or aki(0.5, 1, true),
+ [1] = is_vt and {} or aki(0.5, 1, true),
+ [3] = is_vt and aki(0.25, -1) or aki(0.5, 1, true),
+ [5] = is_vt and {} or aki(0.5, 1, true),
+ [51] = is_vt and {} or aki(0.5, 1, true),
+ [52] = is_vt and {} or aki(0.5, 1, true)
+ }
+ },
+ [42] = {
+ -- 复合/连用叹号问号
+ chars = {'‼', '⁇', '⁈', '⁉'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [3] = aki(0.25, -1)
+ }
+ },
+ [5] = {
+ -- 一字线、省略号、波浪线
+ chars = {
+ '—', -- U+2014
+ '―', -- U+2015
+ '‥',
+ '…',
+ '〜', -- U+301C
+ '~' -- U+FF5E
+ },
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [51] = {
+ -- U+2E3A TWO-EM DASH
+ chars = {'⸺'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 2,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [52] = {
+ -- U+2E3B THREE-EM DASH
+ chars = {'⸻'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 3,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [3] = aki(0.25, -1)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [6] = {
+ -- box end
+ chars = {'boxbdd', 'parbdd', 'glue'}
+ }
+}
diff --git a/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_TW.lua b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_TW.lua
new file mode 100644
index 00000000000..90db78939ec
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/chinese-jfm/jfm-zh_TW.lua
@@ -0,0 +1,333 @@
+-- Chinese JFM for Traditional Chinese fonts (zh_TW)
+-- v1.0.0
+
+local is_vt, is_qj, is_bj, is_km
+
+if luatexja.jfont.jfm_feature then
+ is_vt = luatexja.jfont.jfm_feature.vert
+ is_qj = luatexja.jfont.jfm_feature.quanjiao
+ is_bj = luatexja.jfont.jfm_feature.banjiao
+ is_km = luatexja.jfont.jfm_feature.kaiming
+end
+
+if
+ not ((is_qj and not (is_bj or is_km)) or (is_bj and not (is_qj or is_km)) or
+ (is_km and not (is_qj or is_bj)))
+ then
+ tex.error(
+ 'You must specify ONLY ONE feature among "quanjiao", "banjiao" and ' ..
+ '"kaiming"'
+ )
+end
+
+local function aki(wd, pr, km)
+ -- 插入空白量
+ local p = pr or 0
+ return km and
+ (is_bj and {0, wd, 0, priority = {p, -p}} or
+ {wd, 0, wd, priority = {p, -p}}) or
+ (is_qj and {wd, 0, wd, priority = {p, -p}} or
+ {0, wd, 0, priority = {p, -p}})
+end
+
+luatexja.jfont.define_jfm {
+ version = 3,
+ dir = is_vt and 'tate' or 'yoko',
+ zw = 1,
+ zh = 1,
+ kanjiskip = {0.0, 0.25, 0},
+ xkanjiskip = {0.25, 0.25, .125},
+ [0] = {
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, 1, true)
+ },
+ round_threshold = 0.01
+ },
+ [1] = {
+ -- 开括号
+ chars = {
+ '‘',
+ '“',
+ '〈',
+ '《',
+ '「',
+ '『',
+ '【',
+ '〔',
+ '〖',
+ '〘',
+ '〝',
+ '(',
+ '[',
+ '{',
+ '⦅'
+ },
+ align = 'right',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, 1, true)
+ }
+ },
+ [2] = {
+ -- 闭括号
+ chars = {
+ '’',
+ '”',
+ '〉',
+ '》',
+ '」',
+ '』',
+ '】',
+ '〕',
+ '〗',
+ '〙',
+ '〞',
+ '〟',
+ ')',
+ ']',
+ '}',
+ '⦆'
+ },
+ align = 'left',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.5, -1),
+ [1] = aki(0.5, -1),
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, 1, true),
+ [5] = aki(0.25, -1),
+ [51] = aki(0.25, -1),
+ [52] = aki(0.25, -1)
+ }
+ },
+ [21] = {
+ -- 逗号、顿号
+ chars = {'、', ','},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25),
+ [1] = aki(0.25),
+ [2] = aki(0.25),
+ [21] = aki(0.5),
+ [22] = is_vt and aki(0.5) or aki(0.25),
+ [3] = aki(0.5, -1),
+ [4] = is_qj and {0.5, 0, 0.5, priority = {1, -1}} or
+ (is_bj and {0, 0.5, 0, priority = {1, -1}} or
+ {0.25, 0.25, 0.25, priority = {1, -1}}),
+ [41] = aki(0.25),
+ [5] = aki(0.25),
+ [51] = aki(0.25),
+ [52] = aki(0.25)
+ }
+ },
+ [22] = {
+ -- 冒号、分号
+ chars = {':', ';'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = is_vt and 1 or 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = is_vt and {} or aki(0.25),
+ [1] = is_vt and {} or aki(0.25),
+ [2] = is_vt and {} or aki(0.25),
+ [21] = is_vt and aki(0.25) or aki(0.5),
+ [22] = is_vt and {} or aki(0.5),
+ [3] = is_vt and aki(0.25, -1) or aki(0.5, -1),
+ [4] = is_vt and aki(0.25, 1, true) or
+ (is_qj and {0.5, 0, 0.5, priority = {1, -1}} or
+ (is_bj and {0, 0.5, 0, priority = {1, -1}} or
+ {0.25, 0.25, 0.25, priority = {1, -1}})),
+ [41] = is_vt and {} or aki(0.25),
+ [5] = is_vt and {} or aki(0.25),
+ [51] = is_vt and {} or aki(0.25),
+ [52] = is_vt and {} or aki(0.25)
+ }
+ },
+ [3] = {
+ -- 间隔号
+ chars = {'・', '·'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25, -1),
+ [1] = aki(0.25, -1),
+ [2] = aki(0.25, -1),
+ [21] = aki(0.5, -1),
+ [22] = is_vt and aki(0.25, -1) or aki(0.5, -1),
+ [3] = aki(0.5, 1),
+ [4] = is_qj and {0.5, 0, 0.5, priority = {1, -1}} or
+ (is_bj and {0, 0.5, 0, priority = {1, -1}} or
+ {0.25, 0.25, 0.25, priority = {1, -1}}),
+ [41] = aki(0.25, -1),
+ [5] = aki(0.25, -1),
+ [51] = aki(0.25, -1),
+ [52] = aki(0.25, -1)
+ }
+ },
+ [4] = {
+ -- 句号
+ chars = {'。', '.'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 0.5,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [0] = aki(0.25, 1, true),
+ [1] = aki(0.25, 1, true),
+ [2] = aki(0.25, 1, true),
+ [21] = aki(0.5, 1, true),
+ [22] = is_vt and aki(0.25, 1, true) or aki(0.5, 1, true),
+ [3] = is_qj and {0.5, 0, 0.5, priority = {1, -1}} or
+ (is_bj and {0, 0.5, 0, priority = {1, -1}} or
+ {0.25, 0.25, 0.25, priority = {1, -1}}),
+ [4] = is_qj and {0.5, 0, 0.5, priority = {1, -1}} or
+ (is_bj and {0, 0.5, 0, priority = {1, -1}} or
+ {0.25, 0.25, 0.25, priority = {1, -1}}),
+ [41] = aki(0.25, 1, true),
+ [5] = aki(0.25, 1, true),
+ [51] = aki(0.25, 1, true),
+ [52] = aki(0.25, 1, true)
+ }
+ },
+ [41] = {
+ -- 问号、感叹号
+ chars = {'?', '!', '‼', '⁇', '⁈', '⁉'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, 1, true)
+ }
+ },
+ [5] = {
+ -- 一字线、省略号、波浪线
+ chars = {
+ '—', -- U+2014
+ '―', -- U+2015
+ '‥',
+ '…',
+ '〜', -- U+301C
+ '~' -- U+FF5E
+ },
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 1,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, -1, true)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [51] = {
+ -- U+2E3A TWO-EM DASH
+ chars = {'⸺'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 2,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, -1, true)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [52] = {
+ -- U+2E3B THREE-EM DASH
+ chars = {'⸻'},
+ align = 'middle',
+ left = 0,
+ down = 0,
+ width = 3,
+ height = is_vt and 0.5 or 0.88,
+ depth = is_vt and 0.5 or 0.12,
+ italic = 0,
+ glue = {
+ [1] = aki(0.5, -1),
+ [21] = aki(0.25),
+ [22] = is_vt and {} or aki(0.25),
+ [3] = aki(0.25, -1),
+ [4] = aki(0.25, -1, true)
+ },
+ kern = {
+ [5] = 0,
+ [51] = 0,
+ [52] = 0
+ }
+ },
+ [6] = {
+ -- box end
+ chars = {'boxbdd', 'parbdd', 'glue'}
+ }
+}
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index c318c00a9d6..feed1a5ada9 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -168,7 +168,8 @@ my @TLP_working = qw(
chemfig chemformula chemgreek chemmacros
chemnum chemplants chemschemex chemsec chemstyle cherokee
chess chess-problem-diagrams chessboard chessfss chet chextras
- chhaya chicago chicagoa chicago-annote chickenize childdoc chivo
+ chhaya chicago chicagoa chicago-annote chickenize
+ childdoc chinese-jfm chivo
chkfloat chklref chletter chngcntr chordbars chordbox chronology
chronosys chs-physics-report chscite churchslavonic
cinzel circ circledsteps circuit-macros circuitikz
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index a15bc55e3e9..b60b542e981 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -1839,6 +1839,7 @@ $standardtex
'chemstyle', '\.jdf|' . $standardtex,
'chhaya', 'sankshep.tex|' . $standardtex,
'chickenize', 'chickenize\.tex|\.lua|' . $standardtex,
+ 'chinese-jfm', '\.lua',
'chronosys', '^(x-)?chronosys',
'cirth', 'num\.tex',
'cjw', '\.tex|' . $standardtex,
diff --git a/Master/tlpkg/tlpsrc/chinese-jfm.tlpsrc b/Master/tlpkg/tlpsrc/chinese-jfm.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/chinese-jfm.tlpsrc
diff --git a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
index 15ca897da1d..00fdcd4c699 100644
--- a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
@@ -11,6 +11,7 @@ depend barracuda
depend bezierplot
depend checkcites
depend chickenize
+depend chinese-jfm
depend cloze
depend combofont
depend cstypo