From 2014750e7bcf55bab5c430e3d98d8a11430eb979 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 26 May 2019 21:24:59 +0000 Subject: luatexko (26may19) git-svn-id: svn://tug.org/texlive/trunk@51228 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 273055 -> 277717 bytes .../doc/luatex/luatexko/luatexko-doc.tex | 56 +++-- .../tex/luatex/luatexko/luatexko-normalize.lua | 230 +++++++++++++----- .../tex/luatex/luatexko/luatexko-uhc2utf8.lua | 51 ++-- Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 268 ++++++++++++--------- Master/texmf-dist/tex/luatex/luatexko/luatexko.sty | 26 +- 8 files changed, 417 insertions(+), 224 deletions(-) diff --git a/Master/texmf-dist/doc/luatex/luatexko/ChangeLog b/Master/texmf-dist/doc/luatex/luatexko/ChangeLog index 98901c4201e..68122fd00b6 100644 --- a/Master/texmf-dist/doc/luatex/luatexko/ChangeLog +++ b/Master/texmf-dist/doc/luatex/luatexko/ChangeLog @@ -1,3 +1,11 @@ +2019-05-25 Dohyun Kim + + Version 2.1 + + * luatexko.sty: give smallest stretch to quite short ruby; + allow star option to markoverwith. + + 2019-05-01 Dohyun Kim Version 2.0 diff --git a/Master/texmf-dist/doc/luatex/luatexko/README b/Master/texmf-dist/doc/luatex/luatexko/README index b2569ff3d13..e5f821aa96b 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 2.0 (2019/05/01) +LuaTeX-ko Package version 2.1 (2019/05/25) =========================================== 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 c99174f8825..dacd6f386ef 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 9206e938d40..12ee2ac8786 100644 --- a/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex +++ b/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex @@ -8,9 +8,9 @@ %% %% public domain -%\RequirePackage{luatex85} \documentclass[a4paper]{article} \usepackage[hmargin=3.8cm]{geometry} +\usepackage[svgnames]{xcolor} \usepackage[hangul]{luatexko} \setmainhangulfont{Noto Serif CJK KR}[ AutoFakeSlant, @@ -30,13 +30,13 @@ InterLatinCJK=.125em, ] \setmonofont{Inconsolatazi4}[ - Color=191970, % MidnightBlue + Color=MidnightBlue, ] \setmonohangulfont{Noto Sans CJK KR}[ UprightFont=* DemiLight, BoldFont=* Bold, CharRaise=-.2ex, - Color=191970, % MidnightBlue + Color=MidnightBlue, ] \setmathhangulfont{Noto Sans CJK KR}[ Script=Hangul, @@ -58,7 +58,7 @@ \edef\verbatim{\unexpanded\expandafter{\verbatim\linespread{1.1}\selectfont}} \edef\itemize{\unexpanded\expandafter{\itemize\small}} -\catcode`|=13 \protected\def|{\verb|\let\\=\textbackslash} %| +\catcode`|=13 \protected\def|{\verb|\let\\=\textbackslash} \protected\def\cs#1{\texttt{\language=1 \textbackslash\detokenize{#1}}} \def\logoko{\textsf{k}\kern-.0625em\textit{o}} \def\luatexko{\luatex-\logoko} @@ -66,15 +66,13 @@ \def\kotex{\logoko\kern-.1ex .\kern-.1667em \TeX} \def\hemph#1{\textsf{\bfseries #1}} \def\ldots{$\dots$} -\registerpunctuations{`-} -\automatichyphenmode=1 % for emdash in tl2019 \begin{document} \title{\luatexko\ 간단 매뉴얼} \author{Dohyun Kim \normalsize || \and Soojin Nam \normalsize || \and \normalsize <\url{http://github.com/dohyunkim/luatexko}>} -\date{Version 2.0\quad 2019/05/01} +\date{Version 2.1\quad 2019/05/25} \maketitle \begin{quote}\small @@ -309,7 +307,8 @@ fontspec의 글꼴 옵션 외에 \luatexko가 따로 제공하는 것들이 있 이 옵션은 |CharacterWidth=AlternateHalf| 내지 {\small (세로쓰기의 경우)} |Vertical=HalfMetrics|와 거의 같은 기능을 한다.% \footnote{% - 플레인텍에서는 각각 |+halt| 및 |+vhal|이다. } + 플레인텍에서는 각각 |+halt| 및 |+vhal|이다. 이들과 완전 동일하진 + 않다. 가령 U+3002 (\char"3002) 처리의 경우.} \end{description} \section{고문헌}\label{sec:classic} @@ -485,7 +484,7 @@ v2.0부터는 자동으로 수식 한글을 잡아주지 않는다. \leftskip=3em\noindent |\\font\\rubyfont=UnBatang at \\rubysize em| } -③~|\def\rubysep{0.2ex}|: 루비와 본문 글자 사이의 간격을 지정 +③~|\def\rubysep{0.1ex}|: 루비와 본문 글자 사이의 간격을 지정 ④~\cs{rubynooverlap}: 루비의 폭이 본문 글자의 폭보다 클 때 루비가 이웃 글자들 위로 삐져나가지 못하게 한다. 본문 글자의 흐름을 중시하여 @@ -502,14 +501,14 @@ ulem 패키지가 \luatexko와 궁합이 잘 맞지 않아{\small (줄바꿈에 \def\RA{\>$\Rightarrow$\>} \begin{tabbing} -\cs{dotuline{밑줄을 점선으로 긋는다}}\quad\=$\Rightarrow$\quad\= \kill -\cs{uline{밑줄을 그을 수 있다}}\RA\uline{밑줄을 그을 수 있다}\\ -\cs{sout{취소선을 그을 수 있다}}\RA\sout{취소선을 그을 수 있다}\\ -\cs{uuline{밑줄을 두 줄 긋는다}}\RA\uuline{밑줄을 두 줄 긋는다}\\ -\cs{xout{빗금으로 취소할 수 있다}}\RA\xout{빗금으로 취소할 수 있다}\\ -\cs{uwave{물결표로 밑줄을 삼는다}}\RA\uwave{물결표로 밑줄을 삼는다}\\ -\cs{dashuline{대시로 밑줄을 삼는다}}\RA\dashuline{대시로 밑줄을 삼는다}\\ -\cs{dotuline{밑줄을 점선으로 긋는다}}\RA\dotuline{밑줄을 점선으로 긋는다} + \cs{dotuline{밑줄을 점선으로 긋는다}}\quad\=$\Rightarrow$\quad\= \kill + \cs{uline{밑줄을 그을 수 있다}}\RA\uline{밑줄을 그을 수 있다}\\ + \cs{sout{취소선을 그을 수 있다}}\RA\sout{취소선을 그을 수 있다}\\ + \cs{uuline{밑줄을 두 줄 긋는다}}\RA\uuline{밑줄을 두 줄 긋는다}\\ + \cs{xout{빗금으로 취소할 수 있다}}\RA\xout{빗금으로 취소할 수 있다}\\ + \cs{uwave{물결표로 밑줄을 삼는다}}\RA\uwave{물결표로 밑줄을 삼는다}\\ + \cs{dashuline{대시로 밑줄을 삼는다}}\RA\dashuline{대시로 밑줄을 삼는다}\\ + \cs{dotuline{밑줄을 점선으로 긋는다}}\RA\dotuline{밑줄을 점선으로 긋는다} \end{tabbing} 관련하여 다음 설정을 할 수 있다. @@ -519,6 +518,29 @@ ulem 패키지가 \luatexko와 궁합이 잘 맞지 않아{\small (줄바꿈에 ②~|\def\ulinewidth{0.04em}|: 밑줄의 굵기 +\medskip +사실 위 밑줄 양식들을 만드는 데는 예외없이 \cs{markoverwith} 명령이 사용되었다. +따라서 사용자는 이를 이용해 원하는 양식을 만들 수 있다. +가령 노란색 마커펜을 흉내내려면,% +\footnote{% + 이 명령의 인자로 들어갈 수 있는 것은 box와 rule에 국한된다. + 예시에서는 박스를 넣었다.}\,% +\footnote{% + 별표 붙은 명령 \cs{markoverwith*}는 \cs{xleaders}를 실행하고, + 예시처럼 별표가 없으면 \cs{cleaders}를 실행한다. } +\begin{verbatim} + \def\ymarker{% + \markoverwith{% + \hbox{{\color{yellow!50}\vrule width 1pt height 9pt depth 2pt}}% + }} +\end{verbatim} + +\def\ymarker{\markoverwith{% + \hbox{{\color{yellow!50}\vrule width 1pt height 9pt depth 2pt}}}} + +\cs{ymarker{노란색을 칠해서 강조한다}}\quad$\Rightarrow$\quad +\ymarker{노란색을 칠해서 강조한다}. + \section{자동조사}\label{sec:autojosa} 자동조사는 \kotex 과 동일하게 \cs{은} \cs{는} \cs{이} \cs{가} \cs{을} \cs{를} \cs{와} \cs{과} \cs{로} \cs{으로} \cs{라} \cs{이라} 따위를 사용한다. 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 -- cgit v1.2.3