diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
21 files changed, 1542 insertions, 1187 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-adjust.sty b/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-adjust.sty index a9262106618..cdfad90572b 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-adjust.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-adjust.sty @@ -82,7 +82,6 @@ \expandafter\endinput\fi\relax %%------------------ -\RequirePackage{expl3} %! Main part of luatexja-adjust \RequireLuaTeXjaSubmodule{adjust} @@ -95,23 +94,23 @@ \ifltj@japaram@adjust\ltjenableadjust\else\ltjdisableadjust\fi } -\ExplSyntaxOn -\cs_new:Nn \ltj_adjust_inittable: { - % To be filled... -} -\cs_new:Nn \ltj_adjust_appendtable:n { - % To be filled -} - -\clist_new:N \l_ltj_adjust_priority -\define@key[ltj]{japaram}{adjustpriority}{% COMMA LIST - \clist_set:Nx \l_ltj_adjust_priority {#1} - \ltj_adjust_inittable: - \clist_map_function:NN \l_ltj_adjust_priority \ltj_adjust_appendtable:n -} - -\ExplSyntaxOff - +\ifltj@in@latex + \RequirePackage{expl3} + \ExplSyntaxOn + \cs_new:Nn \ltj_adjust_inittable: { + % To be filled... + } + \cs_new:Nn \ltj_adjust_appendtable:n { + % To be filled + } + \clist_new:N \l_ltj_adjust_priority + \define@key[ltj]{japaram}{adjustpriority}{% COMMA LIST + \clist_set:Nx \l_ltj_adjust_priority {#1} + \ltj_adjust_inittable: + \clist_map_function:NN \l_ltj_adjust_priority \ltj_adjust_appendtable:n + } + \ExplSyntaxOff +\fi %%------------------ all done \ltj@adjust@AtEnd diff --git a/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-fontspec.sty b/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-fontspec.sty index b1a9b4aa5c0..597e53303ff 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-fontspec.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/addons/luatexja-fontspec.sty @@ -3,7 +3,7 @@ % \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luatexja-fontspec}[2013/08/17 fontspec support of LuaTeX-ja] +\ProvidesPackage{luatexja-fontspec}[2014/01/23 fontspec support of LuaTeX-ja] \RequirePackage{fontspec,luatexja} \ExplSyntaxOn @@ -174,38 +174,31 @@ %%%%%%%% Now we completely ignore kanjifont definition file. \DeclareRobustCommand\fontfamily[1]{% - \@notkfamfalse\@notffamfalse\edef\tmp@item{{#1}}% + \@notkfamfalse\@notffamfalse + \edef\tmp@item{'\luatexluaescapestring{#1}'}% + \edef\tmp@enc{'\luatexluaescapestring{\f@encoding}'}% \ifcsname \k@encoding+#1\endcsname % if \k@encoding+#1 is already defined \edef\k@family{#1}% - \else - \def\@temp##1+{\lowercase{\def\@@temp{##1#1.fd}}}\expandafter\@temp\k@encoding+% - \@notkfamtrue - \fi + \else\@notkfamtrue\fi \ifcsname \f@encoding+#1\endcsname \edef\f@family{#1}% \else % search font definition file... - \ifcsname ffam@list@\f@encoding\endcsname\else - \expandafter\gdef\csname ffam@list@\f@encoding\endcsname{}% - \expandafter\gdef\csname notffam@list@\f@encoding\endcsname{}% - \fi - \edef\@templist{\@nameuse{ffam@list@\f@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% - \ifin@\edef\f@family{#1}\else - \edef\@templist{\@nameuse{notffam@list@\f@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% - \ifin@\@notffamtrue\else - \def\@temp##1+{\lowercase{\def\@@temp{##1#1.fd}}}\expandafter\@temp\f@encoding+% - \message{(I search font definition file. \@@temp)}% - \IfFileExists{\@@temp}{\@tempswztrue}{\@tempswzfalse}% - \if@tempswz - \expandafter\xdef\csname ffam@list@\f@encoding\endcsname - {\@nameuse{ffam@list@\f@encoding}\fam@elt<#1>}\edef\f@family{#1}% - \else - \expandafter\xdef\csname notffam@list@\f@encoding\endcsname - {\@nameuse{notffam@list@\f@encoding}\fam@elt<#1>}\@notffamtrue% - \fi - \fi - \fi + \directlua{luatexja.jfont.is_ffam(\tmp@enc, \tmp@item)}% + \ifin@\edef\k@family{#1}\else% + \directlua{luatexja.jfont.is_Nffam(\tmp@enc, \tmp@item)}% + \ifin@\@notffamtrue\else% + \def\@temp##1+{\lowercase{\def\@@temp{##1#1.fd}}}\expandafter\@temp\f@encoding+% + \message{(I search kanjifont definition file: \@@temp)}% + \IfFileExists{\@@temp#1.fd}{\@tempswztrue}{\@tempswzfalse}% + \if@tempswz + \directlua{luatexja.jfont.add_ffam_list(\tmp@enc, \tmp@item)}% + \edef\f@family{#1}% + \else + \directlua{luatexja.jfont.add_Nffam_list(\tmp@enc, \tmp@item)}% + \@notffamtrue% + \fi + \fi + \fi \fi \if@notkfam\if@notffam {\ifcsname D@\k@encoding\endcsname\@nameuse{D@\k@encoding}\fi @@ -219,17 +212,12 @@ \def\try@load@fontshape{% \expandafter \ifx\csname \f@encoding+\f@family\endcsname\relax - \edef\tmp@item{{\directlua{% - tex.print(luatexbase.catcodetables["latex-package"], '\f@encoding')}% - }}% \f@encoding の展開結果の catcode は 12 であるため,これで補正. - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kenc@list}% + \directlua{luatexja.jfont.is_kenc('\luatexluaescapestring{\f@encoding}')}% \ifin@ % Japanese font: we don't search fd. \@font@warning{We don't search kanjifont definition \MessageBreak for \f@encoding/\f@family}% \else % Alphabetic font - \@font@info{Try loading font information for - \f@encoding+\f@family}% + \@font@info{Try loading font information for \f@encoding+\f@family}% \global\expandafter\let \csname\f@encoding+\f@family\endcsname\@empty \nfss@catcodes diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-adjust.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-adjust.lua index c81930a5e8a..5406399613d 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-adjust.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-adjust.lua @@ -3,13 +3,39 @@ -- luatexbase.provides_module({ name = 'luatexja.adjust', - date = '2013/03/14', + date = '2014/02/02', description = 'Advanced line adjustment for LuaTeX-ja', }) module('luatexja.adjust', package.seeall) luatexja.load_module('jfont'); local ltjf = luatexja.jfont luatexja.load_module('jfmglue'); local ltjj = luatexja.jfmglue +luatexja.load_module('stack'); local ltjs = luatexja.stack + +local Dnode = node.direct or node + +local nullfunc = function(n) return n end +local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getlist = (Dnode ~= node) and Dnode.getlist or function(n) return n.head end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end + +local node_traverse_id = Dnode.traverse_id +local node_new = Dnode.new +local node_copy = Dnode.copy +local node_hpack = Dnode.hpack +local node_next = (Dnode ~= node) and Dnode.getnext or node.next +local node_free = Dnode.free +local node_prev = (Dnode ~= node) and Dnode.getprev or node.prev +local node_tail = Dnode.tail +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local insert_after = Dnode.insert_after local id_glyph = node.id('glyph') local id_kern = node.id('kern') @@ -17,22 +43,20 @@ local id_hlist = node.id('hlist') local id_glue = node.id('glue') local id_glue_spec = node.id('glue_spec') local id_whatsit = node.id('whatsit') -local has_attr = node.has_attribute -local set_attr = node.set_attribute local attr_icflag = luatexbase.attributes['ltj@icflag'] local attr_jchar_class = luatexbase.attributes['ltj@charclass'] local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] -local node_copy = node.copy -local node_next = node.next -local node_free = node.free local ltjf_font_metric_table = ltjf.font_metric_table local spec_zero_glue = ltjj.spec_zero_glue +local round, pairs = tex.round, pairs local PACKED = luatexja.icflag_table.PACKED local FROM_JFM = luatexja.icflag_table.FROM_JFM local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP +local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP +local XKANJI_SKIP_JFM = luatexja.icflag_table.XKANJI_SKIP_JFM local priority_table = { FROM_JFM + 2, @@ -44,69 +68,77 @@ local priority_table = { KANJI_SKIP } -local PROCESSED_BEGIN_FLAG = 32 -local function get_attr_icflag(p) - return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG +local get_attr_icflag +do + local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG + get_attr_icflag = function(p) + return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG + end end -- box 内で伸縮された glue の合計値を計算 local function get_stretched(q, go, gs) - local qs = q.spec - if not qs.writable then return 0 end + local qs = getfield(q, 'spec') + if not getfield(qs, 'writable') then return 0 end if gs == 1 then -- stretching - if qs.stretch_order == go then return qs.stretch end + if getfield(qs, 'stretch_order') == go then + return getfield(qs, 'stretch') + end else -- shrinking - if qs.shrink_order == go then return qs.shrink end + if getfield(qs, 'shrink_order') == go then + return getfield(qs, 'shrink') + end end end --- local new_ks, new_xs -local function get_total_stretched(p) - local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign - local res = { - [0] = 0, - glue_set = gf, name = (gs==1) and 'stretch' or 'shrink' - } - for i=1,#priority_table do res[priority_table[i]]=0 end +local res = {} +local gs_used_line = {} +local function get_total_stretched(p, line) + local go, gf, gs + = getfield(p, 'glue_order'), getfield(p, 'glue_set'), getfield(p, 'glue_sign') if go ~= 0 then return nil end - if gs ~= 1 and gs ~= 2 then return res end - local head = p.head - q = p.head - --luatexja.ext_show_node_list(p.head, '>>> ', print) - while q do - if q.id==id_glue then - local a, ic = get_stretched(q, go, gs), get_attr_icflag(q) - if type(res[ic]) == 'number' then - -- kanjiskip, xkanjiskip は段落内で spec を共有しているが, - -- それはここでは望ましくないので,各 glue ごとに異なる spec を使う. - -- JFM グルーはそれぞれ異なる glue_spec を用いているので,問題ない. - res[ic] = res[ic] + a - if ic == KANJI_SKIP or ic == XKANJI_SKIP then - if q.spec ~= spec_zero_glue then - local ts, g; - q.spec, ts = node_copy(q.spec), q.spec - g = node.copy(q); q.spec = ts - node.insert_before(head, q, g); - head = node.remove(head, q); node.free(q); q = g - end - end - else - res[0] = res[0] + a - end + res[0], res.glue_set, res.name = 0, gf, (gs==1) and 'stretch' or 'shrink' + for i=1,#priority_table do res[priority_table[i]]=0 end + if gs ~= 1 and gs ~= 2 then return res, 0 end + local total = 0 + for q in node_traverse_id(id_glue, getlist(p)) do + local a, ic = get_stretched(q, go, gs), get_attr_icflag(q) + if type(res[ic]) == 'number' then + -- kanjiskip, xkanjiskip は段落内で spec を共有しているが, + -- それはここでは望ましくないので,各 glue ごとに異なる spec を使う. + -- 本当は各行ごとに glue_spec を共有させたかったが,安直にやると + -- ref_count が 0 なので Double-free が発生する.どうする? + -- JFM グルーはそれぞれ異なる glue_spec を用いているので,問題ない. + if (ic == KANJI_SKIP or ic == XKANJI_SKIP) and getsubtype(q)==0 then + local qs = getfield(q, 'spec') + if qs ~= spec_zero_glue then + if (gs_used_line[qs] or 0)<line then + setfield(q, 'spec', node_copy(qs)) + local f = node_new(id_glue); setfield(f, 'spec', qs); node_free(f) + -- decrese qs's reference count + else + gs_used_line[qs] = line + end + end + elseif ic == KANJI_SKIP_JFM then ic = KANJI_SKIP + elseif ic == XKANJI_SKIP_JFM then ic = XKANJI_SKIP + end + res[ic], total = res[ic] + a, total + a + else + res[0], total = res[0] + a, total + a end - q = node_next(q) end - return res + return res, total end local function clear_stretch(p, ic, name) - --print('clear ' .. ic) - for q in node.traverse_id(id_glue, p.head) do + for q in node_traverse_id(id_glue, getlist(p)) do if get_attr_icflag(q) == ic then - local qs = q.spec - if qs.writable then - qs[name..'_order'], qs[name] = 0, 0 + local qs = getfield(q, 'spec') + if getfield(qs, 'writable') then + setfield(qs, name..'_order', 0) + setfield(qs, name, 0) end end end @@ -115,19 +147,20 @@ end local set_stretch_table = {} local function set_stretch(p, after, before, ic, name) if before > 0 then - --print (ic, before, after) local ratio = after/before for i,_ in pairs(set_stretch_table) do set_stretch_table[i] = nil end - for q in node.traverse_id(id_glue, p.head) do - if get_attr_icflag(q) == ic then - local qs, do_flag = q.spec, true + for q in node_traverse_id(id_glue, getlist(p)) do + local f = get_attr_icflag(q) + if (f == ic) or ((ic ==KANJI_SKIP) and (f == KANJI_SKIP_JFM)) + or ((ic ==XKANJI_SKIP) and (f == XKANJI_SKIP_JFM)) then + local qs, do_flag = getfield(q, 'spec'), true for i=1,#set_stretch_table do if set_stretch_table[i]==qs then do_flag = false end end - if qs.writable and qs[name..'_order'] == 0 and do_flag then - qs[name] = qs[name]*ratio; + if getfield(qs, 'writable') and getfield(qs, name..'_order')==0 and do_flag then + setfield(qs, name, getfield(qs, name)*ratio) set_stretch_table[#set_stretch_table+1] = qs end end @@ -137,36 +170,40 @@ end -- step 1: 行末に kern を挿入(句読点,中点用) local function aw_step1(p, res, total) - local x = node.tail(p.head); if not x then return false end - local x = node.prev(x) ; if not x then return false end - -- 本当の行末の node を格納 - if x.id == id_glue and x.subtype == 15 then + local x = node_tail(getlist(p)); if not x then return false end + -- x: \rightskip + x = node_prev(x); if not x then return false end + if getid(x) == id_glue and getsubtype(x) == 15 then -- 段落最終行のときは,\penalty10000 \parfillskip が入るので, -- その前の node が本来の末尾文字となる - x = node.prev(node.prev(x)) + x = node_prev(node_prev(x)) end - local xi, xc = x.id - if xi == id_glyph and has_attr(x, attr_curjfnt) == x.font then + -- local xi = getid(x) + -- while (get_attr_icflag(x) == PACKED) + -- and ((xi == id_penalty) or (xi == id_kern) or (xi == id_kern)) do + -- x = node_prev(x); xi = getid(x) + -- end + local xi, xc = getid(x) + if xi == id_glyph and has_attr(x, attr_curjfnt) == getfont(x) then -- 和文文字 xc = x elseif xi == id_hlist and get_attr_icflag(x) == PACKED then -- packed JAchar - xc = x.head - while xc.id == id_whatsit do xc = node.next(xc) end + xc = getlist(x) + while getid(xc) == id_whatsit do xc = node_next(xc) end else return false-- それ以外は対象外. end - local xk = ltjf_font_metric_table[xc.font] - xk = xk.char_type[has_attr(xc, attr_jchar_class) or 0] - xk = xk['end_' .. res.name] or 0 + local xk = ltjf_font_metric_table[getfont(xc)] + xk = xk.char_type[has_attr(xc, attr_jchar_class) or 0] + xk = xk['end_' .. res.name] or 0 if xk>0 and total>=xk then - --print("ADDED") total = total - xk - local kn = node.new(id_kern) - kn.kern = (res.name=='shrink' and -1 or 1) * xk + local kn = node_new(id_kern) + setfield(kn, 'kern', (res.name=='shrink' and -1 or 1) * xk) set_attr(kn, attr_icflag, FROM_JFM) - node.insert_after(p.head, x, kn) + insert_after(head, x, kn) return true else return false end @@ -176,71 +213,80 @@ end local function aw_step2(p, res, total, added_flag) if total == 0 then -- もともと伸縮の必要なし if added_flag then -- 行末に kern 追加したので,それによる補正 - local f = node.hpack(p.head, p.width, 'exactly') - f.head, p.glue_set, p.glue_sign, p.glue_order - = nil, f.glue_set, f.glue_sign, f.glue_order - node.free(f); return + local f = node_hpack(getlist(p), getfield(p, 'width'), 'exactly') + setfield(f, 'head', nil) + setfield(p, 'glue_set', getfield(f, 'glue_set')) + setfield(p, 'glue_order', getfield(f, 'glue_order')) + setfield(p, 'glue_sign', getfield(f, 'glue_sign')) + node_free(f) + return end elseif total <= res[0] then -- 和文処理グルー以外で足りる for _,v in pairs(priority_table) do clear_stretch(p, v, res.name) end - local f = node.hpack(p.head, p.width, 'exactly') - f.head, p.glue_set, p.glue_sign, p.glue_order - = nil, f.glue_set, f.glue_sign, f.glue_order - node.free(f) + local f = node_hpack(getlist(p), getfield(p, 'width'), 'exactly') + setfield(f, 'head', nil) + setfield(p, 'glue_set', getfield(f, 'glue_set')) + setfield(p, 'glue_order', getfield(f, 'glue_order')) + setfield(p, 'glue_sign', getfield(f, 'glue_sign')) + node_free(f) else - total, i = total - res[0], 1 - while i <= #priority_table do + total = total - res[0] + for i = 1, #priority_table do local v = priority_table[i] if total <= res[v] then for j = i+1,#priority_table do clear_stretch(p, priority_table[j], res.name) end - set_stretch(p, total, res[v], v, res.name) - i = #priority_table + 9 -- ループから抜けさせたいため + set_stretch(p, total, res[v], v, res.name); break end - total, i= total - res[v], i+1 - end - if i == #priority_table + 10 or added_flag then - local f = node.hpack(p.head, p.width, 'exactly') - f.head, p.glue_set, p.glue_sign, p.glue_order - = nil, f.glue_set, f.glue_sign, f.glue_order - node.free(f) + total = total - res[v] end + local f = node_hpack(getlist(p), getfield(p, 'width'), 'exactly') + setfield(f, 'head', nil) + setfield(p, 'glue_set', getfield(f, 'glue_set')) + setfield(p, 'glue_order', getfield(f, 'glue_order')) + setfield(p, 'glue_sign', getfield(f, 'glue_sign')) + node_free(f) end end -function adjust_width(head) +local ltjs_fast_get_stack_skip = ltjs.fast_get_stack_skip +local function adjust_width(head) if not head then return head end - for p in node.traverse_id(id_hlist, head) do - local res = get_total_stretched(p) - --print(table.serialize(res)) - if res then - -- 調整量の合計 - local total = 0 - for i,v in pairs(res) do - if type(i)=='number' then - total = total + v - end - end; total = tex.round(total * res.glue_set) - local added_flag = aw_step1(p, res, total) - --print(total, res[0], res[KANJI_SKIP], res[FROM_JFM]) - aw_step2(p, res, total, added_flag) + local line = 1 + for p in node_traverse_id(id_hlist, to_direct(head)) do + line = line + 1 + local res, total = get_total_stretched(p, line) + -- this is the same table as the table which is def'd in l. 92 + if res and res.glue_set<1 then + total = round(total * res.glue_set) + aw_step2(p, res, total, aw_step1(p, res, total)) end end - return head + for i,_ in pairs(gs_used_line) do + gs_used_line[i] = nil + end + return to_node(head) end -local is_reg = false -function enable_cb() - if not is_reg then - luatexbase.add_to_callback('post_linebreak_filter', adjust_width, 'Adjust width', 100) - is_reg = true +do + local is_reg = false + function enable_cb() + if not is_reg then + luatexbase.add_to_callback('post_linebreak_filter', + adjust_width, 'Adjust width', 100) + is_reg = true + end end -end -function disable_cb() - if is_reg then - luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width') - is_reg = false + function disable_cb() + if is_reg then + luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width') + is_reg = false + end end end + +luatexja.unary_pars.adjust = function(t) + return is_reg and 1 or 0 +end diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua index 1ca2a0a8486..495f185fed2 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua @@ -8,9 +8,13 @@ local node, table, tex, token = node, table, tex, token local cat_lp = luatexbase.catcodetables['latex-package'] -------------------- +luatexja.base = {} local public_name = 'luatexja' local public_version = 'alpha' +luatexja.base.public_name = public_name +luatexja.base.public_version = public_version + -------------------- Fully-expandable error messaging local _error_set_break, _error_set_message, _error_show @@ -146,10 +150,9 @@ local function mprint(...) end return tex.print(unpack(lines)) end +luatexja.base.mprint = mprint -------------------- Handling of TeX values -local to_dimen, to_skip, dump_skip - do local glue_spec_id = node.id("glue_spec") @@ -167,7 +170,7 @@ do end --! ixbase.to_dimen() と同じ - to_dimen = function (val) + local function to_dimen(val) if val == nil then return 0 elseif type(val) == "number" then @@ -189,7 +192,7 @@ do end --! ixbase.to_skip() と同じ - to_skip = function (val) + local function to_skip(val) if type(val) == "userdata" then return val end @@ -217,16 +220,19 @@ do return res end - dump_skip = function (s) + local function dump_skip(s) print(("%s+%s<%s>-%s<%s>"):format( s.width or 0, s.stretch or 0, s.stretch_order or 0, s.shrink or 0, s.shrink_order or 0)) end + luatexja.base.to_dimen = to_dimen + luatexja.base.dump_skip = dump_skip + luatexja.base.to_skip = to_skip end --------------------- Virtual table for LaTeX counters -local counter +-------------------- Virtual table for LaTeX counters +-- not used in current LuaTeX-ja do --! ixbase.counter と同じ counter = {} @@ -239,13 +245,12 @@ do function mt_counter.__newindex(tbl, key, val) tex.count['c@'..key] = val end + luatexja.base.counter = counter --! ixbase.length は tex.skip と全く同じなので不要. end -------------------- Number handling in TeX source -local scan_brace, scan_number - do local tok_escape = token.create("ltj@@q@escape") @@ -338,7 +343,7 @@ do ltb.add_to_callback("token_filter", proc, "ltj@grab@num", 1) end - scan_brace = function () + local function scan_brace() scan_with(1, function() local next = token.get_next() if next[1] == 1 then @@ -351,7 +356,7 @@ do end) end - scan_number = function () + local function scan_number() scan_with(1, function() local next = get_expd_next() local res, ok = { tok_num }, false @@ -386,9 +391,12 @@ do end) end + luatexja.base.scan_brace = scan_brace + luatexja.base.scan_number = scan_number end + -------------------- TeX register allocation -local const_number, count_number, attribute_number, dimen_number, skip_number +-- not used in current LuaTeX-ja do local cmod_base_count = token.create('ltj@@count@zero')[2] @@ -396,34 +404,39 @@ do local cmod_base_dimen = token.create('ltj@@dimen@zero')[2] local cmod_base_skip = token.create('ltj@@skip@zero')[2] - const_number = function (name) + local function const_number(name) if name:sub(1, 1) == '\\' then name = name:sub(2) end return token.create(name)[2] end - count_number = function (name) + local function count_number(name) if name:sub(1, 1) == '\\' then name = name:sub(2) end return token.create(name)[2] - cmod_base_count end - attribute_number = function (name) + local function attribute_number(name) if name:sub(1, 1) == '\\' then name = name:sub(2) end return token.create(name)[2] - cmod_base_attr end - dimen_number = function (name) + local function dimen_number(name) if name:sub(1, 1) == '\\' then name = name:sub(2) end return token.create(name)[2] - cmod_base_dimen end - skip_number = function (name) + local function skip_number(name) if name:sub(1, 1) == '\\' then name = name:sub(2) end return token.create(name)[2] - cmod_base_skip end + luatexja.base.const_number = const_number + luatexja.base.count_number = count_number + luatexja.base.attribute_number = attribute_number + luatexja.base.dimen_number = dimen_number + luatexja.base.skip_number = skip_number end --------------------- mock of debug logger +-------------------- mock of debug logger if not debug or debug == _G.debug then local function no_op() end debug = no_op @@ -441,7 +454,25 @@ local function get_cs(s) cstemp = token.csname_name(token.get_next()) tex.sprint(cat_lp,'\\' .. s) end +luatexja.base.get_cs = get_cs +-------------------- common error message +do + local function in_unicode(c, admit_math) + local low = admit_math and -1 or 0 + if type(c)~='number' or c<low or c>0x10FFFF then + local s = 'A character number must be between ' .. tostring(low) + .. ' and 0x10ffff.\n' + .. (admit_math and "(-1 is used for denoting `math boundary')\n" or '') + .. 'So I changed this one to zero.' + package_error('luatexja', + 'bad character code (' .. tostring(c) .. ')', s) + c=0 + end + return c + end + luatexja.base.in_unicode = in_unicode +end -------------------- cache management -- load_cache (filename, outdate) @@ -457,12 +488,16 @@ end require('lualibs-lpeg') -- string.split require('lualibs-os') -- os.type -local load_cache, save_cache_luc, save_cache - do - local path = kpse.expand_var("$TEXMFVAR;$TEXMFSYSVAR;$TEXMFCACHE") + local kpse_var_value = kpse.var_value + local path, pathtmp = kpse_var_value("TEXMFVAR") + pathtmp = kpse_var_value("TEXMFSYSVAR") + if pathtmp then path = (path and path .. ';' or '') .. pathtmp end + pathtmp = kpse_var_value("TEXMFCACHE") + if pathtmp then path = (path and path .. ';' or '') .. pathtmp end + if os.type~='windows' then path = string.gsub(path, ':', ';') end - path = string.split(path, ';') + path = table.unique(string.split(path, ';')) local cache_dir = '/luatexja' local find_file = kpse.find_file @@ -522,6 +557,7 @@ do return result end end + load_cache = function (filename, outdate) local r = load_cache_a(filename .. luc_suffix, outdate) if r then @@ -533,62 +569,36 @@ do end end + luatexja.base.load_cache = load_cache + luatexja.base.save_cache_luc = save_cache_luc + luatexja.base.save_cache = save_cache end +luatexja.base._error_set_break = _error_set_break +luatexja.base._error_set_message = _error_set_message +luatexja.base._error_show = _error_show +luatexja.base._generic_warn_info = _generic_warn_info + +luatexja.base.package_error = package_error +luatexja.base.package_warning = package_warning +luatexja.base.package_warning_no_line = package_warning_no_line +luatexja.base.package_info = package_info +luatexja.base.package_info_no_line = package_info_no_line + +luatexja.base.generic_error = generic_error +luatexja.base.generic_warning = generic_warning +luatexja.base.generic_warning_no_line = generic_warning_no_line +luatexja.base.generic_info = generic_info +luatexja.base.generic_info_no_line = generic_info_no_line + +luatexja.base.ltj_warning_no_line = ltj_warning_no_line +luatexja.base.ltj_error = ltj_error + +luatexja.base.debug = debug +luatexja.base.package_debug = package_debug +luatexja.base.debug_logger = debug_logger +luatexja.base.show_term = show_term +luatexja.base.show_log = show_log -luatexja.base = { - public_name = public_name, - public_version = public_version, - -- - _error_set_break = _error_set_break, - _error_set_message = _error_set_message, - _error_show = _error_show, - _generic_warn_info = _generic_warn_info, - -- - package_error = package_error, - package_warning = package_warning, - package_warning_no_line = package_warning_no_line, - package_info = package_info, - package_info_no_line = package_info_no_line, - -- - generic_error = generic_error, - generic_warning = generic_warning, - generic_warning_no_line = generic_warning_no_line, - generic_info = generic_info, - generic_info_no_line = generic_info_no_line, - -- - ltj_warning_no_line = ltj_warning_no_line, - ltj_error = ltj_error, - -- - mprint = mprint, - -- - to_dimen = to_dimen, - dump_skip = dump_skip, - to_skip = to_skip, - -- - counter = counter, - -- - scan_brace = scan_brace, - scan_number = scan_number, - -- - const_number = const_number, - count_number = count_number, - attribute_number = attribute_number, - dimen_number = dimen_number, - skip_number = skip_number, - -- - get_cs = get_cs, - -- - load_cache = load_cache, - save_cache_luc = save_cache_luc, - save_cache = save_cache, - -- - debug = debug, - package_debug = package_debug, - debug_logger = debug_logger, - show_term = show_term, - show_log = show_log, - -- -} -------------------- all done -- EOF diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-charrange.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-charrange.lua index e3478ab8180..e2d97de7134 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-charrange.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-charrange.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.charrange', - date = '2012/10/21', + date = '2014/01/19', description = 'Handling the range of Japanese characters', }) module('luatexja.charrange', package.seeall) @@ -11,37 +11,47 @@ local err, warn, info, log = luatexbase.errwarinf(_NAME) luatexja.load_module('base'); local ltjb = luatexja.base +local Dnode = node.direct or node +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end +local has_attr = Dnode.has_attribute +local has_attr_node = node.has_attribute +local tex_getattr = tex.getattribute + ATTR_RANGE = 7 +local jcr_cjk, jcr_noncjk = 0, 1 local floor = math.floor local pow = math.pow -local has_attr = node.has_attribute local kcat_attr_table = {} local pow_table = {} +local fn_table = {} -- used in is_ucs_in_japanese_char_direct for i = 0, 31*ATTR_RANGE-1 do kcat_attr_table[i] = luatexbase.attributes['ltj@kcat'..floor(i/31)] pow_table[i] = pow(2, i%31) + fn_table[i] = function(p) + return floor(has_attr(p, kcat_attr_table[i])/pow_table[i])%2 ~= jcr_noncjk + end end pow_table[31*ATTR_RANGE] = pow(2, 31) -- jcr_table_main[chr_code] = index --- index : internal 0, 1, 2, ..., 216 0: 'other' --- external 1 2 216, (out of range): 'other' +-- index : internal 0, 1, 2, ..., 216 0: 'other' +-- external 217, 1 2 216, 217 and (out of range): 'other' -- initialize jcr_table_main = {} local jcr_table_main = jcr_table_main -local jcr_cjk = 0; local jcr_noncjk = 1; local ucs_out = 0x110000 +local ucs_out = 0x110000 for i=0x80 ,0xFF do jcr_table_main[i]=1 end for i=0x100,ucs_out-1 do jcr_table_main[i]=0 end -- EXT: add characters to a range function add_char_range(b,e,ind) -- ind: external range number - if not ind or ind<0 or ind>=31*ATTR_RANGE then -- 0 は error にしない(隠し) + if not ind or ind<0 or ind>31*ATTR_RANGE then -- 0 はエラーにしない(隠し) ltjb.package_error('luatexja', "invalid character range number (" .. ind .. ")", "A character range number should be in the range 1.." - .. 31*ATTR_RANGE-1 .. ",\n" .. + .. 31*ATTR_RANGE .. ",\n" .. "ignored.") return elseif b<0x80 or e>=ucs_out then @@ -51,37 +61,51 @@ function add_char_range(b,e,ind) -- ind: external range number elseif b>e then local j=b; e=b; b=j end + if ind == 31*ATTR_RANGE then ind=0 end for i=math.max(0x80,b),math.min(ucs_out-1,e) do jcr_table_main[i]=ind end end -function char_to_range(c) -- return the (external) range number - if not c or c<0 or c>0x10FFFF then - ltjb.package_error('luatexja', - 'bad character code (' .. tostring(c) .. ')', - 'A character number must be between 0 and 0x10ffff.\n' .. - 'So I changed this one to zero.') - c=0 - elseif c<0x80 then return -1 - else return jcr_table_main[c] or 0 end +function char_to_range(c) -- return the external range number + c=ltjb.in_unicode(c, false) + if c<0x80 then return -1 + else + local r = jcr_table_main[c] or 217 + return (r and r~=0) and r or 217 + end end function get_range_setting(i) -- i: internal range number - return floor(tex.getattribute(kcat_attr_table[i])/pow_table[i])%2 + return floor(tex_getattr(kcat_attr_table[i])/pow_table[i])%2 end -- glyph_node p は和文文字か? -function is_ucs_in_japanese_char(p) +function is_ucs_in_japanese_char_node(p) local c = p.char if c<0x80 then return false else local i=jcr_table_main[c] return (floor( - has_attr(p, kcat_attr_table[i])/pow_table[i])%2 ~= jcr_noncjk) + has_attr_node(p, kcat_attr_table[i])/pow_table[i])%2 ~= jcr_noncjk) end end +is_ucs_in_japanese_char = is_ucs_in_japanese_char_node + +function is_ucs_in_japanese_char_direct(p) + local c = getchar(p) + if c<0x80 then + return false + else + return fn_table[jcr_table_main[c]](p) + end +end + +function is_japanese_char_curlist(c) -- assume that c>=0x80 + local i=jcr_table_main[c] + return get_range_setting(i)~= jcr_noncjk +end -- EXT function toggle_char_range(g, i) -- i: external range number @@ -95,7 +119,7 @@ function toggle_char_range(g, i) -- i: external range number if i>0 then kc=0 else kc=1; i=-i end if i>=7*ATTR_RANGE then i=0 end local attr = kcat_attr_table[i] - local a = tex.getattribute(attr) + local a = tex_getattr(attr) tex.setattribute(g,attr,(floor(a/pow_table[i+1])*2+kc)*pow_table[i]+a%pow_table[i]) end end diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-compat.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-compat.lua index 6fe8e4fd168..af5da70c41c 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-compat.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-compat.lua @@ -4,6 +4,7 @@ luatexja.load_module('base'); local ltjb = luatexja.base luatexja.load_module('stack'); local ltjs = luatexja.stack +local stack_table_index = luatexja.stack_table_index -- load jisx0208 table local cache_ver = 2 @@ -25,7 +26,7 @@ local function to_kansuji(num) local s = "" while num~=0 do s = utf.char( - ltjs.get_penalty_table(luatexja.stack_table_index.KSJ + num%10, + ltjs.get_stack_table(luatexja.stack_table_index.KSJ + num%10, '', tex.getcount('ltj@@stack'))) .. s num=math.floor(num/10) end @@ -115,6 +116,18 @@ local function from_sjis(i) end end +luatexja.binary_pars.kansujichar = function(c, t) + if type(c)~='number' or c<0 or c>9 then + ltjb.package_error('luatexja', + 'Invalid KANSUJI number (' .. tostring(c) .. ')', + 'A KANSUJI number should be in the range 0..9.\n'.. + 'So I changed this one to zero.') + c=0 + end + return ltjs.get_stack_table(stack_table_index.KSJ + c, 0, t) +end + + local t = { from_euc = from_euc, from_kuten = from_kuten, diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-inputbuf.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-inputbuf.lua index f90047247c0..cfef819b869 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-inputbuf.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-inputbuf.lua @@ -11,7 +11,7 @@ local node_new = node.new local node_free = node.free local id_glyph = node.id('glyph') local getcatcode = tex.getcatcode -local ltjc_is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char +local ltjc_is_japanese_char_curlist = ltjc.is_japanese_char_curlist local FFFFF = string.char(0xF3,0xBF,0xBF,0xBF) --- the following function is modified from jafontspec.lua (by K. Maeda). @@ -31,12 +31,9 @@ local function add_comment(buffer) -- Is the catcode of endline character is 5 (end-of-line)? -- Is the catcode of U+FFFFF (new comment char) is 14 (comment)? if ((ct==11) or (ct==12)) and ctl then - local p = node_new(id_glyph) - p.char = c - if ltjc_is_ucs_in_japanese_char(p) then + if ltjc_is_japanese_char_curlist(c) then buffer = buffer .. FFFFF -- U+FFFFF end - node_free(p) end end end diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfmglue.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfmglue.lua index a0df4e7e530..3678027dafc 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfmglue.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfmglue.lua @@ -3,28 +3,45 @@ -- luatexbase.provides_module({ name = 'luatexja.jfmglue', - date = '2013/12/05', + date = '2014/02/02', description = 'Insertion process of JFM glues and kanjiskip', }) module('luatexja.jfmglue', package.seeall) -local err, warn, info, log = luatexbase.errwarinf(_NAME) +local err, warn, info, log = luatexbase .errwarinf(_NAME) luatexja.load_module('stack'); local ltjs = luatexja.stack luatexja.load_module('jfont'); local ltjf = luatexja.jfont -luatexja.load_module('pretreat'); local ltjp = luatexja.pretreat +local pairs = pairs -local has_attr = node.has_attribute -local set_attr = node.set_attribute -local insert_before = node.insert_before -local node_next = node.next +local Dnode = node.direct or node + +local nullfunc = function(n) return n end +local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +local getlist = (Dnode ~= node) and Dnode.getlist or function(n) return n.head end +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end +local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end + +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local insert_before = Dnode.insert_before +local insert_after = Dnode.insert_after +local node_next = (Dnode ~= node) and Dnode.getnext or node.next local round = tex.round local ltjf_font_metric_table = ltjf.font_metric_table local ltjf_find_char_class = ltjf.find_char_class -local node_new = node.new -local node_copy = node.copy +local node_new = Dnode.new +local node_copy = Dnode.copy +local node_remove = luatexja.Dnode_remove -- Dnode.remove +local node_tail = Dnode.tail +local node_free = Dnode.free +local node_end_of_math = Dnode.end_of_math -local ligature_head = 1 -local ligature_tail = 2 local id_glyph = node.id('glyph') local id_hlist = node.id('hlist') @@ -56,8 +73,6 @@ local ITALIC = luatexja.icflag_table.ITALIC local PACKED = luatexja.icflag_table.PACKED local KINSOKU = luatexja.icflag_table.KINSOKU local FROM_JFM = luatexja.icflag_table.FROM_JFM -local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP -local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP local PROCESSED = luatexja.icflag_table.PROCESSED local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED local BOXBDD = luatexja.icflag_table.BOXBDD @@ -93,32 +108,39 @@ local function slow_find_char_class(c, m, oc) end local zero_glue = node_new(id_glue) -spec_zero_glue = node_new(id_glue_spec) -- must be public, since mentioned from other sources -local spec_zero_glue = spec_zero_glue - spec_zero_glue.width = 0; spec_zero_glue.stretch_order = 0; spec_zero_glue.stretch = 0 - spec_zero_glue.shrink_order = 0; spec_zero_glue.shrink = 0 - zero_glue.spec = spec_zero_glue +spec_zero_glue = to_node(node_new(id_glue_spec)) + -- must be public, since mentioned from other sources +local spec_zero_glue = to_direct(spec_zero_glue) +setfield(spec_zero_glue, 'width', 0) +setfield(spec_zero_glue, 'stretch', 0) +setfield(spec_zero_glue, 'shrink', 0) +setfield(spec_zero_glue, 'stretch_order', 0) +setfield(spec_zero_glue, 'shrink_order', 0) +setfield(zero_glue, 'spec', spec_zero_glue) local function skip_table_to_spec(n) - local g, st = node_new(id_glue_spec), ltjs.fast_get_skip_table(n) - g.width = st.width; g.stretch = st.stretch; g.shrink = st.shrink - g.stretch_order = st.stretch_order; g.shrink_order = st.shrink_order + local g, st = node_new(id_glue_spec), ltjs.fast_get_stack_skip(n) + setfield(g, 'width', st.width) + setfield(g, 'stretch', st.stretch) + setfield(g, 'shrink', st.shrink) + setfield(g, 'stretch_order', st.stretch_order) + setfield(g, 'shrink_order', st.shrink_order) return g end -- penalty 値の計算 local function add_penalty(p,e) - local pp = p.penalty + local pp = getfield(p, 'penalty') if pp>=10000 then if e<=-10000 then pp = 0 end elseif pp<=-10000 then if e>=10000 then pp = 0 end else pp = pp + e - if pp>=10000 then p.penalty = 10000 - elseif pp<=-10000 then p.penalty = -10000 - else p.penalty = pp end + if pp>=10000 then setfield(p, 'penalty', 10000) + elseif pp<=-10000 then setfield(p, 'penalty', -10000) + else setfield(p, 'penalty', pp) end end return end @@ -127,7 +149,7 @@ end diffmet_rule = math.two_paverage function math.two_add(a,b) return a+b end function math.two_average(a,b) return (a+b)*0.5 end -function math.two_paverage(a,b) return (a+b)*0.5 end +function math.two_paverage(a,b) return (a+b)/2 end function math.two_pleft(a,b) return a end function math.two_pright(a,b) return b end @@ -150,9 +172,9 @@ local function check_box(box_ptr, box_end) return true end while p and p~=box_end do - local pid = p.id - if pid==id_kern and p.subtype==2 then - p = node_next(node_next(node_next(p))); pid = p.id -- p must be glyph_node + local pid = getid(p) + if pid==id_kern and getsubtype(p)==2 then + p = node_next(node_next(node_next(p))); pid = getid(p) -- p must be glyph_node end if pid==id_glyph then repeat @@ -163,37 +185,32 @@ local function check_box(box_ptr, box_end) if (not p) or p==box_end then return found_visible_node end - until p.id~=id_glyph - pid = p.id -- p must be non-nil + until getid(p)~=id_glyph + pid = getid(p) -- p must be non-nil end if pid==id_kern then - if get_attr_icflag(p)==IC_PROCESSED then + local pa = get_attr_icflag(p) + --if pa==IC_PROCESSED or pa == PACKED then + if pa==IC_PROCESSED then -- do nothing - elseif p.subtype==2 then + elseif getsubtype(p)==2 then p = node_next(node_next(p)); -- Note that another node_next will be executed outside this if-statement. else found_visible_node = true - if find_first_char then - find_first_char = false - else - last_char = nil - end + find_first_char = false; last_char = nil end elseif pid==id_hlist then if PACKED == get_attr_icflag(p) then if find_first_char then - first_char = p.head; find_first_char = false + first_char = getlist(p); find_first_char = false end - last_char = p.head; found_visible_node = true + last_char = getlist(p); found_visible_node = true else - if p.shift==0 then - if check_box(p.head, nil) then found_visible_node = true end - else if find_first_char then - find_first_char = false - else - last_char = nil - end + if getfield(p, 'shift')==0 then + if check_box(getlist(p), nil) then found_visible_node = true end + else + find_first_char = false; last_char = nil end end elseif pid==id_math then @@ -201,15 +218,12 @@ local function check_box(box_ptr, box_end) first_char = p; find_first_char = false end last_char = p; found_visible_node = true + --elseif pid==id_rule and get_attr_icflag(p)==PACKED then -- do nothing elseif not (pid==id_ins or pid==id_mark or pid==id_adjust or pid==id_whatsit or pid==id_penalty) then found_visible_node = true - if find_first_char then - find_first_char = false - else - last_char = nil - end + find_first_char = false; last_char = nil end p = node_next(p) end @@ -221,11 +235,11 @@ function check_box_high(Nx, box_ptr, box_end) if check_box(box_ptr, box_end) then local first_char = first_char if first_char then - if first_char.id==id_glyph then - if first_char.font == (has_attr(first_char, attr_curjfnt) or -1) then + if getid(first_char)==id_glyph then + if getfont(first_char) == (has_attr(first_char, attr_curjfnt) or -1) then set_np_xspc_jachar(Nx, first_char) else - set_np_xspc_alchar(Nx, first_char.char,first_char, ligature_head) + set_np_xspc_alchar(Nx, getchar(first_char),first_char, 1) end else -- math_node set_np_xspc_alchar(Nx, -1,first_char) @@ -257,7 +271,7 @@ local function set_attr_icflag_processed(p) end local function check_next_ickern(lp) - if lp.id == id_kern and ITALIC == get_attr_icflag(lp) then + if lp and getid(lp) == id_kern and ITALIC == get_attr_icflag(lp) then set_attr(lp, attr_icflag, IC_PROCESSED) Np.last = lp; return node_next(lp) else @@ -267,103 +281,99 @@ end local function calc_np_pbox(lp, last) Np.first = Np.first or lp; Np.id = id_pbox - local lpa = KINSOKU -- dummy= + local lpa, nc = KINSOKU, nil set_attr(lp, attr_icflag, get_attr_icflag(lp)); - while lp~=last and lpa>=PACKED and lpa<BOXBDD do - Np.nuc = lp; - lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0 - -- get_attr_icflag() ではいけない! + while lp ~=last and (lpa>=PACKED) and (lpa<BOXBDD) do + nc, lp = lp, node_next(lp); lpa = lp and has_attr(lp, attr_icflag) or 0 + -- get_attr_icflag() ではいけない! end + Np.nuc = nc return check_next_ickern(lp) end local calc_np_auxtable = { [id_glyph] = function (lp) - Np.first, Np.nuc = (Np.first or lp), lp; - Np.id = (lp.font == (has_attr(lp, attr_curjfnt) or -1)) and id_jglyph or id_glyph - --set_attr_icflag_processed(lp) treated in ltj-setwidth.lua - return true, check_next_ickern(node_next(lp)); - end, + Np.first, Np.nuc = (Np.first or lp), lp; + Np.id = (getfont(lp) == (has_attr(lp, attr_curjfnt) or -1)) + and id_jglyph or id_glyph + return true, check_next_ickern(node_next(lp)); + end, [id_hlist] = function(lp) - Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp; - set_attr(lp, attr_icflag, PROCESSED) - --set_attr_icflag_processed(lp) - Np.id = (lp.shift~=0) and id_box_like or id_hlist - return true, node_next(lp) - end, + Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp; + set_attr(lp, attr_icflag, PROCESSED) + Np.id = (getfield(lp, 'shift')~=0) and id_box_like or id_hlist + return true, node_next(lp) + end, box_like = function(lp) - Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp; - Np.id = id_box_like; set_attr(lp, attr_icflag, PROCESSED) - -- set_attr_icflag_processed(lp); - return true, node_next(lp); - end, + Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp; + Np.id = id_box_like; set_attr(lp, attr_icflag, PROCESSED) + return true, node_next(lp); + end, skip = function(lp) - set_attr(lp, attr_icflag, PROCESSED) - -- set_attr_icflag_processed(lp); - return false, node_next(lp) - end, + set_attr(lp, attr_icflag, PROCESSED) + return false, node_next(lp) + end, [id_whatsit] = function(lp) - if lp.subtype==sid_user then - if lp.user_id==luatexja.userid_table.IHB then - local lq = node_next(lp); - head = node.remove(head, lp); node.free(lp); ihb_flag = true - return false, lq; - else - set_attr(lp, attr_icflag, PROCESSED) - -- set_attr_icflag_processed(lp) - luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo", - Np, lp, Nq) - if Np.nuc then - Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc; - return true, node_next(lp) - else - return false, node_next(lp) - end - end - else - -- we do special treatment for these whatsit nodes. - if lp.subtype == sid_start_link or lp.subtype == sid_start_thread then - Np.first = lp - elseif lp.subtype == sid_end_link or lp.subtype == sid_end_thread then - Np.first, Nq.last = nil, lp; - end - set_attr(lp, attr_icflag, PROCESSED) - -- set_attr_icflag_processed(lp); - return false, node_next(lp) - end - end, + local lps = getsubtype(lp) + if lps==sid_user then + if getfield(lp, 'user_id')==luatexja.userid_table.IHB then + local lq = node_next(lp); + head = node_remove(head, lp); node_free(lp); ihb_flag = true + return false, lq; + else + set_attr(lp, attr_icflag, PROCESSED) + luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo", + Np, lp, Nq) + if Np.nuc then + Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc; + return true, node_next(lp) + else + return false, node_next(lp) + end + end + else + -- we do special treatment for these whatsit nodes. + if lps == sid_start_link or lps == sid_start_thread then + Np.first = lp + elseif lps == sid_end_link or lps == sid_end_thread then + Np.first, Nq.last = nil, lp; + end + set_attr(lp, attr_icflag, PROCESSED) + return false, node_next(lp) + end + end, [id_math] = function(lp) - Np.first, Np.nuc = (Np.first or lp), lp; - set_attr(lp, attr_icflag, PROCESSED) -- set_attr_icflag_processed(lp); - lp = node.end_of_math(lp) - set_attr(lp, attr_icflag, PROCESSED) -- set_attr_icflag_processed(lp); - Np.last, Np.id = lp, id_math; - return true, node_next(lp); - end, + Np.first, Np.nuc = (Np.first or lp), lp; + set_attr(lp, attr_icflag, PROCESSED) + lp = node_end_of_math(lp) + set_attr(lp, attr_icflag, PROCESSED) + Np.last, Np.id = lp, id_math; + return true, node_next(lp); + end, discglue = function(lp) - Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp; - Np.id = lp.id; set_attr(lp, attr_icflag, PROCESSED) -- set_attr_icflag_processed(lp); - return true, node_next(lp) - end, + Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp; + Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED) + return true, node_next(lp) + end, [id_kern] = function(lp) - Np.first = Np.first or lp - if lp.subtype==2 then - set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) - set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) - set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) - set_attr(lp, attr_icflag, PROCESSED); Np.nuc = lp - Np.id = (lp.font == (has_attr(lp, attr_curjfnt) or -1)) and id_jglyph or id_glyph - return true, check_next_ickern(node_next(lp)); - else - Np.id = id_kern; set_attr(lp, attr_icflag, PROCESSED); -- set_attr_icflag_processed(lp); - Np.last = lp; return true, node_next(lp) - end - end, + Np.first = Np.first or lp + if getsubtype(lp)==2 then + set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) + set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) + set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp) + set_attr(lp, attr_icflag, PROCESSED); Np.nuc = lp + Np.id = (getfont(lp) == (has_attr(lp, attr_curjfnt) or -1)) and id_jglyph or id_glyph + return true, check_next_ickern(node_next(lp)); + else + Np.id = id_kern; set_attr(lp, attr_icflag, PROCESSED) + Np.last = lp; return true, node_next(lp) + end + end, [id_penalty] = function(lp) - Bp[#Bp+1] = lp; set_attr(lp, attr_icflag, PROCESSED); -- set_attr_icflag_processed(lp); - return false, node_next(lp) - end, + Bp[#Bp+1] = lp; set_attr(lp, attr_icflag, PROCESSED) + return false, node_next(lp) + end, } calc_np_auxtable[id_vlist] = calc_np_auxtable.box_like calc_np_auxtable[id_rule] = calc_np_auxtable.box_like @@ -374,7 +384,6 @@ calc_np_auxtable[id_adjust] = calc_np_auxtable.skip calc_np_auxtable[id_disc] = calc_np_auxtable.discglue calc_np_auxtable[id_glue] = calc_np_auxtable.discglue -local pairs = pairs function calc_np(lp, last) local k -- We assume lp = node_next(Np.last) @@ -382,22 +391,22 @@ function calc_np(lp, last) -- We clear `predefined' entries of Np before pairs() loop, -- because using only pairs() loop is slower. Np.post, Np.pre, Np.xspc = nil, nil, nil - Np.first, Np.id, Np.last, Np.met = nil, nil, nil - Np.auto_kspc, Np.auto_xspc, Np.char, Np.class, Np.nuc = nil, nil, nil, nil, nil + Np.first, Np.id, Np.last, Np.met, Np.class= nil, nil, nil, nil + Np.auto_kspc, Np.auto_xspc, Np.char, Np.nuc = nil, nil, nil, nil for k in pairs(Np) do Np[k] = nil end for k = 1,#Bp do Bp[k] = nil end - while lp ~= last do + while lp ~= last do local lpa = has_attr(lp, attr_icflag) or 0 -- unbox 由来ノードの検出 if lpa>=PACKED then if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then local lq = node_next(lp) - head = node.remove(head, lp); node.free(lp); lp = lq + head = node_remove(head, lp); node_free(lp); lp = lq else return calc_np_pbox(lp, last) end -- id_pbox else - k, lp = calc_np_auxtable[lp.id](lp) + k, lp = calc_np_auxtable[getid(lp)](lp) if k then return lp end end end @@ -411,6 +420,7 @@ local calc_np = calc_np -- We think that "Np is a Japanese character" if Np.met~=nil, -- "Np is an alphabetic character" if Np.pre~=nil, -- "Np is not a character" otherwise. +local after_hlist, after_alchar, extract_np do local PRE = luatexja.stack_table_index.PRE local POST = luatexja.stack_table_index.POST @@ -423,10 +433,10 @@ do local attr_autospc = luatexbase.attributes['ltj@autospc'] local attr_autoxspc = luatexbase.attributes['ltj@autoxspc'] function set_np_xspc_jachar(Nx, x) - local m = ltjf_font_metric_table[x.font] - local cls, c = slow_find_char_class(has_attr(x, attr_orig_char), m, x.char) - Nx.class = cls; set_attr(x, attr_jchar_class, cls) - Nx.met, Nx.char = m, c + local m = ltjf_font_metric_table[getfont(x)] + local cls, c = slow_find_char_class(has_attr(x, attr_orig_char), m, getchar(x)) + Nx.met, Nx.char = m, c; Nx.class = cls; + if cls~=0 then set_attr(x, attr_jchar_class, cls) end Nx.pre = table_current_stack[PRE + c] or 0 Nx.post = table_current_stack[POST + c] or 0 Nx.xspc = table_current_stack[XSP + c] or 3 @@ -439,22 +449,16 @@ do local floor = math.floor function set_np_xspc_alchar(Nx, c,x, lig) if c~=-1 then - local xc, xs = x.components, x.subtype - if lig == 1 then - while xc and xs and xs%4>=2 do - x = xc; xc, xs = x.components, x.subtype - end - c = x.char - else - while xc and xs and xs%4>=2 do - x = node.tail(xc); xc, xs = x.components, x.subtype - end - c = x.char + local f = (lig ==1) and nullfunc or node_tail + local xc, xs = getfield(x, 'components'), getsubtype(x) + while xc and xs and xs%4>=2 do + x = f(xc); xc, xs = getfield(x, 'components'), getsubtype(x) end - Nx.pre = table_current_stack[PRE + c] or 0 - Nx.post = table_current_stack[POST + c] or 0 - Nx.xspc = table_current_stack[XSP + c] or 3 - Nx.char = 'jcharbdd' + c = getchar(x) + Nx.pre = table_current_stack[PRE + c] or 0 + Nx.post = table_current_stack[POST + c] or 0 + Nx.xspc = table_current_stack[XSP + c] or 3 + Nx.char = 'jcharbdd' else Nx.pre, Nx.post, Nx.char = 0, 0, -1 Nx.xspc = table_current_stack[XSP - 1] or 3 @@ -465,27 +469,27 @@ do local set_np_xspc_alchar = set_np_xspc_alchar -- Np の情報取得メインルーチン - function extract_np() + extract_np = function () local x, i = Np.nuc, Np.id; if i == id_jglyph then return set_np_xspc_jachar(Np, x) - elseif i == id_glyph then return set_np_xspc_alchar(Np, x.char, x, ligature_head) - elseif i == id_hlist then Np.last_char = check_box_high(Np, x.head, nil) + elseif i == id_glyph then return set_np_xspc_alchar(Np, getchar(x), x, 1) + elseif i == id_hlist then Np.last_char = check_box_high(Np, getlist(x), nil) elseif i == id_pbox then Np.last_char = check_box_high(Np, Np.first, node_next(Np.last)) - elseif i == id_disc then Np.last_char = check_box_high(Np, x.replace, nil) + elseif i == id_disc then Np.last_char = check_box_high(Np, getfield(x, 'replace'), nil) elseif i == id_math then return set_np_xspc_alchar(Np, -1, x) end end -- change the information for the next loop -- (will be done if Nx is an alphabetic character or a hlist) - function after_hlist(Nx) + after_hlist = function (Nx) local s = Nx.last_char if s then - if s.id==id_glyph then - if s.font == (has_attr(s, attr_curjfnt) or -1) then + if getid(s)==id_glyph then + if getfont(s) == (has_attr(s, attr_curjfnt) or -1) then set_np_xspc_jachar(Nx, s) else - set_np_xspc_alchar(Nx, s.char, s, ligature_tail) + set_np_xspc_alchar(Nx, getchar(s), s, 2) end else set_np_xspc_alchar(Nx, -1, s) @@ -495,13 +499,12 @@ do end end - function after_alchar(Nx) + after_alchar = function (Nx) local x = Nx.nuc - return set_np_xspc_alchar(Nx, x.char,x, ligature_tail) + return set_np_xspc_alchar(Nx, getchar(x), x, 2) end end -local after_hlist, after_alchar, extract_np = after_hlist, after_alchar, extract_np -------------------- 最下層の処理 @@ -509,10 +512,10 @@ local after_hlist, after_alchar, extract_np = after_hlist, after_alchar, extract local function handle_penalty_normal(post, pre, g) local a = (pre or 0) + (post or 0) if #Bp == 0 then - if (a~=0 and not(g and g.id==id_kern)) then - local p = node_new(id_penalty); --copy_attr(p, Nq.nuc) + if (a~=0 and not(g and getid(g)==id_kern)) then + local p = node_new(id_penalty) if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end - p.penalty = a + setfield(p, 'penalty', a) head = insert_before(head, Np.first, p) Bp[1]=p; set_attr(p, attr_icflag, KINSOKU) @@ -524,10 +527,10 @@ end local function handle_penalty_always(post, pre, g) local a = (pre or 0) + (post or 0) if #Bp == 0 then - if not (g and g.id==id_glue) then - local p = node_new(id_penalty); --copy_attr(p, Nq.nuc) + if not (g and getid(g)==id_glue) then + local p = node_new(id_penalty) if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end - p.penalty = a + setfield(p, 'penalty', a) head = insert_before(head, Np.first, p) Bp[1]=p set_attr(p, attr_icflag, KINSOKU) @@ -539,9 +542,9 @@ end local function handle_penalty_suppress(post, pre, g) local a = (pre or 0) + (post or 0) if #Bp == 0 then - if g and g.id==id_glue then - local p = node_new(id_penalty); --copy_attr(p, Nq.nuc) - p.penalty = 10000; head = insert_before(head, Np.first, p) + if g and getid(g)==id_glue then + local p = node_new(id_penalty) + setfield(p, 'penalty', 10000); head = insert_before(head, Np.first, p) Bp[1]=p set_attr(p, attr_icflag, KINSOKU) end @@ -552,20 +555,18 @@ end -- 和文文字間の JFM glue を node 化 local function new_jfm_glue(m, bc, ac) -- bc, ac: char classes - local z = m.char_type[bc] - local g, d = z.glue[ac], 0 + local g, d = m.char_type[bc][ac], 0 + local n if g then - g,d = node_copy(g[1]), g[2]; - g.spec = node_copy(g.spec); -- node_copy は spec をコピーする - else - local k = z.kern[ac] - if k then - g = node_new(id_kern); --copy_attr(g, Nn.nuc) - g.subtype = 1; g.kern, d = k[1], k[2] - set_attr(g, attr_icflag, FROM_JFM); + n,d = node_copy(g[2]), g[3] + if g[1] then + local f = node_new(id_glue) + set_attr(f, attr_icflag, g[4]) + setfield(f, 'spec', n) + return f, d end end - return g, d + return n, d end -- Nq.last (kern w) .... (glue/kern g) Np.first @@ -581,96 +582,110 @@ end -- get kanjiskip local get_kanjiskip - -local function get_kanjiskip_normal() - if Np.auto_kspc or Nq.auto_kspc then - return node_copy(kanji_skip) - else - local g = node_copy(zero_glue) - set_attr(g, attr_icflag, KANJI_SKIP) - return g - end -end -local function get_kanjiskip_jfm() - local g - if Np.auto_kspc or Nq.auto_kspc then - g = node_new(id_glue); --copy_attr(g, Nq.nuc) - local gx = node_new(id_glue_spec); - gx.stretch_order, gx.shrink_order = 0, 0 - local pm, qm = Np.met, Nq.met - local bk = qm.kanjiskip or {0, 0, 0} - if (pm.char_type==qm.char_type) and (qm.var==pm.var) then - gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3] +local get_kanjiskip_normal, get_kanjiskip_jfm +do + local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP + local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM + get_kanjiskip_normal = function () + if Np.auto_kspc or Nq.auto_kspc then + return node_copy(kanji_skip) else - local ak = pm.kanjiskip or {0, 0, 0} - gx.width = round(diffmet_rule(bk[1], ak[1])) - gx.stretch = round(diffmet_rule(bk[2], ak[2])) - gx.shrink = -round(diffmet_rule(-bk[3], -ak[3])) + local g = node_copy(zero_glue) + set_attr(g, attr_icflag, KANJI_SKIP) + return g end - g.spec = gx - else - g = node_copy(zero_glue) end - set_attr(g, attr_icflag, KANJI_SKIP) - return g -end -local function calc_ja_ja_aux(gb,ga, db, da) - local rbb, rab = (1-db)/2, (1-da)/2 -- 「前の文字」由来のグルーの割合 - local rba, raa = (1+db)/2, (1+da)/2 -- 「前の文字」由来のグルーの割合 - if diffmet_rule ~= math.two_pleft and diffmet_rule ~= math.two_pright - and diffmet_rule ~= math.two_paverage then - rbb, rab, rba, raa = 1,0,0,1 - end - if not gb then - if ga then gb = node_new(id_kern); gb.kern = 0 else return nil end - elseif not ga then - ga = node_new(id_kern); ga.kern = 0 + get_kanjiskip_jfm = function () + local g + if Np.auto_kspc or Nq.auto_kspc then + g = node_new(id_glue); --copy_attr(g, Nq.nuc) + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local pm, qm = Np.met, Nq.met + local bk = qm.kanjiskip or {0, 0, 0} + if (pm.char_type==qm.char_type) and (qm.var==pm.var) then + setfield(gx, 'width', bk[1]) + setfield(gx, 'stretch', bk[2]) + setfield(gx, 'shrink', bk[3]) + else + local ak = pm.kanjiskip or {0, 0, 0} + setfield(gx, 'width', round(diffmet_rule(bk[1], ak[1]))) + setfield(gx, 'stretch', round(diffmet_rule(bk[2], ak[2]))) + setfield(gx, 'shrink', -round(diffmet_rule(-bk[3], -ak[3]))) + end + setfield(g, 'spec', gx) + else + g = node_copy(zero_glue) + end + set_attr(g, attr_icflag, KANJI_SKIP_JFM) + return g end +end - local k = node.type(gb.id) .. node.type(ga.id) - if k == 'glueglue' then - -- 両方とも glue. - gb.spec.width = round(diffmet_rule( - rbb*gb.spec.width + rba*ga.spec.width, - rab*gb.spec.width + raa*ga.spec.width )) - gb.spec.stretch = round(diffmet_rule( - rbb*gb.spec.stretch + rba*ga.spec.stretch, - rab*gb.spec.stretch + raa*ga.spec.stretch )) - gb.spec.shrink = -round(diffmet_rule( - -rbb*gb.spec.shrink - rba*ga.spec.shrink, - -rab*gb.spec.shrink - raa*ga.spec.shrink )) - node.free(ga) - return gb - elseif k == 'kernkern' then - -- 両方とも kern. - gb.kern = round(diffmet_rule( - rbb*gb.kern + rba*ga.kern, - rab*gb.kern + raa*ga.kern )) - node.free(ga) - return gb - elseif k == 'kernglue' then - -- gb: kern, ga: glue - ga.spec.width = round(diffmet_rule( - rbb*gb.kern + rba*ga.spec.width, - rab*gb.kern + raa*ga.spec.width )) - ga.spec.stretch = round(diffmet_rule( - rba*ga.spec.stretch, raa*ga.spec.stretch )) - ga.spec.shrink = -round(diffmet_rule( - -rba*ga.spec.shrink,-raa*ga.spec.shrink )) - node.free(gb) - return ga - else - -- gb: glue, ga: kern - gb.spec.width = round(diffmet_rule( - rba*ga.kern + rbb*gb.spec.width, - raa*ga.kern + rab*gb.spec.width )) - gb.spec.stretch = round(diffmet_rule( - rbb*gb.spec.stretch, rab*gb.spec.stretch )) - gb.spec.shrink = -round(diffmet_rule( - -rbb*gb.spec.shrink,-rab*gb.spec.shrink )) - node.free(ga) - return gb +local calc_ja_ja_aux +do + local bg_ag = 2*id_glue - id_glue + local bg_ak = 2*id_glue - id_kern + local bk_ag = 2*id_kern - id_glue + local bk_ak = 2*id_kern - id_kern + + calc_ja_ja_aux = function (gb,ga, db, da) + local rbb, rab = (1-db)/2, (1-da)/2 -- 「前の文字」由来のグルーの割合 + local rba, raa = (1+db)/2, (1+da)/2 -- 「前の文字」由来のグルーの割合 + if diffmet_rule ~= math.two_pleft and diffmet_rule ~= math.two_pright + and diffmet_rule ~= math.two_paverage then + rbb, rab, rba, raa = 1,0,0,1 + end + if not gb then + if ga then + gb = node_new(id_kern); setfield(gb, 'kern', 0) + else return nil end + elseif not ga then + ga = node_new(id_kern); setfield(ga, 'kern', 0) + end + + local k = 2*getid(gb) - getid(ga) + if k == bg_ag then + local bs, as = getfield(gb, 'spec'), getfield(ga, 'spec') + -- 両方とも glue. + local bd, ad = getfield(bs, 'width'), getfield(as, 'width') + setfield(bs, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + bd, ad = getfield(bs, 'stretch'), getfield(as, 'stretch') + setfield(bs, 'stretch', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + bd, ad = getfield(bs, 'shrink'), getfield(as, 'shrink') + setfield(bs, 'shrink', -round(diffmet_rule(-rbb*bd - rba*ad, -rab*bd - raa*ad))) + node_free(ga) + return gb + elseif k == bk_ak then + -- 両方とも kern. + local bd, ad = getfield(gb, 'kern'), getfield(ga, 'kern') + setfield(gb, 'kern', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + node_free(ga) + return gb + elseif k == bk_ag then + local as = getfield(ga, 'spec') + -- gb: kern, ga: glue + local bd, ad = getfield(gb, 'kern'), getfield(as, 'width') + setfield(as, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + ad = getfield(as, 'stretch') + setfield(bs, 'stretch', round(diffmet_rule(rba*ad, raa*ad))) + ad = getfield(as, 'shrink') + setfield(bs, 'shrink', -round(diffmet_rule(-rba*ad, -raa*ad))) + node_free(gb) + return ga + else + local bs = getfield(gb, 'spec') + -- gb: glue, ga: kern + local bd, ad = getfield(bs, 'width'), getfield(ga, 'kern') + setfield(bs, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + bd = getfield(bs, 'stretch') + setfield(bs, 'stretch', round(diffmet_rule(rbb*bd, rab*bd))) + bd = getfield(bs, 'shrink') + setfield(bs, 'shrink', -round(diffmet_rule(-rbb*bd, -rab*bd))) + node_free(ga) + return gb + end end end @@ -683,9 +698,11 @@ local function calc_ja_ja_glue() else local npn, nqn = Np.nuc, Nq.nuc local gb, db = new_jfm_glue(qm, Nq.class, - slow_find_char_class(has_attr(npn, attr_orig_char), qm, npn.char)) + slow_find_char_class(has_attr(npn, attr_orig_char), + qm, getchar(npn))) local ga, da = new_jfm_glue(pm, - slow_find_char_class(has_attr(nqn, attr_orig_char), pm, nqn.char), + slow_find_char_class(has_attr(nqn, attr_orig_char), + pm, getchar(nqn)), Np.class) return calc_ja_ja_aux(gb, ga, db, da); end @@ -696,33 +713,39 @@ end -- get xkanjiskip local get_xkanjiskip -local function get_xkanjiskip_normal(Nn) - if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then - return node_copy(xkanji_skip) - else - local g = node_copy(zero_glue) - set_attr(g, attr_icflag, XKANJI_SKIP) - return g +local get_xkanjiskip_normal, get_xkanjiskip_jfm +do + local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP + local XKANJI_SKIP_JFM = luatexja.icflag_table.XKANJI_SKIP_JFM + get_xkanjiskip_normal = function (Nn) + if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then + local f = node_copy(xkanji_skip) + return f + else + local g = node_copy(zero_glue) + set_attr(g, attr_icflag, XKANJI_SKIP) + return g + end end -end -local function get_xkanjiskip_jfm(Nn) - local g - if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then - g = node_new(id_glue); --copy_attr(g, Nn.nuc) - local gx = node_new(id_glue_spec); - gx.stretch_order, gx.shrink_order = 0, 0 - local bk = Nn.met.xkanjiskip or {0, 0, 0} - gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3] - g.spec = gx - else - g = node_copy(zero_glue) + get_xkanjiskip_jfm = function (Nn) + local g + if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then + g = node_new(id_glue) + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local bk = Nn.met.xkanjiskip or {0, 0, 0} + setfield(gx, 'width', bk[1]) + setfield(gx, 'stretch', bk[2]) + setfield(gx, 'shrink', bk[3]) + setfield(g, 'spec', gx) + else + g = node_copy(zero_glue) + end + set_attr(g, attr_icflag, XKANJI_SKIP_JFM) + return g end - set_attr(g, attr_icflag, XKANJI_SKIP) - return g end - - -------------------- 隣接した「塊」間の処理 local function get_OA_skip() @@ -752,7 +775,7 @@ local function handle_np_jachar(mode) local g = get_OA_skip() or get_kanjiskip() -- O_A->K handle_penalty_normal(0, Np.pre, g); real_insert(g) elseif Nq.pre then - local g = get_OA_skip() or get_xkanjiskip(Np) -- O_A->X + local g = get_OA_skip() or get_xkanjiskip(Np) -- O_A->X handle_penalty_normal((qid==id_hlist and 0 or Nq.post), Np.pre, g); real_insert(g) else local g = get_OA_skip() -- O_A @@ -812,7 +835,7 @@ do local adjust_nq_aux = { [id_glyph] = function() local x = Nq.nuc - return set_np_xspc_alchar(Nq, x.char,x, 2) + return set_np_xspc_alchar(Nq, getchar(x),x, 2) end, -- after_alchar(Nq) [id_hlist] = function() after_hlist(Nq) end, [id_pbox] = function() after_hlist(Nq) end, @@ -831,6 +854,7 @@ end -------------------- 開始・終了時の処理 +do -- リスト末尾の処理 local JWP = luatexja.stack_table_index.JWP @@ -851,7 +875,7 @@ local function handle_list_tail(mode) local g = new_jfm_glue(pm, Np.class, fast_find_char_class('boxbdd', pm)) if g then set_attr(g, attr_icflag, BOXBDD) - head = node.insert_after(head, Np.last, g) + head = insert_after(head, Np.last, g) end end end @@ -865,9 +889,9 @@ local function handle_list_head(par_indented) local g = new_jfm_glue(pm, fast_find_char_class(par_indented, pm), Np.class) if g then set_attr(g, attr_icflag, BOXBDD) - if g.id==id_glue and #Bp==0 then - local h = node_new(id_penalty); --copy_attr(h, Np.nuc) - h.penalty = 10000; set_attr(h, attr_icflag, BOXBDD) + if getid(g)==id_glue and #Bp==0 then + local h = node_new(id_penalty) + setfield(h, 'penalty', 10000); set_attr(h, attr_icflag, BOXBDD) end head = insert_before(head, Np.first, g) end @@ -877,66 +901,68 @@ end -- initialize -- return value: (the initial cursor lp), (last node) -local function init_var(mode) - -- 1073741823: max_dimen - Bp, widow_Bp, widow_Np = {}, {}, {first = nil} - table_current_stack = ltjs.table_current_stack - - kanji_skip = node_new(id_glue) - kanji_skip.spec = skip_table_to_spec('kanjiskip') - set_attr(kanji_skip, attr_icflag, KANJI_SKIP) - get_kanjiskip = (kanji_skip.spec.width == 1073741823) - and get_kanjiskip_jfm or get_kanjiskip_normal - - xkanji_skip = node_new(id_glue) - xkanji_skip.spec = skip_table_to_spec('xkanjiskip') - set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP) - get_xkanjiskip = (xkanji_skip.spec.width == 1073741823) - and get_xkanjiskip_jfm or get_xkanjiskip_normal - - Np = { - auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, - first=nil, id=nil, last=nil, met=nil, nuc=nil, - post=nil, pre=nil, xspc=nil, - } - Nq = { - auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, - first=nil, id=nil, last=nil, met=nil, nuc=nil, - post=nil, pre=nil, xspc=nil, - } - if mode then - -- the current list is to be line-breaked: - -- hbox from \parindent is skipped. - local lp, par_indented, lpi, lps = head, 'boxbdd', head.id, head.subtype - while lp and ((lpi==id_whatsit and lps~=sid_user) - or ((lpi==id_hlist) and (lps==3))) do - if (lpi==id_hlist) and (lps==3) then par_indented = 'parbdd' end - lp=node_next(lp); lpi, lps = lp.id, lp.subtype end - return lp, node.tail(head), par_indented - else - -- the current list is the contents of a hbox: - -- insert a sentinel - local g = node_new(id_kern) - node.insert_after(head, node.tail(head), g); last = g - return head, g, 'boxbdd' +local init_var +do + local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP + local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP + local KSK = luatexja.stack_table_index.KSK + local XSK = luatexja.stack_table_index.XSK + init_var = function (mode) + -- 1073741823: max_dimen + Bp, widow_Bp, widow_Np = {}, {}, {first = nil} + table_current_stack = ltjs.table_current_stack + + kanji_skip = node_new(id_glue) + setfield(kanji_skip, 'spec', skip_table_to_spec(KSK)) + set_attr(kanji_skip, attr_icflag, KANJI_SKIP) + get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823) + and get_kanjiskip_jfm or get_kanjiskip_normal + + xkanji_skip = node_new(id_glue) + setfield(xkanji_skip, 'spec', skip_table_to_spec(XSK)) + set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP) + get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823) + and get_xkanjiskip_jfm or get_xkanjiskip_normal + + Np = { + auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, + first=nil, id=nil, last=nil, met=nil, nuc=nil, + post=nil, pre=nil, xspc=nil, + } + Nq = { + auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, + first=nil, id=nil, last=nil, met=nil, nuc=nil, + post=nil, pre=nil, xspc=nil, + } + if mode then + -- the current list is to be line-breaked: + -- hbox from \parindent is skipped. + local lp, par_indented, lpi, lps = head, 'boxbdd', getid(head), getsubtype(head) + while lp and ((lpi==id_whatsit and lps~=sid_user) + or ((lpi==id_hlist) and (lps==3))) do + if (lpi==id_hlist) and (lps==3) then par_indented = 'parbdd' end + lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end + return lp, node_tail(head), par_indented + else + return head, nil, 'boxbdd' + end end end -local function cleanup(mode, last) +local function cleanup(mode) -- adjust attr_icflag for avoiding error tex.setattribute('global', attr_icflag, 0) - node.free(kanji_skip); node.free(xkanji_skip) + node_free(kanji_skip); node_free(xkanji_skip) if mode then local h = node_next(head) - if h.id == id_penalty and h.penalty == 10000 then - h = h.next - if h.id == id_glue and h.subtype == 15 and not h.next then + if getid(h) == id_penalty and getfield(h, 'penalty') == 10000 then + h = node_next(h) + if getid(h) == id_glue and getsubtype(h) == 15 and not node_next(h) then return false end end return head else - head = node.remove(head, last); node.free(last);-- remove the sentinel set_attr(head, attr_icflag, get_attr_icflag(head) + PROCESSED_BEGIN_FLAG); return head @@ -948,12 +974,12 @@ end function main(ahead, mode) if not ahead then return ahead end head = ahead; - local lp, last, par_indented = init_var(mode); + local lp, last, par_indented = init_var(mode) lp = calc_np(lp, last) if Np then extract_np(); handle_list_head(par_indented) else - return cleanup(mode, last) + return cleanup(mode) end lp = calc_np(lp, last) while Np do @@ -973,31 +999,38 @@ function main(ahead, mode) lp = calc_np(lp, last) end handle_list_tail(mode) - return cleanup(mode, last) + return cleanup(mode) +end end do local IHB = luatexja.userid_table.IHB local BPAR = luatexja.userid_table.BPAR + local node_prev = (Dnode ~= node) and Dnode.getprev or node.prev + local node_write = Dnode.write -- \inhibitglue function create_inhibitglue_node() local tn = node_new(id_whatsit, sid_user) - tn.user_id=IHB; tn.type=100; tn.value=1 - node.write(tn) + setfield(tn, 'user_id', IHB) + setfield(tn, 'type', 100) + setfield(tn, 'value', 1) + node_write(tn) end -- Node for indicating beginning of a paragraph -- (for ltjsclasses) function create_beginpar_node() local tn = node_new(id_whatsit, sid_user) - tn.user_id=BPAR; tn.type=100; tn.value=1 - node.write(tn) + setfield(tn, 'user_id', BPAR) + setfield(tn, 'type', 100) + setfield(tn, 'value', 1) + node_write(tn) end local function whatsit_callback(Np, lp, Nq) if Np and Np.nuc then return Np - elseif Np and lp.user_id == BPAR then + elseif Np and getfield(lp, 'user_id') == BPAR then Np.first = lp; Np.nuc = lp; Np.last = lp Np.char = 'parbdd' Np.met = nil @@ -1008,11 +1041,12 @@ do end end - local function whatsit_after_callback(s, Nq, Np) - if not s and Nq.nuc.user_id == BPAR then - local x, y = node.prev(Nq.nuc), Nq.nuc + local function whatsit_after_callback(s, Nq, Np) + if not s and getfield(Nq.nuc, 'user_id') == BPAR then + local x, y = node_prev(Nq.nuc), Nq.nuc Nq.first, Nq.nuc, Nq.last = x, x, x - head = node.remove(head, y) + head = node_remove(head, y) + node_free(y) end return s end diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua index 0e2673400b5..c3ffb6a57e4 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.jfont', - date = '2014/01/02', + date = '2014/02/01', description = 'Loader for Japanese fonts', }) module('luatexja.jfont', package.seeall) @@ -11,11 +11,25 @@ module('luatexja.jfont', package.seeall) luatexja.load_module('base'); local ltjb = luatexja.base luatexja.load_module('charrange'); local ltjc = luatexja.charrange -local node_new = node.new -local has_attr = node.has_attribute -local set_attr = node.set_attribute +local mem_leak_glue, mem_leak_gs, mem_leak_kern = 0, 0, 0 + +local Dnode = node.direct or node + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end + +local nullfunc = function(n) return n end +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local node_new = Dnode.new +local node_free = Dnode.free +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local node_write = Dnode.write local round = tex.round -local getfont = font.getfont +local font_getfont = font.getfont local attr_icflag = luatexbase.attributes['ltj@icflag'] local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] @@ -55,9 +69,7 @@ function define_jfm(t) else real_char = false for j,w in pairs(v.chars) do - if w == 'lineend' then - if #v.chars ~= 1 then defjfm_res= nil; return end - elseif type(w) == 'number' then + if type(w) == 'number' then real_char = true; elseif type(w) == 'string' and utf.len(w)==1 then real_char = true; w = utf.byte(w) @@ -101,8 +113,7 @@ function define_jfm(t) end v.chars = nil end - if not v.kern then v.kern = {} end - if not v.glue then v.glue = {} end + v.kern = v.kern or {}; v.glue = v.glue or {} for j in pairs(v.glue) do if v.kern[j] then defjfm_res= nil; return end end @@ -122,6 +133,7 @@ function define_jfm(t) defjfm_res = t end +local update_jfm_cache do local function mult_table(old,scale) -- modified from table.fastcopy if old then @@ -139,26 +151,36 @@ do else return nil end end - function update_jfm_cache(j,sz) + update_jfm_cache = function (j,sz) if metrics[j].size_cache[sz] then return end local t = {} metrics[j].size_cache[sz] = t t.chars = metrics[j].chars t.char_type = mult_table(metrics[j].char_type, sz) for i,v in pairs(t.char_type) do + v.align = (v.align=='left') and 0 or + ((v.align=='right') and 1 or 0.5) if type(i) == 'number' then -- char_type for k,w in pairs(v.glue) do - local g, h = node.new(id_glue), node_new(id_glue_spec) - v.glue[k] = {g, (w[5] and w[5]/sz or 0)} - h.width, h.stretch, h.shrink = w[1], w[2], w[3] - h.stretch_order, h.shrink_order = 0, 0 - g.subtype = 0; g.spec = h; set_attr(g, attr_icflag, FROM_JFM + - (w[4] and w[4]/sz or 0)); + local h = node_new(id_glue_spec) +mem_leak_gs = mem_leak_gs+1 + v[k] = {true, h, (w[5] and w[5]/sz or 0), FROM_JFM + (w[4] and w[4]/sz or 0)} + setfield(h, 'width', w[1]) + setfield(h, 'stretch', w[2]) + setfield(h, 'shrink', w[3]) + setfield(h, 'stretch_order', 0) + setfield(h, 'shrink_order', 0) end for k,w in pairs(v.kern) do - w[2] = w[2]/sz + local g = node_new(id_kern) +mem_leak_kern = mem_leak_kern +1 + setfield(g, 'kern', w[1]) + setfield(g, 'subtype', 1) + set_attr(g, attr_icflag, FROM_JFM) + v[k] = {false, g, w[2]/sz} end end + v.glue, v.kern = nil, nil end t.kanjiskip = mult_table(metrics[j].kanjiskip, sz) t.xkanjiskip = mult_table(metrics[j].xkanjiskip,sz) @@ -166,7 +188,7 @@ do t.zh = round(metrics[j].zh*sz) end end -local update_jfm_cache = update_jfm_cache + luatexbase.create_callback("luatexja.find_char_class", "data", function (arg, fmtable, char) return 0 @@ -186,6 +208,7 @@ end do local cstemp + local global_flag -- true if \globaljfont, false if \jfont local function load_jfont_metric() if jfm_file_name=='' then ltjb.package_error('luatexja', @@ -211,7 +234,7 @@ do function jfontdefX(g) local t = token.get_next() cstemp=token.csname_name(t) - if g then luatexja.is_global = '\\global' else luatexja.is_global = '' end + global_flag = g and '\\global' or '' tex.sprint(cat_lp, '\\expandafter\\font\\csname ' .. cstemp .. '\\endcsname') end @@ -221,17 +244,18 @@ do function jfontdefY() -- for horizontal font local j = load_jfont_metric() local fn = font.id(cstemp) - local f = getfont(fn) + local f = font_getfont(fn) if not j then ltjb.package_error('luatexja', "bad JFM `" .. jfm_file_name .. "'", 'The JFM file you specified is not valid JFM file.\n'.. 'So defining Japanese font is cancelled.') - tex.sprint(cat_lp, luatexja.is_global .. '\\expandafter\\let\\csname ' ..cstemp + tex.sprint(cat_lp, global_flag .. '\\expandafter\\let\\csname ' ..cstemp .. '\\endcsname=\\relax') return end update_jfm_cache(j, f.size) + --print('MEMORY LEAK (acc): ', mem_leak_glue, mem_leak_gs, mem_leak_kern) local sz = metrics[j].size_cache[f.size] local fmtable = { jfm = j, size = f.size, var = jfm_var, zw = sz.zw, zh = sz.zh, @@ -241,21 +265,20 @@ do fmtable = luatexbase.call_callback("luatexja.define_jfont", fmtable, fn) font_metric_table[fn]=fmtable - tex.sprint(cat_lp, luatexja.is_global .. '\\protected\\expandafter\\def\\csname ' + tex.sprint(cat_lp, global_flag .. '\\protected\\expandafter\\def\\csname ' .. cstemp .. '\\endcsname{\\ltj@curjfnt=' .. fn .. '\\relax}') end end do --- EXT: zw, zh - function load_zw() + -- PUBLIC function + function get_zw() local a = font_metric_table[tex.attribute[attr_curjfnt]] - tex.setdimen('ltj@zw', a and a.zw or 0) + return a and a.zw or 0 end - - function load_zh() + function get_zh() local a = font_metric_table[tex.attribute[attr_curjfnt]] - tex.setdimen('ltj@zh', a and a.zh or 0) + return a and a.zw or 0 end end @@ -296,6 +319,57 @@ do end ------------------------------------------------------------------------ +-- LATEX INTERFACE +------------------------------------------------------------------------ +do + -- these function are called from ltj-latex.sty + local kyenc_list, ktenc_list = {}, {} + function add_kyenc_list(enc) kyenc_list[enc] = 'true ' end + function add_ktenc_list(enc) ktenc_list[enc] = 'true ' end + function is_kyenc(enc) + tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (kyenc_list[enc] or 'false ')) + end + function is_kyenc(enc) + tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (kyenc_list[enc] or 'false ')) + end + function is_kenc(enc) + tex.sprint(cat_lp, '\\let\\ifin@\\if' + .. (kyenc_list[enc] or ktenc_list[enc] or 'false ')) + end + + local kfam_list, Nkfam_list = {}, {} + function add_kfam_list(enc, fam) + if not kfam_list[enc] then kfam_list[enc] = {} end + kfam_list[enc][fam] = 'true ' + end + function add_Nkfam_list(enc, fam) + if not Nkfam_list[enc] then Nkfam_list[enc] = {} end + Nkfam_list[enc][fam] = 'true ' + end + function is_kfam(enc, fam) + tex.sprint(cat_lp, '\\let\\ifin@\\if' + .. (kfam_list[enc] and kfam_list[enc][fam] or 'false ')) end + function is_Nkfam(enc, fam) + tex.sprint(cat_lp, '\\let\\ifin@\\if' + .. (Nkfam_list[enc] and Nkfam_list[enc][fam] or 'false ')) end + + local ffam_list, Nffam_list = {}, {} + function add_ffam_list(enc, fam) + if not ffam_list[enc] then ffam_list[enc] = {} end + ffam_list[enc][fam] = 'true ' + end + function add_Nffam_list(enc, fam) + if not Nffam_list[enc] then Nffam_list[enc] = {} end + Nffam_list[enc][fam] = 'true ' + end + function is_ffam(enc, fam) + tex.sprint(cat_lp, '\\let\\ifin@\\if' + .. (ffam_list[enc] and ffam_list[enc][fam] or 'false ')) end + function is_Nffam(enc, fam) + tex.sprint(cat_lp, '\\let\\ifin@\\if' + .. (Nffam_list[enc] and Nffam_list[enc][fam] or 'false ')) end +end +------------------------------------------------------------------------ -- ALTERNATE FONTS ------------------------------------------------------------------------ alt_font_table = {} @@ -323,7 +397,7 @@ function set_alt_font(b,e,ind,bfnt) end if not alt_font_table[bfnt] then alt_font_table[bfnt]={} end local t = alt_font_table[bfnt] - local ac = getfont(ind).characters + local ac = font_getfont(ind).characters if bfnt==ind then ind = nil end -- ind == bfnt の場合はテーブルから削除 if e>=0 then -- character range for i=b, e do @@ -348,8 +422,8 @@ end ------ used in ltjp.suppress_hyphenate_ja callback function replace_altfont(pf, pc) - return (alt_font_table[pf] and alt_font_table[pf][pc]) - and alt_font_table[pf][pc] or pf + local a = alt_font_table[pf] + return a and a[pc] or pf end ------ for LaTeX interface @@ -405,26 +479,30 @@ end -- ここから先は 新 \selectfont の内部でしか実行されない do local alt_font_base, alt_font_base_num - --- EXT - function print_aftl_address(bbase) - local t = alt_font_table_latex[bbase] - if not t then t = {}; alt_font_table_latex[bbase] = t end - tex.sprint(cat_lp, (tostring(t):gsub('table: 0x','ltjaltfont'))) + local aftl_base + -- EXT + function does_alt_set(bbase) + aftl_base = alt_font_table_latex[bbase] + tex.sprint(cat_lp, '\\if' .. (aftl_base and 'true' or 'false')) end + -- EXT + function print_aftl_address() + tex.sprint(cat_lp, ';ltjaltfont' .. tostring(aftl_base):sub(8)) + end + -- EXT function output_alt_font_cmd(bbase) alt_font_base = bbase alt_font_base_num = tex.getattribute(attr_curjfnt) local t = alt_font_table[alt_font_base_num] if t then - for i,_ in pairs(t) do t[i]=nil end + for i,_ in pairs(t) do t[i]=nil end end t = alt_font_table_latex[bbase] if t then - for i,_ in pairs(t) do - tex.sprint(cat_lp, '\\ltj@pickup@altfont@aux{' .. i .. '}') - end + for i,_ in pairs(t) do + tex.sprint(cat_lp, '\\ltj@pickup@altfont@aux{' .. i .. '}') + end end end @@ -432,38 +510,38 @@ do function pickup_alt_font_a(size_str) local t = alt_font_table_latex[alt_font_base] if t then - for i,v in pairs(t) do - tex.sprint(cat_lp, '\\expandafter\\ltj@pickup@altfont@copy' - .. '\\csname ' .. i .. '/' .. size_str .. '\\endcsname{' .. i .. '}') - end + for i,v in pairs(t) do + tex.sprint(cat_lp, '\\expandafter\\ltj@pickup@altfont@copy' + .. '\\csname ' .. i .. '/' .. size_str .. '\\endcsname{' .. i .. '}') + end end - end + end local function pickup_alt_font_class(class, afnt_num, afnt_chars) local t = alt_font_table[alt_font_base_num] local tx = font_metric_table[alt_font_base_num].chars for i,v in pairs(tx) do - if v==class and afnt_chars[i] then t[i]=afnt_num end + if v==class and afnt_chars[i] then t[i]=afnt_num end end end -- EXT function pickup_alt_font_b(afnt_num, afnt_base) local t = alt_font_table[alt_font_base_num] - local ac = getfont(afnt_num).characters + local ac = font_getfont(afnt_num).characters if not t then t = {}; alt_font_table[alt_font_base_num] = t end for i,v in pairs(alt_font_table_latex[alt_font_base]) do - if i == afnt_base then - for j,_ in pairs(v) do - if j>=0 then - if ac[j] then t[j]=afnt_num end - else -- -n (n>=1) means that the character class n, - -- which is defined in the JFM - pickup_alt_font_class(-j, afnt_num, ac) - end - end - return - end + if i == afnt_base then + for j,_ in pairs(v) do + if j>=0 then + if ac[j] then t[j]=afnt_num end + else -- -n (n>=1) means that the character class n, + -- which is defined in the JFM + pickup_alt_font_class(-j, afnt_num, ac) + end + end + return + end end end @@ -474,28 +552,29 @@ end -- MISC ------------------------------------------------------------------------ -local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char +local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct -- EXT: italic correction function append_italic() - local p = tex.nest[tex.nest.ptr].tail - if p and p.id==id_glyph then - local f = p.font + local p = to_direct(tex.nest[tex.nest.ptr].tail) + if p and getid(p)==id_glyph then + local f = getfont(p) local g = node_new(id_kern) - g.subtype = 1; node.set_attribute(g, attr_icflag, ITALIC) + setfield(g, 'subtype', 1) + set_attr(g, attr_icflag, ITALIC) if is_ucs_in_japanese_char(p) then f = has_attr(p, attr_curjfnt) local j = font_metric_table[f] - g.kern = j.char_type[find_char_class(p.char, j)].italic + setfield(g, 'kern', j.char_type[find_char_class(getchar(p), j)].italic) else - local h = getfont(f) + local h = font_getfont(f) if h then - g.kern = h.characters[p.char].italic + setfield(g, 'kern', h.characters[getchar(p)].italic) else - tex.attribute[attr_icflag] = -(0x7FFFFFFF) - return node.free(g) + tex.attribute[attr_icflag] = 0 + return node_free(g) end end - node.write(g) - tex.attribute[attr_icflag] = -(0x7FFFFFFF) + node_write(g) + tex.attribute[attr_icflag] = 0 end end diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-kinsoku.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-kinsoku.lua index 328bf99b75b..8b61f55b379 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-kinsoku.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-kinsoku.lua @@ -1,5 +1,19 @@ return { [0]=500, + { + ["shrink"]=26214, + ["shrink_order"]=0, + ["stretch"]=26214, + ["stretch_order"]=0, + ["width"]=0, + }, + { + ["shrink"]=65536, + ["shrink_order"]=0, + ["stretch"]=65536, + ["stretch_order"]=0, + ["width"]=157649, + }, [1024]=12295, [1025]=19968, [1026]=20108, diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-math.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-math.lua index 5f9e650c5ca..4aefe63bb46 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-math.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-math.lua @@ -8,11 +8,24 @@ luatexja.load_module('jfont'); local ltjf = luatexja.jfont luatexja.load_module('stack'); local ltjs = luatexja.stack luatexja.load_module('setwidth'); local ltjw = luatexja.setwidth -local node_new = node.new -local node_next = node.next -local node_free = node.free -local has_attr = node.has_attribute -local set_attr = node.set_attribute +local Dnode = node.direct or node + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +-- getlist cannot be used for sub_box nodes. Use instead λp. getfield(p, 'head') +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end + +local nullfunc = function(n) return n end +local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local node_traverse = Dnode.traverse +local node_new = Dnode.new +local node_next = (Dnode ~= node) and Dnode.getnext or node.next +local node_free = Dnode.free +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute local tex_getcount = tex.getcount local attr_jchar_class = luatexbase.attributes['ltj@charclass'] @@ -46,38 +59,37 @@ local conv_jchar_to_hbox_A -- sty : 0 (display or text), 1 (script), >=2 (scriptscript) local function conv_jchar_to_hbox(head, sty) - local p = head - local bhead = head - while p do - if p.id == id_simple or p.id == id_accent then - p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty) - p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1) - p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1) - elseif p.id == id_choice then - p.display = conv_jchar_to_hbox(p.display, 0) - p.text = conv_jchar_to_hbox(p.text, 0) - p.script = conv_jchar_to_hbox(p.script, 1) - p.scriptscript = conv_jchar_to_hbox(p.scriptscript, 2) - elseif p.id == id_frac then - p.num = conv_jchar_to_hbox_A(p.num, sty + 1) - p.denom = conv_jchar_to_hbox_A(p.denom, sty + 1) - elseif p.id == id_radical then - p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty) - p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1) - p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1) - if p.degree then - p.degree = conv_jchar_to_hbox_A(p.degree, sty + 1) + for p in node_traverse(head) do + local pid = getid(p) + if pid == id_simple or pid == id_accent then + setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty)) + setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1)) + setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1)) + elseif pid == id_choice then + setfield(p, 'display', conv_jchar_to_hbox_A(getfield(p, 'display'), 0)) + setfield(p, 'text', conv_jchar_to_hbox_A(getfield(p, 'text'), 0)) + setfield(p, 'script', conv_jchar_to_hbox_A(getfield(p, 'script'), 1)) + setfield(p, 'scriptscript', conv_jchar_to_hbox_A(getfield(p, 'scriptscript'), 2)) + elseif pid == id_frac then + setfield(p, 'num', conv_jchar_to_hbox_A(getfield(p, 'num'), sty+1)) + setfield(p, 'denom', conv_jchar_to_hbox_A(getfield(p, 'denom'), sty+1)) + elseif pid == id_radical then + setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty)) + setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1)) + setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1)) + if getfield(p, 'degree') then + setfield(p, 'degree', conv_jchar_to_hbox_A(getfield(p, 'degree'), sty + 1)) end - elseif p.id == id_style then - if p.style == "display'" or p.style == 'display' - or p.style == "text'" or p.style == 'text' then + elseif pid == id_style then + local ps = getfield(p, 'style') + if ps == "display'" or ps == 'display' + or ps == "text'" or ps == 'text' then sty = 0 - elseif p.style == "script'" or p.style == 'script' then + elseif ps == "script'" or ps == 'script' then sty = 1 else sty = 2 end end - p = node.next(p) end return head end @@ -85,37 +97,39 @@ end local MJT = luatexja.stack_table_index.MJT local MJS = luatexja.stack_table_index.MJS local MJSS = luatexja.stack_table_index.MJSS +local capsule_glyph_math = ltjw.capsule_glyph_math +local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct conv_jchar_to_hbox_A = function (p, sty) if not p then return nil else - local pid = p.id + local pid = getid(p) if pid == id_sub_mlist then - if p.head then - p.head = conv_jchar_to_hbox(p.head, sty) + if getfield(p, 'head') then + setfield(p, 'head', conv_jchar_to_hbox(getfield(p, 'head'), sty)) end elseif pid == id_mchar then local fam = has_attr(p, attr_jfam) or -1 - if (not is_math_letters[p.char]) and ltjc.is_ucs_in_japanese_char(p) and fam>=0 then - local f = ltjs.get_penalty_table(MJT + 0x100 * sty + fam, -1, tex_getcount('ltj@@stack')) + local pc = getchar(p) + if (not is_math_letters[pc]) and is_ucs_in_japanese_char(p) and fam>=0 then + local f = ltjs.get_stack_table(MJT + 0x100 * sty + fam, -1, tex_getcount('ltj@@stack')) if f ~= -1 then local q = node_new(id_sub_box) - local r = node_new(id_glyph); r.next = nil - r.char = p.char; r.font = f; r.subtype = 256 + local r = node_new(id_glyph); setfield(r, 'next', nil) + setfield(r, 'char', pc); setfield(r, 'font', f); setfield(r, 'subtype', 256) local k = has_attr(r,attr_ykblshift) or 0 set_attr(r, attr_ykblshift, 0) -- ltj-setwidth 内で実際の位置補正はおこなうので,補正量を退避 - ltjw.head = r; local met = ltjf_font_metric_table[f] - ltjw.capsule_glyph(r, tex.mathdir , true, met, ltjf_find_char_class(p.char, met)); - q.head = ltjw.head; node_free(p); p=q; - set_attr(q.head, attr_yablshift, k) + r = capsule_glyph_math(r, met, ltjf_find_char_class(pc, met)); + setfield(q, 'head', r); node_free(p); p=q; + set_attr(r, attr_yablshift, k) end end - elseif pid == id_sub_box and p.head then + elseif pid == id_sub_box and getfield(p, 'head') then -- \hbox で直に与えられた内容は上下位置を補正する必要はない - set_attr(p.head, attr_icflag, PROCESSED) + set_attr(getfield(p, 'head'), attr_icflag, PROCESSED) end end return p @@ -123,7 +137,7 @@ end luatexbase.add_to_callback('mlist_to_hlist', function (n, display_type, penalties) - local head = conv_jchar_to_hbox(n, 0); + local head = to_node(conv_jchar_to_hbox(to_direct(n), 0)) head = node.mlist_to_hlist(head, display_type, penalties) return head end,'ltj.mlist_to_hlist', 1) diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-otf.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-otf.lua index 47973decb14..f84faa436e9 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-otf.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-otf.lua @@ -13,18 +13,34 @@ local id_glyph = node.id('glyph') local id_whatsit = node.id('whatsit') local sid_user = node.subtype('user_defined') -local node_new = node.new -local node_remove = node.remove -local node_next = node.next -local node_free = node.free -local has_attr = node.has_attribute -local set_attr = node.set_attribute -local unset_attr = node.unset_attribute -local node_insert_after = node.insert_after +local Dnode = node.direct or node + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +--local getlist = (Dnode ~= node) and Dnode.getlist or function(n) return n.head end +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end +local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end + +local nullfunc = function(n) return n end +local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local node_new = Dnode.new +local node_remove = luatexja.Dnode_remove -- Dnode.remove +local node_next = (Dnode ~= node) and Dnode.getnext or node.next +local node_free = Dnode.free +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local unset_attr = Dnode.unset_attribute +local node_insert_after = Dnode.insert_after +local node_write = Dnode.write +local node_traverse_id = Dnode.traverse_id + local identifiers = fonts.hashes.identifiers local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] -local attr_jchar_class = luatexbase.attributes['ltj@charclass'] local attr_yablshift = luatexbase.attributes['ltj@yablshift'] local attr_ykblshift = luatexbase.attributes['ltj@ykblshift'] @@ -33,7 +49,9 @@ local ltjf_find_char_class = ltjf.find_char_class local ltjr_cidfont_data = ltjr.cidfont_data local ltjc_is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char -local OTF = luatexja.userid_table.OTF +luatexja.userid_table.OTF = luatexbase.newuserwhatsitid('char_by_cid', 'luatexja') +luatexja.userid_table.VSR = luatexbase.newuserwhatsitid('replace_vs', 'luatexja') +local OTF, VSR = luatexja.userid_table.OTF, luatexja.userid_table.VSR local function get_ucs_from_rmlgbm(c) local v = ltjr_cidfont_data["Adobe-Japan1"].resources.unicodes["Japan1." .. tostring(c)] @@ -63,9 +81,11 @@ end local function append_jglyph(char) local p = node_new(id_whatsit,sid_user) local v = tex.attribute[attr_curjfnt] - p.user_id=OTF; p.type=100; p.value=char + setfield(p, 'user_id', OTF) + setfield(p, 'type', 100) + setfield(p, 'value', char) set_attr(p, attr_yablshift, tex.attribute[attr_ykblshift]) - node.write(p) + node_write(p) end local function cid(key) @@ -94,37 +114,43 @@ local function cid(key) end local function extract(head) + head = to_direct(head) local p = head local v while p do - if p.id==id_whatsit then - if p.subtype==sid_user and p.user_id==OTF then - local g = node_new(id_glyph) - g.subtype = 0; g.char = p.value - v = has_attr(p, attr_curjfnt); g.font = v - set_attr(g, attr_curjfnt, v) - v = has_attr(p, attr_yablshift) - if v then - set_attr(g, attr_yablshift, v) - else - unset_attr(g, attr_yablshift) - end - head = node_insert_after(head, p, g) - head = node_remove(head, p) - node_free(p); p = g - end + if getid(p)==id_whatsit then + if getsubtype(p)==sid_user then + local puid = getfield(p, 'user_id') + if puid==OTF or puid==VSR then + local g = node_new(id_glyph) + setfield(g, 'subtype', 0) + setfield(g, 'char', getfield(p, 'value')) + v = has_attr(p, attr_curjfnt); setfield(g, 'font',v) + set_attr(g, attr_curjfnt, puid==OTF and v or -1) + -- VSR yields ALchar + v = has_attr(p, attr_yablshift) + if v then + set_attr(g, attr_yablshift, v) + else + unset_attr(g, attr_yablshift) + end + head = node_insert_after(head, p, g) + head = node_remove(head, p) + node_free(p); p = g + end + end end p = node_next(p) end - return head + return to_node(head) end -luatexbase.add_to_callback('hpack_filter', - function (head) return extract(head) end,'ltj.hpack_filter_otf', +luatexbase.add_to_callback('hpack_filter', extract, + 'ltj.hpack_filter_otf', luatexbase.priority_in_callback('pre_linebreak_filter', 'ltj.pre_linebreak_filter')) -luatexbase.add_to_callback('pre_linebreak_filter', - function (head) return extract(head) end, 'ltj.pre_linebreak_filter_otf', +luatexbase.add_to_callback('pre_linebreak_filter', extract, + 'ltj.pre_linebreak_filter_otf', luatexbase.priority_in_callback('pre_linebreak_filter', 'ltj.pre_linebreak_filter')) @@ -178,36 +204,39 @@ do local ivs -- temp table local sort = table.sort local uniq_flag - local function add_ivs_table(tg, unitable) - for gu, gv in pairs(tg) do - local ga = gv.altuni - if ga then - for _,at in pairs(ga) do - local bu, vsel = at.unicode, (at.variant or -1) - if vsel~=-1 then - if vsel>=0xE0100 then vsel = vsel - 0xE0100 end - if not ivs[bu] then ivs[bu] = {} end - uniq_flag = true - for i,_ in pairs(ivs[bu]) do - if i==vs then uniq_flag = false; break end - end - if uniq_flag then - ivs[bu][vsel] = unitable[gv.name] - end + local function add_ivs_table(tg, unitable, glyphmax) + for i = 0, glyphmax-1 do + if tg[i] then + local gv = tg[i] + if gv.altuni then + for _,at in pairs(gv.altuni) do + local bu, vsel = at.unicode, at.variant + if vsel then + if vsel>=0xE0100 then vsel = vsel - 0xE0100 end + if not ivs[bu] then ivs[bu] = {} end + uniq_flag = true + for i,_ in pairs(ivs[bu]) do + if i==vs then uniq_flag = false; break end + end + if uniq_flag then + ivs[bu][vsel] = unitable[gv.name] + end + end end end - end + end end end local function make_ivs_table(id, fname) ivs = {} local fl = fontloader.open(fname) - local ft = fontloader.to_table(fl) local unicodes = id.resources.unicodes - add_ivs_table(ft.glyphs, id.resources.unicodes) - if ft.subfonts then - for _,v in pairs(ft.subfonts) do - add_ivs_table(v.glyphs, id.resources.unicodes) + if fl.glyphs then + add_ivs_table(fl.glyphs, id.resources.unicodes, fl.glyphmax) + end + if fl.subfonts then + for _,v in pairs(fl.subfonts) do + add_ivs_table(v.glyphs, id.resources.unicodes, v.glyphmax) end end fontloader.close(fl) @@ -256,44 +285,52 @@ do end -- 組版時 - local function ivs_jglyph(char, bp, pf) + local function ivs_jglyph(char, bp, pf, uid) local p = node_new(id_whatsit,sid_user) - p.user_id=OTF; p.type=100; p.value=char + setfield(p, 'user_id', uid) + setfield(p, 'type', 100) + setfield(p, 'value', char) set_attr(p, attr_curjfnt, pf) set_attr(p, attr_yablshift, has_attr(bp, attr_ykblshift) or 0) return p end local function do_ivs_repr(head) - local p = head + head = to_direct(head) + local p, r = head while p do - local pid = p.id + local pid = getid(p) if pid==id_glyph then - local pf = p.font - if (has_attr(p, attr_curjfnt) or 0) == pf then - -- only works with JAchars - local q = node_next(p) -- the next node of p - if q and q.id==id_glyph then - local qc = q.char - if (qc>=0xFE00 and qc<=0xFE0F) or (qc>=0xE0100 and qc<0xE01F0) then - -- q is a variation selector - if qc>=0xE0100 then qc = qc - 0xE0100 end - local pt = font_ivs_table[pf] - pt = pt and pt[p.char]; pt = pt and pt[qc] - head = node_remove(head,q) - if pt then - local np = ivs_jglyph(pt, p, pf) - head = node_insert_after(head, p, np) - head = node_remove(head,p) - p = np - end + local pf = getfont(p) + local q = node_next(p) -- the next node of p + if q and getid(q)==id_glyph then + local qc = getchar(q) + if (qc>=0xFE00 and qc<=0xFE0F) or (qc>=0xE0100 and qc<0xE01F0) then + -- q is a variation selector + if qc>=0xE0100 then qc = qc - 0xE0100 end + local pt = font_ivs_table[pf] + pt = pt and pt[getchar(p)]; pt = pt and pt[qc] + head, r = node_remove(head,q) + node_free(q) + if pt then + local np = ivs_jglyph(pt, p, pf, + (has_attr(p,attr_curjfnt) or 0)==pf and OTF or VSR) + head = node_insert_after(head, p, np) + head = node_remove(head,p) + node_free(p) end + p = r + else + p = q end + else + p = node_next(p) end + else + p = node_next(p) end - p = node_next(p) end - return head + return to_node(head) end -- font define @@ -309,9 +346,9 @@ do 'luatexja.otf.enable_ivs() was already called, so this call is ignored', '') else luatexbase.add_to_callback('hpack_filter', - function (head) return do_ivs_repr(head) end,'do_ivs', 1) + do_ivs_repr,'do_ivs', 1) luatexbase.add_to_callback('pre_linebreak_filter', - function (head) return do_ivs_repr(head) end, 'do_ivs', 1) + do_ivs_repr, 'do_ivs', 1) local ivs_callback = function (name, size, id) return font_callback( name, size, id, diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-pretreat.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-pretreat.lua index f8eed907d45..14cec985159 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-pretreat.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-pretreat.lua @@ -6,14 +6,28 @@ luatexja.load_module('charrange'); local ltjc = luatexja.charrange luatexja.load_module('stack'); local ltjs = luatexja.stack luatexja.load_module('jfont'); local ltjf = luatexja.jfont +local Dnode = node.direct or node + +local nullfunc = function(n) return n end +local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc +local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc + +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end + +local pairs = pairs local floor = math.floor -local has_attr = node.has_attribute -local set_attr = node.set_attribute -local node_traverse = node.traverse -local node_type = node.type -local node_remove = node.remove -local node_next = node.next -local node_free = node.free +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local node_traverse = Dnode.traverse +local node_remove =luatexja.Dnode_remove -- Dnode.remove +local node_next = (Dnode ~= node) and Dnode.getnext or node.next +local node_free = Dnode.free +local node_end_of_math = Dnode.end_of_math local tex_getcount = tex.getcount local id_glyph = node.id('glyph') @@ -24,7 +38,7 @@ local sid_user = node.subtype('user_defined') local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] local attr_icflag = luatexbase.attributes['ltj@icflag'] -local ltjc_is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char +local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct local ltjf_replace_altfont = ltjf.replace_altfont local attr_orig_char = luatexbase.attributes['ltj@origchar'] local STCK = luatexja.userid_table.STCK @@ -33,37 +47,52 @@ local STCK = luatexja.userid_table.STCK -- MAIN PROCESS STEP 1: replace fonts ------------------------------------------------------------------------ local wt +do + local head -local function suppress_hyphenate_ja(head) - local non_math, p = true, head - wt = {} - while p do - local pid = p.id - if pid == id_glyph then - if (has_attr(p, attr_icflag) or 0)<=0 and ltjc_is_ucs_in_japanese_char(p) then - local pc = p.char - local pf = ltjf_replace_altfont(has_attr(p, attr_curjfnt) or p.font, pc) - p.font = pf; set_attr(p, attr_curjfnt, pf) - p.subtype = floor(p.subtype*0.5)*2 - set_attr(p, attr_orig_char, pc) - end - elseif pid == id_math then - p = node_next(p) -- skip math on - while p and p.id~=id_math do p = node_next(p) end - elseif pid == id_whatsit and p.subtype==sid_user and p.user_id==STCK then + local suppress_hyphenate_ja_aux = {} + suppress_hyphenate_ja_aux[id_glyph] = function(p) + if (has_attr(p, attr_icflag) or 0)<=0 and is_ucs_in_japanese_char(p) then + local pc = getchar(p) + local pf = ltjf_replace_altfont(has_attr(p, attr_curjfnt) or getfont(p), pc) + setfield(p, 'font', pf); set_attr(p, attr_curjfnt, pf) + setfield(p, 'subtype', floor(getsubtype(p)*0.5)*2) + set_attr(p, attr_orig_char, pc) + end + return p + end + suppress_hyphenate_ja_aux[id_math] = function(p) return node_end_of_math(node_next(p)) end + suppress_hyphenate_ja_aux[id_whatsit] = function(p) + if getsubtype(p)==sid_user and getfield(p, 'user_id')==STCK then wt[#wt+1] = p; head = node_remove(head, p) end - p = node_next(p) + return p end - lang.hyphenate(head) - return head + + local function suppress_hyphenate_ja (h) + local p = to_direct(h) + wt, head = {}, p + while p do + local pfunc = suppress_hyphenate_ja_aux[getid(p)] + if pfunc then p = pfunc(p) end + p = node_next(p) + end + head = to_node(head) + lang.hyphenate(head) + return head + end + + luatexbase.add_to_callback('hyphenate', + function (head,tail) + return suppress_hyphenate_ja(head) + end,'ltj.hyphenate') end -- mode: true iff this function is called from hpack_filter local function set_box_stack_level(head, mode) local box_set, cl = 0, tex.currentgrouplevel + 1 for _,p in pairs(wt) do - if mode and p.value==cl then box_set = 1 end; node_free(p) + if mode and getfield(p, 'value')==cl then box_set = 1 end; node_free(p) end ltjs.report_stack_level(tex_getcount('ltj@@stack') + box_set) return head @@ -78,10 +107,6 @@ luatexbase.add_to_callback('pre_linebreak_filter', function (head) return set_box_stack_level(head, false) end,'ltj.pre_linebreak_filter_pre',1) -luatexbase.add_to_callback('hyphenate', - function (head,tail) - return suppress_hyphenate_ja(head) - end,'ltj.hyphenate') luatexja.pretreat = { set_box_stack_level = set_box_stack_level, diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-setwidth.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-setwidth.lua index a3e9f23bf1c..30389e21212 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-setwidth.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-setwidth.lua @@ -1,25 +1,28 @@ -- --- luatexja/setwidth.lua +-- src/ltj-setwidth.lua -- -luatexbase.provides_module({ - name = 'luatexja.setwidth', - date = '2013/12/05', - description = '', -}) -module('luatexja.setwidth', package.seeall) -local err, warn, info, log = luatexbase.errwarinf(_NAME) luatexja.load_module('base'); local ltjb = luatexja.base luatexja.load_module('jfont'); local ltjf = luatexja.jfont -local node_type = node.type -local node_new = node.new -local node_tail = node.tail -local node_next = node.next -local has_attr = node.has_attribute -local set_attr = node.set_attribute -local node_insert_before = node.insert_before -local node_insert_after = node.insert_after +local Dnode = node.direct or node +local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end +local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end +local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end +local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end +local getlist = (Dnode ~= node) and Dnode.getlist or function(n) return n.head end +local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end +local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end + +local node_traverse = Dnode.traverse +local node_new = Dnode.new +local node_remove = luatexja.Dnode_remove -- Dnode.remove +local node_tail = Dnode.tail +local node_next = (Dnode ~= node) and Dnode.getnext or node.next +local has_attr = Dnode.has_attribute +local set_attr = Dnode.set_attribute +local node_insert_before = Dnode.insert_before +local node_insert_after = Dnode.insert_after local round = tex.round local id_glyph = node.id('glyph') @@ -42,90 +45,124 @@ local PROCESSED = luatexja.icflag_table.PROCESSED local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG +local get_pr_begin_flag do local floor = math.floor - function get_pr_begin_flag(p) + get_pr_begin_flag = function (p) local i = has_attr(p, attr_icflag) or 0 return i - i%PROCESSED_BEGIN_FLAG end end -local get_pr_begin_flag = get_pr_begin_flag -head = nil; +local head, dir +local ltjw = {} --export +luatexja.setwidth = ltjw luatexbase.create_callback("luatexja.set_width", "data", function (fstable, fmtable, jchar_class) return fstable end) +local call_callback = luatexbase.call_callback local fshift = { down = 0, left = 0} -- mode: true iff p will be always encapsuled by a hbox -function capsule_glyph(p, dir, mode, met, class) +local function capsule_glyph(p, met, class) local char_data = met.char_type[class] if not char_data then return node_next(p) end - local fwidth, pwidth = char_data.width, p.width + local fwidth, pwidth = char_data.width, getfield(p, 'width') fwidth = (fwidth ~= 'prop') and fwidth or pwidth fshift.down = char_data.down; fshift.left = char_data.left - fshift = luatexbase.call_callback("luatexja.set_width", fshift, met, class) + fshift = call_callback("luatexja.set_width", fshift, met, class) local fheight, fdepth = char_data.height, char_data.depth - fheight = (fheight ~= 'prop') and fheight or p.height - fdepth = (fdepth ~= 'prop') and fdepth or p.depth - if (mode or pwidth ~= fwidth or p.height ~= fheight or p.depth ~= fdepth) then - local y_shift, ca - = - p.yoffset + (has_attr(p,attr_ykblshift) or 0), char_data.align - local q; head, q = node.remove(head, p) - p.yoffset, p.next = -fshift.down, nil - if ca~='left' then - p.xoffset = p.xoffset - fshift.left - + (((ca=='right') and fwidth - pwidth) or round((fwidth - pwidth)*0.5)) - else - p.xoffset = p.xoffset - fshift.left - end - local box = node_new(id_hlist); - box.width, box.height, box.depth = fwidth, fheight, fdepth - box.head, box.shift, box.dir = p, y_shift, (dir or 'TLT') - --box.glue_set, box.glue_order = 0, 0 not needed + if (pwidth ~= fwidth or getfield(p, 'height') ~= fheight or getfield(p, 'depth') ~= fdepth) then + local y_shift + = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0) + local q + head, q = node_remove(head, p) + setfield(p, 'yoffset', -fshift.down); setfield(p, 'next', nil) + setfield(p, 'xoffset', getfield(p, 'xoffset') + char_data.align*(fwidth-pwidth)) + local box = node_new(id_hlist) + setfield(box, 'width', fwidth) + setfield(box, 'height', fheight) + setfield(box, 'depth', fdepth) + setfield(box, 'head', p) + setfield(box, 'shift', y_shift) + setfield(box, 'dir', dir) set_attr(box, attr_icflag, PACKED + get_pr_begin_flag(p)) head = q and node_insert_before(head, q, box) or node_insert_after(head, node_tail(head), box) return q else set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p)) - p.xoffset = p.xoffset - fshift.left - p.yoffset = p.yoffset - (has_attr(p, attr_ykblshift) or 0) - fshift.down + setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left) + setfield(p, 'yoffset', getfield(p, 'yoffset') + - (has_attr(p, attr_ykblshift) or 0) - fshift.down) return node_next(p) end end +luatexja.setwidth.capsule_glyph = capsule_glyph + +local function capsule_glyph_math(p, met, class) + local char_data = met.char_type[class] + if not char_data then return nil end + local fwidth, pwidth = char_data.width, getfield(p, 'width') + fwidth = (fwidth ~= 'prop') and fwidth or pwidth + fshift.down = char_data.down; fshift.left = char_data.left + fshift = call_callback("luatexja.set_width", fshift, met, class) + local fheight, fdepth = char_data.height, char_data.depth + local y_shift, ca + = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0), char_data.align + setfield(p, 'yoffset', -fshift.down) + if ca~='left' then + setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left + + (((ca=='right') and fwidth - pwidth) or round((fwidth - pwidth)*0.5))) + else + setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left) + end + local box = node_new(id_hlist); + setfield(box, 'width', fwidth) + setfield(box, 'height', fheight) + setfield(box, 'depth', fdepth) + setfield(box, 'head', p) + setfield(box, 'shift', y_shift) + setfield(box, 'dir', tex.mathdir) + set_attr(box, attr_icflag, PACKED + get_pr_begin_flag(p)) + return box +end +luatexja.setwidth.capsule_glyph_math = capsule_glyph_math -function set_ja_width(ahead, dir) - local p = ahead; head = ahead +function luatexja.setwidth.set_ja_width(ahead, adir) + local p = ahead; head = p; dir = adir or 'TLT' local m = false -- is in math mode? while p do - local pid = p.id + local pid = getid(p) if (pid==id_glyph) and ((has_attr(p, attr_icflag) or 0)%PROCESSED_BEGIN_FLAG)<=0 then - local pf = p.font + local pf = getfont(p) if pf == has_attr(p, attr_curjfnt) then - p = capsule_glyph(p, dir, false, ltjf_font_metric_table[pf], + p = capsule_glyph(p, ltjf_font_metric_table[pf], has_attr(p, attr_jchar_class)) else set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p)) - p.yoffset = p.yoffset - (has_attr(p,attr_yablshift) or 0); p = node_next(p) + setfield(p, 'yoffset', + getfield(p, 'yoffset') - (has_attr(p,attr_yablshift) or 0)) + p = node_next(p) end - elseif p.id==id_math then - m = (p.subtype==0); p = node_next(p) + elseif pid==id_math then + m = (getsubtype(p)==0); p = node_next(p) else if m then -- 数式の位置補正 if pid==id_hlist or pid==id_vlist then if (has_attr(p, attr_icflag) or 0) ~= PROCESSED then - p.shift = p.shift + (has_attr(p,attr_yablshift) or 0) + setfield(p, 'shift', getfield(p, 'shift') + (has_attr(p,attr_yablshift) or 0)) end elseif pid==id_rule then if (has_attr(p, attr_icflag) or 0) ~= PROCESSED then local v = has_attr(p,attr_yablshift) or 0 - p.height = p.height - v; p.depth = p.depth + v + setfield(p, 'height', getfield(p, 'height')-v) + setfield(p, 'depth', getfield(p, 'depth')+v) set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p)) end end @@ -137,3 +174,4 @@ function set_ja_width(ahead, dir) tex.setattribute('global', attr_icflag, 0) return head end + diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-stack.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-stack.lua index 9602939fdbf..2a90fd2c89f 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-stack.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-stack.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.stack', - date = '2013/04/13', + date = '2014/01/24', description = 'LuaTeX-ja stack system', }) module('luatexja.stack', package.seeall) @@ -28,7 +28,7 @@ function get_stack_level() if j > tex.getcount('ltj@@group@level') then i = i+1 -- new stack level local gd = tex.globaldefs - if gd>0 then tex.globaldefs = 0 end + if gd~=0 then tex.globaldefs = 0 end -- 'tex.globaldefs = 0' is local even if \globaldefs > 0. tex.setcount('ltj@@group@level', j) for k,v in pairs(charprop_stack_table) do -- clear the stack above i @@ -36,7 +36,7 @@ function get_stack_level() end charprop_stack_table[i] = table.fastcopy(charprop_stack_table[i-1]) tex.setcount('ltj@@stack', i) - if gd>0 then tex.globaldefs = gd end + if gd~=0 then tex.globaldefs = gd end if tex.nest[tex.nest.ptr].mode == hmode or tex.nest[tex.nest.ptr].mode == -hmode then local g = node_new(id_whatsit, sid_user) @@ -60,10 +60,19 @@ end -- end -- end +function set_stack_table(m,p) + local i = get_stack_level() + charprop_stack_table[i][m] = p + if luatexja.isglobal=='global' then + for j,v in pairs(charprop_stack_table) do + charprop_stack_table[j][m] = p + end + end +end +local set_stack_table = set_stack_table -- EXT -function set_stack_table(g,m,c,p,lb,ub) - local i = get_stack_level() +function set_stack_perchar(m,c,p,lb,ub) if type(p)~='number' or p<lb or p>ub then ltjb.package_error('luatexja', "invalid code (".. tostring(p) .. ")", @@ -71,25 +80,12 @@ function set_stack_table(g,m,c,p,lb,ub) tostring(ub) .. ".\n" .. "I'm going to use 0 instead of that illegal code value.") p=0 - elseif type(c)~='number' or c<-1 or c>0x10ffff then - ltjb.package_error('luatexja', - 'bad character code (' .. tostring(c) .. ')', - 'A character number must be between -1 and 0x10ffff.\n' .. - "(-1 is used for denoting `math boundary')\n" .. - 'So I changed this one to zero.') - c=0 end - charprop_stack_table[i][c+m] = p - if g=='global' then - for j,v in pairs(charprop_stack_table) do - charprop_stack_table[j][c+m] = p - end - end + set_stack_table(m+ltjb.in_unicode(c, true), p) end -- EXT -function set_stack_font(g,m,c,p) - local i = get_stack_level() +function set_stack_font(m,c,p) if type(c)~='number' or c<0 or c>255 then ltjb.package_error('luatexja', "invalid family number (".. tostring(c) .. ")", @@ -97,16 +93,11 @@ function set_stack_font(g,m,c,p) "I'm going to use 0 instead of that illegal family number.") c=0 end - charprop_stack_table[i][c+m] = p - if g=='global' then - for j,v in pairs(charprop_stack_table) do - charprop_stack_table[j][c+m] = p - end - end + set_stack_table(m+c, p) end -- EXT: store \ltj@tempskipa -function set_stack_skip(g,m,sp) +function set_stack_skip(m,sp) local i = get_stack_level() if not sp then return end if not charprop_stack_table[i][m] then @@ -117,7 +108,7 @@ function set_stack_skip(g,m,sp) charprop_stack_table[i][m].shrink = sp.shrink charprop_stack_table[i][m].stretch_order = sp.stretch_order charprop_stack_table[i][m].shrink_order = sp.shrink_order - if g=='global' then + if luatexja.isglobal=='global' then for j,v in pairs(charprop_stack_table) do if not charprop_stack_table[j][m] then charprop_stack_table[j][m] = {} end charprop_stack_table[j][m].width = sp.width @@ -133,17 +124,17 @@ end function report_stack_level(bsl) table_current_stack = charprop_stack_table[bsl] end -function fast_get_skip_table(m) +function fast_get_stack_skip(m) return table_current_stack[m] or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 } end -- For other situations, use the following instead: -function get_skip_table(m, idx) +function get_stack_skip(m, idx) return charprop_stack_table[idx][m] or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 } end -function get_penalty_table(mc, d, idx) +function get_stack_table(mc, d, idx) local i = charprop_stack_table[idx][mc] return i or d end diff --git a/Master/texmf-dist/tex/luatex/luatexja/luatexja-compat.sty b/Master/texmf-dist/tex/luatex/luatexja/luatexja-compat.sty index 8d1d2d647d1..6b2185e5598 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/luatexja-compat.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/luatexja-compat.sty @@ -145,6 +145,7 @@ \ltjsetparameter{kansujichar={7,`七}} \ltjsetparameter{kansujichar={8,`八}} \ltjsetparameter{kansujichar={9,`九}} +\ltj@@decl@array@param{kansujichar} \ifltj@in@latex \newcommand\printglossary{\@input@{\jobname.gls}} diff --git a/Master/texmf-dist/tex/luatex/luatexja/luatexja-core.sty b/Master/texmf-dist/tex/luatex/luatexja/luatexja-core.sty index 0995eb471a9..553e2001a9f 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/luatexja-core.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/luatexja-core.sty @@ -65,7 +65,7 @@ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname \csname iftrue\endcsname \NeedsTeXFormat{LaTeX2e} - \ProvidesPackage{luatexja-core}[2013/05/14 Core of LuaTeX-ja] + \ProvidesPackage{luatexja-core}[2014/02/01 Core of LuaTeX-ja] \fi %</LaTeX> %% Load prerequisite packages. @@ -101,6 +101,11 @@ {Package loading is aborted now.\MessageBreak} \expandafter\endinput\fi\relax + \@PackageInfoNoLine{luatexja-core} + {using\space% + \directlua{if node.direct==node then tex.write('traditional node') + else tex.write('DIRECT') end} node access model} + %! なお、luatexbase-compat の説明に従うと、LuaTeX 拡張プリミティブは %! plain/LaTeX の両方で \luatex 付の名前(\directlua はそのまま) %! で使えると考えてよい。 @@ -138,7 +143,10 @@ \newluatexattribute\ltj@yablshift % attribute for \yabaselineshift \newluatexattribute\ltj@ykblshift % attribute for \ykbaselineshift \newluatexattribute\jfam % index for current jfam -\ltj@icflag=0\ltj@origchar=0 +\ltj@icflag=0 +\ltj@origchar=0 +\ltj@charclass=0 +\ltj@curjfnt=-1 %%%%%%%% Attributes for character ranges \newcount\ltj@tempcnta @@ -192,9 +200,8 @@ \def\ltj@@jfont{\directlua{luatexja.jfont.jfontdefY()}} %%%%%%%% \zw, \zh -\protected\def\zw{\directlua{luatexja.jfont.load_zw()}\ltj@zw} -\protected\def\zh{\directlua{luatexja.jfont.load_zh()}\ltj@zh} - +\protected\def\zw{\directlua{tex.setdimen('ltj@zw', luatexja.jfont.get_zw())}\ltj@zw} +\protected\def\zh{\directlua{tex.setdimen('ltj@zh', luatexja.jfont.get_zh())}\ltj@zh} %%%%%%%% \inhibitglue \protected\def\ltj@reset@globaldefs{% @@ -238,7 +245,7 @@ \setbox0\hbox{% \directlua{% This value depends on the version of LuaTeX. luatexja.stack.hmode = -tex.nest[tex.nest.ptr].mode - } + }% } % prebreakpenalty = {<char_code>, <penalty>} @@ -249,7 +256,7 @@ \define@key[ltj]{japaram}{postbreakpenalty}{% \expandafter\ltj@@set@stack#1:{POST}{-10000}{10000}} \def\ltj@@set@stack#1,#2:#3#4#5{% - \directlua{luatexja.stack.set_stack_table(luatexja.isglobal, luatexja.stack_table_index.#3, + \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.#3, \ltj@safe@num@or{nil}{#1},\ltj@safe@num@or{nil}{#2},#4,#5)}} % jatextfont = {<char_code>, <font_cs>} @@ -267,8 +274,7 @@ {\string#2 is not a control sequence that represents \MessageBreak a Japanese font}{}% \else - \directlua{luatexja.stack.set_stack_font(luatexja.isglobal, - luatexja.stack_table_index.#3, + \directlua{luatexja.stack.set_stack_font(luatexja.stack_table_index.#3, \ltj@safe@num@or{nil}{#1}, \the\ltj@curjfnt)}% \fi \ltj@curjfnt=\ltj@tempcnta @@ -297,8 +303,7 @@ \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi - \directlua{luatexja.stack.set_stack_table(luatexja.isglobal, - luatexja.stack_table_index.XSP, + \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.XSP, \ltj@safe@num@or{nil}{#1}, \ltj@safe@num@or{nil}{\ltj@temp},0,3)}} @@ -313,8 +318,7 @@ \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi - \directlua{luatexja.stack.set_stack_table(luatexja.isglobal, - luatexja.stack_table_index.XSP, + \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.XSP, \ltj@safe@num@or{nil}{#1}, \ltj@safe@num@or{nil}{\ltj@temp},0,3)}} @@ -336,9 +340,15 @@ % [x]]kanjiskip = <dimen> \define@key[ltj]{japaram}{kanjiskip}{% % SKIP - \directlua{luatexja.stack.set_stack_skip(luatexja.isglobal, 'kanjiskip', \ltj@safe@glue{#1})}} + \directlua{% + local d = \ltj@safe@glue{#1} + luatexja.stack.set_stack_skip(luatexja.stack_table_index.KSK, d); node.free(d) +}} \define@key[ltj]{japaram}{xkanjiskip}{% % SKIP - \directlua{luatexja.stack.set_stack_skip(luatexja.isglobal, 'xkanjiskip', \ltj@safe@glue{#1})}} + \directlua{% + local d = \ltj@safe@glue{#1} + luatexja.stack.set_stack_skip(luatexja.stack_table_index.XSK, d); node.free(d) +}} % jcharwidowpenalty = <count> \define@key[ltj]{japaram}{jcharwidowpenalty}{% %COUNT @@ -373,12 +383,14 @@ } \protected\def\ltj@setpar@global{% - \ifnum\globaldefs>0\directlua{luatexja.isglobal='global'}\else\directlua{luatexja.isglobal=''}\fi + \relax\ifnum\globaldefs>0\directlua{luatexja.isglobal='global'}% + \else\directlua{luatexja.isglobal=''}\fi } \protected\def\ltjsetparameter#1{% \ltj@setpar@global\setkeys[ltj]{japaram}{#1}\ignorespaces} \protected\def\ltjglobalsetparameter#1{% - \ifnum\globaldefs<0\directlua{luatexja.isglobal=''}\else\directlua{luatexja.isglobal='global'}\fi + \relax\ifnum\globaldefs<0\directlua{luatexja.isglobal=''}% + \else\directlua{luatexja.isglobal='global'}\fi% \setkeys[ltj]{japaram}{#1}\ignorespaces} %%%%%%%% \ltjgetparameter @@ -432,9 +444,14 @@ \def\ltj@@alchar{{\directlua{tex.globaldefs = 0}\ltj@allalchar\ltj@@origchar\ltj@tempcnta}} %%%%%%%% \ltjsetmathletter<number>, \ltjunsetmathletter<number> -\protected\def\ltjsetmathletter#1{\directlua{luatexja.math.is_math_letters[#1]=true}} -\protected\def\ltjunsetmathletter#1{\directlua{luatexja.math.is_math_letters[#1]=false}} - +\protected\def\ltjsetmathletter#1{% + \ltj@tempcnta=#1 + \directlua{luatexja.math.is_math_letters[\the\ltj@tempcnta]=true}% +} +\protected\def\ltjunsetmathletter#1{% + \ltj@tempcnta=#1 + \directlua{luatexja.math.is_math_letters[\the\ltj@tempcnta]=false}% +} %%%%%%%% \ltjdeclarealtfont<base_font_cs><alt_font_cs>{100-200,3000-,5000,...} % <base_font_cs> の 第 3 引数の文字達は <alt_font_cs> で組む diff --git a/Master/texmf-dist/tex/luatex/luatexja/luatexja.lua b/Master/texmf-dist/tex/luatex/luatexja/luatexja.lua index c6ccda589fb..cfa499ae0e9 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/luatexja.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/luatexja.lua @@ -22,18 +22,20 @@ end --- 以下は全ファイルで共有される定数 local icflag_table = {} luatexja.icflag_table = icflag_table -icflag_table.ITALIC = 1 -icflag_table.PACKED = 2 -icflag_table.KINSOKU = 3 -icflag_table.FROM_JFM = 6 --- FROM_JFM: 4, 5, 6, 7, 8 →優先度高 +icflag_table.ITALIC = 1 +icflag_table.PACKED = 2 +icflag_table.KINSOKU = 3 +icflag_table.FROM_JFM = 6 +-- FROM_JFM: 4, 5, 6, 7, 8 →優先度高(伸びやすく,縮みやすい) -- 6 が標準 -icflag_table.KANJI_SKIP = 9 -icflag_table.XKANJI_SKIP = 10 -icflag_table.PROCESSED = 11 -icflag_table.IC_PROCESSED = 12 -icflag_table.BOXBDD = 15 -icflag_table.PROCESSED_BEGIN_FLAG = 32 +icflag_table.KANJI_SKIP = 9 +icflag_table.KANJI_SKIP_JFM = 10 +icflag_table.XKANJI_SKIP = 11 +icflag_table.XKANJI_SKIP_JFM = 12 +icflag_table.PROCESSED = 13 +icflag_table.IC_PROCESSED = 14 +icflag_table.BOXBDD = 15 +icflag_table.PROCESSED_BEGIN_FLAG = 128 local stack_table_index = {} luatexja.stack_table_index = stack_table_index @@ -41,7 +43,9 @@ stack_table_index.PRE = 0x200000 -- characterごと stack_table_index.POST = 0x400000 -- characterごと stack_table_index.KCAT = 0x600000 -- characterごと stack_table_index.XSP = 0x800000 -- characterごと -stack_table_index.JWP = 0 -- 0のみ +stack_table_index.JWP = 0 -- これだけ +stack_table_index.KSK = 1 -- これだけ +stack_table_index.XSK = 2 -- これだけ stack_table_index.MJT = 0x100 -- 0--255 stack_table_index.MJS = 0x200 -- 0--255 stack_table_index.MJSS = 0x300 -- 0--255 @@ -51,9 +55,46 @@ local userid_table = {} luatexja.userid_table = userid_table userid_table.IHB = luatexbase.newuserwhatsitid('inhibitglue', 'luatexja') -- \inhibitglue userid_table.STCK = luatexbase.newuserwhatsitid('stack_marker', 'luatexja') -- スタック管理 -userid_table.OTF = luatexbase.newuserwhatsitid('char_by_cid', 'luatexja') -- luatexja-otf userid_table.BPAR = luatexbase.newuserwhatsitid('begin_par', 'luatexja') -- 「段落始め」 +------------------------------------------------------------------------ +-- FIX node.remove +------------------------------------------------------------------------ +do + local node_remove, node_next, node_prev = node.remove, node.next, node.prev + function luatexja.node_remove (head, current) + if head==current then + local q, r = node_next(current), node_prev(current) + if q then q.prev = r end + if r and node_next(r)==current then + r.next = q + end + return q, q + else + return node_remove(head, current) + end + end + local Dnode = node.direct or node + if Dnode~=node then + local Dnode_remove, setfield = Dnode.remove, Dnode.setfield + local Dnode_next, Dnode_prev = Dnode.getnext, Dnode.getprev + function luatexja.Dnode_remove (head, current) + if head==current then + local q, r = Dnode_next(current), Dnode_prev(current) + if q then setfield(q, 'prev', r) end + if r and Dnode_next(r) == current then + setfield(r, 'next', q) + end + return q, q + else + return Dnode_remove(head, current) + end + end + else + luatexja.Dnode_remove = luatexja.node_remove + end +end + --- 定義終わり local load_module = luatexja.load_module @@ -76,10 +117,6 @@ local attr_icflag = luatexbase.attributes['ltj@icflag'] local attr_uniqid = luatexbase.attributes['ltj@uniqid'] local cat_lp = luatexbase.catcodetables['latex-package'] - ----- table: charprop_stack_table [stack_level].{pre|post|xsp}[chr_code] - - -- Three aux. functions, bollowed from tex.web local unity=65536 @@ -132,83 +169,95 @@ end ------------------------------------------------------------------------ -- EXT: print parameters that don't need arguments -function luatexja.ext_get_parameter_unary(k) - local t = tex.getcount('ltj@@stack') - if k == 'yalbaselineshift' then - tex.write(print_scaled(tex.getattribute('ltj@yablshift'))..'pt') - elseif k == 'yjabaselineshift' then - tex.write(print_scaled(tex.getattribute('ltj@ykblshift'))..'pt') - elseif k == 'kanjiskip' then - tex.write(print_spec(ltjs.get_skip_table('kanjiskip', t))) - elseif k == 'xkanjiskip' then - tex.write(print_spec(ltjs.get_skip_table('xkanjiskip', t))) - elseif k == 'jcharwidowpenalty' then - tex.write(ltjs.get_penalty_table(stack_table_index.JWP, 0, t)) - elseif k == 'autospacing' then - tex.write(tex.getattribute('ltj@autospc')) - elseif k == 'autoxspacing' then - tex.write(tex.getattribute('ltj@autoxspc')) - elseif k == 'differentjfm' then - if luatexja.jfmglue.diffmet_rule == math.max then - tex.write('large') - elseif luatexja.jfmglue.diffmet_rule == math.min then - tex.write('small') - elseif luatexja.jfmglue.diffmet_rule == math.two_average then - tex.write('average') - elseif luatexja.jfmglue.diffmet_rule == math.two_paverage then - tex.write('paverage') - elseif luatexja.jfmglue.diffmet_rule == math.two_pleft then - tex.write('pleft') - elseif luatexja.jfmglue.diffmet_rule == math.two_pright then - tex.write('pright') - elseif luatexja.jfmglue.diffmet_rule == math.two_add then - tex.write('both') - else -- This can't happen. - tex.write('???') +do + luatexja.unary_pars = { + yalbaselineshift = function(t) + return print_scaled(tex.getattribute('ltj@yablshift'))..'pt' + end, + yjabaselineshift = function(t) + return print_scaled(tex.getattribute('ltj@ykblshift'))..'pt' + end, + kanjiskip = function(t) + return print_spec(ltjs.get_stack_skip(stack_table_index.KSK, t)) + end, + xkanjiskip = function(t) + return print_spec(ltjs.get_stack_skip(stack_table_index.XSK, t)) + end, + jcharwidowpenalty = function(t) + return ltjs.get_stack_table(stack_table_index.JWP, 0, t) + end, + autospacing = function(t) + return tex.getattribute('ltj@autospc') + end, + autoxspacing = function(t) + return tex.getattribute('ltj@autoxspc') + end, + differentjfm = function(t) + local f, r = luatexja.jfmglue.diffmet_rule, '???' + if f == math.max then r = 'large' + elseif f == math.min then r = 'small' + elseif f == math.two_average then r = 'average' + elseif f == math.two_paverage then r = 'paverage' + elseif f == math.two_pleft then r = 'pleft' + elseif f == math.two_pright then r = 'pright' + elseif f == math.two_add then r = 'both' + end + return r + end + } + + local unary_pars = luatexja.unary_pars + function luatexja.ext_get_parameter_unary(k) + if unary_pars[k] then + tex.write(tostring(unary_pars[k](tex.getcount('ltj@@stack')))) end end end -- EXT: print parameters that need arguments -function luatexja.ext_get_parameter_binary(k,c) - local t = tex.getcount('ltj@@stack') - if type(c)~='number' then - ltjb.package_error('luatexja', - 'invalid the second argument (' .. tostring(c) .. ')', - 'I changed this one to zero.') - c=0 - end - if k == 'jacharrange' then - if c>=31*ltjc.ATTR_RANGE then - ltjb.package_error('luatexja', - 'invalid character range number (' .. c .. ')', - 'A character range number should be in the range 0..' - .. 31*ltjc.ATTR_RANGE-1 .. ",\n".. - 'So I changed this one to zero.') - c=0 - end +do + luatexja.binary_pars = { + jacharrange = function(c, t) + if type(c)~='number' or c<0 or c>31*ltjc.ATTR_RANGE then + -- 0 はエラーにしない(隠し) + ltjb.package_error('luatexja', + 'invalid character range number (' .. tostring(c) .. ')', + 'A character range number should be in the range 1..' + .. 31*ltjc.ATTR_RANGE .. ",\n".. + 'So I changed this one to ' .. 31*ltjc.ATTR_RANGE .. ".") + c=0 -- external range 217 == internal range 0 + elseif c==31*ltjc.ATTR_RANGE then c=0 + end -- 負の値は <U+0080 の文字の文字範囲,として出てくる.この時はいつも欧文文字なので 1 を返す - tex.write( (c<0) and -1 or ltjc.get_range_setting(c)) - else - if c<0 or c>0x10FFFF then - ltjb.package_error('luatexja', - 'bad character code (' .. c .. ')', - 'A character number must be between -1 and 0x10ffff.\n'.. - "(-1 is used for denoting `math boundary')\n".. - 'So I changed this one to zero.') - c=0 - end - if k == 'prebreakpenalty' then - tex.write(ltjs.get_penalty_table(stack_table_index.PRE + c, 0, t)) - elseif k == 'postbreakpenalty' then - tex.write(ltjs.get_penalty_table(stack_table_index.POST+ c, 0, t)) - elseif k == 'kcatcode' then - tex.write(ltjs.get_penalty_table(stack_table_index.KCAT+ c, 0, t)) - elseif k == 'chartorange' then - tex.write(ltjc.char_to_range(c)) - elseif k == 'jaxspmode' or k == 'alxspmode' then - tex.write(ltjs.get_penalty_table(stack_table_index.XSP + c, 3, t)) + return (c<0) and 1 or ltjc.get_range_setting(c) + end, + prebreakpenalty = function(c, t) + return ltjs.get_stack_table(stack_table_index.PRE + + ltjb.in_unicode(c, true), 0, t) + end, + postbreakpenalty = function(c, t) + return ltjs.get_stack_table(stack_table_index.POST + + ltjb.in_unicode(c, true), 0, t) + end, + kcatcode = function(c, t) + return ltjs.get_stack_table(stack_table_index.KCAT + + ltjb.in_unicode(c, false), 0, t) + end, + chartorange = function(c, t) + return ltjc.char_to_range(ltjb.in_unicode(c, false)) + end, + jaxspmode = function(c, t) + return ltjs.get_stack_table(stack_table_index.XSP + + ltjb.in_unicode(c, true), 3, t) + end, + } + local binary_pars = luatexja.binary_pars + + binary_pars.alxspmode = binary_pars.jaxspmode + function luatexja.ext_get_parameter_binary(k,c) + if binary_pars[k] then + tex.write(tostring(binary_pars[k](c,tex.getcount('ltj@@stack')))) end end end @@ -220,12 +269,16 @@ end -- main process do + local Dnode = node.direct or node + local nullfunc = function (n) return n end + local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc + local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc -- mode = true iff main_process is called from pre_linebreak_filter local function main_process(head, mode, dir) - local p = head + local p = to_direct(head) p = ltjj.main(p,mode) if p then p = ltjw.set_ja_width(p, dir) end - return p + return to_node(p) end -- callbacks @@ -319,11 +372,9 @@ local function debug_show_node_X(p,print_fn) if get_attr_icflag(p) == icflag_table.PACKED then s = s .. ' (packed)' end - print_fn(s) - local q = p.head - debug_depth=debug_depth.. '.' - while q do - debug_show_node_X(q, print_fn); q = node_next(q) + print_fn(s); debug_depth=debug_depth.. '.' + for q in node.traverse(p.head) do + debug_show_node_X(q, print_fn) end debug_depth=k elseif pt == 'glue' then @@ -333,8 +384,12 @@ local function debug_show_node_X(p,print_fn) s = s .. ' (from JFM: priority ' .. get_attr_icflag(p)-icflag_table.FROM_JFM .. ')' elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP then s = s .. ' (kanjiskip)' + elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP_JFM then + s = s .. ' (kanjiskip, JFM specified)' elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP then s = s .. ' (xkanjiskip)' + elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP_JFM then + s = s .. ' (xkanjiskip, JFM specified)' end print_fn(s) elseif pt == 'kern' then @@ -391,10 +446,13 @@ local function debug_show_node_X(p,print_fn) elseif pt=='math_char' then s = base .. ' fam: ' .. p.fam .. ' , char = ' .. utf.char(p.char) print_fn(s) - elseif pt=='sub_box' then + elseif pt=='sub_box' or pt=='sub_mlist' then print_fn(base) if p.head then - debug_depth = k .. '.'; debug_show_node_X(p.head, print_fn); + debug_depth = k .. '.'; + for q in node.traverse(p.head) do + debug_show_node_X(q, print_fn) + end end else print_fn(base) diff --git a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjfont.sty b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjfont.sty index 244ae453df2..6c9529f0eaa 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjfont.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjfont.sty @@ -3,7 +3,7 @@ % \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{lltjfont}[2013/05/14 Patch to NFSS2 for LuaTeX-ja] +\ProvidesPackage{lltjfont}[2014/01/23 Patch to NFSS2 for LuaTeX-ja] \let\k@encoding\@empty \let\ck@encoding\@empty @@ -27,15 +27,7 @@ \ifdefined\chs\else\newdimen\chs\fi \ifdefined\cHT\else\newdimen\cHT\fi %\let\afont\font -\def\inlist@#1#2{% - \def\in@@##1<#1>##2##3\in@@{% - \ifx\in@##2\in@false\else\in@true\fi}% - \in@@#2<#1>\in@\in@@} -\def\fam@elt{\noexpand\fam@elt} -\def\enc@elt{\noexpand\enc@elt} -\let\kenc@list\@empty -\let\kyenc@list\@empty -\let\ktenc@list\@empty + \newbox\tstrutbox \newbox\zstrutbox \def\strut{\relax @@ -87,16 +79,13 @@ \expandafter\endgroup \DeclareYokoKanjiEncoding@} \def\DeclareYokoKanjiEncoding@#1#2#3{% - \expandafter - \ifx\csname T@#1\endcsname\relax + \expandafter\ifx\csname T@#1\endcsname\relax \def\cdp@elt{\noexpand\cdp@elt}% \xdef\cdp@list{\cdp@list\cdp@elt{#1}% {\default@k@family}{\default@k@series}% {\default@k@shape}}% \expandafter\let\csname#1-cmd\endcsname\@changed@kcmd - \def\enc@elt{\noexpand\enc@elt}% - \xdef\kyenc@list{\kyenc@list\enc@elt<#1>}% - \xdef\kenc@list{\kenc@list\enc@elt<#1>}% + \directlua{luatexja.jfont.add_kyenc_list('\luatexluaescapestring{#1}')}% \else \@font@info{Redeclaring KANJI (yoko) font encoding #1}% \fi @@ -109,16 +98,13 @@ \expandafter\endgroup \DeclareTateKanjiEncoding@} \def\DeclareTateKanjiEncoding@#1#2#3{% - \expandafter - \ifx\csname T@#1\endcsname\relax + \expandafter\ifx\csname T@#1\endcsname\relax \def\cdp@elt{\noexpand\cdp@elt}% \xdef\cdp@list{\cdp@list\cdp@elt{#1}% {\default@k@family}{\default@k@series}% {\default@k@shape}}% \expandafter\let\csname#1-cmd\endcsname\@changed@kcmd - \def\enc@elt{\noexpand\enc@elt}% - \xdef\ktenc@list{\ktenc@list\enc@elt<#1>}% - \xdef\kenc@list{\kenc@list\enc@elt<#1>}% + \directlua{luatexja.jfont.add_ktenc_list('\luatexluaescapestring{#1}')}% \else \@font@info{Redeclaring KANJI (tate) font encoding #1}% \fi @@ -211,16 +197,11 @@ \math@fontsfalse \every@math@size{}% \fontsize{#6}\z@ - \edef\tmp@item{{#2}}% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kyenc@list}% - \ifin@ + \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{#2}')}\ifin@% \usekanji{#2}{#3}{#4}{#5}% \global\let#1\getjfont \else - %\expandafter\expandafter\expandafter - %\inlist@\expandafter\tmp@item\expandafter{\ktenc@list}% - %\ifin@ + %\directlua{luatexja.jfont.is_ktenc('\luatexluaescapestring{#2}')}\ifin@% % \usekanji{#2}{#3}{#4}{#5}% % \let\font\tfont %\else @@ -278,32 +259,22 @@ \DeclareRobustCommand\selectfont{% \let\tmp@error@fontshape\error@fontshape \let\error@fontshape\error@kfontshape - \edef\tmp@item{{\k@encoding}}% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kyenc@list}% - \ifin@ + \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{\k@encoding}')}\ifin@% \let\cy@encoding\k@encoding \edef\ct@encoding{\csname t@enc@\k@encoding\endcsname}% \else - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\ktenc@list}% - \ifin@ - \let\ct@encoding\k@encoding - \edef\cy@encoding{\csname y@enc@\k@encoding\endcsname}% - \else + %\directlua{luatexja.jfont.is_ktenc('\luatexluaescapestring{\k@encoding}')}\ifin@% + % \let\ct@encoding\k@encoding + % \edef\cy@encoding{\csname y@enc@\k@encoding\endcsname}% + %\else \@latex@error{KANJI Encoding scheme `\k@encoding' unknown}\@eha - \fi + %\fi \fi - %\let\font\tfont - %\let\k@encoding\ct@encoding - %\xdef\font@name{\csname\curr@kfontshape/\f@size\endcsname}% - %\pickup@font - %\font@name \let\k@encoding\cy@encoding \xdef\font@name{\csname\curr@kfontshape/\f@size\endcsname}% \pickup@jfont \font@name - \expandafter\def\expandafter\k@encoding\tmp@item + \edef\tmp@item{{\k@encoding}}\expandafter\def\expandafter\k@encoding\tmp@item \kenc@update \let\error@fontshape\tmp@error@fontshape \if@knjcmd \@knjcmdfalse @@ -318,7 +289,6 @@ \csname rel@\k@encoding/\k@family/\k@series/\k@shape\endcsname \fi \fi - %\let\font\afont \xdef\font@name{\csname\curr@fontshape/\f@size\endcsname}% \pickup@font \font@name @@ -326,7 +296,15 @@ \ifx\f@linespread\baselinestretch \else \set@fontsize\baselinestretch\f@size\f@baselineskip \fi - \size@update} + \size@update +% ここからは altfont 用 + \ltj@@does@alt@set{\curr@kfontshape}% + % alt fonts の定義 + \directlua{luatexja.jfont.output_alt_font_cmd('\luatexluaescapestring{\curr@kfontshape}')}% + % 定義した alt fonts のデータを \ltjdeclarealtfont に渡すのと同等の処理をする + \directlua{luatexja.jfont.pickup_alt_font_a('\f@size')}% + \fi +} \def\KanjiEncodingPair#1#2{\@namedef{t@enc@#1}{#2}\@namedef{y@enc@#2}{#1}} \KanjiEncodingPair{JY3}{JT3} \def\set@fontsize#1#2#3{% @@ -397,27 +375,23 @@ \fi } \DeclareRobustCommand\fontencoding[1]{% - \edef\tmp@item{{#1}}% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kenc@list}% - \ifin@ \kanjiencoding{#1}\else\romanencoding{#1}\fi} + \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{#1}')}\ifin@% + \kanjiencoding{#1}\else\romanencoding{#1}\fi} \def\@@kenc@update{% \default@KT \csname T@\k@encoding\endcsname \csname D@\k@encoding\endcsname \let\kenc@update\relax \let\ck@encoding\k@encoding - \edef\tmp@item{{\k@encoding}}% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kyenc@list}% - \ifin@ \let\cy@encoding\k@encoding + \edef\tmp@enc{'\luatexluaescapestring{\k@encoding}'} + \directlua{luatexja.jfont.is_kyenc(\tmp@enc)}\ifin@% + \let\cy@encoding\k@encoding \else - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\ktenc@list}% - \ifin@ \let\ct@encoding\k@encoding - \else + %\directlua{luatexja.jfont.is_ktenc(\tmp@enc)}\ifin@% + % \let\ct@encoding\k@encoding + %\else \@latex@error{KANJI Encoding scheme `\k@encoding' unknown}\@eha - \fi + %\fi \fi } \let\kenc@update\relax @@ -444,58 +418,47 @@ \newif\if@tempswz \DeclareRobustCommand\romanfamily[1]{\edef\f@family{#1}} \DeclareRobustCommand\kanjifamily[1]{\edef\k@family{#1}} -% \notkfam@list@<enc>: list of non-defined kanji families under <enc> -% \kfam@list@<enc>: list of kanji families under <enc>, defined in a .fd file \DeclareRobustCommand\fontfamily[1]{% - \@notkfamfalse\@notffamfalse\edef\tmp@item{{#1}}% + \@notkfamfalse\@notffamfalse + \edef\tmp@item{'\luatexluaescapestring{#1}'}% + \edef\tmp@enc{'\luatexluaescapestring{\k@encoding}'}% \ifcsname \k@encoding+#1\endcsname % if \k@encoding+#1 is already defined \edef\k@family{#1}% \else % search font definition file... - \ifcsname kfam@list@\k@encoding\endcsname\else - \expandafter\gdef\csname kfam@list@\k@encoding\endcsname{}% - \expandafter\gdef\csname notkfam@list@\k@encoding\endcsname{}% - \fi - \edef\@templist{\@nameuse{kfam@list@\k@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% + \directlua{luatexja.jfont.is_kfam(\tmp@enc, \tmp@item)}% \ifin@\edef\k@family{#1}\else% - \edef\@templist{\@nameuse{notkfam@list@\k@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% + \directlua{luatexja.jfont.is_Nkfam(\tmp@enc, \tmp@item)}% \ifin@\@notkfamtrue\else% \def\@temp##1+{\lowercase{\def\@@temp{##1#1.fd}}}\expandafter\@temp\k@encoding+% \message{(I search kanjifont definition file: \@@temp)}% \IfFileExists{\@@temp#1.fd}{\@tempswztrue}{\@tempswzfalse}% \if@tempswz - \expandafter\xdef\csname kfam@list@\k@encoding\endcsname - {\@nameuse{kfam@list@\k@encoding}\fam@elt<#1>}\edef\k@family{#1}% + \directlua{luatexja.jfont.add_kfam_list(\tmp@enc, \tmp@item)}% + \edef\k@family{#1}% \else - \expandafter\xdef\csname notkfam@list@\k@encoding\endcsname - {\@nameuse{notkfam@list@\k@encoding}\fam@elt<#1>}\@notkfamtrue% + \directlua{luatexja.jfont.add_Nkfam_list(\tmp@enc, \tmp@item)}% + \@notkfamtrue% \fi \fi \fi \fi + \edef\tmp@enc{'\luatexluaescapestring{\f@encoding}'}% \ifcsname \f@encoding+#1\endcsname \edef\f@family{#1}% \else % search font definition file... - \ifcsname ffam@list@\f@encoding\endcsname\else - \expandafter\gdef\csname ffam@list@\f@encoding\endcsname{}% - \expandafter\gdef\csname notffam@list@\f@encoding\endcsname{}% - \fi - \edef\@templist{\@nameuse{ffam@list@\f@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% + \directlua{luatexja.jfont.is_ffam(\tmp@enc, \tmp@item)}% \ifin@\edef\f@family{#1}\else - \edef\@templist{\@nameuse{notffam@list@\f@encoding}}% - \expandafter\expandafter\expandafter\inlist@\expandafter\tmp@item\expandafter{\@templist}% + \directlua{luatexja.jfont.is_Nffam(\tmp@enc, \tmp@item)}% \ifin@\@notffamtrue\else \def\@temp##1+{\lowercase{\def\@@temp{##1#1.fd}}}\expandafter\@temp\f@encoding+% \message{(I search font definition file: \@@temp)}% \IfFileExists{\@@temp#1.fd}{\@tempswztrue}{\@tempswzfalse}% \if@tempswz - \expandafter\xdef\csname ffam@list@\f@encoding\endcsname - {\@nameuse{ffam@list@\f@encoding}\fam@elt<#1>}\edef\f@family{#1}% + \directlua{luatexja.jfont.add_ffam_list(\tmp@enc, \tmp@item)}% + \edef\f@family{#1}% \else - \expandafter\xdef\csname notffam@list@\f@encoding\endcsname - {\@nameuse{notffam@list@\f@encoding}\fam@elt<#1>}\@notffamtrue% + \directlua{luatexja.jfont.add_Nffam_list(\tmp@enc, \tmp@item)}% + \@notffamtrue% \fi \fi \fi @@ -520,10 +483,8 @@ \romanencoding{#1}\romanfamily{#2}\romanseries{#3}\romanshape{#4}% \selectfont\ignorespaces} \protected\def\usefont#1#2#3#4{% - \edef\tmp@item{{#1}}% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kenc@list}% - \ifin@ \usekanji{#1}{#2}{#3}{#4}% + \directlua{luatexja.jfont.is_kenc('\luatexluaescapestring{#1}')}\ifin@% + \usekanji{#1}{#2}{#3}{#4}% \else\useroman{#1}{#2}{#3}{#4}% \fi} \DeclareRobustCommand\normalfont{% @@ -565,12 +526,8 @@ % #1 の展開結果から encoding 部分をとりだし,それが和文用かどうかの結果を \ifin@ に代入 \def\ltj@@IsFontJapanese#1{% - \expandafter\ltj@@IsFontJapaneseX#1//:% - \expandafter\expandafter\expandafter - \inlist@\expandafter\tmp@item\expandafter{\kenc@list}} -\def\ltj@@IsFontJapaneseX#1/#2/:{\edef\tmp@item{{\directlua{% - tex.print(luatexbase.catcodetables["latex-package"], '#1')}% -}}} + \directlua{luatexja.jfont.is_kenc(string.match( + '\luatexluaescapestring{#1}', '[^/]+'))}} \let\extract@afont\extract@font @@ -585,12 +542,13 @@ % 異なる和文 enc/fam/ser/shape からは異なるフォント番号が振られるように % わざと「ゴミをつける」 \def\ltj@@patch@external@font#1 at{% - #1;\directlua{luatexja.jfont.print_aftl_address(% - '\luatexluaescapestring{\f@encoding/\f@family/\f@series/\f@shape}')}\space at% + #1\directlua{luatexja.jfont.print_aftl_address()}\space at% } \def\extract@jfont{% \get@external@font - \edef\external@font{\expandafter\ltj@@patch@external@font\external@font}% + \ltj@@does@alt@set{\f@encoding/\f@family/\f@series/\f@shape}% + \edef\external@font{\expandafter\ltj@@patch@external@font\external@font}% + \fi \expandafter\globaljfont\font@name\external@font\relax \font@name%\global\zw=\zw\global\zh=\zh \csname \f@encoding+\f@family\endcsname @@ -605,7 +563,7 @@ \aftergroup\subst@correction } \def\do@subst@correction{% - \ltj@@IsFontJapanese{\curr@fontshape}\ifin@ + \ltj@@IsFontJapanese{\curr@fontshape}\ifin@% \ltj@@ja@do@subst@correction \else \ltj@@al@do@subst@correction @@ -675,18 +633,8 @@ %%%% \ClearAlternateKanjiFont<Benc><Bfam><Bser><Bshape> % いつも global \def\ClearAlternateKanjiFont#1#2#3#4{% - \directlua{luatexja.jfont.clear_alt_font_latex( - '\luatexluaescapestring{#1/#2/#3/#4}')}} + \directlua{luatexja.jfont.clear_alt_font_latex('\luatexluaescapestring{#1/#2/#3/#4}')}} -% \selectfont 上書き -\let\ltj@@alt@selectfont@orig=\selectfont -\def\selectfont{% - \ltj@@alt@selectfont@orig - % alt fonts の定義 - \directlua{luatexja.jfont.output_alt_font_cmd('\luatexluaescapestring{\curr@kfontshape}')}% - % 定義した alt fonts のデータを \ltjdeclarealtfont に渡すのと同等の処理をする - \directlua{luatexja.jfont.pickup_alt_font_a('\f@size')}% -} \def\ltj@pickup@altfont@aux#1{% {\edef\font@name{\csname #1/\f@size\endcsname}\pickup@jfont}% } @@ -695,4 +643,7 @@ \directlua{luatexja.jfont.pickup_alt_font_b(\the\ltj@tempcntc,'\luatexluaescapestring{#2}')}% } +\def\ltj@@does@alt@set#1{% + \directlua{luatexja.jfont.does_alt_set'\luatexluaescapestring{#1}'}} + \endinput diff --git a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-listings.sty b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-listings.sty index 06f0918140c..b2c7d9afea2 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-listings.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-listings.sty @@ -17,7 +17,7 @@ \def\ltjlistingsvsstdcmd#1{\@tempdima=\f@size pt% \smash{\raisebox{.35\@tempdima}{\tt% \fboxsep=.1\@tempdima\fbox{\fontsize{.5\@tempdima}{\z@}\selectfont - \oalign{\hss VS\hss\crcr#1\crcr}}}}} + \oalign{\hss VS\hss\crcr\hss#1\hss\crcr}}}}} \def\ltj@lst@vscmd{\ltjlistingsvsstdcmd} % override \lst@FillFixed@ @@ -127,6 +127,21 @@ \fi } +% Variation Selector +\def\ltj@lst@ProcessVS#1{% + \lst@whitespacefalse + \if@ltj@lst@vsraw + \lst@Append#1\advance\lst@length\m@ne + \else + \lst@TrackNewLines\lst@OutputLostSpace \lst@PrintToken + \setbox\@tempboxa\hbox to 2\lst@width{\hss + \expandafter\expandafter\expandafter\ltj@lst@vscmd + \expandafter{\the\numexpr`#1-"FDFF\relax}%" + \hss}% + \lst@CalcLostSpaceAndOutput\lst@whitespacefalse + \fi +} + % 半角カナ,異体字セレクタはアクティブ化 \def\ltj@@listing@jpsetN#1#2#3{% for (not large) range @@ -144,6 +159,7 @@ } \@temptokena{} \ltj@@listing@jpsetN{65377}{65439}{\ltj@lst@ProcessJALetterHalf} +\ltj@@listing@jpsetN{65024}{65039}{\ltj@lst@ProcessVS} \ltj@@listing@jpsetN{917760}{917999}{\ltj@lst@ProcessIVS} \xdef\ltj@@listing@jpcmd{\the\@temptokena}\@temptokena{} @@ -154,6 +170,7 @@ \catcode"FFFFF=13%" \SetCatcodeRange{"FF61}{"FF9F}{13}% 半角カナ \SetCatcodeRange{"E0100}{"E01EF}{13}% 漢字用異体字セレクタ + \SetCatcodeRange{"FE00}{"FE0F}{13}% Variation Selector } % We redefine \lst@BeginDropInput, since now we have @@ -260,7 +277,8 @@ \fi}% \lst@lAddTo\lst@PreGotoTabStop{\lst@WFAppend{^^I}}% \lst@lAddTo\lst@ProcessSpace{\lst@WFAppend{ }}% - \def\ltj@lst@ProcessIVS##1{\lst@whitespacefalse\lst@Append##1} + \def\ltj@lst@ProcessIVS##1{\lst@whitespacefalse\lst@Append##1}% + \def\ltj@lst@ProcessVS##1{\lst@whitespacefalse\lst@Append##1}% \let\lst@DeInit\lst@WFDeInit \let\lst@MProcessListing\lst@WFMProcessListing \lst@WFifopen\else diff --git a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-unicode-math.sty b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-unicode-math.sty index 722d66fa984..d33e44f3787 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-unicode-math.sty +++ b/Master/texmf-dist/tex/luatex/luatexja/patches/lltjp-unicode-math.sty @@ -12,10 +12,11 @@ \group_begin: \cs_gset:Npn \um_cs_set_eq_active_char:Nw #1 = "#2 \q_nil {%" \group_begin: - %\typeout {um: \string#1, \int_from_hexadecimal:n {#2}} <- for debug - \char_set_lccode:nn { `! } { "#2 } + %\typeout {um: \string#1, \int_from_hexadecimal:n {#2}, #2}% <- for debug + \char_set_lccode:nn { `! } { "#2 }%" \tex_lowercase:D { - \tl_set:Nn \l_tmpa_tl {\relax\ifmmode!\else{\directlua{tex.globaldefs = 0}\ltj@allalchar!}\fi} + \tl_set:Nn \l_tmpa_tl { \relax + \ifmmode!\else{\directlua{tex.globaldefs = 0}\ltj@allalchar!}\fi} \cs_gset_eq:NN #1 \l_tmpa_tl } \ltjsetmathletter{ \int_from_hexadecimal:n {#2} } |