+require('lualibs')
+require('luatexja.rmlgbm'); local ltjr = luatexja.rmlgbm -- must be 1st
+require('luatexja.base'); local ltjb = luatexja.base
+require('luatexja.charrange'); local ltjc = luatexja.charrange
+require('luatexja.jfont'); local ltjf = luatexja.jfont
+require('luatexja.inputbuf'); local ltji = luatexja.inputbuf
+require('luatexja.jfmglue'); local ltjj = luatexja.jfmglue
+require('luatexja.math'); local ltjm = luatexja.math
+require('luatexja.pretreat'); local ltjp = luatexja.pretreat
+require('luatexja.stack'); local ltjs = luatexja.stack
+require('luatexja.setwidth'); local ltjw = luatexja.setwidth
+
local node_type = node.type
local node_new = node.new
local node_prev = node.prev
local id_rule = node.id('rule')
local id_math = node.id('math')
local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
local attr_jchar_class = luatexbase.attributes['ltj@charclass']
local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
local attr_yablshift = luatexbase.attributes['ltj@yablshift']
-local attr_ykblshift = luatexbase.attributes['ltj@ykblshift']
local attr_icflag = luatexbase.attributes['ltj@icflag']
--- attr_icflag: 1: kern from \/, 2: 'lineend' kern from JFM
-
-local lang_ja_token = token.create('ltj@japanese')
-local lang_ja = lang_ja_token[2]
-
---
-local rgjc_get_range_setting = ltj.int_get_range_setting
-local rgjc_char_to_range = ltj.int_char_to_range
-local rgjc_is_ucs_in_japanese_char = ltj.int_is_ucs_in_japanese_char
-local ljfm_find_char_class = ltj.int_find_char_class
+local cat_lp = luatexbase.catcodetables['latex-package']
+
+local ITALIC = 1
+local PACKED = 2
+local KINSOKU = 3
+local FROM_JFM = 4
+local LINE_END = 5
+local KANJI_SKIP = 6
+local XKANJI_SKIP = 7
+local PROCESSED = 8
+local IC_PROCESSED = 9
+local BOXBDD = 15
------------------------------------------------------------------------
-- naming:
return out
end
--- return true if and only if p is a Japanese character node
-local function is_japanese_glyph_node(p)
- return p and (p.id==id_glyph)
- and (p.font==has_attr(p,attr_curjfnt))
-end
-
-
-------------------------------------------------------------------------
--- CODE FOR STACK TABLE FOR CHARACTER PROPERTIES (prefix: cstb)
-------------------------------------------------------------------------
+function math.two_add(a,b) return a+b end
+function math.two_average(a,b) return (a+b)/2 end
---- table: charprop_stack_table [stack_level][chr_code].{pre|post|xsp}
-local charprop_stack_table={}; charprop_stack_table[0]={}
-
-local function cstb_get_stack_level()
- local i = tex.getcount('ltj@@stack')
- if tex.currentgrouplevel > tex.getcount('ltj@@group@level') then
- i = i+1 -- new stack level
- tex.setcount('ltj@@group@level', tex.currentgrouplevel)
- for j,v in pairs(charprop_stack_table) do -- clear the stack above i
- if j>=i then charprop_stack_table[j]=nil end
- end
- charprop_stack_table[i] = table.fastcopy(charprop_stack_table[i-1])
- tex.setcount('ltj@@stack', i)
- end
- return i
-end
-
--- EXT
-function ltj.ext_set_stack_table(g,m,c,p,lb,ub)
- local i = cstb_get_stack_level()
- if p<lb or p>ub then
- ltj.error('Invalid code (' .. p .. '), should in the range '
- .. tostring(lb) .. '..' .. tostring(ub) .. '.',
- {"I'm going to use 0 instead of that illegal code value."})
- p=0
- elseif c<-1 or c>0x10FFFF then
- ltj.error('Invalid character code (' .. p
- .. '), should in the range -1.."10FFFF.',{})
- return
- elseif not charprop_stack_table[i][c] then
- charprop_stack_table[i][c] = {}
- end
- charprop_stack_table[i][c][m] = p
- if g=='global' then
- for j,v in pairs(charprop_stack_table) do
- if not charprop_stack_table[j][c] then charprop_stack_table[j][c] = {} end
- charprop_stack_table[j][c][m] = p
- end
- end
-end
-
-local function cstb_get_penalty_table(m,c)
- local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
- if i then i=i[m] end
- return i or 0
-end
-
-local function cstb_get_inhibit_xsp_table(c)
- local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
- if i then i=i.xsp end
- return i or 3
-end
-ltj.int_get_inhibit_xsp_table = cstb_get_inhibit_xsp_table
------------------------------------------------------------------------
-- CODE FOR GETTING/SETTING PARAMETERS
elseif k == 'yjabaselineshift' then
tex.write(print_scaled(tex.getattribute('ltj@ykblshift'))..'pt')
elseif k == 'kanjiskip' then
- tex.write(print_spec(tex.getskip('kanjiskip')))
+ tex.write(print_spec(ltjs.get_skip_table('kanjiskip', tex.getcount('ltj@@stack'))))
elseif k == 'xkanjiskip' then
- tex.write(print_spec(tex.getskip('xkanjiskip')))
+ tex.write(print_spec(ltjs.get_skip_table('xkanjiskip', tex.getcount('ltj@@stack'))))
elseif k == 'jcharwidowpenalty' then
- tex.write(tex.getcount('jcharwidowpenalty'))
+ tex.write(ltjs.get_penalty_table('jwp', 0, 0, tex.getcount('ltj@@stack')))
elseif k == 'autospacing' then
- tex.write(tostring(ltj.auto_spacing))
+ tex.write(tex.getattribute('ltj@autospc'))
elseif k == 'autoxspacing' then
- tex.write(tostring(ltj.auto_xspacing))
+ tex.write(tex.getattribute('ltj@autoxspc'))
elseif k == 'differentjfm' then
- if ltj.calc_between_two_jchar_aux==ltj.calc_between_two_jchar_aux_large then
+ if luatexja.jfmglue.diffmet_rule == math.max then
tex.write('large')
- elseif ltj.calc_between_two_jchar_aux==ltj.calc_between_two_jchar_aux_small then
+ elseif luatexja.jfmglue.diffmet_rule == math.min then
tex.write('small')
- elseif ltj.calc_between_two_jchar_aux==ltj.calc_between_two_jchar_aux_average then
+ elseif luatexja.jfmglue.diffmet_rule == math.two_average then
tex.write('average')
- elseif ltj.calc_between_two_jchar_aux==ltj.calc_between_two_jchar_aux_both then
+ elseif luatexja.jfmglue.diffmet_rule == math.two_add then
tex.write('both')
else -- This can't happen.
tex.write('???')
-- EXT: print parameters that need arguments
function ltj.ext_get_parameter_binary(k,c)
if k == 'jacharrange' then
- if c<0 or c>216 then c=0 end
- tex.write(rgjc_get_range_setting(c))
+ if c<0 or c>216 then
+ ltjb.package_error('luatexja',
+ 'invalid character range number (' .. c .. ')',
+ 'A character range number should be in the range 0..216,\n'..
+ 'So I changed this one to zero.')
+ c=0
+ end
+ tex.write(ltjc.get_range_setting(c))
else
if c<0 or c>0x10FFFF then
- ltj.error('Invalid character code (' .. c
- .. '), should in the range 0.."10FFFF.',
- {"I'm going to use 0 instead of that illegal character code."})
+ 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(cstb_get_penalty_table('pre',c))
+ tex.write(ltjs.get_penalty_table('pre', c, 0, tex.getcount('ltj@@stack')))
elseif k == 'postbreakpenalty' then
- tex.write(cstb_get_penalty_table('post',c))
+ tex.write(ltjs.get_penalty_table('post', c, 0, tex.getcount('ltj@@stack')))
elseif k == 'kcatcode' then
- tex.write(cstb_get_penalty_table('kcat',c))
+ tex.write(ltjs.get_penalty_table('kcat', c, 0, tex.getcount('ltj@@stack')))
elseif k == 'chartorange' then
- tex.write(rgjc_char_to_range(c))
+ tex.write(ltjc.char_to_range(c))
elseif k == 'jaxspmode' or k == 'alxspmode' then
- tex.write(cstb_get_inhibit_xsp_table(c))
+ tex.write(ltjs.get_penalty_table('xsp', c, 3, tex.getcount('ltj@@stack')))
end
end
end
-- EXT: print \global if necessary
function ltj.ext_print_global()
- if ltj.isglobal=='global' then tex.sprint('\\global') end
-end
-
-
-------------------------------------------------------------------------
--- MAIN PROCESS STEP 1: replace fonts (prefix: main1)
-------------------------------------------------------------------------
-
---- the following function is modified from jafontspec.lua (by K. Maeda).
---- Instead of "%", we use U+FFFFF for suppressing spaces.
-local function main1_process_input_buffer(buffer)
- local c = utf.byte(buffer, utf.len(buffer))
- local p = node_new(id_glyph)
- p.char = c
- if utf.len(buffer) > 0
- and rgjc_is_ucs_in_japanese_char(p) then
- buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
- end
- return buffer
-end
-
-local function main1_suppress_hyphenate_ja(head)
- local p
- for p in node.traverse(head) do
- if p.id == id_glyph then
- if rgjc_is_ucs_in_japanese_char(p) then
- local v = has_attr(p, attr_curjfnt)
- if v then
- p.font = v
- node.set_attribute(p,attr_jchar_class,
- ljfm_find_char_class(p.char, ltj.font_metric_table[v].jfm))
- end
- v = has_attr(p, attr_ykblshift)
- if v then
- node.set_attribute(p, attr_yablshift, v)
- else
- node.unset_attribute(p, attr_yablshift)
- end
- p.lang=lang_ja
- end
- end
- end
- lang.hyphenate(head)
- return head -- 共通化のため値を返す
-end
-
--- CALLBACKS
-luatexbase.add_to_callback('process_input_buffer',
- function (buffer)
- return main1_process_input_buffer(buffer)
- end,'ltj.process_input_buffer')
-luatexbase.add_to_callback('hpack_filter',
- function (head,groupcode,size,packtype)
- return main1_suppress_hyphenate_ja(head)
- end,'ltj.hpack_filter_pre',0)
-luatexbase.add_to_callback('hyphenate',
- function (head,tail)
- return main1_suppress_hyphenate_ja(head)
- end,'ltj.hyphenate')
-
-
-------------------------------------------------------------------------
--- MAIN PROCESS STEP 2: insert glue/kerns from JFM (prefix: main2)
-------------------------------------------------------------------------
-
--- EXT: for \inhibitglue
-function ltj.ext_create_inhibitglue_node()
- local g=node_new(id_whatsit, node.subtype('user_defined'))
- g.user_id=30111; g.type=number; g.value=1; node.write(g)
-end
-
-
-local function main2_find_size_metric(px)
- if is_japanese_glyph_node(px) then
- return ltj.font_metric_table[px.font].size, ltj.font_metric_table[px.font].jfm
- else
- return nil, nil
- end
-end
-
-local function main2_new_jfm_glue(size,mt,bc,ac)
--- mt: metric key, bc, ac: char classes
- local g=nil
- local w=bc*0x800+ac
- local z = ltj.metrics[mt]
- if z.glue[w] then
- local h = node_new(id_glue_spec)
- h.width = round(size*z.glue[w][0])
- h.stretch = round(size*z.glue[w][1])
- h.shrink = round(size*z.glue[w][2])
- h.stretch_order=0; h.shrink_order=0
- g = node_new(id_glue)
- g.subtype = 0; g.spec = h
- elseif z.kern[w] then
- g = node_new(id_kern)
- g.subtype = 1; g.kern = round(size*z.kern[w])
- end
- return g
-end
-
--- return value: g (glue/kern from JFM), w (width of 'lineend' kern)
-local function main2_calc(qs,qm,q,p,last,ihb_flag)
- -- q, p: node (possibly null)
- local ps, pm, g, h
- local w = 0
- if (not p) or p==last then
- -- q is the last node
- if not qm then
- return nil, 0
- elseif not ihb_flag then
- g=main2_new_jfm_glue(qs,qm,
- has_attr(q,attr_jchar_class),
- ljfm_find_char_class('boxbdd',qm))
- end
- elseif qs==0 then
- -- p is the first node etc.
- ps, pm = main2_find_size_metric(p)
- if not pm then
- return nil, 0
- elseif not ihb_flag then
- g=main2_new_jfm_glue(ps,pm,
- ljfm_find_char_class('boxbdd',pm),
- has_attr(p,attr_jchar_class))
- end
- else -- p and q are not nil
- ps, pm = main2_find_size_metric(p)
- if ihb_flag or ((not pm) and (not qm)) then
- g = nil
- elseif (qs==ps) and (qm==pm) then
- -- Both p and q are Japanese glyph nodes, and same metric and size
- g = main2_new_jfm_glue(ps,pm,
- has_attr(q,attr_jchar_class),
- has_attr(p,attr_jchar_class))
- elseif not qm then
- -- q is not a Japanese glyph node
- g = main2_new_jfm_glue(ps,pm,
- ljfm_find_char_class('jcharbdd',pm),
- has_attr(p,attr_jchar_class))
- elseif not pm then
- -- p is not a Japanese glyph node
- g = main2_new_jfm_glue(qs,qm,
- has_attr(q,attr_jchar_class),
- ljfm_find_char_class('jcharbdd',qm))
- else
- g = main2_new_jfm_glue(qs,qm,
- has_attr(q,attr_jchar_class),
- ljfm_find_char_class('diffmet',qm))
- h = main2_new_jfm_glue(ps,pm,
- ljfm_find_char_class('diffmet',pm),
- has_attr(p,attr_jchar_class))
- g = ltj.calc_between_two_jchar_aux(g,h)
- end
- end
- if g then node.set_attribute(g, attr_icflag, 3) end
- if qm then
- local x = ljfm_find_char_class('lineend', qm)
- if x~=0 then
- x = has_attr(q,attr_jchar_class)*0x800 + x
- if ltj.metrics[qm].kern[x] then
- w = round(qs*ltj.metrics[qm].kern[x])
- end
- end
- end
-
- return g, w
-end
-
-local function main2_between_two_char(head,q,p,p_bp,ihb_flag,last)
- local qs = 0; local g, w
- local qm = nil
- if q then
- qs, qm = main2_find_size_metric(q)
- end
- g, w = main2_calc(qs, qm, q, p, last, ihb_flag)
- if w~=0 and (not p_bp) then
- p_bp = node_new(id_penalty); p_bp.penalty = 0
- head = node_insert_before(head, p, p_bp)
- end
- if g then
- if g.id==id_kern then
- g.kern = round(g.kern - w)
- else
- g.spec.width = round(g.spec.width - w)
- end
- head = node_insert_before(head, p, g)
- elseif w~=0 then
- g = node_new(id_kern); g.kern = -w; g.subtype = 1
- node.set_attribute(g,attr_icflag,2)
- head = node_insert_before(head, p, g)
- -- this g might be replaced by \[x]kanjiskip in step 3.
- end
- if w~=0 then
- g = node_new(id_kern); g.kern = w; g.subtype = 0
- head = node_insert_before(head, p_bp, g)
- end
-return head, p_bp
-end
-
--- In the beginning of a hlist created by line breaking, there are the followings:
--- - a hbox by \parindent
--- - a whatsit node which contains local paragraph materials.
--- When we insert jfm glues, we ignore these nodes.
-local function main2_is_parindent_box(p)
- if p.id==id_hlist then
- return (p.subtype==3)
- -- hlist (subtype=3) is a box by \parindent
- elseif p.id==id_whatsit then
- return (p.subtype==node.subtype('local_par'))
- end
-end
-
--- next three functions deal with inserting penalty by kinsoku.
-local function main2_add_penalty_before(head,p,p_bp,pen)
- if p_bp then
- p_bp.penalty = p_bp.penalty + pen
- else -- we must create a new penalty node
- local g = node_new(id_penalty); g.penalty = pen
- local q = node_prev(p)
- if q then
- if has_attr(q, attr_icflag) ~= 3 then
- q = p
- end
- return node_insert_before(head, q, g)
- end
- end
- return head
-end
-
-local function main2_add_kinsoku_penalty(head,p,p_bp)
- local c = p.char
- local e = cstb_get_penalty_table('pre',c)
- if e~=0 then
- head = main2_add_penalty_before(head, p, p_bp, e)
- end
- e = cstb_get_penalty_table('post',c)
- if e~=0 then
- local q = node_next(p)
- if q and q.id==id_penalty then
- q.penalty = q.penalty + e
- return false
- else
- q = node_new(id_penalty); q.penalty = e
- node_insert_after(head,p,q)
- return true
- end
- end
-end
-
-local function main2_add_widow_penalty(head,widow_node,widow_bp)
- if not widow_node then
- return head
- else
- return main2_add_penalty_before(head, widow_node,
- widow_bp, tex.getcount('jcharwidowpenalty'))
- end
-end
-
-local depth=""
-
--- Insert jfm glue: main routine
--- mode = true iff insert_jfm_glue is called from pre_linebreak_filter
-local function main2_insert_jfm_glue(head, mode)
- local p = head
- local p_bp = nil -- p と直前の文字の間の penalty node
- local q = nil -- the previous node of p
- local widow_node = nil -- 最後の「句読点扱いでない」和文文字
- local widow_bp = nil -- \jcharwidowpenalty 挿入位置
- local last -- the sentinel
- local ihb_flag = false -- is \inhibitglue specified?
- local g
- -- initialization
- if not p then return head
- elseif mode then
- while p and main2_is_parindent_box(p) do p=node_next(p) end
- last=node.tail(head)
- if last and last.id==id_glue and last.subtype==15 then
- last=node.prev(last)
- while (last and last.id==id_penalty) do last=node.prev(last) end
- end
- if last then last=node_next(last) end
- else -- 番人を挿入
- last=node.tail(head); g = node_new('kern')
- node_insert_after(head,last,g); last = g
- end
- -- main loop
- while q~=last do
- if p.id==id_whatsit and p.subtype==node.subtype('user_defined')
- and p.user_id==30111 then
- g = p; p = node_next(p)
- ihb_flag = true; head, p = node.remove(head, g)
- else
- head, p_bp = main2_between_two_char(head, q, p, p_bp, ihb_flag, last)
- q=p; ihb_flag=false
- if is_japanese_glyph_node(p) then
- if cstb_get_penalty_table('kcat',p.char)%2~=1 then
- widow_node = p; widow_bp = p_bp
- end
- if main2_add_kinsoku_penalty(head, p, p_bp) then
- p_bp = node_next(p); p = p_bp
- else p_bp = nil
- end
- else p_bp = nil
- end
- p=node_next(p)
- end
- end
- if mode then
- -- Insert \jcharwidowpenalty
- head = main2_add_widow_penalty(head, widow_node, widow_bp)
- -- cleanup
- p = node_prev(last)
- if p and p.id==id_kern and has_attr(p,attr_icflag)==2 then
- head = node.remove(head, p)
- end
- else
- head = node.remove(head, last)
- end
- return head
-end
-
-
-------------------------------------------------------------------------
--- MAIN PROCESS STEP 4: width of japanese chars (prefix: main4)
-------------------------------------------------------------------------
-
--- TeX's \hss
-local function main4_get_hss()
- local hss = node_new(id_glue)
- local fil_spec = node_new(id_glue_spec)
- fil_spec.width = 0
- fil_spec.stretch = 65536
- fil_spec.stretch_order = 2
- fil_spec.shrink = 65536
- fil_spec.shrink_order = 2
- hss.spec = fil_spec
- return hss
-end
-
-local function main4_set_ja_width(head)
- local p = head
- local met_tb, t, s, g, th, q, a
- local m = false -- is in math mode?
- while p do
- local v=has_attr(p,attr_yablshift) or 0
- if p.id==id_glyph then
- p.yoffset = p.yoffset-v
- if is_japanese_glyph_node(p) then
- met_tb = ltj.font_metric_table[p.font]
- t = ltj.metrics[met_tb.jfm]
- s = t.char_type[has_attr(p,attr_jchar_class)]
- if not(s.left==0.0 and s.down==0.0
- and round(s.width*met_tb.size)==p.width) then
- -- must be encapsuled by a \hbox
- head, q = node.remove(head,p)
- p.next=nil
- p.yoffset=round(p.yoffset-met_tb.size*s.down)
- p.xoffset=round(p.xoffset-met_tb.size*s.left)
- node_insert_after(p, p, main4_get_hss())
- g = node_hpack(p, round(met_tb.size*s.width), 'exactly')
- g.height = round(met_tb.size*s.height)
- g.depth = round(met_tb.size*s.depth)
- head, p = node_insert_before(head, q, g)
- p = q
- else p=node_next(p)
- end
- else p=node_next(p)
- end
- elseif p.id==id_math then
- m=(p.subtype==0); p=node_next(p)
- else
- if m then
- if p.id==id_hlist or p.id==id_vlist then
- p.shift=p.shift+v
- elseif p.id==id_rule then
- p.height=p.height-v; p.depth=p.depth+v
- end
- end
- p=node_next(p)
- end
- end
-return head
+ if ltj.isglobal=='global' then tex.sprint(cat_lp, '\\global') end
end
-- main process
-- mode = true iff main_process is called from pre_linebreak_filter
-local function main_process(head, mode)
+local function main_process(head, mode, dir)
local p = head
- p = main2_insert_jfm_glue(p,mode)
- p = ltj.int_insert_kanji_skip(p)
- p = main4_set_ja_width(p)
+ p = ltjj.main(p,mode)
+ p = ltjw.set_ja_width(p, dir)
return p
end
function ltj.ext_show_node_list(head,depth,print_fn)
debug_depth = depth
if head then
- debug_show_node_list_X(head, print_fn)
+ while head do
+ debug_show_node_X(head, print_fn); head = node_next(head)
+ end
+ else
+ print_fn(debug_depth .. ' (null list)')
+ end
+end
+function ltj.ext_show_node(head,depth,print_fn)
+ debug_depth = depth
+ if head then
+ debug_show_node_X(head, print_fn)
else
print_fn(debug_depth .. ' (null list)')
end
end
-function debug_show_node_list_X(p,print_fn)
- debug_depth=debug_depth.. '.'
+function debug_show_node_X(p,print_fn)
local k = debug_depth
- while p do
- local pt=node_type(p.id)
- if pt == 'glyph' then
- print_fn(debug_depth.. ' glyph ', p.subtype, utf.char(p.char), p.font)
- elseif pt=='hlist' then
- print_fn(debug_depth.. ' hlist ', p.subtype, '(' .. print_scaled(p.height)
- .. '+' .. print_scaled(p.depth)
- .. ')x' .. print_scaled(p.width) )
- debug_show_node_list_X(p.head,print_fn)
- debug_depth=k
- elseif pt == 'whatsit' then
- print_fn(debug_depth.. ' whatsit', p.subtype)
- elseif pt == 'glue' then
- print_fn(debug_depth.. ' glue ', p.subtype, print_spec(p.spec))
- elseif pt == 'kern' then
- print_fn(debug_depth.. ' kern ', p.subtype, print_scaled(p.kern) .. 'pt')
- elseif pt == 'penalty' then
- print_fn(debug_depth.. ' penalty', p.penalty)
+ local s
+ local pt=node_type(p.id)
+ local base = debug_depth .. string.format('%X', has_attr(p,attr_icflag) or 0)
+ .. ' ' .. pt .. ' ' .. p.subtype
+ if pt == 'glyph' then
+ s = base .. ' ' .. utf.char(p.char) .. ' ' .. tostring(p.font)
+ .. ' (' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
+ print_fn(s)
+ elseif pt=='hlist' then
+ s = base .. '(' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
+ if p.shift~=0 then
+ s = s .. ', shifted ' .. print_scaled(p.shift)
+ end
+ if p.glue_sign >= 1 then
+ s = s .. ' glue set '
+ if p.glue_sign == 2 then s = s .. '-' end
+ s = s .. tostring(math.floor(p.glue_set*10000)/10000)
+ if p.glue_order == 0 then
+ s = s .. 'pt'
+ else
+ s = s .. 'fi'
+ for i = 2, p.glue_order do s = s .. 'l' end
+ end
+ end
+ if has_attr(p, attr_icflag, 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)
+ end
+ debug_depth=k
+ elseif pt == 'glue' then
+ s = base .. ' ' .. print_spec(p.spec)
+ if has_attr(p, attr_icflag)==FROM_JFM then
+ s = s .. ' (from JFM)'
+ elseif has_attr(p, attr_icflag)==KANJI_SKIP then
+ s = s .. ' (kanjiskip)'
+ elseif has_attr(p, attr_icflag)==XKANJI_SKIP then
+ s = s .. ' (xkanjiskip)'
+ end
+ print_fn(s)
+ elseif pt == 'kern' then
+ s = base .. ' ' .. print_scaled(p.kern) .. 'pt'
+ if p.subtype==2 then
+ s = s .. ' (for accent)'
+ elseif has_attr(p, attr_icflag)==IC_PROCESSED then
+ s = s .. ' (italic correction)'
+ -- elseif has_attr(p, attr_icflag)==ITALIC then
+ -- s = s .. ' (italic correction)'
+ elseif has_attr(p, attr_icflag)==FROM_JFM then
+ s = s .. ' (from JFM)'
+ elseif has_attr(p, attr_icflag)==LINE_END then
+ s = s .. " (from 'lineend' in JFM)"
+ end
+ print_fn(s)
+ elseif pt == 'penalty' then
+ s = base .. ' ' .. tostring(p.penalty)
+ if has_attr(p, attr_icflag)==KINSOKU then
+ s = s .. ' (for kinsoku)'
+ end
+ print_fn(s)
+ elseif pt == 'whatsit' then
+ s = base .. ' subtype: ' .. tostring(p.subtype)
+ if p.subtype==sid_user then
+ s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value
else
- print_fn(debug_depth.. ' ' .. node.type(p.id), p.subtype)
+ s = s .. node.subtype(p.subtype)
+ end
+ print_fn(s)
+ -- ここから数式用 node
+ elseif pt=='noad' then
+ s = base ; print_fn(s)
+ if p.nucleus then
+ debug_depth = k .. 'N'; debug_show_node_X(p.nucleus, print_fn);
+ end
+ if p.sup then
+ debug_depth = k .. '^'; debug_show_node_X(p.sup, print_fn);
+ end
+ if p.sub then
+ debug_depth = k .. '_'; debug_show_node_X(p.sub, print_fn);
end
- p=node_next(p)
+ debug_depth = k;
+ elseif pt=='math_char' then
+ s = base .. ' fam: ' .. p.fam .. ' , char = ' .. utf.char(p.char)
+ print_fn(s)
+ elseif pt=='sub_box' then
+ print_fn(base)
+ if p.head then
+ debug_depth = k .. '.'; debug_show_node_X(p.head, print_fn);
+ end
+ else
+ print_fn(base)
end
+ p=node_next(p)
end
-
-- callbacks
+
luatexbase.add_to_callback('pre_linebreak_filter',
function (head,groupcode)
- return main_process(head, true)
- end,'ltj.pre_linebreak_filter',2)
+ return main_process(head, true, tex.textdir)
+ end,'ltj.pre_linebreak_filter',
+ luatexbase.priority_in_callback('pre_linebreak_filter',
+ 'luaotfload.pre_linebreak_filter') + 1)
luatexbase.add_to_callback('hpack_filter',
- function (head,groupcode,size,packtype)
- return main_process(head, false)
- end,'ltj.hpack_filter',2)
+ function (head,groupcode,size,packtype, dir)
+ return main_process(head, false, dir)
+ end,'ltj.hpack_filter',
+ luatexbase.priority_in_callback('hpack_filter',
+ 'luaotfload.hpack_filter') + 1)