OSDN Git Service

Moved several Lua programs.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 27 Jun 2011 10:08:01 +0000 (19:08 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 27 Jun 2011 10:08:01 +0000 (19:08 +0900)
 * src/luatexja-jfont.lua -> src/luatexja/jfont.lua
 * src/luatexja-rmlgbm.lua -> src/luatexja/rmlgbm.lua
 * 'main1' in luatexja-core.lua -> src/luatexja/pretreat.lua
 * Fixed rank of callbacks (in luatexja-core.lua)
 * Updated jfmglue.pdf (may be inconsistent with jfmglue.lua, however).

28 files changed:
doc/jfmglue.pdf
doc/jfmglue.tex
doc/sample1.pdf
doc/sample1.tex
src/jfm-mono.lua
src/jfm-ujis.lua
src/luatexja-core.lua
src/luatexja-core.sty
src/luatexja-jfmglue.lua [deleted file]
src/luatexja-xkanji.lua [deleted file]
src/luatexja/charrange.lua
src/luatexja/compat.lua
src/luatexja/inputbuf.lua
src/luatexja/jfmglue.lua
src/luatexja/jfont.lua [moved from src/luatexja-jfont.lua with 78% similarity]
src/luatexja/pretreat.lua [new file with mode: 0644]
src/luatexja/rmlgbm.lua [moved from src/luatexja-rmlgbm.lua with 90% similarity]
src/luatexja/stack.lua
test/jfm-bad.lua
test/jfm-hang.lua
test/jfm-test.lua
test/test01-noembed.pdf
test/test01.pdf
test/test01.tex
test/test04-jfm.pdf
test/test04-jfm.tex
test/test05-speed.pdf
test/test05-speed.tex

index 5e01ed8..cdf9eb5 100644 (file)
Binary files a/doc/jfmglue.pdf and b/doc/jfmglue.pdf differ
index 5a26699..d44ee51 100644 (file)
@@ -352,85 +352,140 @@ $$
 実際には$\emptyset$を返す.
 \enditem
 
-\beginsection main loop その1: $\mibox{head}(\mibox{Np})$が和文文字の場合
+\vfill\eject
+\beginsection main loop
 
-これは,次の3つの場合でおこる:
-\item \IT{Np.id}が\IT{id\_jglyph}の場合(本当に和文文字)
-\item \IT{Np.id}が\IT{id\_pbox}で,$\mibox{head}(\mibox{Np})$が和文文字の場合
-\item \IT{Np.id}が\IT{id\_hlist}で,$\mibox{head}(\mibox{Np})$が和文文字の場合
-\enditem
-前2つの場合は,$\mibox{head}(\mibox{Np})$は処理対象のリスト中に現れる本当の\IT{glyph\_node}である.
-一方,最後の場合では,$\mibox{head}(\mibox{Np})$はリスト中にあるhboxの中身(の最初)に出現する\IT{glyph\_node}である.
+\beginparagraph 一覧表
 
-そのため,挿入される和文処理グルーの種類については,前2つと最後の場合とで扱いを異なったものとしている:
-$$
-\vbox{\hsize=0.85\hsize\bf 
-hboxの外側の文字と内側の文字の間の空白では,|\kanjiskip|, |\xkanjiskip|の量の計算では両方の文字の情報を使うが,
-JFM由来のグルーでは内側の文字の情報は使われない.}
+\IT{Nq}, \IT{Np}の種類別に挿入されるglue/kernの種別を表にすると次のようになる.
+
+\def\;{\hskip0.25em}\ltjsetparameter{jacharrange={+1}}
+\def\gkf#1#2#3#4#5{$\vcenter{\small\rm\halign{\hbox to 1em{\hss##\hss}\;\vrule&%
+\hbox to 3em{\hss##\hss}&\vrule\;\hbox to 1em{\hss##\hss}\cr
+#1\mathstrut&\omit\hfil #2\span\omit\cr\noalign{\hrule}#3&#4\strut&#5\cr}}$}
+\setbox1=\hbox{\gkf{E}{M→K}{○}{nor}{○}}
+\setbox2=\hbox to 0.4pt{\vrule height\dimexpr \ht1+0.5em\relax depth \dimexpr \dp1\relax}
+$$\def\:{\hskip0.5em}\lineskiplimit=\maxdimen\lineskip=0pt
+\vcenter{\halign{\hfil#\hfil\hskip1em\copy2%
+\:&\:\hfil#\hfil\:&\:\hfil#\hfil\:&\:\hfil#\hfil\:&\:\hfil#\hfil%
+\:&\:\hfil#\hfil\:&\:\hfil#\hfil\:&\:\hfil#\hfil\:&\:\hfil#\hfil\cr
+\raise0.5em\hbox{$\vcenter{\hbox{\IT{Nq}→}\smallskip\hbox{\IT{Np}↓}}$}%
+&和文1&和文2&欧文&箱&id\_glue&id\_kern\cr
+\noalign{\hrule}
+和文1&
+\gkf{E}{M→K}{○}{nor}{○}&
+\gkf{}{$\rm O_A$→K}{×}{nor}{○}&
+\gkf{}{$\rm O_A$→X}{○}{nor}{○}&
+\gkf{}{$\rm O_A$}{---}{all}{○}&
+\gkf{}{$\rm O_A$}{---}{nor}{○}&
+\gkf{}{$\rm O_A$}{---}{sup}{○}\cr
+和文2&
+\gkf{E}{$\rm O_B$→K}{○}{nor}{×}&
+\gkf{}{K}{×}{sup}{×}&
+\gkf{}{X}{○}{sup}{×}\cr
+欧文&
+\gkf{E}{$\rm O_B$→X}{○}{nor}{○}&
+\gkf{}{X}{○}{sup}{×}\cr
+箱&\gkf{E}{$\rm O_B$}{○}{alw}{---}\cr
+\IT{id\_glue}&\gkf{E}{$\rm O_B$}{○}{nor}{---}\cr
+\IT{id\_kern}&\gkf{E}{$\rm O_B$}{○}{sup}{---}\cr
+}}$$
+
+\item {\bf 項目名}\quad 表1行目の\IT{Nq}の種類について説明する.\IT{Np}についても同様.
+\itemitem 「和文1」:リスト中に直接出現している和文文字.
+\itemT $\mibox{Nq.id}=\mibox{id\_jglyph}$であったとき.
+\itemT $\mibox{Nq.id}=\mibox{id\_pbox}$かつ$\mibox{last}(\mibox{Nq})$が和文文字であったとき.
+\itemitem 「和文2」:リスト内にあるhboxの中身として出現した和文文字.すなわち,
+$\mibox{Nq.id}=\mibox{id\_hlist}$かつ
+$\mibox{last}(\mibox{Nq})$が和文文字であったとき.
+\itemitem 「欧文」:$\mibox{last}(\mibox{Nq})$が欧文文字であったとき.即ち,
+\itemT リスト中に直接出現しているとき($\mibox{Nq.id}=\mibox{id\_jglyph}$ or~%
+$\mibox{Nq.id}=\mibox{id\_pbox}$かつ$\mibox{last}(\mibox{Nq})$が欧文文字).
+\itemT $\mibox{Nq.id}=\mibox{id\_hlist}$かつ
+$\mibox{last}(\mibox{Nq})$が欧文文字であったとき.
+\itemT $\mibox{Nq.id}=\mibox{id\_math}$であったとき.
+\itemitem 「箱」:前後に和文処理グルーが挿入されない用なbox状のnode.
+\itemT $\mibox{Nq.id}=\mibox{id\_list}$かつ
+$\mibox{last}(\mibox{Nq})$が文字でなかった(未定義)だったとき.
+\itemT $\mibox{Nq.id}=\mibox{id\_box\_like}$のとき.
+\itemitem 「\IT{id\_glue}」:そのまま,$\mibox{Nq.id}=\mibox{id\_glue}$であったとき.
+\itemitem 「\IT{id\_kern}」:そのまま,$\mibox{Nq.id}=\mibox{id\_kern}$であったとき.
+
+\item 表中の各セルは,それぞれ次のような内容を表している:
+$$\vcenter{\rm\halign{\hbox to 3em{\hss#\hss}\;\vrule&%
+\hbox to 3.5em{\hss#\hss}&\vrule\;\hbox to 3em{\hss#\hss}\cr
+左空白\mathstrut&\omit\hfil 右空白\span\omit\cr\noalign{\hrule}L&P取扱\strut&R\cr}}$$
+
+\itemitem 「左空白」:\IT{Nq}の直後に挿入される空白の種類.空欄は,何も入らないことを表す.
+\itemitem 「右空白」:\IT{Np}の直前に挿入される空白の種類.
+
+なお,「A→B」は,まずAの種類のglue/kernを調べ,それが未定義ならば,
+Bの種類のglue/kernを採用することを示している.このとき,矢印の右側に入る空白%
+(K, X)はいつでも定義されていることに注意.
+
+\itemitem 「P取扱」:\IT{Nq}と\IT{Np}の間に入る禁則用ペナルティの取扱の方法を表す.
+\IT{Nq}と\IT{Np}の間で常に行分割を許すかに伴い,
+{\bf nor}mal, {\bf alw}ays, {\bf sup}pressの3種類がある.
+\itemitem 「L」「R」:禁則用ペナルティの挿入処理において,
+\IT{Nq.post}~(L)や\IT{Np.pre}~(R)の値を実際に活用するかどうかを示す.値は次の3種類:
 $$
+\hbox{○(利用する),×(利用せず,0として扱う),---(未定義のため0扱い)}$$
+\enditem
 
 
 \beginparagraph 挿入されるglue/kernの種類
 
-\setbox1=\hbox{hp}\setbox2=\hbox to 0.4pt{\vrule height\dimexpr \ht1+0.25em\relax depth \dimexpr \dp1+0.25em\relax}
-$$\def\:{\hskip0.5em}\lineskiplimit=\maxdimen\lineskip=0pt
-\vcenter{\halign{\hfil\IT{#}\hfil\hskip1em\copy2%
-\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil%
-\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil\:&\:\hfil\IT{#}\hfil\cr
-\IT{Nq}→&id\_jglyph&&&id\_hlist 非文字\cr
-\IT{Np}↓&id\_pbox 和&id\_hlist 和&$\mibox{head}(\mibox{Nq})$\rm: 欧文&id\_box\_like&id\_glue&id\_kern\cr
-\noalign{\vskip.25em\hrule\vskip.25em}
-id\_jglyph&\rm E${}+{}$(M→K)&{\rm $\rm O_A$→$\rm K$}&{\rm $\rm O_A$→X}&$\rm O_A^*$&$\rm O_A$&$\rm O_A^+$\cr
-id\_pbox 和&\rm E${}+{}$(M→K)&{\rm $\rm O_A$→$\rm K$}&{\rm $\rm O_A$→X}&$\rm O_A^*$&$\rm O_A$&$\rm O_A^+$\cr
-id\_hlist 和&\rm E${}+{}$($\rm O_B$→$\rm K$)&{\rm K}${}^+$&{\rm X}${}^+$&---&---&---\cr
-}}$$
-挿入されるglue/kernの種別を表にすると上のようになる.最後の1つ以外は,挿入される位置は\IT{Np.first}の直前であり,
-以降「右側の空白」と呼ぶ.
+前節の表にある空白の種類についての解説を行う.
+
+\item E: \IT{Nq}が行末にきたとき,
+\IT{Nq}と行末の間に入る空白 (kern).挿入位置は\IT{Nq.last}の直後.
+\itemitem JFMでは「文字コード|'lineend'|の文字」との間に入るkern量として設定できる.
+\itemitem 右空白がkernであるときは挿入されない.
+\itemitem この種類のkernが挿入される時,右空白は自然長がEの分だけ引かれる.
+
+
 \item M: \IT{Nq}と\IT{Np}の間に入るJFM由来のglue/kern.
-\IT{Nq}, \IT{Np}の間で|\inhibitglue|を発行した場合は抑止される.
-\itemitem 両方の塊で使われているJFMが(サイズもこめて)等しかったら量の決定は容易い.
+\itemitem \IT{Nq}, \IT{Np}の間で|\inhibitglue|を発行した場合,挿入は抑止される.
+\itemitem 両方の塊で使われているJFMが(サイズもこめて)等しい場合は,両者で使われている
+JFMの情報をそのまま利用できるので,量の決定は容易い.
 \itemitem そうでなければ,まず
 $$
 \vcenter{\halign{\hfil$#:={}$&(\inhibitglue#\inhibitglue)\cr
-gb&\IT{Nq}と「文字コードが|'diffmet'|の文字」との間に入るglue/kern\cr
-ga&「文字コードが|'diffmet'|の文字」と\IT{Np}との間に入るglue/kern\cr
+gb&\IT{Nq}と「文字コードが|'diffmet'|の文字」との間に入るglue/kern\cr
+ga&「文字コードが|'diffmet'|の文字」と\IT{Np}との間に入るglue/kern\cr
 }}
 $$
-として2つの量を計算.少なくとも片方が$\emptyset$の場合は,もう片方の値を用いる.
+として2つの量を計算.少なくとも片方が未定義の場合は,もう片方の値を用いる.
 そうでなければ,両者の値から自然長,伸び量,縮み量ごとに計算
 (方法として,平均,和,大きい方,小さい方)を行い,それによって得られたglue/kernを採用する.
 \item K: |\kanjiskip|を表すglueを挿入($\emptyset$にはならない).
 \itemitem 両方の塊において「|\kanjiskip|の自動挿入が無効」
  ($\mibox{Nq.auto\_kspc}\vee \mibox{Np.auto\_kspc}=\bot$) ならば,長さ0のglueを挿入する.
-\itemitem {\sf kanjiskip}パラメタの自然長が$\hbox{\tt\char92maxdimen}=(2^{30}-1)\,{\rm sp}$であれば,
+\itemitem {\sf kanjiskip}パラメタの自然長が$\hbox{\tt\char92maxdimen}=(2^{30}-1)\,{\rm sp}$で
+あれば,
 JFMに指定されている|\kanjiskip|の量を用いる.\IT{Nq}, \IT{Np}で使われているJFMが異なった時の処理は,
 Mの場合と同じである.
 \itemitem 上のどれにも当てはまらなければ,{\sf kanjiskip}パラメタで表される量のglueを挿入する.
 \item X: |\xkanjiskip|を表すglueを挿入($\emptyset$にはならない).
-\itemitem 両方の塊において「|\xkanjiskip|の自動挿入が無効」
- ($\mibox{Nq.auto\_xspc}\vee \mibox{Np.auto\_xspc}=\bot$) ならば,長さ0のglueを挿入する.
-\itemitem \mibox{Nq}内の文字が「直後への|\xkanjiskip|挿入が無効」という指定
-($\hbox{\sf alxspmode}\ge 2$)であるか,
-\mibox{Np}内の文字が「直前への|\xkanjiskip|挿入が無効」という指定
-($\hbox{\sf jaxspmode}\ge 2$)であるならば,長さ0のglueを挿入する.
+\itemitem 次のいずれかの場合には,|\xkanjiskip|は長さ0のglueとなる:
+\itemT  両方の塊において,「|\xkanjiskip|の自動挿入が無効」という指定
+($\mibox{Nq}.\mibox{auto\_xspc}\vee \mibox{Np}.\mibox{auto\_xspc}=\bot$)
+がされていた場合.
+\itemT \IT{Nq}内の文字について「直後への|\xkanjiskip|挿入が無効」であった場合,即ち
+$\hbox{\sf alxspmode}\ge 2$(欧文)か$\hbox{\sf jaxspmode}\equiv0\pmod2$(和文).
+\itemT \IT{Np}内の文字について「直前への|\xkanjiskip|挿入が無効」であった場合,即ち
+$\hbox{\sf alxspmode}\equiv0\pmod2$(欧文)か$\hbox{\sf jaxspmode}\ge2$(和文).
 \itemitem {\sf xkanjiskip}パラメタの自然長が|\maxdimen|であれば,
-JFMに指定されている|\xkanjiskip|の量を用いる.
+$\mibox{last}(\mibox{Nq})$, $\mibox{head}(\mibox{Np})$の片方が和文文字であるので,
+そこで使われているJFMで指定されている|\xkanjiskip|の量を用いる
+(JFMで指定されていなければ長さ0のglueと見なされる).
 \itemitem 上のどれにも当てはまらなければ,{\sf xkanjiskip}パラメタで表される量のglueを挿入する.
 \item $\rm O_B$: \IT{Nq}と「文字コードが|'jcharbdd'|の文字」との間に入るglue.
 Mのバリエーションと考えればよく,同じように|\inhibitglue|の指定で抑止される.
 \item $\rm O_A$: 「文字コードが|'jcharbdd'|の文字」と\IT{Np}との間に入るglue.
 Mのバリエーションと考えればよく,同じように|\inhibitglue|の指定で抑止される.
-\item E: \IT{Nq}が行末にきたとき,\IT{Nq}と行末の間に入る空白 (kern).挿入位置は\IT{Nq.last}の直後.
-\itemitem JFMでは「文字コード|'lineend'|の文字」との間に入るkern量として設定できる.
-\itemitem 右側の空白がkernであるときは挿入されない.
-\itemitem この種のkernが挿入される時,右側の空白は自然長がEの分だけ引かれる.
 \enditem
 
-あと,注として,
-
-\item 「→」は,左側の種類(例えばM)のglue/kernは$\emptyset$であった場合,右側の種類(例えばK)のglueを挿入することを示す.
-\item ${}^*$, ${}^+$は,penalty処理時のバリエーションを表す.次の節では,上添字なしの場合のpenaltyの処理について述べる.
-\enditem
 
 \beginparagraph penaltyまわりの処理
 
@@ -443,47 +498,39 @@ $$
 \Bigl[\node{\hbox{M, K, X他}}_{3,\,5,\,6}\Bigr]
 \node{\mibox{Np}}
 $$
-このような状況下で,禁則処理に関係するpenaltyの挿入処理は,原則として(上ほど優先度高):
-\item $\#\mibox{Bp}\ge 1$の場合,{\bf 全ての}\IT{Bp}の元$p$~(penalty)に対して,
-$$p.\mibox{penalty}\mathrel{+}=\mibox{Nq.post}+\mibox{Np.pre}.$$
-\itemitem 
-全ての\IT{Bp}の元に対して行うのは,実際にはどのpenaltyの位置で行分割が行われるかわからないからである.
-\itemitem $\mibox{Nq.id}=\mibox{id\_hlist}$の場合には,\IT{Nq.post}は0と扱われる.
-$\mibox{Np.id}=\mibox{id\_hlist}$の場合も同様.
-
-\item $\#\mibox{Bp}=0$かつ$\mibox{Nq.post}+\mibox{Np.pre}=:a\neq 0$,
-さらに「右側の空白がkernでない」場合:
-$p.\mibox{penalty}=a$であるpenalty~$p$を作成し,
-それを(M, K他のglue挿入前に)\IT{Np.first}の直前に挿入する.
-つまり,この場合,
-$$
-\longrightarrow\cdots\longrightarrow\node{\np a}
-\Bigl[\node{\hbox{M, K, X他}}_{3,\,5,\,6}\Bigr]
-\node{\mibox{Np}}
-$$
-となる.
-\item $\#\mibox{Bp}=0$かつ${\rm E}\neq 0$(かつ右側の空白がglue)の場合:同様に新たなpenaltyを作る.\hfil\break
-(Eの位置で改行可能にしたいので)
-\item つまり,$\#\mibox{Bp}=0$であったとき,新たなpenaltyを作らないのは,
-${\rm E}=0$かつ$a=0$の場合に限る.
+禁則処理に関係するpenaltyの挿入処理は,以下に述べるところ部分は共通の動作である.
+
+\medskip 
+$\#\mibox{Bp}\ge 1$の場合には,{\bf 全ての}\IT{Bp}の元$p$~(penalty)に対して次を行う:
+$$p.\mibox{penalty}\mathrel{+}=a,\qquad a:=\mibox{Nq.post}+\mibox{Np.pre}.$$
+\item
+全ての\IT{Bp}の元に対して行うのは,
+実際にはどのpenaltyの位置で行分割が行われるかがわからないからである.
+\item 数ページ前の表で,左下が「×」 or 「---」となっていた場合は,上の計算式において
+\IT{Nq.post}は0と扱われる.右下が「×」 or 「---」なら,\IT{Np.pre}が0と扱われる.
+\item penalty値の計算では,$+10000$は正の無限大,$-10000$は負の無限大として扱っている.
+そのため,$a$の計算や$p.\mibox{penalty}$への加算代入のところでは,
+通常の加減算で絶対値が10000を越えたら分はカットし,さらに$(10000)+(-10000)=0$としている.
 \enditem
 
-なお,penalty値の計算では,$+10000$は正の無限大,$-10000$は負の無限大として扱っている.
-そのため,通常の加減算で絶対値が10000を越えたら,その分はカットしている.
-あと,$(10000)+(-10000)=0$としている.また,\IT{Nq.post}, \IT{Np.pre}が$\emptyset$の場合は,
-それぞれ0として扱う.
+$\#\mibox{Bp}=0$の場合が,penalty挿入の3種類の方法「normal」「always」「suppress」で
+異なる部分である:
 
-\medskip\noindent{\bf バリエーションについて}\quad
-前節の表に出てきた${}^*$, ${}^+$では,上の原則から以下の点が変更されている.
-変更点は,いずれも$\#\mibox{Bp}=0$の場合に関するところのみである:
-
-\item ${}^*$: \IT{Nq}と\IT{Np}の間での行分割を常に可能とするため,
-右側の空白($\rm O_A$)が$\emptyset$の場合であっても新たなpenaltyを作る.
+\item {\bf「normal」の場合:}
+次の場合に,$p.\mibox{penalty}=a$であるpenalty~$p$を作成し,
+それを(M, K他のglue挿入前に)\IT{Np.first}の直前に挿入する:
+$$
+\hbox{左空白(E)が存在しているか,$a\neq 0$かつ右空白がkernである.}
+$$
+\item {\bf「always」の場合:}
+この場合は,\IT{Nq}, \IT{Np}の間で常に行分割可能にしたいので,挿入する条件は以下のようになる:
+$$
+\hbox{左空白(E)が存在しているか,右空白がglueでない(つまり,kernか未定義のとき).}
+$$
 
-\item ${}^+$: このとき,\IT{Nq}と\IT{Np}の間での行分割は元々不可能である.
-Lua\TeX-ja では,そのような場合を「わざわざ行分割可能に」することはしない.そのため,
-\itemitem 右側の空白がglueの場合は,値が10000のpenaltyを作成する.
-\itemitem 右側の空白が$\emptyset$かkernの場合は,新たにpenaltyを作ることはしない.
+\item {\bf「suppress」の場合:}このとき,\IT{Nq}と\IT{Np}の間での行分割は元々不可能である.
+Lua\TeX-ja では,そのような場合を「わざわざ行分割可能に」することはしない.
+つまり,右空白がglueであるとき,その直前に|\penalty 10000|を挿入する.
 \enditem
 
 \beginparagraph いくつかの例:未完
index e078cbb..9c26c0a 100644 (file)
Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ
index e5e4e07..f34a978 100644 (file)
@@ -11,7 +11,6 @@
 \def\XyM{X\kern-.30em\smash{\raise.50ex\hbox{\UPSILON}}\kern-.30em{M}}%
 \def\XyMTeX{\XyM\kern-.1em\TeX}%
 
-
 % main matter
 \centerline{\big Lua\TeX-jaパッケージ}\bigskip
 \centerline{\large\the\year/\the\month/\the\day}\medskip
@@ -31,7 +30,8 @@
 ほげほげ){\gt (ふがふが}
 \endtt
 \item 欧文や和文のベースライン補正が可能.
-\item p\TeX とある程度コマンド名が互換.
+\item p\TeX とある程度コマンド名が互換ではあるが,{\bf 内部動作についてはp\TeX との100\%互換は
+目指していません{\small (p\TeX で不自然なところがあれば,積極的に改める)\inhibitglue}}.
 \enditem
 
 \beginparagraph 制限
 
 \beginparagraph ファイル構成
 
-
-\item {\tt luatexja-core.sty}: 
-コア部分.拡張子は{\tt sty}であるが,この単一のファイルでplain \TeX と\LaTeX 両方に
-対応するように設計する方針である.しかし,
-{\bf 現時点で\LaTeX での使用は全く考慮されていない.}
-\item {\tt luatexja-core.lua}: コア部分に使われるLuaコード.
-\item {\tt luatexja-jfont.lua}: 和文フォント定義部のLuaコード.
-\item {\tt luatexja-xkanji.lua}: |\[x]kanjiskip|自動挿入処理のLuaコード.
-\item {\tt luatexja-rmlgbm-data.lua}: 非埋込和文フォント用のデータ(小塚明朝Pr6N R由来).
-\item {\tt luatexja-rmlgbm.lua}: 非埋込和文フォント (Ryumin-Light etc.) 定義部.
-\item {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト
+\item {\tt src/}: 核となる\TeX ソースとLuaコードはこのディレクトリ内に入っている.
+\itemitem \TeX 用スタイルファイル達
+\itemT {\tt luatexja.sty}: 利用者はこのファイルを読み込む.
+拡張子は{\tt sty}であるが,plain \TeX と\LaTeX 両方に対応させる方針である.しかし,
+{\bf 現時点で\LaTeX での使用は考慮されていない.}
+\itemT {\tt luatexja-core.sty}: 
+\itemT {\tt luatexja-base.sty}: 
+\itemT {\tt luatexja-cctbreg.sty}: 
+\itemT {\tt luatexja-compat.sty}: p\TeX 互換用primitive(|\euc|, |\kansuji|)定義部.
+\itemT {\tt luatexja-compat-ptex.sty}: 
+\itemT {\tt luatexja-plain.sty}: 
+\itemT {\tt luatexja-kinsoku.tex}: 禁則用ペナルティ等のパラメータを書いたファイル.
+{\tt ukinsoku.tex} (in up\TeX-0.30) から自動生成されたもの.
+
+\itemT {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト
 {\small(小塚明朝を{\tt luaotfload}で読み込んだ時のキャッシュが必要)\inhibitglue}.
-\item {\tt luatexja-kinsoku.tex}: 禁則用ペナルティ等のパラメータを書いたファイル.
-下のファイルによって{\tt ukinsoku.tex} (in up\TeX-0.30) から自動生成されたもの.
-\item {\tt jfm-ujis.lua}: up\TeX-0.30の{\tt ujis.tfm}ベースのメトリックサンプル.
-\item {\tt jfm-mono.lua}: 「全文字が全角幅」のメトリックサンプル.
+
+\itemitem Luaコード達(旧フォーマット)
+\itemT {\tt luatexja-core.lua}: コア部分に使われるLuaコード.
+\itemT {\tt luatexja-rmlgbm-data.lua}: 非埋込和文フォント用のデータ(小塚明朝Pr6N R由来).
+\itemT {\tt jfm-ujis.lua}: up\TeX-0.30の{\tt ujis.tfm}ベースのメトリックサンプル.
+\itemT {\tt jfm-mono.lua}: 「全文字が全角幅」のメトリックサンプル.
+
+\itemitem Luaコード達(新フォーマット,{\tt src/luatexja/}以下)
+
+\itemT {\tt base.lua}
+\itemT {\tt compat.lua}: p\TeX 互換用primitive(|\euc|, |\kansuji|)実装部.
+\itemT {\tt jisx0208.lua}: |\euc|等で使うJIS~X~0208→Unicode変換表.
+\itemT {\tt infomute.lua}
+\itemT {\tt jfont.lua}: 和文フォント定義部のLuaコード.
+\itemT {\tt rmlgbm.lua}: 非埋込和文フォント (Ryumin-Light etc.) 定義用コード.
+\itemT {\tt jfmglue.lua}: 和文処理に伴う空白の挿入処理部.
+\itemT {\tt tangle.lua}
+\itemT {\tt charrange.lua}: 「和文文字の範囲」管理部.
+\itemT {\tt debug.lua}
+\itemT {\tt inputbuf.lua}: 「和文文字直後の改行」処理用.
+\itemT {\tt stack.lua}: Lua\TeX-ja スタック管理システム.
 \enditem
 
 \beginsection 使用方法
 
 大雑把に言うと,plain \TeX の状況で,以下のようにすればよい.
 \begintt
-\input luatexja-core.sty               % ←マクロ本体を読み込み
+\input luatexja.sty               % ←マクロ本体を読み込み
 \jfont\tenipam={file:ipam.ttf:jfm=ujis} at 13.5\jQ 
 \tenipam\parindent=1\zw 
 
@@ -331,7 +352,7 @@ Lua\TeX-jaで用いる和文用のメトリック情報は,次のようなLua
 見本として,|jfm-ujis.lua|を入れてある.
 
 \begintt
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko', zw = 1.0, zh = 1.0,
    [0] = {
       align = 'left', left = 0.0, down = 0.0,
@@ -358,7 +379,7 @@ ltj.define_jfm {
 }
 \endtt
 
-全体は,「関数|ltj.define_jfm|にテーブルを引数として与える」という構造になっている.
+全体は,「関数|luatexja.jfont.define_jfm|にテーブルを引数として与える」という構造になっている.
 以下に,テーブルの中身を述べる.
 \item |dir|: 組方向を指定する.将来的にはいずれ縦組(|'tate'|)を実装したいが,
 現時点では横組(|'yoko'|)のみの対応.
@@ -493,7 +514,7 @@ $p$は「現在の和文フォント」の番号もattribute |\ltj@curjfnt|と
 
 \item {\bf 和文処理グルーの挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
 
-動作については,{\tt jfmglue.pdf}(未完)を参照.
\8b\95ä½\9cã\81®è©³ç´°ã\81«ã\81¤ã\81\84ã\81¦ã\81¯ï¼\8c{\tt jfmglue.pdf}ï¼\88æ\9cªå®\8cï¼\89ã\82\92å\8f\82ç\85§ï¼\8e
 
 \item {\bf ベースライン補正: |pre_linebreak_filter|, |hpack_filter| callbacks}
 
index f3eb63b..185e817 100644 (file)
@@ -1,4 +1,4 @@
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko',
    zw = 1.0, zh = 1.0,
 
index 6b4324e..6c5ea0d 100644 (file)
@@ -1,4 +1,4 @@
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko',
    zw = 1.0, zh = 1.0,
 
index c2c2468..dff6d99 100644 (file)
@@ -2,6 +2,7 @@ local ltjb = luatexja.base
 local ltjc = luatexja.charrange
 local ltjs = luatexja.stack
 local ltjj = luatexja.jfmglue
+local ltjf = luatexja.jfont
 
 local node_type = node.type
 local node_new = node.new
@@ -28,16 +29,8 @@ 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']
 
-local lang_ja_token = token.create('ltj@japanese')
-local lang_ja = lang_ja_token[2]
-
--- 
-local ljfm_find_char_class = ltj.int_find_char_class
-
-
 local ITALIC = 1
 local PACKED = 2
 local KINSOKU = 3
@@ -46,6 +39,7 @@ local LINE_END = 5
 local KANJI_SKIP = 6
 local XKANJI_SKIP = 7
 local PROCESSED = 8
+local IC_PROCESSED = 9
 local BOXBDD = 15
 
 ------------------------------------------------------------------------
@@ -189,73 +183,6 @@ end
 
 
 ------------------------------------------------------------------------
--- MAIN PROCESS STEP 1: replace fonts (prefix: main1)
-------------------------------------------------------------------------
-ltj.box_stack_level = 0
--- This is used in Step 2 (JFM glue/kern) and Step 3 (\[x]kanjiskip).
-
-local function main1_suppress_hyphenate_ja(head)
-   for p in node.traverse_id(id_glyph, head) do
-      if ltjc.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
-   lang.hyphenate(head)
-   return head
-end
-
--- mode: true iff this function is called from hpack_filter
-local function main1_set_box_stack_level(head, mode)
-   local box_set = false
-   local p = head
-   local cl = tex.currentgrouplevel + 1
-   while p do
-      if p.id==id_whatsit and p.subtype==sid_user and p.user_id==30112 then
-        local g = p
-        if mode and g.value==cl then box_set = true end
-        head, p = node.remove(head, g)
-      else p = node_next(p)
-      end
-   end
-   if box_set then 
-      ltj.box_stack_level = tex.getcount('ltj@@stack') + 1 
-   else 
-      ltj.box_stack_level = tex.getcount('ltj@@stack') 
-   end
-   if not head then -- prevent that the list is null
-      head = node_new(id_kern); head.kern = 0; head.subtype = 1
-   end
-   return head
-end
-
--- CALLBACKS
-luatexbase.add_to_callback('hpack_filter', 
-   function (head)
-     return main1_set_box_stack_level(head, true)
-   end,'ltj.hpack_filter_pre',1)
-luatexbase.add_to_callback('pre_linebreak_filter', 
-  function (head)
-     return main1_set_box_stack_level(head, false)
-  end,'ltj.pre_linebreak_filter_pre',1)
-luatexbase.add_to_callback('hyphenate', 
- function (head,tail)
-    return main1_suppress_hyphenate_ja(head)
- end,'ltj.hyphenate')
-
-
-------------------------------------------------------------------------
 -- MAIN PROCESS STEP 4: width of japanese chars (prefix: main4)
 ------------------------------------------------------------------------
 
@@ -281,8 +208,8 @@ local function main4_set_ja_width(head, dir)
       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]
+           met_tb = ltjf.font_metric_table[p.font]
+           t = ltjf.metrics[met_tb.jfm]
            s = t.char_type[has_attr(p,attr_jchar_class)]
            if s.width ~= 'prop' and
               not(s.left==0.0 and s.down==0.0 and s.align=='left' 
@@ -417,8 +344,10 @@ function debug_show_node_X(p,print_fn)
       s = base .. ' ' .. print_scaled(p.kern) .. 'pt'
       if p.subtype==2 then
         s = s .. ' (for accent)'
-      elseif has_attr(p, attr_icflag)==ITALIC then
+      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
@@ -447,11 +376,16 @@ end
 
 
 -- callbacks
+
 luatexbase.add_to_callback('pre_linebreak_filter', 
    function (head,groupcode)
       return main_process(head, true, tex.textdir)
-   end,'ltj.pre_linebreak_filter',2)
+   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, dir)
      return main_process(head, false, dir)
-  end,'ltj.hpack_filter',2)
+  end,'ltj.hpack_filter',
+   luatexbase.priority_in_callback('hpack_filter',
+                                  'luaotfload.hpack_filter') + 1)
index dbce5de..a59e56d 100644 (file)
     dofile(path)
   end
   require('lualibs')
-  ltj.loadlua('luatexja-rmlgbm.lua') 
-    % For Ryumin-Light and GothicBBB-Medium.
+  
+
     }
+\RequireLuaModule{luatexja.rmlgbm} % For Ryumin-Light and GothicBBB-Medium.
 \RequireLuaModule{luatexja.charrange}
-\directlua{
-  ltj.loadlua('luatexja-jfont.lua')}
+\RequireLuaModule{luatexja.jfont}
 \RequireLuaModule{luatexja.stack}
+\RequireLuaModule{luatexja.pretreat}
 \RequireLuaModule{luatexja.inputbuf}
 \RequireLuaModule{luatexja.jfmglue}
 
 \directlua{
   ltj.loadlua('luatexja-core.lua')
-  %ltj.loadlua('luatexja-jfmglue.lua')
-  %ltj.loadlua('luatexja-xkanji.lua')
 }
 
 
 
 %%%%%%%% Redefine \/
 %\let\ltj@ic=\/ \protected\def\/{{\ltj@icflag=1\ltj@ic}}
-\protected\def\/{\directlua{ltj.ext_append_italic()}}
+\protected\def\/{\directlua{luatexja.jfont.append_italic()}}
 
 %%%%%%%% \jfont\CS={...:...;jfm=metric;...}, \globaljfont
-\protected\def\jfont{\afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(false)}}
+\protected\def\jfont{\afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(false)}}
 \protected\def\globaljfont{%
-  \afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(true)}}
-\def\ltj@@jfont{\directlua{ltj.ext_jfontdefY()}}
+  \afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(true)}}
+\def\ltj@@jfont{\directlua{luatexja.jfont.jfontdefY()}}
 
 %%%%%%%% \inhibitglue
 \protected\def\inhibitglue{\directlua{luatexja.jfmglue.create_inhibitglue_node()}}
diff --git a/src/luatexja-jfmglue.lua b/src/luatexja-jfmglue.lua
deleted file mode 100644 (file)
index 5a3b9d5..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-------------------------------------------------------------------------
--- MAIN PROCESS STEP 2: insert glue/kerns from JFM (prefix: none)
-------------------------------------------------------------------------
-
-local ltjs = luatexja.stack
-
-local node_type = node.type
-local node_new = node.new
-local node_remove = node.remove
-local node_prev = node.prev
-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 round = tex.round
-
-local id_penalty = node.id('penalty')
-local id_glyph = node.id('glyph')
-local id_glue_spec = node.id('glue_spec')
-local id_glue = node.id('glue')
-local id_kern = node.id('kern')
-local id_hlist = node.id('hlist')
-local id_whatsit = node.id('whatsit')
-local sid_user = node.subtype('user_defined')
-
-local TEMPORARY = 2
-local FROM_JFM = 3
-local KINSOKU = 4
-local LINE_END = 5
-
-
-local attr_jchar_class = luatexbase.attributes['ltj@charclass']
-local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
-local attr_icflag = luatexbase.attributes['ltj@icflag']
--- attr_icflag: 1: kern from \/, 2: 'lineend' kern from JFM
-
--- 
-local ljfm_find_char_class = ltj.int_find_char_class
-
--- arithmetic with penalty.
--- p += e
-local function add_penalty(p,e)
-   local i = p
-   if i>=10000 then
-      if e<=-10000 then i = 0 end
-   elseif i<=-10000 then
-      if e>=10000 then i = 0 end
-   else
-      i = i + e
-      if i>=10000 then i = 10000
-      elseif i<=-10000 then i = -10000 end
-   end
-   return i
-end
-
--- return true if and only if p is a Japanese character node
-local function is_japanese_glyph_node(p)
-   return (p.id==id_glyph) and (p.font==has_attr(p,attr_curjfnt))
-end
-
--- EXT: for \inhibitglue
-function ltj.ext_create_inhibitglue_node()
-   local g=node_new(id_whatsit, sid_user)
-   g.user_id=30111; g.type=100; g.value=1; node.write(g)
-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 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
-
-local function 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, ltj.font_metric_table[px.font].var }
-   else 
-      return nil
-   end
-end
-
-local function new_jfm_glue(size,mt,bc,ac)
--- mt: metric key, bc, ac: char classes
-   local g=nil
-   local z = ltj.metrics[mt].char_type[bc]
-   if z.glue and z.glue[ac] then
-      local h = node_new(id_glue_spec)
-      h.width   = round(size*z.glue[ac][1])
-      h.stretch = round(size*z.glue[ac][2])
-      h.shrink  = round(size*z.glue[ac][3])
-      h.stretch_order=0; h.shrink_order=0
-      g = node_new(id_glue)
-      g.subtype = 0; g.spec = h
-   elseif z.kern and z.kern[ac] then
-      g = node_new(id_kern)
-      g.subtype = 1; g.kern = round(size*z.kern[ac])
-   end
-   return g
-end
-
--- Insert jfm glue: main routine
--- local variables
-local p
-local q = nil  -- the previous node of p
-local q_post   -- the postbreakpenalty of q
-local ps, qs
-local widow_node -- 最後の「句読点扱いでない」和文文字
-local widow_bp -- 挿入位置 (a penalty)
-local last -- the sentinel 
-local chain = false -- is q a Japanese character?
-local ihb_flag = false -- is \inhibitglue specified?
-local head -- the head of current list
-local mode -- true iff insert_jfm_glue is called from pre_linebreak_filter
-
--- initialize (insert the sentinel, etc.)
-local function init_var()
-   p = head;  q = nil; widow_node = nil; widow_bp = nil
-   chain = false; ihb_flag = false; 
-   if mode then
-      while p and 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); local g = node_new('kern')
-      node_insert_after(head, last, g); last = g
-   end
-end
-
--- Insert JFM glue before the first node (which is a Japanese glyph node)
-local function ins_gk_head()
-   if is_japanese_glyph_node(p) then
-      ps = find_size_metric(p)
-      local g = new_jfm_glue(ps[1], ps[2],
-                            ljfm_find_char_class('boxbdd',ps[2]),
-                            has_attr(p,attr_jchar_class))
-      if g then
-        set_attr(g, attr_icflag, FROM_JFM)
-        head = node_insert_before(head, p, g)
-      end
-      q_post = ltjs.get_penalty_table('post', p.char, 0, ltj.box_stack_level); chain = true
-   elseif p.id==id_glyph then
-      q_post = ltjs.get_penalty_table('post', p.char, 0, ltj.box_stack_level)
-   end
-   qs = ps; q = p; p = node_next(p)
-end
-
--- The real insertion process is handled in this procedure.
-local function real_insert(g, w, pen, always_penalty_ins)
-   -- g: glur/kern from JFM
-   -- w: the width of kern that will be inserted between q and the end of a line
-   -- pen: penalty
-   -- always_penalty_ins: true iff we insert a penalty,
-   --   for the linebreak between q and p.
-   if w~=0 then
-      if not g then
-        g = node_new(id_kern); g.kern = -w; g.subtype = 1
-        set_attr(g, attr_icflag, TEMPORARY)
-        -- this g might be replaced by \[x]kanjiskip in step 3.
-      else 
-        set_attr(g, attr_icflag, FROM_JFM)
-        if g.id==id_kern then w=0
-        else g.spec.width = round(g.spec.width - w) 
-        end
-      end
-   end
-   if w~=0 then
-      local h = node_new(id_kern)
-      set_attr(h, attr_icflag, LINE_END)
-      h.kern = w; h.subtype = 0; node_insert_before(head, p, h)
-   elseif g then
-      set_attr(g, attr_icflag, FROM_JFM)
-      if g.id==id_kern  then
-        pen=0; always_penalty_ins = false
-      end
-   end
-   if w~=0  or pen~=0 or ((not g) and always_penalty_ins) then
-      local h = node_new(id_penalty)
-      h.penalty = pen; set_attr(h, attr_icflag, KINSOKU)
-      node_insert_before(head, p, h)
-   end
-   if g then
-      node_insert_before(head, p, g); 
-   end
-end
-
--- This is a variant of real_insert (the case which a kern is related)
-local function real_insert_kern(g)
-   if g then
-      if g.id==id_glue then
-        local h = node_new(id_penalty)
-        h.penalty = 10000; set_attr(h, attr_icflag, KINSOKU)
-        node_insert_before(head, p, h)
-      end
-      set_attr(g, attr_icflag, FROM_JFM)
-      node_insert_before(head, p, g)
-   end
-end
-
-ltj.ja_diffmet_rule = math.two_average
-
-local function calc_ja_ja_aux(gb,ga)
-   if not gb then 
-      return ga
-   else
-      if not ga then return gb end
-      local k = node.type(gb.id) .. node.type(ga.id)
-      if k == 'glueglue' then 
-        -- 両方とも glue.
-        gb.spec.width   = round(ltj.ja_diffmet_rule(gb.spec.width, ga.spec.width))
-        gb.spec.stretch = round(ltj.ja_diffmet_rule(gb.spec.stretch,ga.spec.shrink))
-        gb.spec.shrink  = -round(ltj.ja_diffmet_rule(-gb.spec.shrink, -ga.spec.shrink))
-        return gb
-      elseif k == 'kernkern' then
-        -- 両方とも kern.
-        gb.kern = round(ltj.ja_diffmet_rule(gb.kern, ga.kern))
-        return gb
-      elseif k == 'kernglue' then 
-        -- gb: kern, ga: glue
-        ga.spec.width   = round(ltj.ja_diffmet_rule(gb.kern,ga.spec.width))
-        ga.spec.stretch = round(ltj.ja_diffmet_rule(ga.spec.stretch, 0))
-        ga.spec.shrink  = -round(ltj.ja_diffmet_rule(-ga.spec.shrink, 0))
-        return ga
-      else
-        -- gb: glue, ga: kern
-        gb.spec.width   = round(ltj.ja_diffmet_rule(ga.kern, gb.spec.width))
-        gb.spec.stretch = round(ltj.ja_diffmet_rule(gb.spec.stretch, 0))
-        gb.spec.shrink  = -round(ltj.ja_diffmet_rule(-gb.spec.shrink, 0))
-        return gb
-      end
-   end
-end
-
--- Calc the glue between two Japanese characters
-local function calc_ja_ja_glue()
-   if ihb_flag then return nil
-   elseif table.are_equal(qs,ps) then
-      return new_jfm_glue(ps[1],ps[2],
-                         has_attr(q,attr_jchar_class),
-                         has_attr(p,attr_jchar_class))
-   else
-      local g = new_jfm_glue(qs[1],qs[2],
-                            has_attr(q,attr_jchar_class),
-                            ljfm_find_char_class('diffmet',qs[2]))
-      local h = new_jfm_glue(ps[1],ps[2],
-                            ljfm_find_char_class('diffmet',ps[2]),
-                            has_attr(p,attr_jchar_class))
-      return calc_ja_ja_aux(g,h)
-   end
-end
-
-local function ins_gk_any_JA()
-   ps = find_size_metric(p)
-   if chain then -- (q,p): JA-JA
-      local g = calc_ja_ja_glue()
-      local w = 0; local x = ljfm_find_char_class('lineend', qs[2])
-      if (not ihb_flag) and x~=0  then
-        local h = ltj.metrics[qs[2]].char_type[has_attr(q, attr_jchar_class)]
-        if h.kern and h.kern[x] then w = round(qs[1]*h.kern[x]) end
-      end
-      q_post = add_penalty(q_post, ltjs.get_penalty_table('pre', p.char, 0, ltj.box_stack_level))
-      real_insert(g, w, q_post, false)
-   elseif q.id==id_glyph then -- (q,p): AL-JA
-      local g = nil
-      if not ihb_flag then
-        g = new_jfm_glue(ps[1], ps[2],
-                         ljfm_find_char_class('jcharbdd',ps[2]),
-                         has_attr(p,attr_jchar_class))
-      end
-      q_post = add_penalty(q_post, ltjs.get_penalty_table('pre', p.char, 0, ltj.box_stack_level))
-      real_insert(g, 0, q_post, true)
-   elseif q.id==id_kern then -- (q,p): kern-JA
-      local g = nil
-      if not ihb_flag then
-        g = new_jfm_glue(ps[1], ps[2],
-                         ljfm_find_char_class('jcharbdd',ps[2]),
-                         has_attr(p,attr_jchar_class))
-      end
-      real_insert_kern(g)
-   else
-      local g = nil
-      if not ihb_flag then
-        g = new_jfm_glue(ps[1], ps[2],
-                         ljfm_find_char_class('jcharbdd',ps[2]),
-                         has_attr(p,attr_jchar_class))
-      end
-      real_insert(g, 0, q_post, true)
-   end
-   q, qs, q_post = p, ps, ltjs.get_penalty_table('post', p.char, 0, ltj.box_stack_level)
-   if ltjs.get_penalty_table('kcat', p.char, 0, ltj.box_stack_level)%2~=1 then
-      widow_node = p
-   end
-   p = node_next(p); chain = true
-end
-
-local function ins_gk_JA_any()
-   -- the case (q,p): JA-JA is treated in ins_gk_any_JA()
-   local g = nil
-   if not ihb_flag then
-      g = new_jfm_glue(qs[1], qs[2],
-                      has_attr(q,attr_jchar_class),
-                      ljfm_find_char_class('jcharbdd',qs[2]))
-   end
-   if p.id==id_glyph then -- (q,p): JA-AL
-      local w = 0; local x = ljfm_find_char_class('lineend', qs[2])
-      if (not ihb_flag) and x~=0  then
-        local h = ltj.metrics[qs[2]].char_type[has_attr(q,attr_jchar_class)]
-        if h.kern and h.kern[x] then w = round(qs[1]*h.kern[x]) end
-      end
-      q_post = add_penalty(q_post, ltjs.get_penalty_table('pre', p.char, 0, ltj.box_stack_level))
-      real_insert(g, w, q_post, true)
-   elseif p.id==id_kern then -- (q,p): JA-kern
-      real_insert_kern(g)
-   else
-      local w = 0; local x = ljfm_find_char_class('lineend', qs[2])
-      if (not ihb_flag) and x~=0  then
-        local h = ltj.metrics[qs[2]].char_type[has_attr(q,attr_jchar_class)]
-        if h.kern and h.kern[x] then w = round(qs[1]*h.kern[x]) end
-      end
-      if p.id~=penalty then
-        real_insert(g, w, q_post, true)
-      else
-        real_insert(g, w, q_post, false)
-      end
-   end
-   chain = false; q, qs, q_post = p, nil, 0; p = node_next(p)
-end
-
--- Insert JFM glue after thr last node
-local function ins_gk_tail()
-   local g
-   if is_japanese_glyph_node(p) then
-      if mode then
-        local w = 0; local x = ljfm_find_char_class('lineend', qs[2])
-        if (not ihb_flag) and x~=0  then
-           local h = ltj.metrics[qs[2]].char_type[has_attr(q,attr_jchar_class)]
-           if h.kern and h.kern[x] then w = round(qs[1]*h.kern[x]) end
-        end
-        if w~=0 then
-           g = node_new(id_kern); g.subtype = 0; g.kern = w
-           set_attr(g, attr_icflag, LINE_END)
-           node_insert_before(head, last, g)
-        end
-      end
-   end
-end
-
-local function add_widow_penalty()
-   -- widoe_node: must be 
-   if not widow_node then return end
-   local a = node_prev(widow_node)
-   local i = has_attr(a, attr_icflag) or 0
-   local wp = ltjs.get_penalty_table('jwp', 0, 0, ltj.box_stack_level)
-   if i==4 then
-      a.penalty=add_penalty(a.penalty, wp)
-   elseif i>=2 then
-      local b = node_prev(a)
-      if i==4 then
-        b.penalty=add_penalty(b.penalty, wp)
-      else
-        local g = node_new(id_penalty)
-        g.penalty = wp; head = node_insert_before(head,a,g)
-      end
-   else
-      local g = node_new(id_penalty)
-      g.penalty = wp; head = node_insert_before(head,widow_node,g)
-   end
-end
-
--- Finishing: add \jcharwidowpenalty or remove the sentinel
-local function finishing()
-   if mode then
-      -- Insert \jcharwidowpenalty
-      add_widow_penalty()
-   else
-      head = node_remove(head, last)
-   end
-end
-
--- The interface
-function ltj.int_insert_jfm_glue(ahead, amode)
-   if not ahead then return ahead end
-   head = ahead; mode = amode; init_var(); 
-   while p~=last and p.id==id_whatsit and p.subtype==sid_user and p.user_id==30111 do
-      local g = p; p = node_next(p); ihb_flag = true; head, p = node.remove(head, g)
-   end
-   if p~=last then ins_gk_head() else finishing() return head end
-   while p~=last do
-      if p.id==id_whatsit and p.subtype==sid_user and p.user_id==30111 then
-        local g = p; p = node_next(p)
-        ihb_flag = true; head, p = node.remove(head, g)
-      else
-        if is_japanese_glyph_node(p) then -- p: JAchar
-           ins_gk_any_JA()
-        elseif chain then -- q: JAchar
-           ins_gk_JA_any()
-        else 
-           q, qs, q_post = p, nil, 0; p = node_next(p)
-        end
-        ihb_flag = false
-      end
-   end
-   ins_gk_tail(); finishing(); return head
-end
-
diff --git a/src/luatexja-xkanji.lua b/src/luatexja-xkanji.lua
deleted file mode 100644 (file)
index 2335966..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-------------------------------------------------------------------------
--- MAIN PROCESS STEP 3: insert \xkanjiskip (prefix: none)
-------------------------------------------------------------------------
-local ltjs = luatexja.stack
-
-local node_type = node.type
-local node_new = node.new
-local node_prev = node.prev
-local node_next = node.next
-local node_copy = node.copy
-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 node_hpack = node.hpack
-local round = tex.round
-
-local id_penalty = node.id('penalty')
-local id_glyph = node.id('glyph')
-local id_glue = node.id('glue')
-local id_glue_spec = node.id('glue_spec')
-local id_kern = node.id('kern')
-local id_hlist = node.id('hlist')
-local id_ins = node.id('ins')
-local id_mark = node.id('mark')
-local id_adjust = node.id('adjust')
-local id_math = node.id('math')
-local id_whatsit = node.id('whatsit')
-
-local attr_icflag = luatexbase.attributes['ltj@icflag']
-local attr_autospc = luatexbase.attributes['ltj@autospc']
-local attr_autoxspc = luatexbase.attributes['ltj@autoxspc']
-local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
-local max_dimen = 1073741823
-
-local ITALIC = 1
-local TEMPORARY = 2
-local FROM_JFM = 3
-local KINSOKU = 4
-local LINE_END = 5
-local KANJI_SKIP = 6
-local XKANJI_SKIP = 7
-local PACKED = 8
-
-local kanji_skip
-local xkanji_skip
-
--- (glyph_node nr) ... (node nq) <GLUE> ,,, (node np)
-local np, nq, nrc, nrf
-local np_spc, nr_spc
-local no_skip = 0 
-local after_schar = 1
-local after_wchar = 2 -- nr is a Japanese glyph_node
-local insert_skip = no_skip
-local head
-
-local function is_japanese_glyph_node(p)
-   return p and (p.id==id_glyph) 
-   and (p.font==has_attr(p,attr_curjfnt))
-end
-
-local function get_zero_glue()
-   local g = node_new(id_glue_spec)
-   g.width = 0; g.stretch_order = 0; g.stretch = 0
-   g.shrink_order = 0; g.shrink = 0
-   return g
-end
-
-local function skip_table_to_spec(n)
-   local g = node_new(id_glue_spec)
-   local st = ltjs.get_skip_table(n, ltj.box_stack_level)
-   g.width = st.width; g.stretch = st.stretch; g.shrink = st.shrink
-   g.stretch_order = st.stretch_order; g.shrink_order = st.shrink_order
-   return g
-end
-
-local function add_glue_spec(g,h)
-   -- g := g + h
-   g.width = g.width + h.width
-   if g.stretch_order<h.stretch_order then
-      g.stretch_order = h.stretch_order
-      g.stretch = h.stretch
-   elseif g.stretch_order==h.stretch_order then
-      g.stretch = g.stretch + h.stretch
-   end
-   if g.shrink_order<h.shrink_order then
-      g.shrink_order = h.shrink_order
-      g.shrink = h.shrink
-   elseif g.shrink_order==h.shrink_order then
-      g.shrink = g.shrink + h.shrink
-   end
-end
-
--- lowest part of \xkanjiskip 
-local function get_xkanji_skip_from_jfm(pf)
-   if pf then
-      local px = { ltj.font_metric_table[pf].size, 
-                  ltj.font_metric_table[pf].jfm }
-      local i = ltj.metrics[px[2]].xkanjiskip
-      if i then
-        return { round(i[1]*px[1]), round(i[2]*px[1]), round(i[3]*px[1]) }
-      else return nil
-      end
-   else return nil
-   end
-end
-
-local function insert_xkanjiskip_node(q, f, p)
-   if nr_spc[2] or np_spc[2] then
-      local g = node_new(id_glue); g.subtype = 0
-      if xkanji_skip.width==max_dimen then -- use xkanjiskip from JFM
-        local gx = node_new(id_glue_spec)
-        gx.stretch_order = 0; gx.shrink_order = 0
-        local ak = get_xkanji_skip_from_jfm(f)
-        if ak then
-           gx.width = ak[1]; gx.stretch = ak[2]; gx.shrink = ak[3]
-        else gx = get_zero_glue() -- fallback
-        end
-        g.spec = gx
-      else g.spec=node_copy(xkanji_skip)
-      end
-      local h = node_prev(p)
-      if h  and has_attr(h, attr_icflag)==TEMPORARY then
-        if h.id==id_kern then
-           g.spec.width = g.spec.width + h.kern
-           set_attr(g,attr_icflag,XKANJI_SKIP)
-           node_insert_after(head, q, g)
-           head = node.remove(head, h)
-           node.free(h)
-        else
-           add_glue_spec(h.spec, g.spec)
-           node.free(g.spec); node.free(g)
-        end
-      else
-        set_attr(g,attr_icflag,XKANJI_SKIP)
-        node_insert_after(head, q, g)
-      end
-   end
-end
-
-local function insert_ascii_kanji_xkskip(q, p)
-   if ltjs.get_penalty_table('xsp', p.char, 3, ltj.box_stack_level)<=1 then return end
-   insert_xkanjiskip_node(q, p.font, p)
-end
-
-local function insert_kanji_ascii_xkskip(q, p)
-   local g = true
-   local c = p.char
-   while p.components and p.subtype 
-      and math.floor(p.subtype/2)%2==1 do
-      p = p.components; c = p.char
-   end
-   if ltjs.get_penalty_table('xsp', c, 3, ltj.box_stack_level)%2 == 1 then
-      if ltjs.get_penalty_table('xsp', nrc, 3, ltj.box_stack_level)%2 == 0 then g = false end
-   else g = false
-   end
-   if g then insert_xkanjiskip_node(q, nrf, p) end
-end
-
-local function set_insert_skip_after_achar(p)
-   local c = p.char
-   while p.components and p.subtype 
-      and math.floor(p.subtype/2)%2 == 1 do
-      p=node.tail(p.components); c = p.char
-   end
-  if ltjs.get_penalty_table('xsp', c, 3, ltj.box_stack_level)>=2 then
-     insert_skip = after_schar
-  else
-     insert_skip = no_skip
-  end
-end
-
--- lowest part of \kanjiskip 
-local function get_kanji_skip_from_jfm(pf)
-   if pf then
-      local px = { ltj.font_metric_table[pf].size, 
-                  ltj.font_metric_table[pf].jfm }
-      local i = ltj.metrics[px[2]].kanjiskip
-      if i then
-        return { round(i[1]*px[1]), round(i[2]*px[1]), round(i[3]*px[1]) }
-      else return nil
-      end
-   else return nil
-   end
-end
-
-local function insert_kanji_skip(ope, p)
-   local g = node_new(id_glue); g.subtype=0
-   if nr_spc[1] or np_spc[1] then
-      if kanji_skip.width==max_dimen then -- use kanjiskip from JFM
-        local gx = node_new(id_glue_spec);
-        gx.stretch_order = 0; gx.shrink_order = 0
-        local bk = get_kanji_skip_from_jfm(nrf)
-        local ak = get_kanji_skip_from_jfm(p.font)
-        if bk then
-           if ak then
-              gx.width = round(ltj.ja_diffmet_rule(bk[1], ak[1]))
-              gx.stretch = round(ltj.ja_diffmet_rule(bk[2], ak[2]))
-              gx.shrink = -round(ltj.ja_diffmet_rule(-bk[3], -ak[3]))
-           else
-              gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
-           end
-        elseif ak then
-           gx.width = ak[1]; gx.stretch = ak[2]; gx.shrink = ak[3]
-        else gx = get_zero_glue() -- fallback
-        end
-        g.spec = gx
-      else g.spec=node_copy(kanji_skip)
-      end
-   else g.spec = get_zero_glue()
-   end
-   local h = node_prev(p)
-   if h  and has_attr(h, attr_icflag)==TEMPORARY then
-      if h.id==id_kern then
-        g.spec.width = g.spec.width + h.kern
-        head = node.remove(head, h)
-        node.free(h)
-        set_attr(g,attr_icflag,KANJI_SKIP)
-        ope(head, p, g)
-      else
-        add_glue_spec(h.spec, g.spec)
-        node.free(g.spec); node.free(g)
-      end
-   else
-      set_attr(g,attr_icflag,KANJI_SKIP)
-      ope(head, p, g)
-   end
-end
-
--- When p is a glyph_node ...
-local function insks_around_char()
-   if is_japanese_glyph_node(np) then
-      if insert_skip==after_wchar then
-        insert_kanji_skip(node_insert_before, np)
-      elseif insert_skip==after_schar then
-        insert_ascii_kanji_xkskip(nq, np)
-      end
-      insert_skip=after_wchar
-      nrc = np.char; nrf = np.font; nr_spc = np_spc
-   else
-      if insert_skip==after_wchar then
-        insert_kanji_ascii_xkskip(nq, np)
-      end
-      set_insert_skip_after_achar(np); nr_spc = np_spc
-   end
-   nq = np
-end
-
--- Return first and last glyph nodes in a hbox
-local first_char = nil
-local last_char = nil
-local find_first_char = nil
-local function check_box(box_ptr)
-   local p = box_ptr; local found_visible_node = false
-   if not p then 
-      find_first_char = false; first_char = nil; last_char = nil
-      return true
-   end
-   while p do
-      if p.id==id_glyph then
-        repeat 
-           if find_first_char 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
-        until p.id~=id_glyph
-      end
-      if p.id==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
-              end
-              last_char = q; found_visible_node = true
-           end
-        else
-           if p.shift==0 then
-              if check_box(p.head) then found_visible_node = true end
-           else if find_first_char then 
-                 find_first_char = false
-              else 
-                 last_char = nil
-              end
-           end
-        end
-      elseif p.id==id_ins    or p.id==id_mark
-          or p.id==id_adjust or p.id==id_whatsit
-          or p.id==id_penalty then
-        p=p
-      else
-        found_visible_node = true
-        if find_first_char then 
-           find_first_char = false
-        else 
-           last_char = nil
-        end
-      end
-      p = node_next(p)
-   end
-   return found_visible_node
-end 
-
--- When np is a hlist_node ...
-local function insks_around_hbox()
-   if np.shift==0 then
-      find_first_char = true; first_char = nil; last_char = nil
-      if check_box(np.head) then
-        -- first char
-        if is_japanese_glyph_node(first_char) then
-           nrc = first_char.char; nrf = first_char.font
-           if insert_skip==after_schar then 
-              insert_ascii_kanji_xkskip(nq, first_char)
-           elseif insert_skip==after_wchar then
-              np_spc = { has_attr(first_char, attr_autospc)==1, 
-                         has_attr(first_char, attr_autoxspc)==1 }
-              insert_kanji_skip(node_insert_before, np)
-           end
-           insert_skip = after_wchar
-        elseif first_char then
-           if insert_skip==after_wchar then
-              insert_kanji_ascii_xkskip(nq, first_char)
-           end
-           set_insert_skip_after_achar(first_char)
-        end
-        -- last char
-        if is_japanese_glyph_node(last_char) then
-           insert_skip = after_wchar
-           nrc = last_char.char; nrf = last_char.font
-           nr_spc = { has_attr(last_char, attr_autospc)==1, 
-                      has_attr(last_char, attr_autoxspc)==1 }
-           if is_japanese_glyph_node(node_next(np)) then
-              insert_kanji_skip(node_insert_after, np)
-           end
-        elseif last_char then
-           set_insert_skip_after_achar(last_char)
-           nr_spc = { has_attr(last_char, attr_autospc)==1, 
-                      has_attr(last_char, attr_autoxspc)==1 }
-        else insert_skip = no_skip
-        end
-      else insert_skip = no_skip
-      end
-   else insert_skip = no_skip
-   end
-   nq = np
-end
-
--- When np is a penalty ...
-local function insks_around_penalty()
-   nq = np
-end
-
--- When np is a kern ...
--- 
-local function insks_around_kern()
-   if np.subtype==1 then -- \kern or \/
-      local i = has_attr(np, attr_icflag)
-      if not i or i==FROM_JFM then -- \kern
-        insert_skip = no_skip
-      elseif i==ITALIC or i==LINE_END or i==TEMPORARY then
-        nq = np
-      end
-   elseif np.subtype==2 then 
-      -- (np = kern from \accent) .. (accent char) .. (kern from \accent) .. (glyph)
-      np = node_next(node_next(np))
-   else  -- kern from TFM
-      nq = np
-   end
-end
-
--- When np is a math_node ...
-local function insks_around_math()
-   local g = { char = -1 }
-   if (np.subtype==0) and (insert_skip==after_wchar) then
-      insert_kanji_ascii_xkskip(nq, g)
-      insert_skip = no_skip
-   else
-      nq = np; set_insert_skip_after_achar(g); nr_spc = np_spc
-   end
-end
-
-function ltj.int_insert_kanji_skip(ahead)
-   kanji_skip=skip_table_to_spec('kanjiskip')
-   xkanji_skip=skip_table_to_spec('xkanjiskip')
-   head = ahead
-   np = head; nq = nil; insert_skip = no_skip
-   while np do
-      np_spc = { (has_attr(np, attr_autospc)==1), 
-                (has_attr(np, attr_autoxspc)==1) }
-      if np.id==id_glyph then
-        repeat 
-           np_spc = { has_attr(np, attr_autospc)==1, 
-                      has_attr(np, attr_autoxspc)==1 }
-           insks_around_char(); np=node_next(np)
-        until (not np) or np.id~=id_glyph
-      else
-        if np.id==id_hlist then
-           insks_around_hbox()
-        elseif np.id==id_penalty then
-           insks_around_penalty()
-        elseif np.id==id_kern then
-           insks_around_kern()
-        elseif np.id==id_math then
-           insks_around_math()
-        elseif np.id==id_ins    or np.id==id_mark
-             or np.id==id_adjust or np.id==id_whatsit then
-           -- do nothing
-           np = np
-        else
-           -- rule, disc, glue, margin_kern
-           insert_skip = no_skip
-        end
-        np = node_next(np)
-      end
-   end
-   return head
-end
\ No newline at end of file
index be7bbb6..d69d74f 100644 (file)
@@ -10,7 +10,7 @@ luatexbase.provides_module({
 module('luatexja.charrange', package.seeall)
 local err, warn, info, log = luatexbase.errwarinf(_NAME)
 
-local ltjb = luatexja.base
+require('luatexja.base');      local ltjb = luatexja.base
 
 local floor = math.floor
 local has_attr = node.has_attribute
index b6916d4..7b4e3fa 100644 (file)
@@ -10,8 +10,8 @@ luatexbase.provides_module({
 module('luatexja.compat', package.seeall)
 local err, warn, info, log = luatexbase.errwarinf(_NAME)
 
-local ltjb = luatexja.base
-local ltjs = luatexja.stack
+require('luatexja.base');      local ltjb = luatexja.base
+require('luatexja.stack');     local ltjs = luatexja.stack
 
 -- \kuten, \jis, \euc, \sjis, \ucs, \kansuji
 function to_kansuji(num)
index 09f35dd..9ba3d82 100644 (file)
@@ -10,7 +10,7 @@ luatexbase.provides_module({
 module('luatexja.inputbuf', package.seeall)
 local err, warn, info, log = luatexbase.errwarinf(_NAME)
 
-local ltjc = luatexja.charrange
+require('luatexja.charrange'); local ltjc = luatexja.charrange
 
 local node_new = node.new
 local id_glyph = node.id('glyph')
index 5e5c256..423e683 100644 (file)
@@ -3,15 +3,17 @@
 --
 luatexbase.provides_module({
   name = 'luatexja.jfmglue',
-  date = '2011/06/09',
-  version = '0.1',
+  date = '2011/06/27',
+  version = '0.2',
   description = 'Insertion process of JFM glues and kanjiskip',
 })
 module('luatexja.jfmglue', package.seeall)
 local err, warn, info, log = luatexbase.errwarinf(_NAME)
 
-local ltjb = luatexja.base
-local ltjs = luatexja.stack
+require('luatexja.base');     local ltjb = luatexja.base
+require('luatexja.stack');    local ltjs = luatexja.stack
+require('luatexja.jfont');    local ltjf = luatexja.jfont
+require('luatexja.pretreat'); local ltjp = luatexja.pretreat
 
 local node_type = node.type
 local node_new = node.new
@@ -55,6 +57,7 @@ local LINE_END = 5
 local KANJI_SKIP = 6
 local XKANJI_SKIP = 7
 local PROCESSED = 8
+local IC_PROCESSED = 9
 local BOXBDD = 15
 
 local kanji_skip
@@ -84,7 +87,7 @@ end
 
 local function skip_table_to_spec(n)
    local g = node_new(id_glue_spec)
-   local st = ltjs.get_skip_table(n, ltj.box_stack_level)
+   local st = ltjs.get_skip_table(n, ltjp.box_stack_level)
    g.width = st.width; g.stretch = st.stretch; g.shrink = st.shrink
    g.stretch_order = st.stretch_order; g.shrink_order = st.shrink_order
    return g
@@ -159,7 +162,7 @@ local function check_box(box_ptr, box_end)
       if pid==id_kern then
         if p.subtype==2 then
            p = node_next(node_next(node_next(p))); pid = p.id
-        elseif has_attr(p, attr_icflag)==ITALIC then
+        elseif has_attr(p, attr_icflag)==IC_PROCESSED then
            p = node_next(p); pid = p.id
         end
       end
@@ -207,16 +210,21 @@ end
 
 -------------------- Np の計算と情報取得
 -- calc next Np
+local function set_attr_icflag_processed(p)
+   local a = has_attr(p, attr_icflag) or 0
+   if a<=1 then set_attr(p, attr_icflag, PROCESSED) end
+end
+
 local function check_next_ickern()
    if lp.id == id_kern and has_attr(lp, attr_icflag)==ITALIC then
-      Np.last = lp; lp = node_next(lp)
+      set_attr(lp, attr_icflag, IC_PROCESSED); Np.last = lp; lp = node_next(lp)
    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
+   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
    end
    check_next_ickern()
@@ -229,45 +237,47 @@ local function calc_np()
    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 
+      elseif lpa>=PACKED 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)
+        set_attr_icflag_processed(lp); lp = node_next(lp)
       elseif lpi == id_penalty then
-        table.insert(Bp, lp); Bp[0] = Bp[0] + 1; lp = node_next(lp)
+        table.insert(Bp, lp); Bp[0] = Bp[0] + 1
+        set_attr_icflag_processed(lp); lp = node_next(lp)
       elseif lpi == id_whatsit then
         if lp.subtype==sid_user and lp.user_id==30111 then
            local lq = node_next(lp)
            head = node_remove(head, lp); lp = lq; ihb_flag = true
         else
-           lp = node_next(lp)
+           set_attr_icflag_processed(lp); lp = node_next(lp)
         end
       else -- a `cluster' is found
         Np.first = lp
         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
+           Np.nuc = lp; set_attr_icflag_processed(lp)
+           lp = node_next(lp); check_next_ickern(); return
         elseif lpi == id_hlist then -- hlist
-           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
+           Np.last = lp; Np.nuc = lp; set_attr_icflag_processed(lp)
            if lp.shift~=0 then Np.id = id_box_like
            else Np.id = lpi end
            lp = node_next(lp); return
         elseif lpi == id_vlist or lpi == id_rule then -- id_box_like
            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
+           Np.nuc = lp
+           while lp.id~=id_math do 
+              set_attr_icflag_processed(lp); 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
+           set_attr_icflag_processed(lp); lp = node_next(lp)
+           set_attr_icflag_processed(lp); lp = node_next(lp)
+           set_attr_icflag_processed(lp); lp = node_next(lp)
+           set_attr_icflag_processed(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
@@ -276,7 +286,7 @@ local function calc_np()
         end
       end
    end
-   Np.last = lp; Np.id = lpi; lp = node_next(lp)
+   set_attr_icflag_processed(lp); Np.last = lp; Np.id = lpi; lp = node_next(lp)
 end
 
 -- extract informations from Np
@@ -288,12 +298,12 @@ end
 local function set_np_xspc_jachar(c,x)
    Np.class = has_attr(x, attr_jchar_class)
    Np.char = c
-   local z = ltj.font_metric_table[x.font]
+   local z = ltjf.font_metric_table[x.font]
    Np.size= z.size
-   Np.met = ltj.metrics[z.jfm]
+   Np.met = ltjf.metrics[z.jfm]
    Np.var = z.var
-   Np.pre = ltjs.get_penalty_table('pre', c, 0, ltj.box_stack_level)
-   Np.post = ltjs.get_penalty_table('post', c, 0, ltj.box_stack_level)
+   Np.pre = ltjs.get_penalty_table('pre', c, 0, ltjp.box_stack_level)
+   Np.post = ltjs.get_penalty_table('post', c, 0, ltjp.box_stack_level)
    z = find_char_class('lineend', Np.met)
    local y = Np.met.char_type[Np.class]
    if y.kern and y.kern[z] then 
@@ -301,7 +311,7 @@ local function set_np_xspc_jachar(c,x)
    else 
       Np.lend = 0 
    end
-   y = ltjs.get_penalty_table('xsp', c, 3, ltj.box_stack_level)
+   y = ltjs.get_penalty_table('xsp', c, 3, ltjp.box_stack_level)
    Np.xspc_before = (y>=2)
    Np.xspc_after  = (y%2==1)
    Np.auto_kspc = (has_attr(x, attr_autospc)==1)
@@ -322,13 +332,13 @@ local function set_np_xspc_alchar(c,x, lig)
            x = node_tail(x.components); c = x.char
         end
       end
-      Np.pre = ltjs.get_penalty_table('pre', c, 0, ltj.box_stack_level)
-      Np.post = ltjs.get_penalty_table('post', c, 0, ltj.box_stack_level)
+      Np.pre = ltjs.get_penalty_table('pre', c, 0, ltjp.box_stack_level)
+      Np.post = ltjs.get_penalty_table('post', c, 0, ltjp.box_stack_level)
    else
       Np.pre = 0; Np.post = 0
    end
    Np.met = nil
-   local y = ltjs.get_penalty_table('xsp', c, 3, ltj.box_stack_level)
+   local y = ltjs.get_penalty_table('xsp', c, 3, ltjp.box_stack_level)
    Np.xspc_before = (y%2==1)
    Np.xspc_after  = (y>=2)
    Np.auto_xspc = (has_attr(x, attr_autoxspc)==1)
@@ -655,7 +665,7 @@ local function handle_np_jachar()
       real_insert(0, g)
    end
    -- \jcharwidowpenalty 挿入予定箇所更新
-   if ltjs.get_penalty_table('kcat', Np.char, 0, ltj.box_stack_level)%2~=1 then
+   if ltjs.get_penalty_table('kcat', Np.char, 0, ltjp.box_stack_level)%2~=1 then
       widow_Np = Np; widow_Bp = Bp
    end
 end
@@ -720,7 +730,7 @@ local function handle_list_tail()
       Bp = widow_Bp; Np = widow_Np
       if Np then
         handle_penalty_normal(0,
-                              ltjs.get_penalty_table('jwp', 0, 0, ltj.box_stack_level))
+                              ltjs.get_penalty_table('jwp', 0, 0, ltjp.box_stack_level))
       end
    else
       -- the current list is the contents of a hbox
@@ -805,10 +815,6 @@ function main(ahead, amode)
    end
    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
similarity index 78%
rename from src/luatexja-jfont.lua
rename to src/luatexja/jfont.lua
index d081e17..61a3af6 100644 (file)
@@ -1,5 +1,16 @@
-local ltjb = luatexja.base
-local ltjc = luatexja.charrange
+--
+-- luatexja/jfont.lua
+--
+luatexbase.provides_module({
+  name = 'luatexja.jfont',
+  date = '2011/06/27',
+  version = '0.1',
+  description = 'Loader for Japanese fonts',
+})
+module('luatexja.jfont', package.seeall)
+
+require('luatexja.base');      local ltjb = luatexja.base
+require('luatexja.charrange'); local ltjc = luatexja.charrange
 
 local node_new = node.new
 local has_attr = node.has_attribute
@@ -12,16 +23,16 @@ local id_kern = node.id('kern')
 
 local ITALIC = 1
 ------------------------------------------------------------------------
--- LOADING JFM (prefix: ljfm)
+-- LOADING JFM
 ------------------------------------------------------------------------
 
-ltj.metrics={} -- this table stores all metric informations
-ltj.font_metric_table={} -- [font number] -> jfm_name, jfm_var, size
+metrics={} -- this table stores all metric informations
+font_metric_table={} -- [font number] -> jfm_name, jfm_var, size
 
 local jfm_file_name, jfm_var
 local defjfm_res
 
-function ltj.define_jfm(t)
+function define_jfm(t)
    local real_char -- Does current character class have the 'real' character?
    if t.dir~='yoko' then
       defjfm_res= nil; return
@@ -71,14 +82,13 @@ function ltj.define_jfm(t)
    defjfm_res= t
 end
 
-local function ljfm_find_char_class(c,m)
+function find_char_class(c,m)
 -- c: character code, m
-   if not ltj.metrics[m] then return 0 end
-   return ltj.metrics[m].chars[c] or 0
+   if not metrics[m] then return 0 end
+   return metrics[m].chars[c] or 0
 end
-ltj.int_find_char_class = ljfm_find_char_class
 
-local function ljfm_load_jfont_metric()
+local function load_jfont_metric()
    if jfm_file_name=='' then 
       ltjb.package_error('luatexja',
                         'no JFM specified',
@@ -86,14 +96,14 @@ local function ljfm_load_jfont_metric()
                          "The JFM 'ujis' will be  used for now."})
       jfm_file_name='ujis'
    end
-   for j,v in ipairs(ltj.metrics) do 
+   for j,v in ipairs(metrics) do 
       if v.name==jfm_file_name then return j end
    end
    ltj.loadlua('jfm-' .. jfm_file_name .. '.lua')
    if defjfm_res then
       defjfm_res.name = jfm_file_name
-      table.insert(ltj.metrics,defjfm_res)
-      return #ltj.metrics
+      table.insert(metrics, defjfm_res)
+      return #metrics
    else 
       return nil
    end
@@ -101,12 +111,12 @@ end
 
 
 ------------------------------------------------------------------------
--- LOADING JAPANESE FONTS (prefix: ljft)
+-- LOADING JAPANESE FONTS
 ------------------------------------------------------------------------
 local cstemp
 
 -- EXT
-function ltj.ext_jfontdefX(g)
+function jfontdefX(g)
   local t = token.get_next()
   cstemp=token.csname_name(t)
   if g then ltj.is_global = '\\global' else ltj.is_global = '' end
@@ -114,8 +124,8 @@ function ltj.ext_jfontdefX(g)
 end
 
 -- EXT
-function ltj.ext_jfontdefY() -- for horizontal font
-   local j = ljfm_load_jfont_metric()
+function jfontdefY() -- for horizontal font
+   local j = load_jfont_metric()
    local fn = font.id(cstemp)
    local f = font.fonts[fn]
    if not j then 
@@ -127,19 +137,19 @@ function ltj.ext_jfontdefY() -- for horizontal font
                 .. cstemp .. '\\endcsname=\\relax')
      return 
    end
-   ltj.font_metric_table[fn]={}
-   ltj.font_metric_table[fn].jfm=j
-   ltj.font_metric_table[fn].size=f.size
-   ltj.font_metric_table[fn].var=jfm_var
+   font_metric_table[fn]={}
+   font_metric_table[fn].jfm=j
+   font_metric_table[fn].size=f.size
+   font_metric_table[fn].var=jfm_var
    tex.sprint(ltj.is_global .. '\\protected\\expandafter\\def\\csname '
               .. cstemp .. '\\endcsname'
               .. '{\\csname ltj@curjfnt\\endcsname=' .. fn
-              .. ' \\zw=' .. round(f.size*ltj.metrics[j].zw) .. 'sp'
-              .. '\\zh=' .. round(f.size*ltj.metrics[j].zh) .. 'sp\\relax}')
+              .. ' \\zw=' .. round(f.size*metrics[j].zw) .. 'sp'
+              .. '\\zh=' .. round(f.size*metrics[j].zh) .. 'sp\\relax}')
 end
 
 -- extract jfm_file_name and jfm_var
-local function ljft_extract_metric(name)
+local function extract_metric(name)
    local basename=name
    local tmp = utf.sub(basename, 1, 5)
    jfm_file_name = ''; jfm_var = ''
@@ -168,7 +178,7 @@ end
 -- replace fonts.define.read()
 local ljft_dr_orig = fonts.define.read
 function fonts.define.read(name, size, id)
-   ljft_extract_metric(name)
+   extract_metric(name)
    -- In the present imple., we don't remove "jfm=..." from name.
    return ljft_dr_orig(name, size, id)
 end
@@ -178,7 +188,7 @@ end
 ------------------------------------------------------------------------
 
 -- EXT: italic correction
-function ltj.ext_append_italic()
+function append_italic()
    local p = tex.nest[tex.nest.ptr].tail
    if p and p.id==id_glyph then
       local f = p.font
@@ -186,9 +196,9 @@ function ltj.ext_append_italic()
       g.subtype = 1; node.set_attribute(g, attr_icflag, ITALIC)
       if ltjc.is_ucs_in_japanese_char(p) then
         f = has_attr(p, attr_curjfnt)
-        local j = ltj.font_metric_table[f]
-        local c = ljfm_find_char_class(p.char, j.jfm)
-        g.kern = round(j.size * ltj.metrics[j.jfm].char_type[c].italic)
+        local j = font_metric_table[f]
+        local c = find_char_class(p.char, j.jfm)
+        g.kern = round(j.size * metrics[j.jfm].char_type[c].italic)
       else
         g.kern = font.fonts[f].characters[p.char].italic
       end
diff --git a/src/luatexja/pretreat.lua b/src/luatexja/pretreat.lua
new file mode 100644 (file)
index 0000000..04e1546
--- /dev/null
@@ -0,0 +1,95 @@
+--
+-- luatexja/pretreat.lua
+--
+luatexbase.provides_module({
+  name = 'luatexja.pretreat',
+  date = '2011/06/27',
+  version = '0.1',
+  description = '',
+})
+module('luatexja.pretreat', package.seeall)
+local err, warn, info, log = luatexbase.errwarinf(_NAME)
+
+require('luatexja.charrange'); local ltjc = luatexja.charrange
+require('luatexja.jfont');     local ltjf = luatexja.jfont
+require('luatexja.stack');     local ltjs = luatexja.stack
+
+local has_attr = node.has_attribute
+local set_attr = node.set_attribute
+local unset_attr = node.unset_attribute
+local node_remove = node.remove
+local node_next = node.next
+
+local id_glyph = node.id('glyph')
+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 lang_ja_token = token.create('ltj@japanese')
+local lang_ja = lang_ja_token[2]
+
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 1: replace fonts
+------------------------------------------------------------------------
+box_stack_level = 0
+-- This is used in jfmglue.lua.
+
+local function suppress_hyphenate_ja(head)
+   for p in node.traverse_id(id_glyph, head) do
+      if ltjc.is_ucs_in_japanese_char(p) then
+        local v = has_attr(p, attr_curjfnt)
+        if v then 
+           p.font = v 
+           set_attr(p, attr_jchar_class,
+                    ltjf.find_char_class(p.char, ltjf.font_metric_table[v].jfm))
+        end
+        v = has_attr(p, attr_ykblshift)
+        if v then 
+           set_attr(p, attr_yablshift, v)
+        else
+           unset_attr(p, attr_yablshift)
+        end
+        p.lang=lang_ja
+      end
+   end
+   lang.hyphenate(head)
+   return head
+end
+
+-- mode: true iff this function is called from hpack_filter
+function set_box_stack_level(head, mode)
+   local box_set = false
+   local p = head
+   local cl = tex.currentgrouplevel + 1
+   for p in node.traverse_id(id_whatsit, head) do
+      if p.subtype==sid_user and p.user_id==30112 then
+        local g = p
+        if mode and g.value==cl then box_set = true end
+        head, p = node_remove(head, g); break
+      end
+   end
+   if box_set then 
+      box_stack_level = tex.getcount('ltj@@stack') + 1 
+   else 
+      box_stack_level = tex.getcount('ltj@@stack') 
+   end
+   return head
+end
+
+-- CALLBACKS
+luatexbase.add_to_callback('hpack_filter', 
+   function (head)
+     return set_box_stack_level(head, true)
+   end,'ltj.hpack_filter_pre',1)
+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')
similarity index 90%
rename from src/luatexja-rmlgbm.lua
rename to src/luatexja/rmlgbm.lua
index 7e78ef8..cbf7a2b 100644 (file)
@@ -1,3 +1,15 @@
+--
+-- luatexja/rmlgbm.lua
+--
+luatexbase.provides_module({
+  name = 'luatexja.rmlgbm',
+  date = '2011/06/27',
+  version = '0.1',
+  description = 'Definitions of non-embedded Japanese fonts',
+})
+module('luatexja.rmlgbm', package.seeall)
+local err, warn, info, log = luatexbase.errwarinf(_NAME)
+
 local rmlgbm_data = require('luatexja-rmlgbm-data')
 local cache_chars = { [655360] = rmlgbm_data.characters }
 
index 244d186..263706b 100644 (file)
@@ -10,7 +10,7 @@ luatexbase.provides_module({
 module('luatexja.stack', package.seeall)
 local err, warn, info, log = luatexbase.errwarinf(_NAME)
 
-local ltjb = luatexja.base
+require('luatexja.base');      local ltjb = luatexja.base
 
 local node_new = node.new
 local id_whatsit = node.id('whatsit')
index 422006f..aa45cd4 100644 (file)
@@ -1,4 +1,4 @@
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko2',
    zw = 1.0, zh = 1.0,
 
index 9d88f6c..a88a058 100644 (file)
@@ -1,4 +1,4 @@
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko',
    zw = 1.0, zh = 1.0,
    
index 83c48ea..aa74647 100644 (file)
@@ -1,4 +1,4 @@
-ltj.define_jfm {
+luatexja.jfont.define_jfm {
    dir = 'yoko',
    zw = 1.0, zh = 1.0,
    kanjiskip = { 0.1, 0.04, 0.05 },
index 327b77a..1e02470 100644 (file)
Binary files a/test/test01-noembed.pdf and b/test/test01-noembed.pdf differ
index a6ae9a8..093f968 100644 (file)
Binary files a/test/test01.pdf and b/test/test01.pdf differ
index d4eb87e..141782a 100644 (file)
@@ -2,6 +2,7 @@
 \input luatexja-core.sty
 
 \jfont\jisninety={file:ipaexm.ttf:script=latn;+jp90;jfm=ujis}
+\jfont\jisfour={file:ipaexm.ttf:script=latn;+jp04;jfm=ujis}
 \jfont\jisexpt={file:ipaexm.ttf:script=latn;+expt;jfm=ujis}
 \jfont\jishwid={file:ipaexm.ttf:script=latn;+hwid;jfm=ujis}
 %\font\tmihwid={file:ipaexm.ttf:script=latn;+hwid}
@@ -23,6 +24,8 @@
 
 {\tentt jp90} feature: 辻→{\jisninety 辻}
 
+{\tentt jp04} feature: 辻→{\jisfour 辻}
+
 {\tentt hwid} feature: アイウエ→{\jishwid アイウエ}\hfil\break
 ↑文字クラスが変わらないので幅も変わらない.
 
index 01d3149..ba2980f 100644 (file)
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
index 8916de6..f7a82aa 100644 (file)
 
 \setbox0=\hbox{\rmlh え\hbox{}}\dumplist0
 
+\setbox0=\hbox{\rmlh あ\hbox{ア}}\dumplist0
+
+\setbox0=\hbox{\rmlh あ\hbox{a}}\dumplist0
+
+\setbox0=\hbox{\rmlh い\hbox{a}}\dumplist0
+
 \head{hbox--JA (penなし)}
 
 \setbox0=\hbox{\rmlh \hbox{}あ}\dumplist0
 
 \ltjsetparameter{prebreakpenalty={`(,123}}
 \ltjsetparameter{postbreakpenalty={`あ,123}}
-\ltjsetparameter{postbreakpenalty={`い,123}}
+\ltjsetparameter{prebreakpenalty={`い,571}, postbreakpenalty={`い,123}}
 \ltjsetparameter{postbreakpenalty={`う,123}}
 \ltjsetparameter{postbreakpenalty={`え,123}}
 \ltjsetparameter{postbreakpenalty={`お,123}}
 
 \setbox0=\hbox{\rmlh aう}\dumplist0
 
+\head{JA--hbox (penあり)}
+
+\setbox0=\hbox{\rmlh あ\hbox{ア}}\dumplist0
+
+\setbox0=\hbox{\rmlh あ\hbox{a}}\dumplist0
+
+\setbox0=\hbox{\rmlh い\hbox{a}}\dumplist0
+
+\setbox0=\hbox{\rmlh \hbox{(}い\hbox{)}}\dumplist0
+
 \head{italic correction}
 
 \setbox0=\hbox{\it f\/(\/あ}\dumplist0
index 8167ed0..d6dc39f 100644 (file)
Binary files a/test/test05-speed.pdf and b/test/test05-speed.pdf differ
index 02431e9..1be795a 100644 (file)
@@ -1,10 +1,10 @@
-%#! time luatex  test05-speed.tex
+%#! time luatex  "\count300=40\input test05-speed.tex"
 \input luatexja-core.sty
 
 \newcount\cnt\newcount\cnta
-\cnt=0
+\cnt=0\output={\deadcycles=0\setbox2000=\box255}
 \long\def\loop#1\repeat{\def\body{#1}\iterate}
-\loop\ifnum\cnt<20 % <= this value
+\loop\ifnum\cnt<\count300 % <= this value
   \cnta=0 \message{\the\cnt:}\par
   {\loop\ifnum\cnta<500 あ.「い,うえお・か(き)く)(けこ\advance\cnta1\repeat}
   \advance\cnt1
@@ -13,6 +13,8 @@
 \end
 
 %     real time:
-% 20:  9.950s    10.584
-% 10:  5.209s    5.523
+% 40: 17.453
+% 30: 13.254
+% 20:  8.771
+% 10:  4.927
 % env: C2D E7300, Mem 4GB, LuaTeX 0.71.0pre, Gentoo amd64 unstable
\ No newline at end of file