\bigskip
{\large\bf\noindent これは仕様・内部処理の提案の1つにしかすぎません.最終的にこのようになる
-保証はどこにもありませんし,これを書いている時点では実際のLuaコードは書きあがっていません.}
+保証はどこにもありませんし,現時点でのLuaコードが本文書に従っている保証もありません.
+バグが混入している可能性も大きいです.}
\beginsection 予備知識
$$
\vbox{\halign{#:\ \hfil&#\hfil\quad&#:\ \hfil&#\hfil\cr
1&イタリック補正由来のkern &
-2&禁則処理用penalty\cr
-3&JFM由来のglue/kern&
-4&「行末」との間に入るkern\cr
-5&|\kanjiskip|用glue&
-6&|\xkanjiskip|用glue\cr
-7&リスト先頭/末尾に入るglue/kern/penalty&
+2&幅補正のため,hboxにカプセル化された和文文字\cr
+3&禁則処理用penalty&
+4&JFM由来のglue/kern\cr
+5&「行末」との間に入るkern&
+6&|\kanjiskip|用glue\cr
+7&|\xkanjiskip|用glue&
8&既に処理対象となったnode\cr
+15&リスト先頭/末尾に入るglue/kern/penalty\span\omit\span\cr
}}
$$
-和文処理グルーの挿入処理に一度通されたnodeは,みなicflagが2以上となることに注意.
+和文処理グルーの挿入処理に一度通されたnodeは,みなicflagが3以上となることに注意.
なお,上添字はnodeのsubtypeを表す.
\item {\sf jaxspmode}のようなサンセリフ体で,|\ltjsetparameter|で設定可能なパラメタ値を表す.
\medskip\noindent{\bf 定義}\quad
「{\bf 塊}」(\IT{Nn}などで表す)とは,次の4つのいずれかの条件を満たすnode(達のリスト)
のことである:
-\enum icflagが2以上6以下 or 8であるnode達の連続からなるリスト.
+\enum icflagが3以上15未満であるnode達の連続からなるリスト.
このようなnode達は,既に組み上がったhboxを|\unpackage|により解体したときに発生する.
一度和文処理グルーの挿入処理が行われているため,二重の処理を防ぐためにこうして1つの塊を構成させている.
-なお,icflagが7であるnodeは,処理中に発見されしだい削除される
+なお,icflagが15であるnodeは,処理中に発見されしだい削除される
(hboxの先頭や末尾に挿入されたglue/kern/penaltyであるので,
本来の「段落/hboxの中身に適宜グルーを挿入する」という目的を考えると存在すべきでない).
\enum 数式開始を表す\IT{math\_node}から始まる文中数式を表すnodeのリスト:
\node{p}
\Bigl[\node{\nk\hskip-.5em}_1\Bigr]
$$
+但し,これには$p$が${\rm icflag}=2$のhboxである場合も含む.%
+{\small ←この場合の処理は実はおこらない?}
\enum {\bf 以下のどれにもあてはまらない}node~$p$:
\itemitem 組版結果からは消えてしまう,\IT{ins\_node},
\IT{mark\_node}, \IT{adjust\_node}, \IT{whatsit\_node}.
\item \IT{.id}: \IT{Np}の種類を表す値.
\itemitem 1.によるものである場合,\IT{id\_pbox}(Pseudo BOXのつもり).
\itemitem 3.によるものであり,$p$が和文文字だった場合,\IT{id\_jglyph}.
-\itemitem 3.によるものであり,$p$が垂直変位がnon-zeroなhbox,
+\itemitem 4.によるものであり,$p$が垂直変位がnon-zeroなhbox,
あるいはvbox, ruleだった場合,\IT{id\_box\_like}.
\itemitem それ以外の場合,node~$p$の種別を表す数値$p.\mibox{id}$そのもの.
(数値そのものだと使い勝手が悪いので,\IT{id\_glyph}, \IT{id\_glue}, \IT{id\_kern}などと
\enditem
$$
\vcenter{\halign{$\mibox{mode}=#$:\qquad\hfil&$#$\hfil\cr
-\bot&\node{\kern-1em}\,\hbox{(リスト先頭)}\longrightarrow\cdots\node{g}_7\node{\mibox{Np}}\cr
-\top&\node{\hbox{{\tt\char92 parindent}由来hbox}}\longrightarrow\cdots\Bigl[\node{\np 10000}_7\Bigr]\node{g}_7\node{\mibox{Np}}\cr
+\bot&\node{\kern-1em}\,\hbox{(リスト先頭)}\longrightarrow\cdots\node{g}_{15}
+\node{\mibox{Np}}\cr
+\top&\node{\hbox{{\tt\char92 parindent}由来hbox}}\longrightarrow\cdots
+\Bigl[\node{\np 10000}_{15}\Bigr]\node{g}_{15}\node{\mibox{Np}}\cr
}}
$$
ここで,$g$がglueかつ$\mibox{mode}=\top$かつ$\#\mibox{Bp}=0$のときのみ,|\parindent|由来のhboxの直後で改行されることを防ぐために
\item $\mibox{Nq.id}=\mibox{id\_pbox}$であり,$\mibox{tail}(\mibox{Nq})$が和文文字であるとき.
\enditem
$$
-\node{\mibox{Nq}}\node{g}_7\longrightarrow\cdots\node{\nk\hbox{(番人)}}
+\node{\mibox{Nq}}\node{g}_{15}\longrightarrow\cdots\node{\nk\hbox{(番人)}}
$$
上の番人は,次のstepで除去されるのだった.
\item $\mibox{Nq.id}=\mibox{id\_pbox}$であり,$\mibox{tail}(\mibox{Nq})$が和文文字であるとき.
\enditem
$$
-\node{\mibox{Nq}}\node{\nk w}_7\node{\np10000}\longrightarrow\cdots
+\node{\mibox{Nq}}\node{\nk w}_{15}\node{\np10000}\longrightarrow\cdots
\node{\ng (\hbox{\tt\char92 parfillskip})}
$$
次に,|\jcharwidowpenalty|の挿入処理を行う→省略.
\globaljfont<font>={<font_name>:<features>} <size> % global に定義
\endtt
-
\item {\bf <font_name> の指定について}\par\noindent
内部でluaotfloadパッケージを読み込んでいる.大きくわけて,以下の4種類がある.
このうち,前の2つはluaotfloadパッケージの機能である.
\beginsection 互換用命令(書きかけ)
{\tt luatexja-compat.sty}を読み込むことで,次が追加.
-\item |\euc|, |\jis|, |\sjis|, |\kuten|, |\ucs|: up\TeX と同じ動作.
+\item |\euc|, |\jis|, |\sjis|, |\kuten|, |\ucs|:
+それぞれEUC-JP,ISO-2022-JP,Shift-JIS,区点コードからUnicodeへの変換を行う.
+JIS~X~0208→Unicodeへの変換テーブルとしては,up\TeX-0.30で用いられているものを利用している.
\item |\kansuji|
-\item |kansujichar={<num>, <char>}| key in |\ltjsetparameter|.
+\item |kansujichar={<num>, <char>}|~key in |\ltjsetparameter|.
\enditem
\item {\bf (luaotfloadパッケージによるグリフ置換等の処理はこの位置で)}
-\item {\bf JFM由来glue/kernの挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
-
-ここで,JFMに由来する和文文字間のglue/kernを挿入する.
-基本的には連続する和文文字(を表すnode)間に挿入するが,
-\itemitem 水平ボックスの先頭/末尾,段落の先頭/末尾には「文字コード|'boxbdd'|の文字」があると
-見做して空白を挿入する.
-\itemitem 和文文字とそうでないもの(欧文文字,ボックス等)の間に関しては,
-和文文字でない方は「文字コード|'jcharbdd'|の文字」であると見做す.
-\itemitem フォントの異なる2つの和文文字においても,
-両者のフォントのJFMとsizeが一致した場合は,
-挿入処理においては「同じフォント」であるかのように扱う.
-\itemitem そうでない場合は,両者の間に「文字コード|'diffmet'|の文字」があると見做して,
-両和文文字からそれぞれglue/kern |gb|, |ga|を計算し,そこから実際に入るglue/kernを
-計算している(|\ltjsetparameter|中の|differentjfm|キーを参照).
-\itemitem もうちょっと詳しく書くと,本処理前において,和文文字を表す
-2つの連続した|glyph_node| $Q$, $P$の間には,次のnode達が挿入される:
-$$
- \ldots,\ Q,\ (\hbox{|\kern|}\ w\,{\rm pt}),\ (\hbox{|\penalty|}\ p),\
-(\hbox{|\kern|}\ (k-w)\,{\rm pt})
-,\ P,\ \ldots
-$$
-上に書いた全てのnodeが挿入されるとは限らず,また4つめのkernもglueに変わる可能性がある.
-上に出てきた量の意味は次の通りである:
-\itemT $w$: $Q$が行末にきたときに,行末からどれだけずらすかを指定した量.
-\itemT $p$: $Q$の行末禁則用penaltyと$P$の行頭禁則用penaltyの合計値.ウィドウ防止用の
-|\jcharwidowpenalty|が挿入される時は,値はここに加算される.
-\itemT |\kern| $k$: 本来の$Q$と$P$の間に入る空き(glueであることも).
-$w$のために自然長を補正している.
-
-\item {\bf |kanjiskip|, |xkanjiskip|の挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
-
-p\TeX の|adjust_hlist| procedureとほぼ同様の処理を用いて,
-和文間glue |kanjiskip|や和欧文間glue |xkanjiskip|を
-挿入する.
-\itemitem 数式境界 (|math_node|) との間に|xkanjiskip|を自動挿入するかの決定は,
-p\TeX では数字{\tt 0}との間に挿入するかどうかで判定していたが,Lua\TeX-jaでは
-「文字コード$-1$の文字」で判定している.
-\itemitem 合字の周囲の空白挿入については,構成要素の文字列を通じて判断している.例えば,
-「漢ffi字」という文字列に対して,
-\itemT 「漢」と「ffi」間の空白挿入:「漢」と「f」間に入るかで判断
-\itemT 「ffi」と「字」間の空白挿入:「i」と「字」間に入るかで判断
+\item {\bf 和文処理グルーの挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
+
+動作については,{\tt jfmglue.pdf}(未完)を参照.
\item {\bf ベースライン補正: |pre_linebreak_filter|, |hpack_filter| callbacks}
local ITALIC = 1
-local KINSOKU = 2
-local FROM_JFM = 3
-local LINE_END = 4
-local KANJI_SKIP = 5
-local XKANJI_SKIP = 6
-local BOXBDD = 7
+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 PACKED = 9
+local BOXBDD = 15
------------------------------------------------------------------------
-- naming:
return hss
end
-local function main4_set_ja_width(head)
+local function main4_set_ja_width(head, dir)
local p = head
local met_tb, t, s, g, q, a, h
local m = false -- is in math mode?
not(s.left==0.0 and s.down==0.0 and s.align=='left'
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)
- if s.align=='middle' or s.align=='right' then
- h = node_insert_before(p, p, main4_get_hss())
- else h=p end
- if s.align=='middle' or s.align=='left' then
- node_insert_after(h, p, main4_get_hss())
+ head, q = node.remove(head, p)
+ local full_width = round(s.width*met_tb.size)
+ p.yoffset=p.yoffset-round(met_tb.size*s.down)
+ p.xoffset=p.xoffset-round(met_tb.size*s.left)
+
+ -- The next if block sets h:=(head of a new list)
+ if s.align=='left' then
+ h = node_new(id_kern); h.subtype = 0
+ h.kern = full_width - p.width
+ p.next = h; h = p
+ elseif s.align=='right' then
+ h = node_new(id_kern); h.subtype = 0
+ h.kern = full_width - p.width
+ p.next = nil; h.next = p
+ elseif s.align=='middle' then
+ local total = full_width - p.width
+ h = node_new(id_kern); h.subtype = 0
+ h.kern = round(total/2); p.next = h
+ h = node_new(id_kern); h.subtype = 0
+ h.kern = total - round(total/2); h.next = p
end
- g = node_hpack(h, round(met_tb.size*s.width), 'exactly')
+ g = node_new(id_hlist); g.width = full_width
g.height = round(met_tb.size*s.height)
g.depth = round(met_tb.size*s.depth)
+ g.glue_set = 0; g.glue_order = 0; g.head = h
+ g.shift = 0; g.dir = dir or 'TLT'
node.set_attribute(g, attr_icflag, PACKED)
if q then
head = node_insert_before(head, q, g)
-- 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 = ltjj.main(p,mode)
- p = main4_set_ja_width(p)
+ p = main4_set_ja_width(p, dir)
return p
end
local k = debug_depth
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
- print_fn(debug_depth.. ' GLYPH ', p.subtype, utf.char(p.char), p.font)
+ print_fn(base, utf.char(p.char), p.font)
elseif pt=='hlist' then
- s = debug_depth .. ' hlist ' .. p.subtype
- .. '(' .. print_scaled(p.height) .. '+' .. print_scaled(p.depth) .. ')x'
- .. print_scaled(p.width)
+ s = base .. '(' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
if p.glue_sign >= 1 then
s = s .. ' glue set '
if p.glue_sign == 2 then s = s .. '-' end
end
debug_depth=k
elseif pt == 'glue' then
- s = debug_depth.. ' glue ' .. p.subtype
- .. ' ' .. print_spec(p.spec)
+ 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
end
print_fn(s)
elseif pt == 'kern' then
- s = debug_depth.. ' kern ' .. p.subtype
- .. ' ' .. print_scaled(p.kern) .. 'pt'
- if has_attr(p, attr_icflag)==ITALIC then
+ s = base .. ' ' .. print_scaled(p.kern) .. 'pt'
+ if p.subtype==2 then
+ s = s .. ' (for accent)'
+ elseif has_attr(p, attr_icflag)==ITALIC then
s = s .. ' (italic correction)'
- elseif has_attr(p, attr_icflag)==TEMPORARY then
- s = s .. ' (might be replaced)'
elseif has_attr(p, attr_icflag)==FROM_JFM then
s = s .. ' (from JFM)'
elseif has_attr(p, attr_icflag)==LINE_END then
end
print_fn(s)
elseif pt == 'penalty' then
- s = debug_depth.. ' penalty ' .. tostring(p.penalty)
+ 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 = debug_depth.. ' whatsit ' .. tostring(p.subtype)
+ s = base .. ' subtype: ' .. tostring(p.subtype)
if p.subtype==sid_user then
s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value
else
end
print_fn(s)
else
- print_fn(debug_depth.. ' ' .. node.type(p.id), p.subtype)
+ 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)
+ return main_process(head, true, tex.textdir)
end,'ltj.pre_linebreak_filter',2)
luatexbase.add_to_callback('hpack_filter',
- function (head,groupcode,size,packtype)
- return main_process(head, false)
+ function (head,groupcode,size,packtype, dir)
+ return main_process(head, false, dir)
end,'ltj.hpack_filter',2)
local sid_user = node.subtype('user_defined')
local ITALIC = 1
-local KINSOKU = 2
-local FROM_JFM = 3
-local LINE_END = 4
-local KANJI_SKIP = 5
-local XKANJI_SKIP = 6
-local BOXBDD = 7
+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 PACKED = 9
+local BOXBDD = 15
local kanji_skip
local xkanji_skip
find_first_char = false; first_char = nil; last_char = nil
return true
end
- while p~=box_end do
+ while p and p~=box_end do
local pid = p.id
if pid==id_kern then
if p.subtype==2 then
first_char = p; find_first_char = false
end
last_char = p; found_visible_node = true; p=node_next(p)
- if not p then return found_visible_node end
+ if (not p) or p==box_end then return found_visible_node end
until p.id~=id_glyph
end
if pid==id_hlist then
if has_attr(p, attr_icflag)==PACKED then
for q in node.traverse_id(id_glyph, p.head) do
if find_first_char then
- first_char = q; find_first_char = false
+ first_char = q; find_first_char = false
end
- last_char = q; found_visible_node = true
+ last_char = q; found_visible_node = true; break
end
else
if p.shift==0 then
- if check_box(p.head) then found_visible_node = true end
+ if check_box(p.head, nil) then found_visible_node = true end
else if find_first_char then
find_first_char = false
else
else Np.last = Np.nuc end
end
+local function calc_np_pbox()
+ Np.first = lp; Np.id = id_pbox
+ lpa = KINSOKU -- dummy
+ while lp~=last and lpa>=KINSOKU and lpa~=BOXBDD do
+ Np.nuc = lp; lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0
+ end
+ check_next_ickern()
+end
+
local function calc_np()
-- We assume lp = node_next(Np.last)
- local pBp = Bp
- local lpi, lpa
+ local pBp = Bp; local lpi, lpa
Nq = Np; Bp = {}; Bp[0] = 0; Np = {}; ihb_flag = false
while true do
lpi = lp.id; lpa = has_attr(lp, attr_icflag) or 0
if lp==last then Np = nil; return
+ elseif lpa>=PACKED then -- elseif lpa>=KINSOKU then
+ if lpa == BOXBDD then
+ local lq = node_next(lp)
+ head = node_remove(head, lp); lp = lq
+ else calc_np_pbox(); return end -- id_pbox
elseif lpi == id_ins or lpi == id_mark or lpi == id_adjust then
lp = node_next(lp)
elseif lpi == id_penalty then
end
else -- a `cluster' is found
Np.first = lp
- if lpa >=2 then
- if lpa == BOXBDD then
- local lq = node_next(lp)
- head = node_remove(head, lp); lp = lq
- else -- id_pbox
- Np.id = id_pbox; Np.nuc = lp
- while lp~=last and lpa>=2 and lpa~=7 do
- lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0
- end
- Np.last = lp; check_next_ickern(); return
- end
- elseif lpi == id_glyph then -- id_[j]glyph
+ if lpi == id_glyph then -- id_[j]glyph
if lp.font == has_attr(lp, attr_curjfnt) then Np.id = id_jglyph
else Np.id = id_glyph end
Np.nuc = lp; lp = node_next(lp); check_next_ickern(); return
elseif lpi == id_hlist then -- hlist
- Np.nuc = lp; Np.last = lp
+ Np.last = lp; Np.nuc = lp
+ --if lpa == PACKED then
+ -- Np.id = id_jglyph
+ -- for q in node.traverse_id(id_glyph, lp.head) do
+ -- Np.nuc = q; break
+ -- end
if lp.shift~=0 then Np.id = id_box_like
else Np.id = lpi end
lp = node_next(lp); return
Np.nuc = lp; Np.last = lp; Np.id = id_box_like; break
elseif lpi == id_math then -- id_math
Np.nuc = lp; lp = node_next(lp)
- while lp.id~=id_math do lp = node_next(lp) end
- break
+ while lp.id~=id_math do lp = node_next(lp) end; break
elseif lpi == id_kern and lp.subtype==2 then -- id_kern
- lp = node_next(node_next(node_next(lp)))
- Np.nuc = lp ; lp = node_next(lp); check_next_ickern(); return
+ lp = node_next(node_next(node_next(lp))); Np.nuc = lp
+ if lp.font == has_attr(lp, attr_curjfnt) then Np.id = id_jglyph
+ else Np.id = id_glyph end
+ lp = node_next(lp); check_next_ickern(); return
else -- id_disc, id_glue, id_kern
Np.nuc = lp; break
end
end
elseif Np.id == id_pbox then -- mikann
find_first_char = true; first_char = nil; last_char = nil
- if check_box(Np.first, Np.last) then
+ if check_box(Np.first, node_next(Np.last)) then
if first_char then
if first_char.font == has_attr(first_char, attr_curjfnt) then
set_np_xspc_jachar(first_char.char,first_char)
end
-- change penalties (or create a new penalty, if needed)
-local function handle_penalty_normal(pre, post, g)
+local function handle_penalty_normal(post, pre, g)
local a = (pre or 0) + (post or 0)
if Bp[0] == 0 then
- if (a~=0 and not(g and g.id==id_kern)) or Nq.lend~=0 then
+ if (a~=0 and not(g and g.id==id_kern)) or (Nq.lend and Nq.lend~=0) then
local p = node_new(id_penalty)
if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
p.penalty = a
head = node_insert_before(head, Np.first, p)
Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
end
- else
- for i, v in ipairs(Bp) do add_penalty(v,a) end
+ else for i, v in ipairs(Bp) do add_penalty(v,a) end
end
end
-local function handle_penalty_always(pre, post, g)
+local function handle_penalty_always(post, pre, g)
local a = (pre or 0) + (post or 0)
if Bp[0] == 0 then
- if not (g and g.id==id_glue) or Nq.lend~=0 then
+ if not (g and g.id==id_glue) or (Nq.lend and Nq.lend~=0) then
local p = node_new(id_penalty)
if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
p.penalty = a
head = node_insert_before(head, Np.first, p)
Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
end
- else
- for i, v in ipairs(Bp) do add_penalty(v,a) end
+ else for i, v in ipairs(Bp) do add_penalty(v,a) end
end
end
-local function handle_penalty_suppress(pre, post, g)
+local function handle_penalty_suppress(post, pre, g)
local a = (pre or 0) + (post or 0)
if Bp[0] == 0 then
if g and g.id==id_glue then
p.penalty = 10000; head = node_insert_before(head, Np.first, p)
Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
end
- else
- for i, v in ipairs(Bp) do add_penalty(v,a) end
+ else for i, v in ipairs(Bp) do add_penalty(v,a) end
end
end
end
-- (anything) .. (和文文字で終わる hlist)
-local function handle_nq_ja_hlist()
+local function handle_np_ja_hlist()
local g = nil
- if Nq.id==id_jglyph or (Nq.id==id_pbox and Nq.pre) then
+ if Nq.id==id_jglyph or (Nq.id==id_pbox and Nq.met) then
g = get_OB_skip() or get_kanjiskip() -- O_B->K
g = lineend_fix(g)
- handle_penalty_normal(Nq.post, Np.pre, g); real_insert(Nq.lend, g)
+ handle_penalty_normal(Nq.post, 0, g); real_insert(Nq.lend, g)
elseif Nq.met then -- Nq.id==id_hlist
g = get_kanjiskip() -- K
handle_penalty_suppress(0, 0, g); real_insert(0, g)
end
-- (和文文字で終わる hlist) .. (anything)
-local function handle_np_ja_hlist()
+local function handle_nq_ja_hlist()
local g = nil
- if Nq.pre then
+ if Np.pre then
g = get_xkanjiskip(Nq) -- X
handle_penalty_suppress(0, 0, g); real_insert(0, g)
end
if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then
if Np.lend~=0 then
g = node_new(id_kern); g.subtype = 0; g.kern = Np.lend
- set_attr(g, attr_icflag, LINE_END)
+ set_attr(g, attr_icflag, BOXBDD)
node_insert_after(head, Np.last, g)
end
end
if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then
local g = new_jfm_glue(Np, Np.class, find_char_class('boxbdd',Np.met))
if g then
- set_attr(g, attr_icflag, FROM_JFM)
+ set_attr(g, attr_icflag, BOXBDD)
head = node_insert_after(head, Np.last, g)
end
end
if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then
local g = new_jfm_glue(Np, find_char_class('boxbdd',Np.met), Np.class)
if g then
- set_attr(g, attr_icflag, FROM_JFM)
- if g.id==id_glue then
- handle_penalty_suppress(0, 0)
+ set_attr(g, attr_icflag, BOXBDD)
+ if g.id==id_glue and Bp[0]==0 then
+ local h = node_new(id_penalty)
+ h.penalty = 10000; set_attr(h, attr_icflag, BOXBDD)
end
head = node_insert_before(head, Np.first, g)
end
head = ahead; mode = amode; init_var(); calc_np()
if Np then
extract_np(); handle_list_head()
- else
- if not mode then
- head = node_remove(head, last) -- remove the sentinel
+ if Np.id==id_glyph then after_alchar()
+ elseif Np.id==id_hlist or Np.id==id_pbox or Np.id==id_disc then after_hlist()
end
+ else
+ if not mode then head = node_remove(head, last) end
return head
end
calc_np()
end
calc_np()
end
- handle_list_tail(); return head
+ handle_list_tail()
+ -- adjust attr_icflag
+ for p in node.traverse(head) do
+ local a = has_attr(p, attr_icflag) or 0
+ if a==0 then set_attr(p, attr_icflag, PROCESSED) end
+ end
+ tex.attribute[attr_icflag] = -(0x7FFFFFFF)
+ return head
end
-- \inhibitglue
g.user_id=30111; g.type=100; g.value=1; node.write(g)
end
--- TODO: 二重挿入の回避
\ No newline at end of file
+-- TODO: 二重挿入の回避
\def\dumplist#1{\par\noindent\leavevmode
\hbox to 0.2\hsize{\copy#1\hss}%
\vbox{\hsize=0.6\hsize\sixtt\baselineskip=7.2pt\sixgt\let\\=\relax
-\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par', tex.print)}\hrule}}
+\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par ', tex.print)}\hrule}}
%\tracingonline=1\tracingoutput=1\showboxdepth=3\showboxbreadth=100
\setbox0=\hbox{\rmlh \hbox{}う}\dumplist0
-\head{JA--penalty (penなし)} TODO: この場合の挙動はこれで良いか?
-
-\setbox0=\hbox{\rmlh あ\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh い\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh う\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh え\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh か\penalty567}\dumplist0
-
-\head{penalty--JA (penなし)} TODO: この場合の挙動はこれで良いか?
-
-\setbox0=\hbox{\rmlh \penalty567あ}\dumplist0
-
-\setbox0=\hbox{\rmlh \penalty567い}\dumplist0
-
-\setbox0=\hbox{\rmlh \penalty567う}\dumplist0
-
{\vfill\eject%
\ltjsetparameter{prebreakpenalty={`(,123}}
{\ltjsetparameter{alxspmode={`x,postonly}}
\setbox0=\hbox{\rmlh まx}\dumplist0}
-\head{kanjiskip from JFM/autoxspacing (EN--JA)}
+\head{xkanjiskip from JFM/autoxspacing (EN--JA)}
\setbox0=\hbox{\rmlh xま}\dumplist0
\setbox0=\hbox{\rmlh x\naxspc ま}\dumplist0
\setbox0=\hbox{\rmlh あ\penalty1701\penalty1701\penalty1701お}
\dumplist0
-\head{その他}
+\head{その他: italic correction and accents}
-\setbox0=\hbox{\tenrm あ\/\v{A}あ}
+\setbox0=\hbox{\tenrm あ\/j}
\dumplist0
+\setbox0=\hbox{\tenrm\rmlh れ\v{A})}
+\dumplist0
+
+\head{その他: box boundary}
+
\setbox0=\hbox{\rmlh かあか}
\dumplist0
-\setbox0=\hbox{\rmlh あか}
+\setbox0=\hbox{a\setbox3=\hbox{\rmlh かあか}\unhbox3a}
+\dumplist0
+\setbox0=\hbox{a\setbox3=\hbox{\rmlh か}\box3a}
\dumplist0
-\setbox0=\hbox{\setbox3=\hbox{\rmlh かa}\unhbox3}
+\setbox0=\hbox{\rmlh き\hbox{か}き\hbox{き}き}
\dumplist0
+{\ltjsetparameter{postbreakpenalty={`あ,1000},prebreakpenalty={`あ,1000}}
+\setbox0=\hbox{あ\hbox{(}あ\setbox3=\hbox{(}\unhbox3あ}
+\dumplist0}
+
\end
\newcount\cnt\newcount\cnta
\cnt=0
\long\def\loop#1\repeat{\def\body{#1}\iterate}
-\loop\ifnum\cnt<10 % <= this value
+\loop\ifnum\cnt<20 % <= this value
\cnta=0 \message{\the\cnt:}\par
{\loop\ifnum\cnta<500 あ.「い,うえお・か(き)く)(けこ\advance\cnta1\repeat}
\advance\cnt1
\end
% real time:
-% 20: 9.950s 9.214
-% 10: 5.209s 5.119
+% 20: 9.950s 10.584
+% 10: 5.209s 5.523
% env: C2D E7300, Mem 4GB, LuaTeX 0.71.0pre, Gentoo amd64 unstable
\ No newline at end of file