From e3046418e7cf8000138d9871e0387a15a3efd6bd Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 20 Apr 2021 20:14:00 +0000 Subject: luatexko (20apr21) git-svn-id: svn://tug.org/texlive/trunk@58928 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/luatex/luatexko/ChangeLog | 8 + Master/texmf-dist/doc/luatex/luatexko/README | 2 +- .../doc/luatex/luatexko/luatexko-doc.pdf | Bin 328095 -> 326736 bytes .../doc/luatex/luatexko/luatexko-doc.tex | 52 +- .../tex/luatex/luatexko/luatexko-normalize.lua | 4 +- .../tex/luatex/luatexko/luatexko-uhc2utf8.lua | 4 +- Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 651 ++++++++++++--------- Master/texmf-dist/tex/luatex/luatexko/luatexko.sty | 55 +- 8 files changed, 456 insertions(+), 320 deletions(-) diff --git a/Master/texmf-dist/doc/luatex/luatexko/ChangeLog b/Master/texmf-dist/doc/luatex/luatexko/ChangeLog index e0dc310e650..87afc21887a 100644 --- a/Master/texmf-dist/doc/luatex/luatexko/ChangeLog +++ b/Master/texmf-dist/doc/luatex/luatexko/ChangeLog @@ -1,3 +1,11 @@ +2021-04-20 Dohyun Kim + + Version 3.1 + + * luatexko.lua: insert 1/4 quad after vertical colons; + cleverer behavior when protrusion option is given; + process_fonts() is now called by hyphenate callback + 2021-03-01 Dohyun Kim Version 3.0 diff --git a/Master/texmf-dist/doc/luatex/luatexko/README b/Master/texmf-dist/doc/luatex/luatexko/README index 204f8183bb0..1b9329ffca1 100644 --- a/Master/texmf-dist/doc/luatex/luatexko/README +++ b/Master/texmf-dist/doc/luatex/luatexko/README @@ -1,4 +1,4 @@ -LuaTeX-ko Package version 3.0 (2021/03/01) +LuaTeX-ko Package version 3.1 (2021/04/20) =========================================== This is a Lua(La)TeX macro package that supports typesetting Korean diff --git a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf index a8b7ae9d402..dc87222ab28 100644 Binary files a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf and b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf differ diff --git a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex index ea7d4fc9389..d23b010e8f3 100644 --- a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex +++ b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex @@ -14,22 +14,31 @@ \usepackage{luacolor} \usepackage[hangul]{luatexko} \directlua{ - local gidoffset = 0x120000 - local notoserifcjkkr_hb = { - [171] = { 0.5, 0 }, % « - [187] = { 0, 0.5 }, % » - [62253+gidoffset] = { 0.5, 0 }, % ( - [62254+gidoffset] = { 0, 0.5 }, % ) - [62255+gidoffset] = { 0, 1 }, % , - [62257+gidoffset] = { 0, 1 }, % . - [62259+gidoffset] = { 0, 0.5 }, % : - [62260+gidoffset] = { 0, 0.5 }, % ; - [62270+gidoffset] = { 1, 0 }, % ‘ - [62271+gidoffset] = { 0, 1 }, % ’ - [62273+gidoffset] = { 0.5, 0 }, % “ - [62274+gidoffset] = { 0, 0.5 }, % ” + fonts.protrusions.setups.notoserifcjk = { + [0x28] = { 0.5, 0 }, % ( + [0x29] = { 0, 0.5 }, % ) + [0x2C] = { 0, 1 }, % , + [0x2E] = { 0, 1 }, % . + [0x3A] = { 0, 0.5 }, % : + [0x3B] = { 0, 0.5 }, % ; + [0xAB] = { 0.5, 0 }, % « + [0xBB] = { 0, 0.5 }, % » + [0x2018] = { 1, 0 }, % ‘ + [0x2019] = { 0, 1 }, % ’ + [0x201C] = { 0.5, 0 }, % “ + [0x201D] = { 0, 0.5 }, % ” + } + fonts.protrusions.setups.notosanscjk = { + % compresspunctuations 가 이미 반각을 강제했으므로 여기선 0.5만 준다. + % +halt, +vhal 따위의 옵션이 주어진 때에도 마찬가지 + [0x3001] = { 0, .5 }, + [0x3002] = { 0, .5 }, + [0xFF0C] = { 0, .5 }, + [0xFF0E] = { 0, .5 }, + [0xFE10] = { 0, .5 }, + [0xFE11] = { 0, .5 }, + [0xFE12] = { 0, .5 }, } - fonts.protrusions.setups.notoserifcjk = notoserifcjkkr_hb } \defaultfontfeatures+{Renderer=HarfBuzz} \setmainfont{Latin Modern Roman}[Expansion] % for hb tlig @@ -87,6 +96,7 @@ InterCharStretch=1pt, CharRaise=1pt, CharacterWidth=Full, + Protrusion=notosanscjk, ] \newhangulfontface\rubyfont{Noto Serif CJK KR Medium}[ Script=Hangul, @@ -124,7 +134,7 @@ \author{Dohyun Kim \normalsize || \and Soojin Nam \normalsize || \and \normalsize <\url{http://github.com/dohyunkim/luatexko}>} -\date{Version 3.0\quad 2021/03/01} +\date{Version 3.1\quad 2021/04/20} \maketitle \begin{quote} @@ -455,6 +465,7 @@ v2.0부터는 고문헌 조판에서 한글^^b7한자와 영문자가 붙어 나 참조. \begin{figure} + \fboxsep=5pt \framebox[\linewidth]{ \begin{vertical}{20em} \linespread{1.5}\sffamily \verticalhangulfont @@ -465,17 +476,21 @@ v2.0부터는 고문헌 조판에서 한글^^b7한자와 영문자가 붙어 나 \end{figure} \begin{figure} + \fboxsep=5pt \framebox[\linewidth]{ - \begin{vertical}{19em} + \begin{vertical}{17em} \linespread{1.5}\sffamily \verticalhangulfont \parindent0pt \everypar{\hangindent1em \hangafter1 } \analectstext \end{vertical} } - \caption{세로쓰기의 다른 예. 박스 높이 |19em|을 지시했다. + \caption{세로쓰기의 다른 예. 박스 높이 |17em|을 지시했다. 글꼴에 |CompressPunctuations|와 더불어 |InterCharStretch=1pt|를 옵션으로 주었다. 공백이 없는 문서는 자간늘이기 값을 넉넉하게 주는 것이 좋다. + |Protrusion| 옵션으로 구두점들이 행 끝에 매달린 것도 볼 수 있다. + |CompressPunctuations|로 이미 반각이 강제되고 있으므로 글자내밀기 값으로 |0.5|를 + 주어야 전부 내밀기가 된다. }\label{fig:vertical3} \end{figure} @@ -498,6 +513,7 @@ v2.0부터는 고문헌 조판에서 한글^^b7한자와 영문자가 붙어 나 가로쓰기 영역의 폰트 설정은 사용자의 몫이다. \begin{figure} + \fboxsep=5pt \framebox[\linewidth]{ \begin{vertical}{17em} \linespread{1.5}\sffamily \verticalhangulfont diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua index 2dec726fb65..a86b7093900 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua @@ -13,8 +13,8 @@ luatexbase.provides_module({ name = "luatexko-normalize", - version = "3.0", - date = "2021/03/01", + version = "3.1", + date = "2021/04/20", author = "Dohyun Kim, Soojin Nam", description = "Hangul normalization", license = "LPPL v1.3+", diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua index e82bf2cdfe0..d3d86fcb25e 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua @@ -13,8 +13,8 @@ luatexbase.provides_module({ name = "luatexko-uhc2utf8", - version = "3.0", - date = "2021/03/01", + version = "3.1", + date = "2021/04/20", author = "Dohyun Kim, Soojin Nam", description = "UHC (CP949) input encoding", license = "LPPL v1.3+", diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index 22fcaf54cf1..d0360a8b728 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua @@ -13,8 +13,8 @@ luatexbase.provides_module { name = 'luatexko', - date = '2021/03/01', - version = '3.0', + date = '2021/04/20', + version = '3.1', description = 'typesetting Korean with LuaTeX', author = 'Dohyun Kim, Soojin Nam', license = 'LPPL v1.3+', @@ -112,9 +112,6 @@ local rubyattr = attributes.luatexkorubyattr local hangulbyhangulattr = attributes.luatexkohangulbyhangulattr local hanjabyhanjaattr = attributes.luatexkohanjabyhanjaattr -local vert_classic = 1 -local SC_classic = 2 - local stretch_f = 5/100 -- should be consistent for ruby local function get_font_data (fontid) @@ -170,31 +167,79 @@ local function font_opt_dim (fd, optname) end end -local function is_harf (f) +local function has_harf_data (f) if type(f) == "number" then f = get_font_data(f) end return f.hb end -local function is_not_harf (f) - if option_in_font(f, "mode") == "harf" then -- mode=harf with non-luahbtex - return false - end - return not is_harf(f) -end +local harfbuzz = luaotfload.harfbuzz +local os2tag = harfbuzz and harfbuzz.Tag.new"OS/2" -local function harf_reordered_tonemark (curr) - if is_harf(curr.font) then - local props = getproperty(curr) or {} - local actualtext = props.luaotfload_startactualtext or "" - return actualtext:find"302[EF]$" - end -end +local fontoptions = { + is_not_harf = setmetatable( {}, { __index = function (t, fid) + if fid then + local bool = has_harf_data(fid) and false or true + t[fid] = bool + return bool + end + end }), -local os2tag = luaotfload.harfbuzz and luaotfload.harfbuzz.Tag.new"OS/2" + mode = setmetatable( {}, { __index = function (t, fid) + if fid then + local m = option_in_font(fid, "mode") or false + if m == "harf" and not has_harf_data(fid) then + m = "node" -- default mode when 'mode=harf' in non-luahbtex + end + t[fid] = m + return m + end + end }), + + is_widefont = setmetatable( {}, { __index = function(t, fid) + if fid then + local fontdata = get_font_data(fid) + local format = fontdata.format + local encode = fontdata.encodingbytes + local bool = encode == 2 or format == "opentype" or format == "truetype" + t[fid] = bool + return bool + end + end }), + + is_hangulscript = setmetatable( {}, { __index = function(t, fid) + if fid then + local bool = option_in_font(fid, "script") == "hang" + t[fid] = bool + return bool + end + end }), + + compresspunctuations = setmetatable( {}, { __index = function(t, fid) + if fid then + local bool = option_in_font(fid, "compresspunctuations") or false + t[fid] = bool + return bool + end + end }), + + removeclassicspaces = setmetatable( {}, { __index = function(t, fid) + if fid then + local bool = option_in_font(fid, "removeclassicspaces") or false + t[fid] = bool + return bool + end + end }), + + slantvalue = setmetatable( {}, { __index = function(t, fid) + if fid then + local val = option_in_font(fid, "slant") or false + t[fid] = val + return val + end + end }), -local font_options = { charraise = setmetatable( {}, { __index = function(t, fid) if fid then local dim = font_opt_dim(fid, "charraise") or false @@ -247,7 +292,7 @@ local font_options = { hangulspaceskip = setmetatable( {}, { __index = function(t, fid) if fid then local newwd - if is_harf(fid) then + if has_harf_data(fid) then newwd = getparameters(fid) or false if newwd then newwd = { newwd.space, newwd.space_stretch, newwd.space_shrink } @@ -274,29 +319,27 @@ local font_options = { t[fid] = true; return true end -- but not in harf mode; so we simply test widths of some glyphs - if is_harf(fid) then - local chars = get_font_data(fid).characters or {} - local i, M = chars[0x69], chars[0x4D] - if i and M and i.width == M.width then - t[fid] = true; return true - end + local chars = get_font_data(fid).characters or {} + local i, M = chars[0x69], chars[0x4D] + if i and M and i.width == M.width then + t[fid] = true; return true end t[fid] = false; return false end end } ), - tonemarkwidth = setmetatable( {}, { __index = function(t, fid) + tonemark_xmax = setmetatable( {}, { __index = function(t, fid) if fid then - local hwidth - -- check horizontal width; vertical width is mostly non-zero + -- check horizontal metric local fontdata = get_font_data(fid) local shared = fontdata.shared or {} local rawdata = shared.rawdata or {} local descriptions = rawdata.descriptions or {} local description = descriptions[0x302E] or {} - hwidth = description.width or 0 - t[fid] = hwidth - return hwidth + local bbox = description.boundingbox or {} + local xmax = bbox[3] or -1 + t[fid] = xmax + return xmax end return 0 end } ), @@ -307,7 +350,7 @@ local font_options = { -- luaharfbuzz's Font:get_h_extents() gets ascender value from hhea table; -- Node mode's parameters.ascender is gotten from OS/2 table. -- TypoAscender in OS/2 table seems to be more suitable for our purpose. - local hb = is_harf(fid) + local hb = has_harf_data(fid) if hb and os2tag then local hbface = hb.shared.face local tags = hbface:get_table_tags() @@ -348,6 +391,14 @@ local function char_in_font(fontdata, char) end end +local function harf_reordered_tonemark (curr) + if not fontoptions.is_not_harf[curr.font] then + local props = getproperty(curr) or {} + local actualtext = props.luaotfload_startactualtext or "" + return actualtext:find"302[EF]$" + end +end + local function my_node_props (n) local t = getproperty(n) if not t then @@ -358,8 +409,6 @@ local function my_node_props (n) return t.luatexko end -local active_processes = {} - local function is_hanja (c) return c >= 0x3400 and c <= 0xA4C6 or c >= 0xF900 and c <= 0xFAD9 @@ -438,6 +487,135 @@ local function is_hangul_jamo (c) or is_jongsong(c) end +local intercharclass = { [0] = + { [0] = nil, {1,1}, nil, {.5,.5} }, + { [0] = nil, nil, nil, {.5,.5} }, -- openers + { [0] = {1,1}, {1,1}, nil, {.5,.5}, nil, {1,1}, {1,1} }, -- closers + { [0] = {.5,.5},{.5,.5},{.5,.5},{1,.5}, {.5,.5},{.5,.5},{.5,.5},{.5,.5} }, -- middle dots + { [0] = {1,0}, {1,0}, nil, {1.5,.5},nil, {1,0}, {1,0} }, -- full stops + { [0] = nil, {1,1}, nil, {.5,.5} }, -- leaders and ellipses + { [0] = {1,1}, {1,1}, nil, {.5,.5} }, -- questions and exclamations + { [0] = {.5,.5},{.5,.5},nil, {.5,.5} }, -- vertical colons +} + +local charclass = setmetatable({ + [0x2018] = 1, [0x201C] = 1, [0x2329] = 1, [0x3008] = 1, + [0x300A] = 1, [0x300C] = 1, [0x300E] = 1, [0x3010] = 1, + [0x3014] = 1, [0x3016] = 1, [0x3018] = 1, [0x301A] = 1, + [0x301D] = 1, [0xFE17] = 1, [0xFE35] = 1, [0xFE37] = 1, + [0xFE39] = 1, [0xFE3B] = 1, [0xFE3D] = 1, [0xFE3F] = 1, + [0xFE41] = 1, [0xFE43] = 1, [0xFE47] = 1, [0xFF08] = 1, + [0xFF3B] = 1, [0xFF5B] = 1, [0xFF5F] = 1, [0xFF62] = 1, + -- + [0x2019] = 2, [0x201D] = 2, [0x232A] = 2, [0x3001] = 2, + [0x3009] = 2, [0x300B] = 2, [0x300D] = 2, [0x300F] = 2, + [0x3011] = 2, [0x3015] = 2, [0x3017] = 2, [0x3019] = 2, + [0x301B] = 2, [0x301E] = 2, [0x301F] = 2, [0xFE10] = 2, + [0xFE11] = 2, [0xFE18] = 2, [0xFE36] = 2, [0xFE38] = 2, + [0xFE3A] = 2, [0xFE3C] = 2, [0xFE3E] = 2, [0xFE40] = 2, + [0xFE42] = 2, [0xFE44] = 2, [0xFE48] = 2, [0xFF09] = 2, + [0xFF0C] = 2, [0xFF3D] = 2, [0xFF5D] = 2, [0xFF60] = 2, + [0xFF63] = 2, [0xFF64] = 2, + -- + [0x00B7] = 3, [0x30FB] = 3, [0xFF1A] = 3, [0xFF1B] = 3, + [0xFF65] = 3, + -- + [0x3002] = 4, [0xFE12] = 4, [0xFF0E] = 4, [0xFF61] = 4, + -- + [0x2015] = 5, [0x2025] = 5, [0x2026] = 5, [0xFE19] = 5, + [0xFE30] = 5, [0xFE31] = 5, + -- + [0xFE15] = 6, [0xFE16] = 6, [0xFF01] = 6, [0xFF1F] = 6, +}, { __index = function() return 0 end }) + +local special_classes = { + [0] = charclass, + setmetatable({ -- vert + [0xFF1A] = 7, [0xFF1B] = 7, -- 0xFE13, 0xFE14 + }, { __index = charclass }), + setmetatable({ -- SC + [0xFF01] = 4, [0xFF1A] = 2, [0xFF1B] = 2, [0xFF1F] = 4, + }, { __index = charclass }), + setmetatable({ -- TC + [0x3001] = 3, [0x3002] = 3, [0xFF0C] = 3, [0xFF0E] = 3, + }, { __index = charclass }), + setmetatable({ -- TC vert + [0x3001] = 3, [0x3002] = 3, [0xFF0C] = 3, [0xFF0E] = 3, + [0xFF1A] = 7, [0xFF1B] = 7, -- 0xFE13, 0xFE14 + }, { __index = charclass }), +} + +local function get_char_class (c, classic) + return special_classes[classic or 0][c] +end + +local breakable_after = setmetatable({ + [0x21] = true, [0x22] = true, [0x25] = true, [0x27] = true, + [0x29] = true, [0x2C] = true, [0x2D] = true, [0x2E] = true, + [0x3A] = true, [0x3B] = true, [0x3E] = true, [0x3F] = true, + [0x5D] = true, [0x7D] = true, [0x7E] = true, [0xBB] = true, + [0x2013] = true, [0x2014] = true, [0x25A1] = true, [0x25CB] = true, + [0x2E80] = true, [0x3003] = true, [0x3005] = true, [0x3007] = true, + [0x301C] = true, [0x3035] = true, [0x303B] = true, [0x303C] = true, + [0x309D] = true, [0x309E] = true, [0x30A0] = true, [0x30FC] = true, + [0x30FD] = true, [0x30FE] = true, [0xFE13] = true, [0xFE14] = true, + [0xFE32] = true, [0xFE50] = true, [0xFE51] = true, [0xFE52] = true, + [0xFE54] = true, [0xFE55] = true, [0xFE57] = true, [0xFE57] = true, + [0xFE58] = true, [0xFE5A] = true, [0xFE5C] = true, [0xFE5E] = true, + [0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true, [0x226B] = true, -- ≫ +},{ __index = function (_,c) + return is_hangul_jamo(c) -- chosong also is breakable_after + or is_noncjk_char(c) + or is_hanja(c) + or is_cjk_combining(c) + or is_kana(c) + or charclass[c] >= 2 +end }) +luatexko.breakableafter = breakable_after + +local breakable_before = setmetatable({ + [0x28] = true, [0x3C] = true, [0x5B] = true, [0x60] = true, + [0x7B] = true, [0xAB] = true, [0x25A1] = true, [0x25CB] = true, + [0x3007] = true, [0xFE59] = true, [0xFE5B] = true, [0xFE5D] = true, + [0xFF1C] = true, [0x226A] = true, -- ≪ + -- small kana + [0x3041] = 1000, [0x3043] = 1000, [0x3045] = 1000, [0x3047] = 1000, + [0x3049] = 1000, [0x3063] = 1000, [0x3083] = 1000, [0x3085] = 1000, + [0x3087] = 1000, [0x308E] = 1000, [0x3095] = 1000, [0x3096] = 1000, + [0x30A1] = 1000, [0x30A3] = 1000, [0x30A5] = 1000, [0x30A7] = 1000, + [0x30A9] = 1000, [0x30C3] = 1000, [0x30E3] = 1000, [0x30E5] = 1000, + [0x30E7] = 1000, [0x30EE] = 1000, [0x30F5] = 1000, [0x30F6] = 1000, + [0x31F0] = 1000, [0x31F1] = 1000, [0x31F2] = 1000, [0x31F3] = 1000, + [0x31F4] = 1000, [0x31F5] = 1000, [0x31F6] = 1000, [0x31F7] = 1000, + [0x31F8] = 1000, [0x31F9] = 1000, [0x31FA] = 1000, [0x31FB] = 1000, + [0x31FC] = 1000, [0x31FD] = 1000, [0x31FE] = 1000, [0x31FF] = 1000, + [0xFF67] = 1000, [0xFF68] = 1000, [0xFF69] = 1000, [0xFF6A] = 1000, + [0xFF6B] = 1000, [0xFF6C] = 1000, [0xFF6D] = 1000, [0xFF6E] = 1000, + [0xFF6F] = 1000, [0x1B150] = 1000, [0x1B151] = 1000, [0x1B152] = 1000, + [0x1B164] = 1000, [0x1B165] = 1000, [0x1B166] = 1000, [0x1B167] = 1000, +},{ __index = function(_,c) + return is_hangul(c) + or is_compat_jamo(c) + or is_chosong(c) + or is_hanja(c) + or is_kana(c) + or charclass[c] == 1 +end +}) +luatexko.breakablebefore = breakable_before + +local function is_cjk_char (c) + return is_hangul_jamo(c) + or is_hanja(c) + or is_cjk_combining(c) + or is_kana(c) + or charclass[c] >= 1 + or rawget(breakable_before, c) and c >= 0x2000 + or rawget(breakable_after, c) and c >= 0x2000 +end + +local active_processes = {} + -- font fallback local force_hangul = { @@ -479,7 +657,7 @@ local function hangul_space_skip (curr, newfont) -- command does the same thing), which we will bypass here -- for alignment of CJK and Latin glyphs in verbatim environment. -- See http://www.ktug.org/xe/index.php?document_srl=249772 - if not font_options.monospaced[curr.font] then + if not fontoptions.monospaced[curr.font] then local n = getnext(curr) if n and n.id == glueid and n.subtype == spaceskip then local params = getparameters(curr.font) @@ -491,7 +669,7 @@ local function hangul_space_skip (curr, newfont) and oldsto == 0 and oldsho == 0 then -- not user's spaceskip - local newwd = font_options.hangulspaceskip[newfont] + local newwd = fontoptions.hangulspaceskip[newfont] if newwd then setglue(n, newwd[1], newwd[2], newwd[3]) end @@ -516,24 +694,28 @@ local function process_fonts (head) if p.id == glyphid and curr.font ~= p.font then hangul_space_skip(curr, p.font) curr.font = p.font + curr.lang = p.lang end if not active_processes.reorderTM and hangul_tonemark[c] and - is_not_harf(curr.font) and - option_in_font(curr.font, "script") == "hang" then + fontoptions.is_not_harf[curr.font] and + fontoptions.is_hangulscript[curr.font] then luatexko.activate("reorderTM") -- activate reorderTM here end else + if curr.subtype == 1 and curr.lang ~= nohyphen and is_cjk_char(c) then + curr.lang = langkor -- suppress hyphenation of cjk chars + end + local hf = has_attribute(curr, hangulfontattr) or false local hjf = has_attribute(curr, hanjafontattr) or false - local fontdata = get_font_data(curr.font) - local format = fontdata.format - local encode = fontdata.encodingbytes - local widefont = encode == 2 or format == "opentype" or format == "truetype" - if hf and widefont and force_hangul[c] and curr.lang ~= nohyphen and not font_options.monospaced[curr.font] then + if hf and force_hangul[c] + and fontoptions.is_widefont[curr.font] -- exclude legacy fonts + and curr.lang ~= nohyphen and not fontoptions.monospaced[curr.font] -- exclude ttfamily + then curr.font = hf elseif hf and has_attribute(curr, hangulbyhangulattr) and is_hangul_jamo(c) then hangul_space_skip(curr, hf) @@ -541,7 +723,7 @@ local function process_fonts (head) elseif hjf and has_attribute(curr, hanjabyhanjaattr) and is_hanja(c) then hangul_space_skip(curr, hjf) curr.font = hjf - elseif not char_in_font(fontdata, c) then + elseif not char_in_font(curr.font, c) then local fbf = has_attribute(curr, fallbackfontattr) or false for _,f in ipairs{ hf, hjf, fbf } do if f and char_in_font(f, c) then @@ -577,120 +759,6 @@ end -- linebreak -local intercharclass = { [0] = - { [0] = nil, {1,1}, nil, {.5,.5} }, - { [0] = nil, nil, nil, {.5,.5} }, - { [0] = {1,1}, {1,1}, nil, {.5,.5}, nil, {1,1}, {1,1} }, - { [0] = {.5,.5},{.5,.5},{.5,.5},{1,.5}, {.5,.5},{.5,.5},{.5,.5} }, - { [0] = {1,0}, {1,0}, nil, {1.5,.5},nil, {1,0}, {1,0} }, - { [0] = nil, {1,1}, nil, {.5,.5} }, - { [0] = {1,1}, {1,1}, nil, {.5,.5} }, - { }, -- vertical colon -} - -local charclass = setmetatable({ - [0x2018] = 1, [0x201C] = 1, [0x2329] = 1, [0x3008] = 1, - [0x300A] = 1, [0x300C] = 1, [0x300E] = 1, [0x3010] = 1, - [0x3014] = 1, [0x3016] = 1, [0x3018] = 1, [0x301A] = 1, - [0x301D] = 1, [0xFE17] = 1, [0xFE35] = 1, [0xFE37] = 1, - [0xFE39] = 1, [0xFE3B] = 1, [0xFE3D] = 1, [0xFE3F] = 1, - [0xFE41] = 1, [0xFE43] = 1, [0xFE47] = 1, [0xFF08] = 1, - [0xFF3B] = 1, [0xFF5B] = 1, [0xFF5F] = 1, [0xFF62] = 1, - -- - [0x2019] = 2, [0x201D] = 2, [0x232A] = 2, [0x3001] = 2, - [0x3009] = 2, [0x300B] = 2, [0x300D] = 2, [0x300F] = 2, - [0x3011] = 2, [0x3015] = 2, [0x3017] = 2, [0x3019] = 2, - [0x301B] = 2, [0x301E] = 2, [0x301F] = 2, [0xFE10] = 2, - [0xFE11] = 2, [0xFE18] = 2, [0xFE36] = 2, [0xFE38] = 2, - [0xFE3A] = 2, [0xFE3C] = 2, [0xFE3E] = 2, [0xFE40] = 2, - [0xFE42] = 2, [0xFE44] = 2, [0xFE48] = 2, [0xFF09] = 2, - [0xFF0C] = 2, [0xFF3D] = 2, [0xFF5D] = 2, [0xFF60] = 2, - [0xFF63] = 2, [0xFF64] = 2, - -- - [0x00B7] = 3, [0x30FB] = 3, [0xFF1A] = 3, [0xFF1B] = 3, - [0xFF65] = 3, - -- - [0x3002] = 4, [0xFE12] = 4, [0xFF0E] = 4, [0xFF61] = 4, - -- - [0x2015] = 5, [0x2025] = 5, [0x2026] = 5, [0xFE19] = 5, - [0xFE30] = 5, [0xFE31] = 5, - -- - [0xFE15] = 6, [0xFE16] = 6, [0xFF01] = 6, [0xFF1F] = 6, -}, { __index = function() return 0 end }) - -local SC_charclass = setmetatable({ - [0xFF01] = 4, [0xFF1A] = 4, [0xFF1B] = 4, [0xFF1F] = 4, -}, { __index = charclass }) - -local vert_charclass = setmetatable({ - [0xFF1A] = 7, -- 0xFE13 - [0xFF1B] = 7, -- 0xFE14 -}, { __index = charclass }) - -local function get_char_class (c, classic) - if classic == vert_classic then - return vert_charclass[c] - elseif classic == SC_classic then - return SC_charclass[c] - end - return charclass[c] -end - -local breakable_after = setmetatable({ - [0x21] = true, [0x22] = true, [0x25] = true, [0x27] = true, - [0x29] = true, [0x2C] = true, [0x2D] = true, [0x2E] = true, - [0x3A] = true, [0x3B] = true, [0x3E] = true, [0x3F] = true, - [0x5D] = true, [0x7D] = true, [0x7E] = true, [0xBB] = true, - [0x2013] = true, [0x2014] = true, [0x25A1] = true, [0x25CB] = true, - [0x2E80] = true, [0x3003] = true, [0x3005] = true, [0x3007] = true, - [0x301C] = true, [0x3035] = true, [0x303B] = true, [0x303C] = true, - [0x309D] = true, [0x309E] = true, [0x30A0] = true, [0x30FC] = true, - [0x30FD] = true, [0x30FE] = true, [0xFE13] = true, [0xFE14] = true, - [0xFE32] = true, [0xFE50] = true, [0xFE51] = true, [0xFE52] = true, - [0xFE54] = true, [0xFE55] = true, [0xFE57] = true, [0xFE57] = true, - [0xFE58] = true, [0xFE5A] = true, [0xFE5C] = true, [0xFE5E] = true, - [0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true, -},{ __index = function (_,c) - return is_hangul_jamo(c) -- chosong also is breakable_after - or is_noncjk_char(c) - or is_hanja(c) - or is_cjk_combining(c) - or is_kana(c) - or charclass[c] >= 2 -end }) -luatexko.breakableafter = breakable_after - -local breakable_before = setmetatable({ - [0x28] = true, [0x3C] = true, [0x5B] = true, [0x60] = true, - [0x7B] = true, [0xAB] = true, [0x25A1] = true, [0x25CB] = true, - [0x3007] = true, [0xFE59] = true, [0xFE5B] = true, [0xFE5D] = true, - [0xFF1C] = true, - -- small kana - [0x3041] = 1000, [0x3043] = 1000, [0x3045] = 1000, [0x3047] = 1000, - [0x3049] = 1000, [0x3063] = 1000, [0x3083] = 1000, [0x3085] = 1000, - [0x3087] = 1000, [0x308E] = 1000, [0x3095] = 1000, [0x3096] = 1000, - [0x30A1] = 1000, [0x30A3] = 1000, [0x30A5] = 1000, [0x30A7] = 1000, - [0x30A9] = 1000, [0x30C3] = 1000, [0x30E3] = 1000, [0x30E5] = 1000, - [0x30E7] = 1000, [0x30EE] = 1000, [0x30F5] = 1000, [0x30F6] = 1000, - [0x31F0] = 1000, [0x31F1] = 1000, [0x31F2] = 1000, [0x31F3] = 1000, - [0x31F4] = 1000, [0x31F5] = 1000, [0x31F6] = 1000, [0x31F7] = 1000, - [0x31F8] = 1000, [0x31F9] = 1000, [0x31FA] = 1000, [0x31FB] = 1000, - [0x31FC] = 1000, [0x31FD] = 1000, [0x31FE] = 1000, [0x31FF] = 1000, - [0xFF67] = 1000, [0xFF68] = 1000, [0xFF69] = 1000, [0xFF6A] = 1000, - [0xFF6B] = 1000, [0xFF6C] = 1000, [0xFF6D] = 1000, [0xFF6E] = 1000, - [0xFF6F] = 1000, [0x1B150] = 1000, [0x1B151] = 1000, [0x1B152] = 1000, - [0x1B164] = 1000, [0x1B165] = 1000, [0x1B166] = 1000, [0x1B167] = 1000, -},{ __index = function(_,c) - return is_hangul(c) - or is_compat_jamo(c) - or is_chosong(c) - or is_hanja(c) - or is_kana(c) - or charclass[c] == 1 -end -}) -luatexko.breakablebefore = breakable_before - local allowbreak_false_nodes = { [hlistid] = true, [vlistid] = true, @@ -758,12 +826,12 @@ local function insert_glue_before (head, curr, par, br, brb, classic, ict, dim, dim = dim or 0 local gl = nodenew(glueid) - local en = font_options.en_size[fid] + local en = fontoptions.en_size[fid] if ict then en = classic and en or en/4 setglue(gl, en * ict[1] + dim, nil, en * ict[2]) else - local str = font_options.intercharstretch[fid] or stretch_f*en + local str = fontoptions.intercharstretch[fid] or stretch_f*en setglue(gl, dim, str, str*0.6) end @@ -777,7 +845,7 @@ local function maybe_linebreak (head, curr, pc, pcl, cc, old, fid, par) local ict = intercharclass[pcl][ccl] local brb = breakable_before[cc] local br = brb and breakable_after[pc] - local dim = font_options.intercharacter[fid] + local dim = fontoptions.intercharacter[fid] if ict or br or dim and (pcl >= 1 or ccl >= 1) then head = insert_glue_before(head, curr, par, br, brb, old, ict, dim, fid) end @@ -825,69 +893,13 @@ local function process_linebreak (head, par) return head end --- compress punctuations - -local function process_glyph_width (head) - local curr = head - while curr do - local id = curr.id - if id == glyphid then - if curr.lang ~= nohyphen - and option_in_font(curr.font, "compresspunctuations") then - - local cc = my_node_props(curr).unicode or curr.char - local old = has_attribute(curr, classicattr) - local class = get_char_class(cc, old) - if class >= 1 and class <= 4 and - (old or cc < 0x2000 or cc > 0x202F) then -- exclude general puncts - - -- harf-node always puts kern after the glyph - local gpos = class == 1 and is_not_harf(curr.font) and getprev(curr) or getnext(curr) - gpos = gpos and gpos.id == kernid and gpos.subtype == fontkern - - if not gpos then - local wd = font_options.en_size[curr.font] - curr.width - if wd ~= 0 then - local k = nodenew(kernid) -- fontkern (subtype 0) is default - k.kern = class == 3 and wd/2 or wd - if class == 1 then - head = insert_before(head, curr, k) - elseif class == 2 or class == 4 then - head, curr = insert_after(head, curr, k) - else - local k2 = nodecopy(k) - head = insert_before(head, curr, k) - head, curr = insert_after(head, curr, k2) - end - end - end - end - end - elseif id == mathid then - curr = end_of_math(curr) - end - curr = getnext(curr) - end - return head -end - -- interhangul & interlatincjk -local function is_cjk_char (c) - return is_hangul_jamo(c) - or is_hanja(c) - or is_cjk_combining(c) - or is_kana(c) - or charclass[c] >= 1 - or rawget(breakable_before, c) and c >= 0x2000 - or rawget(breakable_after, c) and c >= 0x2000 -end - local function do_interhangul_option (head, curr, pc, c, fontid, par) local cc = (is_hangul(c) or is_compat_jamo(c) or is_chosong(c)) and 1 or 0 if cc*pc == 1 and curr.lang ~= nohyphen then - local dim = font_options.interhangul[fontid] + local dim = fontoptions.interhangul[fontid] if dim then head = insert_glue_before(head, curr, par, true, true, false, false, dim, fontid) end @@ -944,11 +956,11 @@ local function do_interlatincjk_option (head, curr, pc, pf, pcl, c, cf, par) local brb = cc == 2 or breakable_before[c] -- numletter != br_before if brb then local f = cc == 1 and cf or pf - local dim = font_options.interlatincjk[f] + local dim = fontoptions.interlatincjk[f] if dim then local ict = old and intercharclass[pcl][ccl] -- under classic env. only if ict then - dim = font_options.intercharacter[f] or 0 + dim = fontoptions.intercharacter[f] or 0 end head = insert_glue_before(head, curr, par, true, brb, old, ict, dim, f) end @@ -1011,10 +1023,56 @@ local function process_interlatincjk (head, par) return head end +-- compress punctuations + +local function process_glyph_width (head) + local curr = head + while curr do + local id = curr.id + if id == glyphid then + if curr.lang ~= nohyphen + and fontoptions.compresspunctuations[curr.font] then + + local cc = my_node_props(curr).unicode or curr.char + local old = has_attribute(curr, classicattr) + local class = get_char_class(cc, old) + if class >= 1 and class <= 4 and + (old or cc < 0x2000 or cc > 0x202F) then -- exclude general puncts + + -- harf-node always puts kern after the glyph + local gpos = class == 1 and fontoptions.is_not_harf[curr.font] and getprev(curr) or getnext(curr) + gpos = gpos and gpos.id == kernid and gpos.subtype == fontkern + + if not gpos then + local wd = fontoptions.en_size[curr.font] - curr.width + if wd ~= 0 then + local k = nodenew(kernid) -- fontkern (subtype 0) is default + k.kern = class == 3 and wd/2 or wd + if class == 1 then + head = insert_before(head, curr, k) + elseif class == 2 or class == 4 then + head, curr = insert_after(head, curr, k) + else + local k2 = nodecopy(k) + head = insert_before(head, curr, k) + head, curr = insert_after(head, curr, k2) + end + end + end + end + end + elseif id == mathid then + curr = end_of_math(curr) + end + curr = getnext(curr) + end + return head +end + -- remove classic spaces local function process_remove_spaces (head) - local curr, opt_name, to_free = head, "removeclassicspaces", {} + local curr, to_free = head, {} while curr do local id = curr.id if id == glueid then @@ -1037,7 +1095,7 @@ local function process_remove_spaces (head) elseif id == hlistid and v.list then vchar, vfont = hbox_char_font(v, k == "n") end - if vchar and vfont and option_in_font(vfont, opt_name) then + if vchar and vfont and fontoptions.removeclassicspaces[vfont] then ok = is_cjk_char(vchar) end @@ -1243,7 +1301,7 @@ local function process_dotemph (head) end local currwd = curr.width - if currwd >= font_options.en_size[curr.font] then + if currwd >= fontoptions.en_size[curr.font] then local box = nodecopy(dotemphbox[dotattr]).list -- bypass unwanted nodes injected by some other packages while box.id ~= hlistid do @@ -1289,7 +1347,7 @@ function luatexko.get_strike_out_down (box) local down local ex = get_font_param(f, "x_height") or texsp"1ex" if is_cjk_char(c) then - local ascender, descender = tableunpack(font_options.asc_desc[f]) + local ascender, descender = tableunpack(fontoptions.asc_desc[f]) if ascender and descender then down = descender - (ascender + descender)/2 else @@ -1299,7 +1357,7 @@ function luatexko.get_strike_out_down (box) down = -0.5*ex end - local raise = font_options.charraise[f] or 0 + local raise = fontoptions.charraise[f] or 0 return down - raise end return -texsp"0.5ex" @@ -1423,9 +1481,9 @@ luatexko.rubybox = rubybox function luatexko.getrubystretchfactor (box) local _, fid = hbox_char_font(box, true, true) - local str = font_options.intercharstretch[fid] + local str = fontoptions.intercharstretch[fid] if str then - local em = font_options.en_size[fid] * 2 + local em = fontoptions.en_size[fid] * 2 set_macro("luatexkostretchfactor", stringformat("%.4f", str/em/2)) end end @@ -1483,7 +1541,7 @@ local function process_ruby_post_linebreak (head) local shift = shift_put_top(curr, ruby) local _, f = hbox_char_font(curr, true, true) - local ascender = tableunpack(font_options.asc_desc[f]) or curr.height + local ascender = tableunpack(fontoptions.asc_desc[f]) or curr.height ruby.shift = shift - ascender - ruby.depth - ruby_t[2] -- rubysep head = insert_before(head, curr, ruby) end @@ -1539,10 +1597,9 @@ local function process_reorder_tonemarks (head) while curr do local id = curr.id if id == glyphid and - is_not_harf(curr.font) and - option_in_font(curr.font, "script") == "hang" then + fontoptions.is_not_harf[curr.font] and + fontoptions.is_hangulscript[curr.font] then - local fontdata = get_font_data(curr.font) local uni = my_node_props(curr).unicode or curr.char if is_hangul(uni) or is_chosong(uni) or uni == 0x25CC then init = curr @@ -1559,7 +1616,7 @@ local function process_reorder_tonemarks (head) n = getnext(n) end - if #syllable > 1 and font_options.tonemarkwidth[curr.font] ~= 0 then + if #syllable > 1 and fontoptions.tonemark_xmax[curr.font] >= 0 then local TM = curr local actual = pdfliteral_direct_actual(syllable) @@ -1572,10 +1629,10 @@ local function process_reorder_tonemarks (head) end init = nil - elseif char_in_font(fontdata, 0x25CC) then -- isolated tone mark + elseif char_in_font(curr.font, 0x25CC) then -- isolated tone mark local dotcircle = nodecopy(curr) dotcircle.char = 0x25CC - if font_options.tonemarkwidth[curr.font] ~= 0 then + if fontoptions.tonemark_xmax[curr.font] >= 0 then local actual = pdfliteral_direct_actual{ init = curr, uni } local endactual = pdfliteral_direct_actual() head = insert_before(head, curr, actual) @@ -1845,7 +1902,7 @@ function luatexko.gethorizboxmoveright () if v and v > 0 then local amount = get_font_data(v).vertcharraise if amount then - amount = amount + (font_options.charraise[v] or 0) + amount = amount + (fontoptions.charraise[v] or 0) set_macro("luatexkohorizboxmoveright", texsp(amount).."sp") break end @@ -1863,8 +1920,7 @@ local function process_charraise (head) local id = curr.id if id == glyphid then if not has_attribute(curr,raiseattr) then - local f = curr.font - local raise = font_options.charraise[f] + local raise = fontoptions.charraise[curr.font] if raise then curr.yoffset = (curr.yoffset or 0) + raise end @@ -1896,7 +1952,7 @@ local function process_fake_slant_corr (head) -- for font fallback break end - local slant = option_in_font(p.font, "slant") + local slant = fontoptions.slantvalue[p.font] if slant and slant > 0 then tableinsert(t, char_in_font(p.font, p.char).italic or 0) end @@ -1934,7 +1990,7 @@ local function process_fake_slant_font (fontdata, fsl) local params = fontdata.parameters or {} params.slant = (params.slant or 0) + fsl*65536 -- slant per point - local hb = is_harf(fontdata) + local hb = has_harf_data(fontdata) local scale = hb and hb.scale or params.factor or 655.36 local shared = fontdata.shared or {} local descrs = shared.rawdata and shared.rawdata.descriptions or {} @@ -1968,6 +2024,13 @@ end -- wrap up +add_to_callback ("hyphenate", +function(head) + local head = process_fonts(head) + lang.hyphenate(head) +end, +"luatexko.hyphenate.fonts_and_languages") + local pass_fun = function(...) return ... end create_callback("luatexko_prelinebreak_first", "data", pass_fun) create_callback("luatexko_prelinebreak_second", "data", pass_fun) @@ -1985,7 +2048,6 @@ add_to_callback("pre_shaping_filter", function(h, gc) or gc == "vtop" or gc == "insert" or gc == "vcenter" - h = process_fonts(h) h = call_callback("luatexko_prelinebreak_first", h, par) h = call_callback("luatexko_prelinebreak_second", h, par) return process_linebreak(h, par) @@ -2047,10 +2109,10 @@ otfregister { description = "raise chars", default = false, manipulators = { - node = function(fontdata) + node = function() activate_process("post_shaping_filter", process_charraise, "charraise") end, - plug = function(fontdata) + plug = function() activate_process("post_shaping_filter", process_charraise, "charraise") end, }, @@ -2123,25 +2185,23 @@ otfregister { }, } -local function process_protrusion (fontdata, _, value) - local setup = fonts.protrusions.setups[value] or {} - local quad = fontdata.parameters.quad - for i, v in pairs(setup) do - local chr = fontdata.characters[i] - if chr then - local wdq = chr.width/quad - chr.left_protruding = chr.left_protruding or wdq*v[1]*1000 - chr.right_protruding = chr.right_protruding or wdq*v[2]*1000 - end - end - if tex.protrudechars == 0 then - texset("global", "protrudechars", 2) - end - if option_in_font(fontdata, "compresspunctuations") then - local fullname = fontdata.fullname - fontdata_warning("protrude."..fullname, - "Both `compresspunctuations' and `protrusion' are\nenabled for `%s'.\n".. - "Beware bad justifications.", fullname) +local dir_ltr = harfbuzz and harfbuzz.Direction.new"ltr" + +local function get_HB_variant_char (fontdata, charcode) + local hbfont = fontdata.hb.shared.font + local spec = fontdata.specification + local shaper = spec.features.raw.shaper + local buff = harfbuzz.Buffer.new() + buff:set_direction(dir_ltr) + buff:set_script(spec.script) + buff:set_language(spec.language) + buff:add_codepoints{charcode} + harfbuzz.shape_full(hbfont, buff, spec.hb_features, shaper and {shaper} or {}) + local glyphs = buff:get_glyphs() + if glyphs and glyphs[1] then + local glyph = glyphs[1].codepoint + local offset = fontdata.hb.shared.gid_offset + return glyph + offset end end @@ -2150,8 +2210,41 @@ otfregister { description = "glyph protrusion", default = false, manipulators = { - node = process_protrusion, - plug = process_protrusion, + node = function(fontdata, _, value) + local setup = fonts.protrusions.setups[value] or {} + local quad = fontdata.parameters.quad + for i, v in pairs(fontdata.characters) do + local uni = v.unicode + if uni then + local lr = setup[uni] + if lr then + local wdq = v.width/quad*1000 + v.left_protruding = wdq*lr[1] + v.right_protruding = wdq*lr[2] + end + end + end + if tex.protrudechars == 0 then + texset("global", "protrudechars", 2) + end + end, + plug = function(fontdata, _, value) + local setup = fonts.protrusions.setups[value] or {} + local quad = fontdata.parameters.quad + for i, v in pairs(setup) do + for _, ii in ipairs{i, get_HB_variant_char(fontdata,i)} do + local chr = fontdata.characters[ii] + if chr then + local wdq = chr.width/quad*1000 + chr.left_protruding = wdq*v[1] + chr.right_protruding = wdq*v[2] + end + end + end + if tex.protrudechars == 0 then + texset("global", "protrudechars", 2) + end + end, }, } @@ -2181,32 +2274,6 @@ function luatexko.activate (name) active_processes[name] = true end -add_to_callback ("hyphenate", -function(head) - local curr = head - while curr do - local id = curr.id - if id == glyphid and curr.subtype == 1 and curr.lang ~= nohyphen then - local c = curr.char - if c then - if is_unicode_var_sel(c) then - local p = getprev(curr) - if p.id == glyphid then - curr.lang = p.lang - end - elseif is_cjk_char(c) then - curr.lang = langkor - end - end - elseif id == mathid then - curr = end_of_math(curr) - end - curr = getnext(curr) - end - lang.hyphenate(head) -end, -"luatexko.hyphenate.prevent_disc_nodes") - -- aux functions function luatexko.deactivateall (str) diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty index f1e01791649..c44ccedcbe0 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty @@ -14,7 +14,7 @@ \ifdefined\luatexkohangulfontattr \endinput\fi \ifdefined\selectfont \NeedsTeXFormat{LaTeX2e}[2020/10/01] - \ProvidesPackage{luatexko}[2021/03/01 v3.0 typesetting Korean with LuaTeX] + \ProvidesPackage{luatexko}[2021/04/20 v3.1 typesetting Korean with LuaTeX] \RequirePackage{luatexbase} \RequirePackage{fontspec}[2020/02/03] \else @@ -55,12 +55,57 @@ \DeclareHookRule{shipout/before}{.}{before}{luacolor} \fi % classic -\protected\def\typesetclassic{\luatexkoclassicattr\z@\parindent1em } -\protected\def\typesetvertical{\luatexkoclassicattr\@ne\parindent1em } +\protected\def\typesetclassic{% 0 + \ifnum\luatexkoclassicattr<\z@ + \luatexkoclassicattr\z@ + \parindent1em + \fi + } +\protected\def\typesetvertical{% 1 + \ifcase\luatexkoclassicattr + \luatexkoclassicattr\@ne + \parindent1em + \or + \or + \luatexkoclassicattr\@ne + \or + \luatexkoclassicattr=4\relax + \or + \else + \luatexkoclassicattr\@ne + \parindent1em + \fi + } \protected\def\typesetmodern{\unsetattribute\luatexkoclassicattr} \protected\def\inhibitglue{\hskip\z@skip} -\protected\def\Schinese{\luatexkoclassicattr\tw@\parindent2em } -\protected\def\Tchinese{\luatexkoclassicattr\thr@@\parindent2em } % +halt +\protected\def\Schinese{% 2, 1 + \ifcase\luatexkoclassicattr + \luatexkoclassicattr\tw@ + \or + \or + \or + \luatexkoclassicattr\tw@ + \or + \luatexkoclassicattr\@ne + \else + \luatexkoclassicattr\tw@ + \fi + \parindent2em + } +\protected\def\Tchinese{% 3, 4 + \ifcase\luatexkoclassicattr + \luatexkoclassicattr\thr@@ + \or + \luatexkoclassicattr=4\relax + \or + \luatexkoclassicattr\thr@@ + \or + \or + \else + \luatexkoclassicattr\thr@@ + \fi + \parindent2em + } \let\korean\typesetmodern \let\japanese\typesetclassic \let\chinese\Schinese % josa \count@"AC00 -- cgit v1.2.3