summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luatexko
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-05-26 21:24:59 +0000
committerKarl Berry <karl@freefriends.org>2019-05-26 21:24:59 +0000
commit2014750e7bcf55bab5c430e3d98d8a11430eb979 (patch)
treebef9a778b3b51cea29fefadfbbf930a261791875 /Master/texmf-dist/tex/luatex/luatexko
parent5a993557f8f849481525f4d473d6c9f1da51981d (diff)
luatexko (26may19)
git-svn-id: svn://tug.org/texlive/trunk@51228 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexko')
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua230
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua51
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko.lua268
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko.sty26
4 files changed, 369 insertions, 206 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua
index 895ee5b60c3..0690a685c4d 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 = "2.0",
- date = "2019/05/01",
+ version = "2.1",
+ date = "2019/05/25",
author = "Dohyun Kim, Soojin Nam",
description = "Hangul normalization",
license = "LPPL v1.3+",
@@ -23,11 +23,6 @@ luatexbase.provides_module({
luatexkonormalize = luatexkonormalize or {}
local luatexkonormalize = luatexkonormalize
-local ncho = "[\225\132\128-\225\132\146]"
-local njung = "[\225\133\161-\225\133\181]"
-local jong = "[\225\134\168-\225\135\191\237\159\139-\237\159\187]"
-local ojong = "[\225\135\131-\225\135\191\237\159\139-\237\159\187]"
-local compathanja = "[\239\164\128-\239\168\139]"
local chanjatohanja = {
[0xF900] = {0x8C48, 0xFE00},
[0xF901] = {0x66F4, 0xFE00},
@@ -401,72 +396,199 @@ local jamotocjamo = {
}
}
-require "unicode"
-local unicodeutf8 = unicode.utf8
-local gsub = unicodeutf8.gsub
-local byte = unicodeutf8.byte
-local char = unicodeutf8.char
-local find = unicodeutf8.find
-local concat = table.concat
-local add_to_callback = luatexbase.add_to_callback
-local remove_from_callback = luatexbase.remove_from_callback
+local function is_hangul (c)
+ return c >= 0xAC00 and c <= 0xD7A3
+end
+
+local function is_modern_cho (c)
+ return c >= 0x1100 and c <= 0x1112
+end
+
+local function is_modern_jung (c)
+ return c >= 0x1161 and c <= 0x1175
+end
+
+local function is_modern_jong (c)
+ return c >= 0x11A8 and c <= 0x11C2
+end
+
+local function is_old_jong (c)
+ return c >= 0x11C3 and c <= 0x11FF
+ or c >= 0xD7CB and c <= 0xD7FB
+end
-local jamo2syllable = function(l,v,t)
- if find(t,ojong) then return end
- l, v = byte(l), byte(v)
- local s = (l - 0x1100) * 21
- s = (s + v - 0x1161) * 28
- if t ~= "" then
- s = s + byte(t) - 0x11a7
+local function is_jongsong (c)
+ return is_modern_jong(c) or is_old_jong(c)
+end
+
+local function jamo2syllable (t) -- table -> integer
+ local cho, jung, jong = table.unpack(t)
+ local s = (cho - 0x1100) * 21
+ s = (s + jung - 0x1161) * 28
+ if jong then
+ s = s + jong - 0x11A7
end
- return char(s + 0xac00)
+ return s + 0xAC00
end
-local syllable2jamo = function(s)
- s = byte(s) - 0xac00
+local function syllable2jamo (s) -- integer -> table
local t = {}
- t[1] = char(s // 588 + 0x1100)
- t[2] = char(s % 588 // 28 + 0x1161)
+ s = s - 0xAC00
+ t[1] = s // 588 + 0x1100
+ t[2] = s % 588 // 28 + 0x1161
local jong = s % 28
- t[3] = jong > 0 and char(jong + 0x11a7) or nil
- return concat(t)
+ if jong ~= 0 then
+ t[3] = jong + 0x11A7
+ end
+ return t
+end
+
+local function hanguldecompose (buffer)
+ local t = {}
+ for _, c in utf8.codes(buffer) do
+ if is_hangul(c) then
+ table.append(t, syllable2jamo(c))
+ else
+ table.insert(t, c)
+ end
+ end
+ return utf8.char(table.unpack(t))
end
-local hanguldecompose = function(buffer)
- return gsub(buffer, "[\234\176\128-\237\158\163]", syllable2jamo)
+-- LV | LVT, T -> L, V, T+
+local function flush_syllable_jong (t, s)
+ if #s == 2 then
+ table.append(t, syllable2jamo( s[1] ))
+ table.insert(t, s[2])
+ else
+ table.append(t, s)
+ end
+ return t, {}
end
-local function hanjanormalize(c)
- local hanja = chanjatohanja[byte(c)]
- hanja = hanja and char(hanja[1], hanja[2])
- return hanja
+local function compose_hanguldecompose (buffer) -- string -> table
+ local t, s = {}, {}
+ for _, c in utf8.codes(buffer) do
+ if #s == 1 and is_jongsong(c) then
+ table.insert(s, c)
+ else
+ t, s = flush_syllable_jong(t, s)
+ table.insert(is_hangul(c) and s or t, c)
+ end
+ end
+ t = flush_syllable_jong(t, s)
+ return t
end
-local function jamo2cjamocho(c)
- local jamo = jamotocjamo.ccho[byte(c)]
- jamo = jamo and char(jamo)
- return jamo
+-- L, V, [T & ^OT]? -> LV | LVT
+local function flush_syllable (t, s)
+ if #s == 2 or #s == 3 and is_modern_jong( s[3] ) then
+ table.insert(t, jamo2syllable(s))
+ else
+ table.append(t, s)
+ end
+ return t, {}
end
-local function jamo2cjamojung(c,t)
- if t ~= "" then return end
- local jamo = jamotocjamo.cjung[byte(c)]
- jamo = jamo and char(jamo)
- return jamo
+local function compose_modern_hangul (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and is_modern_jung(c) or #s >= 2 and is_jongsong(c) then
+ table.insert(s, c)
+ else
+ t, s = flush_syllable(t, s)
+ table.insert(is_modern_cho(c) and s or t, c)
+ end
+ end
+ t = flush_syllable(t, s)
+ return t
end
-local hangulcompose = function(buffer)
- buffer = gsub(buffer, "[\234\176\128-\237\158\163]"..jong, hanguldecompose)
- buffer = gsub(buffer, "("..ncho..")("..njung..")("..jong.."?)", jamo2syllable)
- buffer = gsub(buffer,
- "([\225\132\128-\225\133\153])\225\133\160", jamo2cjamocho)
- buffer = gsub(buffer,
- "\225\133\159([\225\133\161-\225\134\161])("..jong.."?)", jamo2cjamojung)
- buffer = gsub(buffer, compathanja, hanjanormalize)
- return buffer
+-- L, VF -> CL
+local function flush_cjamocho (t, s)
+ if #s == 2 then
+ table.insert(t, jamotocjamo.ccho[ s[1] ])
+ else
+ table.append(t, s)
+ end
+ return t, {}
+end
+
+local function compose_jamo_chosong (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and c == 0x1160 then
+ table.insert(s, c)
+ else
+ t, s = flush_cjamocho(t, s)
+ table.insert(jamotocjamo.ccho[c] and s or t, c)
+ end
+ end
+ t = flush_cjamocho(t, s)
+ return t
+end
+
+-- LF, V, ^T -> CV, ^T
+local function flush_cjamojung (t, s)
+ if #s == 2 then
+ table.insert(t, jamotocjamo.cjung[ s[2] ])
+ else
+ table.append(t, s)
+ end
+ return t, {}
+end
+
+local function compose_jamo_jungsong (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and jamotocjamo.cjung[c] or #s == 2 and is_jongsong(c) then
+ table.insert(s, c)
+ else
+ t, s = flush_cjamojung(t, s)
+ table.insert(c == 0x115F and s or t, c)
+ end
+ end
+ t = flush_cjamojung(t, s)
+ return t
+end
+
+-- CHJ -> HJ, VS
+local function flush_compat_hanja (t, s)
+ if #s == 1 then
+ table.append(t, chanjatohanja[ s[1] ])
+ else
+ table.append(t, s)
+ end
+ return t, {}
+end
+
+local function compose_compat_hanja (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and c >= 0xFE00 and c <= 0xFE02 then
+ table.insert(s, c)
+ else
+ t, s = flush_compat_hanja(t, s)
+ table.insert(chanjatohanja[c] and s or t, c)
+ end
+ end
+ t = flush_compat_hanja(t, s)
+ return t
+end
+
+local function hangulcompose (buffer)
+ local t = compose_hanguldecompose(buffer)
+ t = compose_modern_hangul(t)
+ t = compose_jamo_chosong (t)
+ t = compose_jamo_jungsong(t)
+ t = compose_compat_hanja (t)
+
+ return utf8.char(table.unpack(t))
end
local loaded = false
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
local function unload()
if loaded then
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua
index d23de4bc968..af346161b8b 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 = "2.0",
- date = "2019/05/01",
+ version = "2.1",
+ date = "2019/05/25",
author = "Dohyun Kim, Soojin Nam",
description = "UHC (CP949) input encoding",
license = "LPPL v1.3+",
@@ -23,13 +23,6 @@ luatexbase.provides_module({
luatexkouhc2utf8 = luatexkouhc2utf8 or {}
local luatexkouhc2utf8 = luatexkouhc2utf8
-local format = string.format
-local utf8len = utf8.len
-require "unicode"
-local unicodeutf8 = unicode.utf8
-local ugsub = unicodeutf8.gsub
-local ubyte = unicodeutf8.byte
-local uchar = unicodeutf8.char
local kpse_find_file = kpse.find_file
local add_to_callback = luatexbase.add_to_callback
local remove_from_callback = luatexbase.remove_from_callback
@@ -40,9 +33,9 @@ local function get_uhc_uni_table()
if file then
file = io.open(file, "r")
while true do
- local line = file:read("*line")
+ local line = file:read"*line"
if not line then break end
- local ea,eb,uni = line:match("<(%x+)>%s+<(%x+)>%s+<(%x+)>")
+ local ea,eb,uni = line:match"<(%x+)>%s+<(%x+)>%s+<(%x+)>"
if ea and eb and uni then
ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16)
for i=ea,eb do
@@ -58,15 +51,14 @@ end
local t_uhc2ucs = t_uhc2ucs or get_uhc_uni_table()
-local uhc_to_utf8 = function(buffer)
+local function uhc_to_utf8 (buffer)
if not buffer then return end
- -- check if buffer is already utf-8
- if utf8len(buffer) then return nil end
- -- now convert to utf8
- buffer = buffer:gsub("([\129-\253])([\65-\254])",
- function(a, b)
- local utf = t_uhc2ucs[a:byte() * 256 + b:byte()]
- if utf then return uchar(utf) end
+ if utf8.len(buffer) then return end -- check if buffer is already utf-8
+ buffer = buffer:gsub("([\129-\253])([\65-\254])", function(a, b)
+ local u = t_uhc2ucs[a:byte() * 256 + b:byte()]
+ if u then
+ return utf8.char(u)
+ end
end)
return buffer
end
@@ -96,14 +88,21 @@ local t_ucs2uhc = t_ucs2uhc or get_uni_uhc_table()
local function utf8_to_uhc (name)
if not name then return end
- name = ugsub(name, "[\161-\239\191\166]", -- 00A1..FFE6
- function(u)
- local c = t_ucs2uhc[ubyte(u)]
- if c then
- return format("%c%c", c//256, c%256)
+ local t = {}
+ for _, u in utf8.codes(name) do
+ if u >= 0xA1 and u <= 0xFFE6 then
+ local c = t_ucs2uhc[u]
+ if c then
+ table.insert(t, c // 256)
+ table.insert(t, c % 256)
+ else
+ table.insert(t, u)
+ end
+ else
+ table.insert(t, u)
end
- end)
- return name
+ end
+ return string.char(table.unpack(t))
end
local function uhc_find_file (file, ...)
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
index 01a274bfeda..87478153ada 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 = '2019/05/01',
- version = '2.0',
+ date = '2019/05/25',
+ version = '2.1',
description = 'typesetting Korean with LuaTeX',
author = 'Dohyun Kim, Soojin Nam',
license = 'LPPL v1.3+',
@@ -61,6 +61,7 @@ local stringformat = string.format
local tableconcat = table.concat
local tableinsert = table.insert
+local tableunpack = table.unpack
local add_to_callback = luatexbase.add_to_callback
local attributes = luatexbase.attributes
@@ -95,7 +96,6 @@ local italcorr = 3
local lua_number = 100
local lua_value = 108
local spaceskip = 13
-local xleaders = 102
local nohyphen = registernumber"l@nohyphenation" or -1 -- verbatim
local hangulfontattr = attributes.luatexkohangulfontattr
@@ -110,69 +110,69 @@ local vert_classic = 1
local SC_classic = 2
local function is_hanja (c)
- return (c >= 0x3400 and c <= 0xA4C6)
- or (c >= 0xF900 and c <= 0xFAD9)
- or (c >= 0x20000 and c <= 0x2FFFD)
- or (c >= 0x2E81 and c <= 0x2FD5)
+ return c >= 0x3400 and c <= 0xA4C6
+ or c >= 0xF900 and c <= 0xFAD9
+ or c >= 0x20000 and c <= 0x2FFFD
+ or c >= 0x2E81 and c <= 0x2FD5
end
local function is_hangul (c)
- return (c >= 0xAC00 and c <= 0xD7A3)
+ return c >= 0xAC00 and c <= 0xD7A3
end
local function is_chosong (c)
- return (c >= 0x1100 and c <= 0x115F)
- or (c >= 0xA960 and c <= 0xA97C)
+ return c >= 0x1100 and c <= 0x115F
+ or c >= 0xA960 and c <= 0xA97C
end
local function is_jungsong (c)
- return (c >= 0x1160 and c <= 0x11A7)
- or (c >= 0xD7B0 and c <= 0xD7C6)
+ return c >= 0x1160 and c <= 0x11A7
+ or c >= 0xD7B0 and c <= 0xD7C6
end
local function is_jongsong (c)
- return (c >= 0x11A8 and c <= 0x11FF)
- or (c >= 0xD7CB and c <= 0xD7FB)
+ return c >= 0x11A8 and c <= 0x11FF
+ or c >= 0xD7CB and c <= 0xD7FB
end
local hangul_tonemark = {
[0x302E] = true, [0x302F] = true,
}
-local function is_unicode_vs (c)
- return (c >= 0xFE00 and c <= 0xFE0F)
- or (c >= 0xE0100 and c <= 0xE01EF)
+local function is_unicode_var_sel (c)
+ return c >= 0xFE00 and c <= 0xFE0F
+ or c >= 0xE0100 and c <= 0xE01EF
end
local function is_cjk_combining (c)
- return (c >= 0x302A and c <= 0x302F)
- or (c >= 0x3099 and c <= 0x309C)
- or (c >= 0xFF9E and c <= 0xFF9F)
- or is_unicode_vs(c)
+ return c >= 0x302A and c <= 0x302F
+ or c >= 0x3099 and c <= 0x309C
+ or c >= 0xFF9E and c <= 0xFF9F
+ or is_unicode_var_sel(c)
end
local function is_noncjkletter (c)
- return (c >= 0x30 and c <= 0x39)
- or (c >= 0x41 and c <= 0x5A)
- or (c >= 0x61 and c <= 0x7A)
- or (c >= 0xC0 and c <= 0xD6)
- or (c >= 0xD8 and c <= 0xF6)
- or (c >= 0xF8 and c <= 0x10FC)
- or (c >= 0x1200 and c <= 0x1FFE)
- or (c >= 0xA4D0 and c <= 0xA877)
- or (c >= 0xAB01 and c <= 0xABBF)
- or (c >= 0xFB00 and c <= 0xFDFD)
- or (c >= 0xFE70 and c <= 0xFEFC)
+ return c >= 0x30 and c <= 0x39
+ or c >= 0x41 and c <= 0x5A
+ or c >= 0x61 and c <= 0x7A
+ or c >= 0xC0 and c <= 0xD6
+ or c >= 0xD8 and c <= 0xF6
+ or c >= 0xF8 and c <= 0x10FC
+ or c >= 0x1200 and c <= 0x1FFE
+ or c >= 0xA4D0 and c <= 0xA877
+ or c >= 0xAB01 and c <= 0xABBF
+ or c >= 0xFB00 and c <= 0xFDFD
+ or c >= 0xFE70 and c <= 0xFEFC
end
local function is_kana (c)
- return (c >= 0x3041 and c <= 0x3096)
- or (c >= 0x30A1 and c <= 0x30FA)
- or (c >= 0x31F0 and c <= 0x31FF)
- or (c >= 0xFF66 and c <= 0xFF6F)
- or (c >= 0xFF71 and c <= 0xFF9D)
- or c == 0x309F or c == 0x30FF
- or (c >= 0x1B000 and c <= 0x1B16F)
+ return c >= 0x3041 and c <= 0x3096
+ or c >= 0x30A1 and c <= 0x30FA
+ or c >= 0x31F0 and c <= 0x31FF
+ or c >= 0xFF66 and c <= 0xFF6F
+ or c >= 0xFF71 and c <= 0xFF9D
+ or c == 0x309F or c == 0x30FF
+ or c >= 0x1B000 and c <= 0x1B16F
end
local function is_hangul_jamo (c)
@@ -180,7 +180,7 @@ local function is_hangul_jamo (c)
or is_chosong(c)
or is_jungsong(c)
or is_jongsong(c)
- or (c >= 0x3131 and c <= 0x318E)
+ or c >= 0x3131 and c <= 0x318E
end
local stretch_f, shrink_f = 5/100, 3/100 -- should be consistent for ruby
@@ -189,14 +189,24 @@ local function get_font_data (fontid)
return fontgetfont(fontid) or fontfonts[fontid] or {}
end
-local function get_en_size (f)
- local pm
+local function get_font_param (f, key)
+ local t
if type(f) == "number" then
- pm = getparameters(f)
- elseif type(f) == "table" then
- pm = f.parameters
+ t = getparameters(f)
+ if t and t[key] then
+ return t[key]
+ end
+ f = get_font_data(f)
+ end
+ if type(f) == "table" then
+ t = f.parameters
+ return t and t[key]
end
- return pm and pm.quad and pm.quad/2 or 327680
+end
+
+local function get_en_size (f)
+ local quad = get_font_param(f, "quad")
+ return quad and quad/2 or 327680
end
local function char_in_font(fontdata, char)
@@ -264,7 +274,7 @@ luatexko.updateforcehangul = update_force_hangul
local active_processes = {}
-local char_font_options ={
+local char_font_options = {
interhangul = {},
interlatincjk = {},
intercharacter = {},
@@ -278,7 +288,8 @@ local function hangul_space_skip (curr, newfont)
if n and n.id == glueid and n.subtype == spaceskip then
local params = getparameters(curr.font)
local oldwd, oldst, oldsh, oldsto, oldsho = getglue(n)
- if oldwd == params.space
+ if params
+ and oldwd == params.space
and oldst == params.space_stretch
and oldsh == params.space_shrink
and oldsto == 0
@@ -316,13 +327,12 @@ local function process_fonts (head)
local c = curr.char
- if is_unicode_vs(c) then
+ if is_unicode_var_sel(c) then
local p = getprev(curr)
if p.id == glyphid and curr.font ~= p.font then
hangul_space_skip(curr, p.font)
curr.font = p.font
end
-
else
local hf = has_attribute(curr, hangulfontattr) or false
local hjf = has_attribute(curr, hanjafontattr) or false
@@ -358,6 +368,10 @@ local function process_fonts (head)
props.unicode = c
end
+ elseif id == discid then
+ curr.pre = process_fonts(curr.pre)
+ curr.post = process_fonts(curr.post)
+ curr.replace = process_fonts(curr.replace)
elseif id == mathid then
curr = end_of_math(curr)
elseif id == whatsitid
@@ -450,7 +464,7 @@ local breakable_after = setmetatable({
[0xFE58] = true, [0xFE5A] = true, [0xFE5C] = true, [0xFE5E] = true,
[0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true,
},{ __index = function (_,c)
- return (is_hangul_jamo(c) and not is_chosong(c))
+ return is_hangul_jamo(c) and not is_chosong(c)
or is_noncjkletter(c)
or is_hanja(c)
or is_cjk_combining(c)
@@ -480,7 +494,7 @@ local breakable_before = setmetatable({
[0xFF6F] = 1000, [0x1B150] = 1000, [0x1B151] = 1000, [0x1B152] = 1000,
[0x1B164] = 1000, [0x1B165] = 1000, [0x1B166] = 1000, [0x1B167] = 1000,
},{ __index = function(_,c)
- return (is_hangul_jamo(c) and not is_jungsong(c) and not is_jongsong(c))
+ return is_hangul_jamo(c) and not is_jungsong(c) and not is_jongsong(c)
or is_hanja(c)
or is_kana(c)
or charclass[c] == 1
@@ -499,7 +513,7 @@ local allowbreak_false_nodes = {
local function is_blocking_node (curr)
local id, subtype = curr.id, curr.subtype
- return allowbreak_false_nodes[id] or (id == kernid and subtype == userkern)
+ return allowbreak_false_nodes[id] or id == kernid and subtype == userkern
end
local function ruby_char_font (rb)
@@ -551,17 +565,13 @@ local function fontdata_opt_dim (fd, optname)
end
end
-local function get_font_opt_dimen (fontid, option_name)
- local fop_t = char_font_options[option_name]
- local dim = fop_t and fop_t[fontid]
+local function get_font_opt_dimen (fontid, optionname)
+ local t = char_font_options[optionname]
+ local dim = t and t[fontid]
if dim == nil then
local fd = get_font_data(fontid)
- dim = fontdata_opt_dim(fd, option_name)
- if dim then
- fop_t[fontid] = dim -- cache
- else
- fop_t[fontid] = false
- end
+ dim = fontdata_opt_dim(fd, optionname)
+ t[fontid] = dim or false -- cache
end
return dim
end
@@ -592,15 +602,15 @@ local function insert_glue_before (head, curr, par, br, brb, classic, ict, dim)
return insert_before(head, curr, gl)
end
-local function maybe_linebreak (head, curr, pc, pcl, cc, gomun, fid, par)
- local ccl = get_char_class(cc, gomun)
+local function maybe_linebreak (head, curr, pc, pcl, cc, old, fid, par)
+ local ccl = get_char_class(cc, old)
if pc and cc and curr.lang ~= nohyphen then
local ict = intercharclass[pcl][ccl]
local brb = breakable_before[cc]
local br = brb and breakable_after[pc]
local dim = get_font_opt_dimen(fid, "intercharacter")
if ict or br or dim and (pcl >= 1 or ccl >= 1) then
- head = insert_glue_before(head, curr, par, br, brb, gomun, ict, dim)
+ head = insert_glue_before(head, curr, par, br, brb, old, ict, dim)
end
end
return head, cc, ccl
@@ -612,20 +622,19 @@ local function process_linebreak (head, par)
local id = curr.id
if id == glyphid then
local cc = my_node_props(curr).unicode or curr.char
- local gomun = has_attribute(curr, classicattr)
-
- head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, gomun, curr.font, par)
+ local old = has_attribute(curr, classicattr)
+ head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, curr.font, par)
elseif id == hlistid and has_attribute(curr, rubyattr) then
local cc, fi = ruby_char_font(curr) -- rubybase
- local gomun = has_attribute(curr, classicattr)
- head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, gomun, fi, par)
+ local old = has_attribute(curr, classicattr)
+ head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, fi, par)
elseif id == whatsitid and curr.mode == directmode then
local glyf, cc, fin = get_actualtext(curr)
if cc and fin and glyf then
- local gomun = has_attribute(glyf, classicattr)
- head = maybe_linebreak(head, curr, pc, pcl, cc, gomun, glyf.font, par)
+ local old = has_attribute(glyf, classicattr)
+ head = maybe_linebreak(head, curr, pc, pcl, cc, old, glyf.font, par)
pc, pcl, curr = fin, 0, goto_end_actualtext(curr)
end
@@ -652,17 +661,12 @@ local function process_glyph_width (head)
and option_in_font(curr.font, "compresspunctuations") then
local cc = my_node_props(curr).unicode or curr.char
- local gomun = has_attribute(curr, classicattr)
- local class = get_char_class(cc, gomun)
- if (gomun or cc < 0x2000 or cc > 0x202F) -- exclude general puncts
- and class >= 1 and class <= 4 then
-
- local gpos
- if class ~= 1 then
- gpos = getnext(curr)
- else
- gpos = getprev(curr)
- end
+ 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
+
+ local gpos = class == 1 and getprev(curr) or getnext(curr)
gpos = gpos and gpos.id == kernid and gpos.subtype == fontkern
if not gpos then
@@ -699,8 +703,8 @@ local function is_cjk (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)
+ 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)
@@ -752,7 +756,7 @@ local function process_interhangul (head, par)
end
local function do_interlatincjk_option (head, curr, pc, pf, c, cf, par)
- local cc = (is_cjk(c) and 1) or (is_noncjkletter(c) and 2) or 0
+ local cc = is_cjk(c) and 1 or is_noncjkletter(c) and 2 or 0
local brb = cc == 2 or breakable_before[c] -- numletter != br_before
if brb and cc*pc == 2 and curr.lang ~= nohyphen then
@@ -899,19 +903,19 @@ local josa_code = setmetatable({
return c ~= 0x1160 and 2
elseif is_jongsong(c) then
return c == 0x11AF and 1 or 3
- elseif (is_noncjkletter(c) and c <= 0x7A )
- or (c >= 0x2160 and c <= 0x217F) -- roman
- or (c >= 0x2460 and c <= 0x24E9) -- ①
- or (c >= 0x314F and c <= 0x3163) or (c >= 0x3187 and c <= 0x318E) -- ㅏ
- or (c >= 0x320E and c <= 0x321E) -- ㈎
- or (c >= 0x326E and c <= 0x327F) -- ㉮
- or (c >= 0xFF10 and c <= 0xFF19) -- 0
- or (c >= 0xFF21 and c <= 0xFF3A) -- A
- or (c >= 0xFF41 and c <= 0xFF5A) -- a
+ elseif is_noncjkletter(c) and c <= 0x7A
+ or c >= 0x2160 and c <= 0x217F -- roman
+ or c >= 0x2460 and c <= 0x24E9 -- ①
+ or c >= 0x314F and c <= 0x3163 or c >= 0x3187 and c <= 0x318E -- ㅏ
+ or c >= 0x320E and c <= 0x321E -- ㈎
+ or c >= 0x326E and c <= 0x327F -- ㉮
+ or c >= 0xFF10 and c <= 0xFF19 -- 0
+ or c >= 0xFF21 and c <= 0xFF3A -- A
+ or c >= 0xFF41 and c <= 0xFF5A -- a
then return 2
- elseif (c >= 0x3131 and c <= 0x314E) or (c >= 0x3165 and c <= 0x3186) -- ㄱ
- or (c >= 0x3200 and c <= 0x320D) -- ㈀
- or (c >= 0x3260 and c <= 0x326D) -- ㉠
+ elseif c >= 0x3131 and c <= 0x314E or c >= 0x3165 and c <= 0x3186 -- ㄱ
+ or c >= 0x3200 and c <= 0x320D -- ㈀
+ or c >= 0x3260 and c <= 0x326D -- ㉠
then return 3
end
end })
@@ -1031,11 +1035,11 @@ end
local uline_f, uline_id = new_user_whatsit("uline","luatexko")
local no_uline_id = new_user_whatsit_id("no_uline","luatexko")
-local function ulboundary (i, n)
+local function ulboundary (i, n, subtype)
local what = uline_f()
if n then
what.type = lua_value -- table
- what.value = { i, nodecopy(n) }
+ what.value = { i, nodecopy(n), subtype }
else
what.type = lua_number
what.value = i
@@ -1061,17 +1065,19 @@ function skip_white_nodes (n, ltr)
end
local function draw_uline (head, curr, parent, t, final)
- local start, list = t.start or head, t.list
+ local start, list, subtype = t.start or head, t.list, t.subtype
start = skip_white_nodes(start, true)
- nodeslide(start) -- to get correct getprev.
+ if final then
+ nodeslide(start) -- to get correct getprev.
+ end
curr = skip_white_nodes(curr)
- if getnext(curr) then curr = getnext(curr) end
+ curr = getnext(curr) or curr
local len = parent and rangedimensions(parent, start, curr)
or dimensions(start, curr) -- it works?!
if len and len ~= 0 then
local g = nodenew(glueid)
setglue(g, len)
- g.subtype = xleaders
+ g.subtype = subtype
g.leader = final and list or nodecopy(list)
local k = nodenew(kernid)
k.kern = -len
@@ -1081,8 +1087,8 @@ local function draw_uline (head, curr, parent, t, final)
return head
end
-local function process_uline (head, parent, ulitems, level)
- local curr, ulitems, level = head, ulitems or {}, level or 0
+local function process_uline (head, parent, items, level)
+ local curr, items, level = head, items or {}, level or 0
while curr do
local id = curr.id
if id == whatsitid
@@ -1091,31 +1097,36 @@ local function process_uline (head, parent, ulitems, level)
local value = curr.value
if curr.type == lua_value then
- local count, list = value[1], value[2]
- ulitems[count] = { start = curr, list = list, level = level }
- elseif ulitems[value] then
- head = draw_uline(head, curr, parent, ulitems[value], true)
- ulitems[value] = nil
+ local count, list, subtype = tableunpack(value)
+ items[count] = {
+ start = curr,
+ list = list,
+ subtype = subtype,
+ level = level,
+ }
+ elseif items[value] then
+ head = draw_uline(head, curr, parent, items[value], true)
+ items[value] = nil
end
curr.user_id = no_uline_id -- avoid multiple run
elseif id == hlistid then
local list = curr.list
if list then
- curr.list, ulitems = process_uline(list, curr, ulitems, level+1)
+ curr.list, items = process_uline(list, curr, items, level+1)
end
end
curr = getnext(curr)
end
curr = nodeslide(head)
- for i, t in pairs(ulitems) do
+ for i, t in pairs(items) do
if level == t.level then
head = draw_uline(head, curr, parent, t)
t.start = nil
end
end
- return head, ulitems
+ return head, items
end
-- ruby
@@ -1171,7 +1182,9 @@ local function process_ruby_post_linebreak (head)
ruby.list = insert_before(list, list, k)
end
ruby.width = 0
- ruby.shift = -(curr.height + ruby_t[2]) -- rubysep
+ local _, f = ruby_char_font(curr)
+ local ascender = get_font_param(f, "ascender") or curr.height
+ ruby.shift = -ascender - ruby.depth - ruby_t[2] -- rubysep
head = insert_before(head, curr, ruby)
end
ruby_t = nil
@@ -1740,9 +1753,32 @@ local function activate (name)
end
luatexko.activate = activate
--- default hangul font
+-- aux functions
local function current_has_hangul_chars (cnt)
texcount[cnt] = char_in_font(fontcurrent(), 0xAC00) and 1 or 0
end
luatexko.currenthashangulchars = current_has_hangul_chars
+
+local function get_gid_of_charslot (fd, slot)
+ if type(fd) == "number" then
+ fd = get_font_data(fd)
+ end
+ local character = fd.characters[slot]
+ return character and character.index
+end
+luatexko.get_gid_of_charslot = get_gid_of_charslot
+
+local function get_charslots_of_gid (fd, gid)
+ if type(fd) == "number" then
+ fd = get_font_data(fd)
+ end
+ local t = {}
+ for i, v in pairs(fd.characters) do
+ if v.index == gid then
+ table.insert(t, i)
+ end
+ end
+ return t
+end
+luatexko.get_charslots_of_gid = get_charslots_of_gid
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
index d575a0ce1df..bf151279768 100644
--- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
@@ -13,7 +13,7 @@
\ifdefined\luatexkohangulfontattr \endinput\fi
\ifdefined\selectfont
- \ProvidesPackage{luatexko}[2019/05/01 v2.0 typesetting Korean with LuaTeX]
+ \ProvidesPackage{luatexko}[2019/05/25 v2.1 typesetting Korean with LuaTeX]
\RequirePackage{luatexbase}
\RequirePackage{fontspec}
\else
@@ -129,7 +129,14 @@
% uline
\newcount\luatexkoulinecount
\def\ulinedown{0.5ex }\def\ulinewidth{0.04em }
-\protected\def\markoverwith#1#2{%
+\protected\def\markoverwith#1#{%
+ \ifx\empty#1\empty
+ \def\luatexkoleaderstype{101}% cleaders
+ \else
+ \def\luatexkoleaderstype{102}% xleaders
+ \fi
+ \luatexkomarkoverwith }
+\def\luatexkomarkoverwith#1#2{%
\global\advance\luatexkoulinecount\@ne
\begingroup
\count@\luatexkoulinecount
@@ -140,17 +147,17 @@
\setbox\z@\hbox{#1}%
\directlua{
if \the\luatexkoulinecount == 1 then luatexko.activate("uline") end
- luatexko.ulboundary(\the\count@, tex.box[0].list)
+ luatexko.ulboundary(\the\count@, tex.box[0].list, \luatexkoleaderstype)
}#2\directlua{
luatexko.ulboundary(\the\count@)
}\endgroup }
\protected\def\uline{\markoverwith{%
\vrule width\z@ height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax }}
-\protected\def\dashuline{\markoverwith{%
+\protected\def\dashuline{\markoverwith*{%
\hbox{\kern.125em
\vrule width.3em height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax
\kern.125em }}}
-\protected\def\dotuline{\markoverwith{%
+\protected\def\dotuline{\markoverwith*{%
\lower\dimexpr\ulinedown+.1ex\relax\hbox{\kern.07em .\kern.07em }}}
\protected\def\uuline#1{\uline{\uline{#1}}}
\protected\def\sout#1{\begingroup
@@ -161,7 +168,7 @@
\markoverwith{\lower4\p@\hbox{\luatexkofontsixly\char58}}}
% ruby
\def\rubysize{0.6} % size of ruby compared to base chars
-\def\rubysep{0.2ex} % distance between base chars and ruby
+\def\rubysep{0.1ex} % distance between base chars and ruby
\def\luatexkostretchfactor{.0125} % .5em/20/2 is hard coded.
\newif\ifruby@overlap
\let\rubyoverlap\ruby@overlaptrue
@@ -173,8 +180,7 @@
\global\advance\luatexkorubycount\@ne
\begingroup
\leavevmode
- \setbox\z@\luatexkorubybasehbox{% base
- \vrule width\z@ height 2ex depth\z@ #1}%
+ \setbox\z@\luatexkorubybasehbox{#1}% base
\setbox\tw@\hbox{% ruby
\ifdefined\rubyfont \rubyfont \fi
\ifdefined\selectfont % <- latex
@@ -202,9 +208,9 @@
\else
\ifdim\rubysize\wd\z@ > 2\wd\tw@ % ruby is far shorter
\setbox\tw@\hbox to\wd\z@{%
- \hskip\dimen@ii\relax
+ \hskip\dimen@ii plus 1sp\relax
\unhbox\tw@
- \hskip\dimen@ii\relax }%
+ \hskip\dimen@ii plus 1sp\relax }%
\else
\setbox\tw@\hbox to\wd\z@{%
\hskip\z@ plus \luatexkostretchfactor \dimen@ii\relax