OSDN Git Service

Initial Commit.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 23 Mar 2011 00:54:36 +0000 (09:54 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 23 Mar 2011 00:54:36 +0000 (09:54 +0900)
src/doc-sample.pdf [new file with mode: 0644]
src/doc-sample.tex [new file with mode: 0644]
src/doc-sampsty.tex [new file with mode: 0644]
src/luatexja-core-aux.lua [new file with mode: 0644]
src/luatexja-core.lua [new file with mode: 0644]
src/luatexja-core.sty [new file with mode: 0644]
src/luatexja-kinsoku.tex [new file with mode: 0644]
src/luatexja-kinsoku_make.tex [new file with mode: 0644]
src/luatj-mono.lua [new file with mode: 0644]
src/luatj-ujis.lua [new file with mode: 0644]

diff --git a/src/doc-sample.pdf b/src/doc-sample.pdf
new file mode 100644 (file)
index 0000000..1c7a9f7
Binary files /dev/null and b/src/doc-sample.pdf differ
diff --git a/src/doc-sample.tex b/src/doc-sample.tex
new file mode 100644 (file)
index 0000000..bf5c11f
--- /dev/null
@@ -0,0 +1,477 @@
+%#! luatex doc-sample
+\input doc-sampsty.tex % style file
+
+\overfullrule=0pt
+\def\LaTeX{L\kern-.36em\setbox0=\hbox{T}\vbox to\ht0{\hbox{\sevenrm A}\vss}\kern-.15em\TeX}
+\xkanjiskip=0.25\zw plus .10\zw minus .10\zw
+\font\mff=manfnt at 10pt
+\def\mf{{\mff META{\rm\-}FONT}}
+\def\textfontii{\the\textfont2 }
+\def\AmS{{\textfontii A\kern-.1667em\lower.5ex\hbox{M}\kern-.125emS}}
+\def\UPSILON{\char'7}%
+\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
+
+\bigskip
+本パッケージは,(最低でもp\TeX と同等の水準の)日本語組版をLua\TeX 上で実現させることを
+目標としたマクロである.まだまだ足りないところはあるが,とりあえず動くようになった?ので公開する. 
+
+\beginparagraph 特徴
+
+\item 欧文フォント/和文フォントの内部独立管理.
+\item 違う和文フォントでも「メトリックが同じ」なら,字間に空白を挿入する際には同じものとして扱う.
+{\bf 例}: 「ほげほげ){\gt (ふがふが}」は以下の出力より得られた:
+\begintt
+ほげほげ){\gt (ふがふが}
+\endtt
+\item 欧文や和文のベースライン補正が可能.
+\item p\TeX とある程度コマンド名が互換.
+\enditem
+
+\beginparagraph 制限
+
+\item 全体的にテスト不足です.
+\item 合字の前後の和欧文間空白の挿入処理は適当{\small(合字でない場合の処理をそのまま流用)\inhibitglue}.
+\item {\bf 現時点で\LaTeX での使用は全く考慮されていません.``plain Lua\TeX''で使ってください.}
+\item |\accent|を和文文字に対して使うことはできません.これは「フォントを後で置換する」という実装上,
+仕方のないことだと思われます.
+\item 数式中の日本語は想定していません.|\hbox|か何かで囲ってください.
+\item p\TeX にあった以下の機能はまだ実装していません.
+\itemitem |\euc|, |\jis|, |\sjis|, |\kuten|といった,コード変換プリミティブ.
+\itemitem |\kansuji|, |\kansujichar|.
+\itemitem |\showmode|, |\jfam|, |\jcharwidowpenalty|.
+\itemitem 縦組み関連一式.|\tate|, |\tfont|, |\tbaselineshift|, |\dtou|,$\,\ldots$
+\enditem
+
+\beginparagraph ファイル構成
+
+
+\item {\tt luatexja-core.sty}: 
+マクロ本体.拡張子は{\tt sty}であるが,この単一のファイルでplain \TeX と\LaTeX 両方に
+対応するように設計する方針である.しかし,
+{\bf 現時点で\LaTeX での使用は全く考慮されていない.}
+\item {\tt luatexja-core.lua}: Luaコード部分.
+\item {\tt luatexja-kinsoku.tex}: 禁則用ペナルティ等のパラメータを書いたファイル.
+下のファイルによって{\tt ukinsoku.tex} (in up\TeX-0.30) から自動生成されたもの.
+\item {\tt luatexja-kinsoku\_make.tex}: 上の{\tt luatexja-kinsoku.tex}を作るためのファイル.
+\item {\tt luatj-ujis.lua}: up\TeX-0.30の{\tt ujis.tfm}ベースのメトリックサンプル.
+\item {\tt luatj-mono.lua}: 「全文字が全角幅」のメトリックサンプル.
+\enditem
+
+\beginsection 使用方法
+
+大雑把に言うと,plain \TeX の状況で,以下のようにすればよい.
+\begintt
+\input luatexja-core.sty               % ←マクロ本体を読み込み
+\loadjfontmetric{mt}{ujis}             % ←メトリックの読み込み
+\font\tenipam={file:ipam.ttf}at13.5\jQ 
+\jfont\tenipam{mt}                     % 和文フォントとして認識
+\tenipam\parindent=1\zw 
+\yabaselineshift=32768                 % 32768 sp =  0.5 pt
+
+\rm abcほげほげ)(あいう本文本文……
+\endtt
+
+\beginsection 実装解説
+
+\beginparagraph attributes, dimensions,$\,\ldots$
+
+以下はLua\TeX-jaパッケージ内で使用するattributeやその他の種類のレジスタである.
+上3つは内部処理用なので利用者が意識することはない.それ以外は,p\TeX に類似の名前の
+primitiveがあることから,意味は容易にわかるだろう:
+
+\item attribute |\luatexja@curjfn|: 現在の和文フォント番号
+
+p\TeX では内部のグローバル変数で「現在の横組/縦組和文フォント」をそれぞれ保持していたが,
+当然ながら欧文用\TeX ではそのようなことはそのままではできない.
+node $p$が保持しているattribute |\luatexja@curjfn|の値$k$は,
+「もし$p$の中身が和文文字であれば,そのフォントは$k$番の番号のフォントである」という意味をもつ.
+
+\item attribute |\luatexja@icflag|: この属性をもつkernはイタリック補正由来である
+
+p\TeX では,|\kern|由来のkernと,イタリック補正由来のkernを内部で区別していた.しかし,
+欧文用の\TeX ではそのような区別はなく,Lua\TeX においても区別がないようである.
+
+\item language |\luatexja@japanese|: 「日本語」に対応する|\language|番号
+
+\item attribute |\yabaselineshift|: 欧文文字ベースラインの補正量.
+\itemitem {\bf sp${}=2^{-16}\,{\rm pt}$単位の整数値}で指定.
+正値を指定すると,欧文文字は下にずれる.
+\itemitem 数式中では,boxやruleもこの量だけずれる
+(よって,行中数式は全体が|\yabaselineshift|だけずれたように見えるだろう).
+\item attribute |\ykbaselineshift|: 和文文字ベースラインの補正量.
+
+p\TeX では「和文が主」という考えからか,常に和文文字のベースラインが基準であり,
+欧文文字の方をずらすことになっていた.しかし,「欧文の中に和文をちょっと入れる」ような場合では,
+逆に和文文字をずらす方が理にかなっているので,和文文字のベースラインもずらせるようにした.
+
+また,これを用いることで%
+{\small 異なる文字サイズの文字を「上下中央揃え」で組む}ことも可能.
+\item skip |\kanjiskip|: 和文文字同士の間に入る空白量.
+\item skip |\xkanjiskip|: 和文文字と欧文文字の間に入る空白量.
+\item dimen |\zw|, |\zh|: 現在の和文フォントの「幅」/「高さ」(メトリックから指定)
+\item dimen |\jQ|, |\jH|${}= 0.25\,{\rm mm}$
+\enditem
+
+
+\beginparagraph 和文フォントの定義
+
+Lua\TeX-jaでは,大雑把にいうと
+和文フォントは「実際の字形」と「和文用のメトリック情報」の組である.
+\item メトリック情報は,和文文字の幅や,和文文字間の空白の入り方などを規定する.
+p\TeX における{\tt JFM}ファイルのようなものと考えてよい.
+\enditem
+
+このため,和文フォントを使うには,以下のような手順が必要である.
+
+\enum |\font<font>={file: <fontfile>} at 13.5\jQ|
+
+\TeX の|\font| primitiveを用いてひとまずフォントを読み込む.和文フォントの場合は,
+このようにTrueType/OpenTypeフォントをこのように読み込むことになると思われる%
+{\small(システムにインストールされているフォントの指定も可能と思われる)\inhibitglue}.
+
+この段階では,制御綴<font>は「現在の欧文フォントを変更する」意味である.
+
+\enum |\loadjcharmetric{<key>}{<file>}|
+
+Luaソース|luatj-<file>.lua|に書かれたメトリック情報を読み込む.
+内部では<key>というキーで参照されることとなる.同じkeyで2回以上読み込むことはできないが,
+同じメトリック情報に異なるキーをつけることは差し支えない.
+
+\enum |\jfont<font>{<key>}|
+
+制御綴<font>を「metric keyが<key>の和文フォント」と認識させる.
+\itemitem 制御綴<font>で指定されるフォントから,
+<key>で参照されるメトリックの字幅情報のみを反映させた仮想フォント$v$を作る.
+\itemitem 制御綴<font>の意味を,「$\hbox{|\luatexja@curjfn|}\leftarrow v$」というように変更する.
+これにより,以後<font>を発行しても,欧文フォントは変わらない.
+
+\enditem
+
+\beginparagraph その他命令類
+
+\item |\inhibitxspcode{<code>}{<num>}|, |\xspcode{<code>}{<num>}|,\hfil\break
+|\prebreakpenalty{<code>}{<num>}|,  |\postbreakpenalty{<code>}{<num>}|
+
+これらはp\TeX の対応する命令と意味は概ね同じであるが,以下の点が異なる.
+
+\itemitem 同じ文字コードについて|\prebreakpenalty|, |\postbreakpenalty|を両方指定することが
+可能.
+\itemitem |\xspcode|(欧文文字用)は|\inhibitxspcode|(和文文字用)の別名であり,
+\begintt
+\xspcode{12289}{1}  \inhibitxspcode{12289}{1}
+\endtt
+は全く同じ意味である.|\xspcode|, |\inhibitxspcode|の第2引数の意味は異なるが,
+両者の意味は文字コードにより判断している.
+
+\item |\inhibitglue|: 指定箇所での和文フォントメトリック由来のglue/kernの挿入を禁止する.
+内部的には,|user_id|が30111のwhatsit nodeを作成している{\small(メトリック由来の
+glue/kern挿入処理で役目を終え,削除される)\inhibitglue}.
+\enditem
+
+
+\beginparagraph 大まかな処理の流れ
+
+Lua\TeX-jaパッケージでは,次のような流れで処理を行う.
+
+\item 行末空白の削除: |process_input_buffer| callback
+
+通常,\TeX において改行は空白とほぼ同じ意味であり,
+改行した箇所には自動的に空白が入るようになっている.
+だが,日本語ではそのような振る舞いは不自然であり,p\TeX でも
+「和文文字で行が終わった場合,改行文字は無視する」という
+使用になっている.
+
+そこで,入力が和文文字で終わった場合,コメント文字を挿入することにより
+この問題を解決する方法をとっている.
+この部分のコードは前田氏のjafontspecパッケージの部分から拝借したが,挿入する文字を|%|から
+(通常使用されることはないと思われる)|U+FFFFF|へと変更している.
+
+\item 和文フォントへの置換: |hyphenate|, |hpack_filter| callbacks
+
+この段階の前では,和文文字であっても,それを内部で表している|glyph_node| $p$は,
+「|\temrm あ|」のように,欧文フォントが指定されている状態になっている.しかし,
+$p$は「現在の和文フォント」の番号もattribute |\luatexja@curjfn|として保持している.そのため,
+この段階では,「和文文字が格納されている」|glyph_node| $p$に対して,次を行う.
+
+\itemitem $p$のフォントをattribute |\luatexja@curjfn|の値に置換.
+\itemitem $p$の|language| fieldを|\luatexja@japanese|の値に置換.
+誤って和文文字間でハイフネーションがされてしまうのを防止するため.
+
+\item メトリック由来glue/kernの挿入: |pre_linebreak_filter|, |hpack_filter|
+
+ここで,メトリックに由来する和文文字間のglue/kernを挿入する.
+基本的には連続する和文文字間に挿入するが,
+\itemitem 水平ボックスの先頭/末尾,段落の先頭/末尾には「文字コード|'boxbdd'|の文字」があると
+見做して空白を挿入する.
+\itemitem 和文文字とそうでないもの(欧文文字,ボックス等)の間に関しては,
+和文文字でない方は「文字コード|'jcharbdd'|の文字」であると見做す.
+\itemitem フォントの異なる2つの和文文字においても,
+両者のフォントのmetric keyとsizeが一致した場合は,挿入処理においては「同じフォント」であるかのように扱う.
+\itemitem  そうでない場合は,両者の間に「文字コード|'diffmet'|の文字」があると見做して,
+両和文文字からそれぞれglue/kern |gb|, |ga|を計算し,そこから実際に入るglue/kernを,
+関数|ltj.calc_between_two_jchar_aux|で計算している:
+\itemT |gb|, |ga|の片方がglue,もう片方がkernの場合は,glue側のみ挿入.
+\itemT そうでないときは,両者の平均値の空白を挿入する.
+
+\item |\kanjiskip|, |\xkanjiskip|の挿入: |pre_linebreak_filter|, |hpack_filter|
+
+p\TeX の|adjust_hlist| procedureと同様の処理を用いて,
+和文間glue |\kanjiskip|や和欧文間glue |\xkanjiskip|を
+挿入する.
+\itemitem p\TeX と同様に,これらの自動挿入は(box/段落ごとに)
+|\[no]auto[x]spacing|を用いて制御できる.
+\itemitem 数式境界 (|math_node|) との間に|\xkanjiskip|を自動挿入するかの決定は,
+p\TeX では数字{\tt 0}との間に挿入するかどうかで判定していたが,Lua\TeX-jaでは
+「文字コード|'math'|の文字」で判定している.
+
+
+\item ベースライン補正: |pre_linebreak_filter|, |hpack_filter|
+
+この段階では,(主として)欧文文字のベースラインをずらす作業を行う.幸いにして,
+Lua\TeX で文字を表す|glyph_node|には|y_offset| fieldがあるので,作業は楽である.
+
+補正量は,attribute |\luatexja@yablshift|の値(先も書いた通り,sp単位)である.和文文字の
+補正量は|\luatexja@ykblshift|の値で指定されるが,以前の「和文フォントへの置換」処理において,
+|\luatexja@yablshift|へと値を移し変えているので,この段階では|\luatexja@yablshift|の値のみを気にしている.
+
+
+さて,実際に補正されるのは次の場合である:
+\itemitem 文字 (|glyph_node|)
+\itemitem ボックス・rule(文中数式内部).これによって,数式全体が下がったように見えるはず.
+\enditem 
+
+\beginparagraph 和文フォントメトリックについて
+
+Lua\TeX-jaで用いる和文用のメトリック情報は,次のような構文で書かれたLuaファイルである.
+見本として,|luatj-ujis.lua|を入れてある.
+
+\item |jfm.dir|: 組方向を指定する.将来的にはいずれ縦組(|'tate'|)を実装したいが,
+現時点では横組(|'yoko'|)のみの対応.
+\item |jfm.zw|, |jfm.zh|: それぞれ|\zw|, |\zh|のフォントサイズに対する割合を記述する.
+通常は両方とも1.0となるだろう.
+\item |jfm.define_char_type(<class>, <chars>)|
+
+p\TeX 用{\tt JFM}で言うところの「文字クラス」を定義する.
+\itemitem <class>は文字クラスを表す1以上$\hbox{\tt0x800}=2048$未満の整数.
+\itemitem <chars>には,<class>に属する「文字」達のUnicodeにおけるコード番号を
+リストの形|{...}|で記述する.
+
+また,このリストには,以下の「仮想的な文字」も指定可能である.
+\itemT |'\boxbdd'|: 水平ボックスの先頭/末尾,段落の先頭/末尾.
+\itemT |'jcharbdd'|: 和文文字達の連続の境界.
+\itemT |'diffmet'|: 異なるメトリックの和文文字間に入るglueの計算に使われる.
+\item |jfm.define_type_dim(<class>, <left>, <width>, <height>, <depth>, <italic>)|
+
+文字クラス<class>ごとに,文字の寸法のフォントサイズに対する割合を記述する.
+\itemitem <left>: 例えば開き括弧類は組版をする際には半角幅だが,TrueTypeフォント内では
+左に半角空白が付け加わって全角幅となっていることが多い.このような場合,逆に
+TrueTypeフォントを基準にすると,「左に半角幅ずらす」ことをしないといけない.
+<left>はその「左へのずらし量」を指定する.
+\itemitem <width>, <height>, <depth>: それぞれ幅,高さ,深さ.
+\itemitem <italic>: イタリック補正値.
+
+\item |jfm.define_glue(<bclass>, <aclass>, <width>, <stretch>, <shrink>)|
+
+文字クラス<bclass>の文字と<aclass>の文字の間に,自然長<width>,伸び<stretch>, 縮み<shrink>
+(いずれもフォントサイズ基準)のglueを挿入する.
+
+\item |jfm.define_kern(<bclass>, <aclass>, <width>)|
+
+文字クラス<bclass>の文字と<aclass>の文字の間に,幅<width>のkernを挿入.
+
+
+\enditem
+
+
+
+\vfill\eject
+\leftline{{\big 組版サンプル}\hfill
+\noindent 出典: 日本語Wikipediaの「\TeX」の項,2011/3/10}
+
+\bigskip
+%% sample
+\TeX(読み方については、「読み方」の小節を参照)は数学者・計算機科学者である
+ドナルド・クヌース (Donald~E. Knuth) により作られた組版処理ソフトウェアである。
+
+\beginsection 名称について
+
+製作者であるクヌースによって以下のように要請されている。
+
+\beginparagraph 表記法
+
+正しくは “\TeX”と表記するが、それができない場合には
+“{\tt TeX}”と表記する(“{\tt TEX}”と表記するのは誤り)。
+
+\beginparagraph 読み方
+
+\TeX はギリシャ文字の T-E-X(タウ・イプシロン・カイ)であるから、「テックス」ではなく、
+ギリシャ語読みの [tex](「テフ」)のように発音するのが正しい。
+しかしそのような発音は難しいので、クヌースは「テック」と読んでも構わないとしている。
+日本では「テフ」または「テック」という読み方が広まっている。
+
+\beginsection 機能
+
+\TeX はマークアップ言語処理系であり、チューリング完全性を備えた関数型言語でもある。
+文章そのものと、文章の構造を指定する命令とが混在して記述されたテキストファイルを読み込み、
+そこに書かれた命令に従って文章を組版して、組版結果を{\tt DVI}形式のファイルに書き出す。
+{\tt DVI}形式というのは、装置に依存しない (device-independent) 中間形式である。
+
+{\tt DVI}ファイルには紙面のどの位置にどの文字を配置するかといった情報が書き込まれている。
+実際に紙に印刷したりディスプレイ上に表示したするためには、{\tt DVI}ファイルを解釈する
+別のソフトウェアが用いられる。{\tt DVI}ファイルを扱うソフトウェアとして、各種のヴューワや
+Post\-Scriptなど他のページ記述言語へのトランスレータ、プリンタドライバなどが利用されている。
+
+組版処理については、行分割およびページ分割位置の判別、ハイフネーション、リガチャ、
+およびカーニングなどを自動で処理でき、その自動処理の内容も種々のパラーメータを変更する
+ことによりカスタマイズできる。数式組版についても、多くの機能が盛り込まれている。
+\TeX が文字などを配置する精度は$25.4 / (72.27\times 2^{16})\,{\rm mm}$%
+(約$5.363\,{\rm nm}$、$4{,}736{,}286.72\,{\rm dpi}$)である。
+
+\TeX の扱う命令文の中には、組版に直接係わる命令文の他に、新しい命令文を定義するための
+命令文もある。\TeX のこの機能を使って使用者が独自に作った命令文はマクロと呼ばれ、
+こうした独自の改良をマクロパッケージと呼ばれる形で配布できる。
+
+比較的よく知られている\TeX 上のマクロパッケージには、クヌース自身による plain \TeX、
+一般的な文書記述に優れた\LaTeX\ ({\tt LaTeX})、数学的文書用の\AmS-\TeX などがある。
+一般の使用者は、\TeX を直接使うよりも、\TeX に何らかのマクロパッケージを読み込ませたものを
+使うことの方が多い。そのため、これらのマクロパッケージのことも “\TeX” と呼ぶ場合があるが、
+本来は誤用である。
+
+\TeX のマクロパッケージには、他にも次のようなものなどがある。
+
+\item B{\sc ib}\TeX\ ({\tt BibTeX}) ……参考文献リストの作成に用いる。
+\item S{\sc li}\TeX\ ({\tt SLiTeX}) ……プレゼンテーション用スライドの作成に用いる。
+\item \AmS-\LaTeX\ ({\tt AMS-LaTeX}) ……
+数学的な文書の記述に強い\AmS-\TeX の機能と\LaTeX の機能を併せ持つ。
+\item \XyMTeX\ ({\tt XyMTeX}) ……化学構造式の描画に用いる。
+\item MusiX\TeX\ ({\tt MusiXTeX}) ……楽譜の記述に用いる。
+\enditem
+
+\TeX とそれに関連するプログラム、および\TeX のマクロパッケージなどは CTAN(Comprehensive TeX Archive Network、
+包括 TeX アーカイブネットワーク)からダウンロードできる。
+
+
+\beginsection 数式の表示例
+
+たとえば
+\begintt
+-b \pm \sqrt{b^{2} - 4ac} \over 2a
+\endtt
+は以下のように表示される。
+$$
+-b \pm \sqrt{b^{2} - 4ac} \over 2a
+$$
+
+また、
+\begintt
+f(a,b) = \int_{a}^{b}\frac{1 + x}{a + x^{2} + x^{3}}dx
+\endtt
+は以下のように表示される。
+$$
+f(a,b) = \int_{a}^{b}{1 + x \over a + x^{2} + x^{3}}dx
+$$
+
+
+\beginsection 生い立ち
+
+\TeX は、クヌースが自身の著書The Art of Computer Programmingを書いたときに、組版の汚さに憤慨し、
+自分自身で心行くまで組版を制御するために作成したとされている。開発にあたって、伝統的な組版および
+その関連技術に対する広範囲にわたる調査を行った。その調査結果を取り入れることで、\TeX は
+商業品質の組版ができる柔軟で強力な組版システムになった。
+
+\TeX はフリーソフトウェアであり、ソースコードも公開されていて、誰でも改良を加えることができる。
+その改良版の配布も、\TeX と区別できるような別名を付けさえすれば許される。また、\TeX は非常に
+バグが少ないソフトウェアとしても有名で、ジョーク好きのクヌースが、バグ発見者に対しては
+前回のバグ発見者の2倍の懸賞金をかけるほどである。この賞金は小切手で払われるのだが、貰った人は
+記念に取っておく人ばかりなので、結局クヌースの出費はほとんど無いという。
+
+クヌースは\TeX のバージョン 3 を開発した際に、これ以上の機能拡張はしないことを宣言した。
+その後は不具合の修正のみがなされ、バージョン番号は 3.14、3.141、3.1415、$\ldots$というように
+付けられている。これは更新のたびに数字が円周率に近づいていくようになっていて、
+クヌースの死の時点をもってバージョン$\pi$として、バージョンアップを打ち切るとのことである。
+
+クヌースは\TeX の開発と同時に、\TeX で利用するフォントを作成するためのシステムである
+\mf も開発した。こちらのバージョン番号は 2.71、2.718、2.7182、$\ldots$というように、
+更新のたびに数字がネイピア数に近づいていくようになっている。さらにクヌースは\mf を使って、
+\TeX の初期設定欧文フォントであるComputer Modernのデザインも行った。
+
+\TeX および\mf は、これもクヌース自身によって提唱されている文芸的プログラミング\ 
+(Literate Programming) を実現する{\tt WEB}というシステムでPascalへトランスレートされることを
+前提に記述されている。しかし実際には{\tt WEB2C}でC言語に変換してコンパイルされ実行形式を
+得ることが多い。
+
+\beginsection \TeX の日本語化
+
+日本語組版処理のできる日本語版の\TeX および\LaTeX には、アスキー・メディアワークスによるp\TeX\ 
+(pTeX) およびp\LaTeX\ (pLaTeX) と、NTTの斉藤康己によるNTT J\TeX\ (NTT JTeX) およびNTT J\LaTeX\
+(NTT JLaTeX) などがある。
+
+\TeX の日本語対応において技術的に最も大きな課題は、複数バイト文字コードへの対応である。
+p\TeX(および前身の日本語\TeX)は、JIS X 0208を文字集合とした文字コード(ISO-2022-JP、EUC-JP、
+およびShift\_JIS)を直接扱う。DVIフォーマットは元々16ビット以上の文字コードを格納できる仕様が
+含まれていた。しかしオリジナルの英語版では使われていなかったため、既存プログラムの多くはp\TeX が
+出力するDVIファイルを処理できない。またフォントに関係するファイルフォーマットが拡張されている。
+これに対してNTT J\TeX は、複数の1バイト文字セットに分割することで対応している。例えば、
+ひらがなとカタカナは内部的には別々の1バイト文字セットとして扱われる。このためにオリジナルの
+英語版からの変更が小さく、移植も比較的容易である。ファイルフォーマットが同じなので英語版の
+プログラムでDVIファイル等を処理することもできる。しかし後述するフォントのマッピングの問題が
+あるため、実際には多くの使用者がNTT J\TeX 用に拡張されたプログラムを使っている。
+
+使用する日本語用フォントについてはp\TeX が写研フォントの使用を、NTT J\TeX が大日本印刷フォントの
+使用を前提としており、それぞれフォントメトリック情報(フォントの文字寸法の情報)をバンドルして
+配布している。しかし有償であるこれらのフォントのグリフ情報を持っていなくても、画面表示や印刷の
+際に使用者が利用できる他の日本語用フォントで代用することができる。つまり写研フォントや
+大日本印刷フォントのフォントメトリック情報を用いて文字の位置を固定し、画面表示や印刷には
+他の日本語用フォントを用いていることが可能である。このため日本語化された\TeX 関係プログラムの
+ほとんどは、画面表示や印刷で実際に使うフォントを選択できるように、フォントのマッピング
+(対応付け)を定義する機能を持っている。
+
+歴史的には、アスキーが日本語\TeX の PC-9800 シリーズ対応版を販売したために個人の使用者を中心に
+普及した。一方、NTT J\TeX は元の英語版プログラムからの変更が比較的小さいという利点を受けて、
+UNIX®およびUNIX互換OSを使う大学や研究機関の関係者を中心に普及した。
+
+しかし現在では次に挙げる理由から、日本語対応\TeX としてp\TeX が使われていることが多い。
+
+\item UNIX®用、およびUNIX互換OS用の主な日本語対応\TeX 配布形態である
+ptexliveやptetex3がp\TeX のみを採用している。
+\item Microsoft Windows用の主な日本語対応\TeX 配布形態であるW32\TeX が
+p\TeX を扱える(NTT J\TeX も扱える)。
+\item p\TeX の扱い方を解説する文献の方が、NTT J\TeX のものに比べて、
+出版物とWeb上文書の両方で多い。
+\item p\TeX は縦組みにも対応しているが、NTT J\TeX は対応していない。
+\enditem
+
+\beginsection \TeX による組版の作業工程
+
+\TeX を利用して組版を行うには、通常次のような作業工程を取る。
+
+\enum テキストエディタなどを用いて、文章に組版用命令文を織り込んだソースファイルを作成する。
+\enum OSのコマンドラインから “|tex FileName.tex|” などと入力して\TeX を起動し、
+  {\tt DVI}ファイルを生成させる。
+\itemitem ソースファイルにエラーがあれば、修正して再度\TeX を起動する。
+\enum {\tt DVI}ウェアとよばれる{\tt DVI}命令文を解するソフトウェアを用いて組版結果を表示し、確認する。
+\itemitem {\tt DVI}ウェアにはxdvi/xdvikやdviout for Windowsなどの{\tt DVI}ヴューア、
+  Dvips(k)やdvipdfm/DVIPDFM$x$などのファイル形式変換ソフトウェアなどがある。
+\itemitem {\tt DVI}ファイルを{\tt DVI}ヴューアで画面表示または印刷する、
+  あるいはPDFやPost\-Scriptに変換して画面表示または印刷することで、組版結果を確認する。
+\itemitem 修正の必要があれば、ソースファイルを修正して再度{\tt DVI}ファイルを作成、確認する。
+\enditem
+
+この間、作業工程が変わるたびにそれぞれのプログラムを切り替えたり、
+扱う文書が大きいと章ごとにソースファイルを分割して管理したりと、比較的煩雑な作業を伴う。
+そのため、この工程に係わる各種のプログラムやソースファイルの管理を一元的に行う
+\TeX 用の統合環境がいくつか作成されている。
+
+\beginparagraph GUI環境と\TeX
+
+GUIはPCの普及に一役買ったが、同時にGUIしか触ったことのないPC利用者が増加した。
+そのような利用者が、コマンドラインでの操作を余儀なくされる\TeX を非常に扱いづらく
+感じてしまうのは否めないことである。
+このため、GUIに特化した\TeX 用統合環境もいくつか作成されている。
+\end
diff --git a/src/doc-sampsty.tex b/src/doc-sampsty.tex
new file mode 100644 (file)
index 0000000..702ec85
--- /dev/null
@@ -0,0 +1,113 @@
+
+% Fonts  for 8pt
+\font\eightrm=cmr8
+\font\eightbf=cmbx8
+\font\eightit=cmti8
+\font\eightsl=cmsl8
+\font\eightmus=cmmi8
+\font\eighttt=cmtt8
+% Fonts  for 12pt
+\font\twelverm=cmr12
+\font\twelvebf=cmbx12
+\font\twelveit=cmti12
+\font\twelvesl=cmsl12
+\font\twelvemus=cmmi12
+\font\twelvett=cmtt12
+
+\font\bigbf=cmbx12 scaled \magstep3
+\font\eightsc=cmcsc10 at 8pt
+\font\tensc=cmcsc10
+\font\twelvesc=cmcsc10 at 12pt
+
+% Japanese fonts
+\input luatexja-core.sty
+\loadjfontmetric{mt}{ujis}
+\loadjfontmetric{zero}{mono}
+\def\minfnt{file:ipam.ttf }
+\def\gothfnt{file:ipag.ttf }
+\font\eightipam=\minfnt at 10.5\jQ\jfont\eightipam{mt}
+\font\eightipag=\gothfnt at 10.5\jQ\jfont\eightipag{mt}
+\font\tenipam=\minfnt at 13.5\jQ\jfont\tenipam{mt}
+\font\tenjtt=\gothfnt at 13.5\jQ\jfont\tenjtt{zero}
+\font\tenipag=\gothfnt at 13.5\jQ\jfont\tenipag{mt}
+\font\twelveipam=\minfnt at 16\jQ\jfont\twelveipam{mt}
+\font\twelveipag=\gothfnt at 16\jQ\jfont\twelveipag{mt}
+\font\bigipag=\gothfnt at 28\jQ\jfont\bigipag{mt}
+
+% Size 
+\def\large{\def\rm{\textfont0=\twelverm\twelverm\fam0}\def\bf{\twelvebf\gt}%
+  \let\it=\twelveit  \let\sl=\twelvesl \let\mus=\twelvemus 
+  \let\sc=\twelvesc  \let\tt=\twelvett
+  \let\mc=\twelveipam \let\gt=\twelveipag
+  \baselineskip=18pt\rm\mc\xkanjiskip=0.25\zw plus 0.10\zw minus 0.10\zw}
+
+\def\big{\bigbf\bigipag\xkanjiskip=0.25\zw plus 0.10\zw minus 0.10\zw}
+
+\def\normalsize{\def\rm{\textfont0=\tenrm\tenrm\fam0}\def\bf{\tenbf\gt}%
+  \let\it=\tenit \let\sl=\tensl \let\mus=\tenmus 
+  \let\sc=\tensc \def\tt{\tentt\tenjtt}%
+  \let\mc=\tenipam \let\gt=\tenipag
+  \baselineskip=15pt\rm\mc\xkanjiskip=0.25\zw plus 0.10\zw minus 0.10\zw}
+\def\small{\def\rm{\textfont0=\eightrm\eightrm\fam0}\def\bf{\eightbf\gt}%
+  \let\it=\eightit \let\sl=\eightsl \let\mus=\eightmus 
+  \let\sc=\eightsc \def\tt{\eighttt\eightjtt}%
+  \let\mc=\eightipam \let\gt=\eightipag%
+  \rm\mc\xkanjiskip=0.25\zw plus 0.10\zw minus 0.10\zw%
+  \ykbaselineshift=-49807\yabaselineshift=-49807% 0.76 pt
+}
+
+
+
+% layout
+\normalsize\parindent=1\zw\parskip=0pt
+\pdfpagewidth=210mm\pdfpageheight=297mm
+\hsize=40\zw\hoffset=\dimexpr(\pdfpagewidth-\hsize)/2-1in\relax
+\vsize=246mm
+
+% heading
+\outer\def\beginsection#1\par{\vskip0pt plus.1\vsize\penalty-250%
+  \vskip0pt plus-.1\vsize\bigskip\vskip\parskip%
+  \message{#1}\leftline{\large\bf#1\hskip0.5\zw\hrulefill}\nobreak\smallskip}
+\outer\def\beginparagraph#1\par{\vskip0pt plus.1\vsize\penalty-100%
+  \vskip0pt plus-.1\vsize\medskip\vskip\parskip%
+  \message{#1}\leftline{\bf■#1}\nobreak}
+
+% verbatim
+% borrowed from manmac.tex
+\chardef\other=12
+\newbox\vspbox
+\setbox\vspbox=\hbox{\tt\char32}
+{\catcode`\ =\active%\catcode`\%=\active
+\gdef\ttverbatim{\begingroup\xkanjiskip=0pt
+\catcode`\ =\active\let =~\catcode`\%=\other
+\catcode`\\=\other\catcode`\{=\other\catcode`\}=\other
+\catcode`\$=\other\catcode`\&=\other\catcode`\#=\other\catcode`\~=\other
+\catcode`\_=\other\catcode`\^=\other\catcode"FFFFF=12%" <- needed
+\obeyspaces\obeylines\tt}}
+
+\abovedisplayskip=\medskipamount
+\abovedisplayshortskip=\medskipamount
+\belowdisplayskip=\medskipamount
+\belowdisplayshortskip=\medskipamount
+%
+\outer\def\begintt{$$\let\par=\endgraf \ttverbatim\parskip=0pt\catcode`\|=0 \rightskip-5pc\ttfinish}
+{\catcode`\|=0 |catcode`|\=\other% | is temporary escape character
+|obeylines% end of line is active
+|gdef|ttfinish#1^^M#2\endtt{#1|parindent3|zw|noindent|vbox{#2}|hss|endgroup$$}}
+
+\catcode`\|=\active
+{\obeylines \gdef|{\ttverbatim \spaceskip.5em\let^^M=\  \let|=\endgroup}}
+
+\catcode`\<=\active
+\def<#1>{{\it$\langle$#1$\rangle$}}
+
+% itemize
+\newcount\enumi\enumi=0
+\def\item{\par\medskip\leftskip=3\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss$\bullet$\hss}\kern-1\zw }
+\def\itemitem{\par\leftskip=5\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss$-$\hss}\kern-1\zw }
+\def\itemT{\par\leftskip=7\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss$\bullet$\hss}\kern-1\zw }
+\def\enum{\par\medskip\advance\enumi1\leftskip=3\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss\the\enumi.\kern0.5\zw}\kern-1\zw }
+\def\enditem{\medskip\par\enumi=0\leftskip=0pt\parskip=0pt\noindent}
+
+
+\endinput
diff --git a/src/luatexja-core-aux.lua b/src/luatexja-core-aux.lua
new file mode 100644 (file)
index 0000000..7e17db9
--- /dev/null
@@ -0,0 +1,43 @@
+
+--  和文文字と満たす unicode の範囲(適当)
+function ltj.is_ucs_in_japanese_char(c)
+   if (c>=0x2000)and(c<=0x27FF) then return true
+   elseif (c>=0x2900)and(c<=0x29FF) then return true
+   elseif (c>=0x3000)and(c<=0x30FF) then return true
+   elseif (c>=0x31F0)and(c<=0x4DBF) then return true
+   elseif (c>=0x4E00)and(c<=0x9FFF) then return true
+   elseif (c>=0xF900)and(c<=0xFAFF) then return true
+   elseif (c>=0xFF00)and(c<=0xFFEF) then return true
+   elseif (c>=0x20000)and(c<=0xDFFFF) then return true
+   else return false
+   end
+end
+
+
+-- gb: 前側の和文文字 b 由来の glue/kern (maybe nil)
+-- ga: 後側の和文文字 a 由来の glue/kern (maybe nil)
+-- 両者から,b と a の間に入る glue/kern を計算する
+
+function ltj.calc_between_two_jchar_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   = tex.round((gb.spec.width+ga.spec.width)/2)
+        gb.spec.stretch = tex.round((gb.spec.stretch+ga.spec.shrink)/2)
+        gb.spec.shrink  = tex.round((gb.spec.shrink+ga.spec.shrink)/2)
+      elseif k == 'kernkern' then
+        -- 両方とも kern.平均をとる
+        gb.kern = tex.round((gb.kern+ga.kern)/2)
+      elseif k == 'kernglue' then 
+        -- gb: kern, ga: glue
+        return ga
+      else
+        -- gb: glue, ga: kern
+        return gb
+      end
+   end
+end
diff --git a/src/luatexja-core.lua b/src/luatexja-core.lua
new file mode 100644 (file)
index 0000000..bb8f0ce
--- /dev/null
@@ -0,0 +1,707 @@
+-- error messages
+function ltj.error(s)
+  tex.error("LuaTeX-ja error: " .. s ); 
+end
+
+-- procedures for loading Japanese font metric
+jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}
+
+function jfm.define_char_type(t,lt) 
+   if not jfm.char_type[t] then jfm.char_type[t]={} end
+   jfm.char_type[t].chars=lt 
+end
+function jfm.define_type_dim(t,l,w,h,d,i)
+   if not jfm.char_type[t] then jfm.char_type[t]={} end
+   jfm.char_type[t].width=w; jfm.char_type[t].height=h;
+   jfm.char_type[t].depth=d; jfm.char_type[t].italic=i; jfm.char_type[t].left=l
+end
+function jfm.define_glue(b,a,w,st,sh)
+   local j=b*0x800+a
+   if not jfm.glue[j] then jfm.glue[j]={} end
+   jfm.glue[j].width=w; jfm.glue[j].stretch=st; 
+   jfm.glue[j].shrink=sh
+end
+function jfm.define_kern(b,a,w)
+   local j=b*0x800+a
+   if not jfm.kern[j] then jfm.kern[j]=w end
+end
+
+-- procedures for \loadjfontmetric
+ltj.metrics={} -- this table stores all metric information
+
+function ltj.loadjfontmetric()
+   if string.len(jfm.name)==0 then
+      ltj.error("the key of font metric is null"); return nil
+   elseif ltj.metrics[jfm.name] then
+      ltj.error("the metric '" .. jfm.name .. "' is already loaded"); return nil
+   end
+   ltj.metrics[jfm.name]={}
+   if jfm.dir~='yoko' then
+      ltj.error("jfm.dir must be 'yoko'"); return nil
+   end
+   ltj.metrics[jfm.name].dir=jfm.dir
+   ltj.metrics[jfm.name].zw=jfm.zw
+   ltj.metrics[jfm.name].zh=jfm.zh
+   ltj.metrics[jfm.name].char_type=jfm.char_type
+   ltj.metrics[jfm.name].glue=jfm.glue
+   ltj.metrics[jfm.name].kern=jfm.kern
+end
+
+function ltj.find_char_type(c,metrickey)
+-- c: character code, metrickey: key
+   for i, v in pairs(ltj.metrics[metrickey].char_type) do
+      if i~=0 then
+        for j,w in pairs(v.chars) do
+           if w==c then return i; end
+        end
+      end
+   end
+   return 0
+end
+
+-- procedures for \jfont command.
+function ltj.jfontdefA(b)
+  ltj.fntbki=font.current()
+  ltj.cstemp=token.csname_name(token.get_next())
+  tex.sprint('\\csname ' .. ltj.cstemp .. '\\endcsname\\csname @jfont\\endcsname')
+  -- A trick to get font id associated of the argument of \jfont.
+  -- font.id() does not seem to work in my environment...
+end
+function ltj.jfontdefB(s) -- for horizontal font
+   if not ltj.metrics[s] then
+      ltj.error("metric named '" .. s .. "' didn't loaded")
+      return
+   end
+   local i = ltj.transform_jfont(font.current(), s)
+   tex.sprint('\\expandafter\\def\\csname ' .. ltj.cstemp .. '\\endcsname' 
+             .. '{\\csname luatexja@curjfnt\\endcsname=' .. i
+             .. '\\zw=' .. font.fonts[i].parameters.quad .. 'sp' 
+             .. '\\zh=' .. font.fonts[i].parameters.x_height .. 'sp\\relax}')
+   font.current(ltj.fntbki); ltj.fntbk = {}; ltj.cstemp = {}
+end
+
+-- "transform" font according to a font metric
+function ltj.transform_jfont(index,metrickey)
+   local f = {}
+   local of=font.fonts[index]
+   f.name = of.name
+   f.fullname = metrickey
+   f.size = of.size
+   f.parameters = {}
+   f.parameters.quad=tex.round(f.size*ltj.metrics[metrickey].zw)
+   f.parameters.x_height=tex.round(f.size*ltj.metrics[metrickey].zh)
+   f.designsize = of.designsize
+   f.type = 'virtual'
+   f.characters = {}
+   f.fonts = { { id = index } }
+   for i,v in pairs(of.characters) do
+      f.characters[i]={}
+      local ci = ltj.metrics[metrickey].char_type[ltj.find_char_type(i,metrickey)]
+      if ci.left~=0.0 then
+         f.characters[i].commands = { 
+            {'right', tex.round(-ci.left*f.size)}, 
+            {'char',i} 
+         }
+      else
+         f.characters[i].commands = { {'char',i} }
+      end
+      f.characters[i].italic = tex.round(ci.italic*f.size)
+      f.characters[i].width  = tex.round(ci.width*f.size)
+      f.characters[i].height = tex.round(ci.height*f.size)
+      f.characters[i].depth  = tex.round(ci.depth*f.size)
+   end
+   if not f.characters[0x3000] then
+      f.characters[0x3000]={}
+      local ci = ltj.metrics[metrickey].char_type[ltj.find_char_type(0x3000,metrickey)]
+      f.characters[0x3000].commands = {{'right', tex.round(ci.width*f.size)} }
+      f.characters[0x3000].italic = tex.round(ci.italic*f.size)
+      f.characters[0x3000].width  = tex.round(ci.width*f.size)
+      f.characters[0x3000].height = tex.round(ci.height*f.size)
+      f.characters[0x3000].depth  = tex.round(ci.depth*f.size)
+   end
+   return font.define(f)
+end
+
+
+-- Replace font in nodes which character code is in the range of
+-- Japanese characters, using two attributes
+function ltj.replace_ja_font(head)
+   local p=head
+   while p do 
+      if node.type(p.id)=='glyph' then
+        if ltj.is_ucs_in_japanese_char(p.char) then
+           local v = node.has_attribute(p,luatexbase.attributes['luatexja@curjfnt'])
+           if v then p.font=v end
+           v=node.has_attribute(p,luatexbase.attributes['luatexja@ykblshift'])
+           if v then 
+              node.set_attribute(p,luatexbase.attributes['luatexja@yablshift'],v)
+           else
+              node.unset_attribute(p,luatexbase.attributes['luatexja@yablshift'])
+           end
+        end
+      end
+      p=node.next(p)
+   end
+   return head
+end
+
+
+-- return true if and only if p is a Japanese character node
+function ltj.is_japanese_glyph_node(p)
+   if not p then return false
+   elseif node.type(p.id)~='glyph' then return false
+   elseif p.font==node.has_attribute(p,luatexbase.attributes['luatexja@curjfnt']) then
+      return true
+   else return false
+   end
+end
+
+---------- Kinsoku 
+----------
+ltj.penalty_table = {}
+function ltj.set_penalty_table(m,c,p)
+   if not ltj.penalty_table[c] then ltj.penalty_table[c]={} end
+   if m=='pre' then
+      ltj.penalty_table[c].pre=p
+   elseif m=='post' then
+      ltj.penalty_table[c].post=p
+   end
+end
+
+ltj.inhibit_xsp_table = {}
+function ltj.set_inhibit_xsp_table(c,p)
+   ltj.inhibit_xsp_table[c]=p
+end
+
+----------
+----------
+function ltj.create_ihb_node()
+   local g=node.new(node.id('whatsit'), node.subtype('user_defined'))
+   g.user_id=30111; g.type=number; g.value=1
+   node.write(g)
+end
+
+-- The fullname field of virtual font expresses its metric
+function ltj.find_size_metrickey(p)
+   if ltj.is_japanese_glyph_node(p) then
+      return font.fonts[p.font].size, font.fonts[p.font].fullname
+   else 
+      return nil, nil
+   end
+end
+
+function ltj.new_jfm_glue(size,mt,bc,ac)
+-- mt: metric key, bc, ac: char classes
+   local g=nil
+   local h
+   local w=bc*0x800+ac
+   if ltj.metrics[mt].glue[w] then
+      h=node.new(node.id('glue_spec'))
+      h.width  =tex.round(size*ltj.metrics[mt].glue[w].width)
+      h.stretch=tex.round(size*ltj.metrics[mt].glue[w].stretch)
+      h.shrink =tex.round(size*ltj.metrics[mt].glue[w].shrink)
+      h.stretch_order=0; h.shrink_order=0
+      g=node.new(node.id('glue'))
+      g.subtype=0; g.spec=h; return g
+   elseif ltj.metrics[mt].kern[w] then
+      g=node.new(node.id('kern'))
+      g.subtype=0; g.kern=tex.round(size*ltj.metrics[mt].kern[w]); return g
+   else
+      return nil
+   end
+end
+
+-- The fullname field of virtual font expresses its metric
+function ltj.calc_between_two_jchar(q,p)
+   -- q, p: node (possibly null)
+   local ps,pm,qs,qm,g,h
+   if not p then -- q is the last node
+      qs, qm = ltj.find_size_metrickey(q)
+      if not qm then 
+        return nil
+      else
+        g=ltj.new_jfm_glue(qs,qm,
+                               ltj.find_char_type(q.char,qm),
+                               ltj.find_char_type('boxbdd',qm))
+      end
+   elseif not q then
+      -- p is the first node etc.
+      if q then print(node.type(q.id)) end
+      ps, pm = ltj.find_size_metrickey(p)
+      if not pm then
+        return nil
+      else
+        g=ltj.new_jfm_glue(ps,pm,
+                               ltj.find_char_type('boxbdd',pm),
+                               ltj.find_char_type(p.char,pm))
+      end
+   else -- p and q are not nil
+      qs, qm = ltj.find_size_metrickey(q)
+      ps, pm = ltj.find_size_metrickey(p)
+      if (not pm) and (not qm) then 
+        -- Both p and q are NOT Japanese glyph node
+        return nil
+      elseif (qs==ps) and (qm==pm) then 
+        -- Both p and q are Japanese glyph node, and same metric and size
+        g=ltj.new_jfm_glue(ps,pm,
+                               ltj.find_char_type(q.char,qm),
+                               ltj.find_char_type(p.char,pm))
+      elseif not qm then
+        -- q is not Japanese glyph node
+        g=ltj.new_jfm_glue(ps,pm,
+                               ltj.find_char_type('jcharbdd',pm),
+                               ltj.find_char_type(p.char,pm))
+      elseif not pm then
+        -- p is not Japanese glyph node
+        g=ltj.new_jfm_glue(qs,qm,
+                               ltj.find_char_type(q.char,qm),
+                               ltj.find_char_type('jcharbdd',qm))
+      else
+        g=ltj.new_jfm_glue(qs,qm,
+                               ltj.find_char_type(q.char,qm),
+                               ltj.find_char_type('diffmet',qm))
+        h=ltj.new_jfm_glue(ps,pm,
+                               ltj.find_char_type('diffmet',pm),
+                               ltj.find_char_type(p.char,pm))
+        g=ltj.calc_between_two_jchar_aux(g,h)
+      end
+   end
+   return g
+end
+
+
+-- In the beginning of a hbox created by line breaking, there are the followings:
+--   o a hbox by \parindent
+--   o a whatsit node which contains local paragraph materials.
+-- When we insert jfm glues, we ignore these nodes.
+function ltj.is_parindent_box(p)
+   if node.type(p.id)=='hlist' then 
+      return (p.subtype==3)
+      -- hlist (subtype=3) is a box by \parindent
+   elseif node.type(p.id)=='whatsit' then 
+      return (p.subtype==node.subtype('local_par'))
+   end
+end
+
+function ltj.add_kinsoku_penalty(head,p)
+   local c = p.char
+   if not ltj.penalty_table[c] then return false; end
+   if ltj.penalty_table[c].pre then
+      local q = node.prev(p)
+      if (not q) and node.type(q.id)=='penalty' then
+        q.penalty=q.penalty+ltj.penalty_table[c].pre
+      else 
+        q=node.new(node.id('penalty'))
+        q.penalty=ltj.penalty_table[c].pre
+        node.insert_before(head,p,q)
+      end
+   end
+   if ltj.penalty_table[c].post then
+      local q = node.next(p)
+      if (not q) and node.type(q.id)=='penalty' then
+        q.penalty=q.penalty+ltj.penalty_table[c].post
+        return false
+      else 
+        q=node.new(node.id('penalty'))
+        q.penalty=ltj.penalty_table[c].post
+        node.insert_after(head,p,q)
+        return true
+      end
+   end
+end
+
+-- Insert jfm glue: main routine
+
+function ltj.insert_jfm_glue(head)
+   local p = head
+   local q = nil  -- the previous node of p
+   local g
+   local ihb_flag = false
+   if not p then 
+      return head 
+   end
+   while p and  ltj.is_parindent_box(p) do p=node.next(p) end
+   while p do
+      if node.type(p.id)=='whatsit' and p.subtype==44
+         and p.user_id==30111 then
+        g=p; p=node.next(p); 
+        ihb_flag=true; head,p=node.remove(head, g)
+      else
+        g=ltj.calc_between_two_jchar(q,p)
+        if g and (not ihb_flag) then
+           h = node.insert_before(head,p,g)
+           if not q then head=h end 
+           -- If p is the first node (=head), the skip is inserted
+           -- before head. So we must change head.
+        end
+        q=p; ihb_flag=false
+        if ltj.is_japanese_glyph_node(p) 
+            and ltj.add_kinsoku_penalty(head,p) then
+           p=node.next(p)
+        end
+        p=node.next(p)
+      end
+   end
+   -- Insert skip after the last node
+   g=ltj.calc_between_two_jchar(q,nil)
+   if g then
+      h = node.insert_after(head,q,g)
+   end
+   return head
+end
+
+
+
+-- Insert \xkanjiskip at the boundaries between Japanese characters 
+-- and non-Japanese characters. 
+-- We also insert \kanjiskip between Kanji in this function.
+ltj.kanji_skip={}
+ltj.xkanji_skip={}
+ltj.insert_skip=0 
+ltj.cx = nil
+    -- 0: ``no_skip'', 1: ``after_schar'', 2: ``after_wchar''
+-- These variables are ``global'', because we want to avoid to write one large function.
+function ltj.insert_kanji_skip(head)
+   if tex.count['luatexja@autospc']==0 then
+      ltj.kanji_skip=tex.skip['kanjiskip']
+   else
+      ltj.kanji_skip=node.new(node.id('glue_spec'))
+      ltj.kanji_skip.width=0;  ltj.kanji_skip.stretch=0; ltj.kanji_skip.shrink=0
+   end
+   if tex.count['luatexja@autoxspc']==0 then
+      ltj.xkanji_skip=tex.skip['xkanjiskip']
+   else
+      ltj.xkanji_skip=node.new(node.id('glue_spec'))
+      ltj.xkanji_skip.width=0;  ltj.xkanji_skip.stretch=0; ltj.xkanji_skip.shrink=0
+   end
+   local p=head -- 「現在のnode」
+   local q=nil  -- pの一つ前 
+   ltj.insert_skip=0
+   while p do
+      if node.type(p.id)=='glyph' then
+        repeat 
+           ltj.insks_around_char(head,q,p)
+           q=p; p=node.next(p)
+        until (not p) or node.type(p.id)~='glyph'
+      else
+        if node.type(p.id) == 'hlist' then
+           ltj.insks_around_hbox(head,q,p)
+        elseif node.type(p.id) == 'penalty' then
+           ltj.insks_around_penalty(head,q,p)
+        elseif node.type(p.id) == 'kern' then
+           ltj.insks_around_kern(head,q,p)
+        elseif node.type(p.id) == 'math' then
+           ltj.insks_around_math(head,q,p)
+        elseif node.type(p.id) == 'ins' or node.type(p.id) == 'mark'
+            or node.type(p.id) == 'adjust'
+            or node.type(p.id) == 'whatsit' then
+           -- do nothing
+           p=p
+        else
+           -- rule, disc, glue, margin_kern
+           ltj.insert_skip=0
+        end
+        q=p; p=node.next(p)
+      end
+   end
+   return head
+end
+
+-- Insert \xkanjiskip before p, a glyph node
+-- TODO; ligature
+function ltj.insks_around_char(head,q,p)
+   local a=ltj.inhibit_xsp_table[p.char]
+   if ltj.is_japanese_glyph_node(p) then
+      ltj.cx=p.char
+      if ltj.is_japanese_glyph_node(q)  then
+        local g = node.new(node.id('glue'))
+        g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
+        node.insert_before(head,p,g)
+      elseif ltj.insert_skip==1 then
+        ltj.insert_akxsp(head,q)
+      end
+      ltj.insert_skip=2
+   else
+      if not a then a=3 end
+      if ltj.insert_skip==2 then
+        ltj.insert_kaxsp(head,q,a)
+      end
+      if  a>=2 then
+        ltj.insert_skip=1
+      else
+        ltj.insert_skip=0
+      end
+   end
+end
+
+function ltj.insert_akxsp(head,q)
+   local f = ltj.inhibit_xsp_table[ltj.cx]
+   local g
+   if f then 
+      if f<=1 then return end
+   end
+   g = node.new(node.id('glue'))
+   g.subtype=0; g.spec=node.copy(ltj.xkanji_skip)
+   node.insert_after(head,q,g)
+end
+
+function ltj.insert_kaxsp(head,q,a)
+   local g=true
+   local f=ltj.inhibit_xsp_table[ltj.cx]
+   if a%2 == 1 then
+      if f then 
+        if f%2==0 then g=false end
+      end
+   else 
+      g=false
+   end
+   if g then
+      g = node.new(node.id('glue'))
+      g.subtype=0; g.spec=node.copy(ltj.xkanji_skip)
+      node.insert_after(head,q,g)
+   end
+end
+
+-- Return first and last glyph nodes in a hbox
+ltj.first_char = nil
+ltj.last_char = nil
+ltj.find_first_char = nil
+function ltj.check_box(bp)
+   local p, flag
+   p=bp; flag=false
+   while p do
+      if node.type(p.id)=='glyph' then
+        repeat 
+           if ltj.find_first_char then
+              ltj.first_char=p; ltj.find_first_char=false
+           end
+           ltj.last_char=p; flag=true; p=node.next(p)
+           if not p then return flag end
+        until node.type(p.id)~='glyph'
+      end
+      if node.type(p.id)=='hlist' then
+        flag=true
+        if p.shift==0 then
+           if ltj.check_box(p.head) then flag=true end
+        else if ltj.find_first_char then 
+              ltj.find_first_char=false
+           else 
+              ltj.last_char=nil
+           end
+        end
+      elseif node.type(p.id) == 'ins' or node.type(p.id) == 'mark'
+         or node.type(p.id) == 'adjust' 
+         or node.type(p.id) == 'whatsit' or node.type(p.id) == 'penalty' then
+        p=p
+      else
+        flag=true
+        if ltj.find_first_char then 
+           ltj.find_first_char=false
+        else 
+           ltj.last_char=nil
+        end
+      end
+      p=node.next(p)
+   end
+   return flag
+end 
+
+-- Insert \xkanjiskip around p, an hbox
+function ltj.insks_around_hbox(head,q,p)
+   if p.shift==0 then
+      ltj.find_first_char=true
+      if ltj.check_box(p.head) then
+        -- first char
+        if ltj.is_japanese_glyph_node(ltj.first_char) then
+           ltj.cx=ltj.first_char.char
+           if ltj.insert_skip==1 then 
+              ltj.insert_akxsp(head,q)
+           elseif ltj.insert_skip==2 then
+              local g = node.new(node.id('glue'))
+              g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
+              node.insert_before(head,p,g)
+           end
+           ltj.insert_skip=2
+        elseif ltj.first_char then
+           local a=ltj.inhibit_xsp_table[ltj.first_char.char]
+           if not a then a=3 end
+           if ltj.insert_skip==2 then
+              local g = node.new(node.id('glue'))
+              g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
+              node.insert_after(head,q,g)
+           end
+           if  a>=2 then
+              ltj.insert_skip=1
+           else
+              ltj.insert_skip=0
+           end
+        end
+        -- last char
+        if ltj.is_japanese_glyph_node(ltj.last_char) then
+           if ltj.is_japanese_glyph_node(node.next(p)) then
+              local g = node.new(node.id('glue'))
+              g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
+              node.insert_after(head,p,g)
+           end
+           ltj.insert_skip=2
+        elseif ltj.last_char then
+           local a=ltj.inhibit_xsp_table[ltj.last_char.char]
+           if not a then a=3 end
+           if a>=2 then
+              ltj.insert_skip=1
+           else
+              ltj.insert_skip=0
+           end
+        else ltj.insert_skip=0
+        end
+      else ltj.insert_skip=0
+      end
+   else ltj.insert_skip=0
+   end
+end
+
+-- Insert \xkanjiskip around p, a penalty
+function ltj.insks_around_penalty(head,q,p)
+   local r=node.next(p)
+   if (not r) and node.type(r.id)=='glyph' then
+      local a=ltj.inhibit_xsp_table[r.char]
+      if ltj.is_japanese_glyph_node(r) then
+        ltj.cx=r.char
+        if ltj.is_japanese_glyph_node(p)  then
+           local g = node.new(node.id('glue'))
+           g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
+           node.insert_before(head,r,g)
+        elseif ltj.insert_skip==1 then
+           ltj.insert_akxsp(head,p)
+        end
+        q=p; p=node.next(p)
+        ltj.insert_skip=2
+      else
+        if not a then a=3 end
+        if ltj.insert_skip==2 then
+           ltj.insert_kaxsp(head,p,a)
+        end
+        if  a>=2 then
+           ltj.insert_skip=1
+        else
+           ltj.insert_skip=0
+        end
+      end
+   end
+end
+
+-- Insert \xkanjiskip around p, a kern
+function ltj.insks_around_kern(head,q,p)
+   if p.subtype==1 then -- \kern or \/
+      if node.has_attribute(p,luatexbase.attributes['luatexja@icflag']) then
+        p=p -- p is a kern from \/: do nothing
+      else
+        ltj.insert_skip=0
+      end
+   elseif p.subtype==2 then -- \accent: We ignore the accent character.
+      local v = node.next(node.next(node.next(p)))
+      if v and node.type(v.id)=='glyph' then
+        ltj.insks_around_char(head,q,v)
+      end
+   end
+end
+
+-- Insert \xkanjiskip around p, a math_node
+function ltj.insks_around_math(head,q,p)
+   local a=ltj.inhibit_xsp_table['math']
+   if not a then a=3 end
+   if (p.subtype==0) and (ltj.insert_skip==2) then
+      ltj.insert_kaxsp(head,q,a)
+      ltj.insert_skip=0
+   else
+      ltj.insert_skip=1
+   end
+end
+
+-- Shift baseline
+function ltj.baselineshift(head)
+   local p=head
+   local m=false -- is in math mode?
+   while p do 
+      local v=node.has_attribute(p,luatexbase.attributes['luatexja@yablshift'])
+      if v then
+        if node.type(p.id)=='glyph' then
+           p.yoffset=p.yoffset-v
+        elseif node.type(p.id)=='math' then
+           m=(p.subtype==0)
+        end
+        if m then -- boxes and rules are shifted only in math mode
+           if node.type(p.id)=='hlist' or node.type(p.id)=='vlist' then
+              p.shift=p.shift+v
+           elseif node.type(p.id)=='rule' then
+              p.height=p.height-v; p.depth=p.depth+v 
+           end
+        end
+      end
+      p=node.next(p)
+   end
+   return head
+end
+
+
+-- main process
+function ltj.main_process(head)
+   local p = head
+   p = ltj.insert_jfm_glue(p)
+   p = ltj.insert_kanji_skip(p)
+   p = ltj.baselineshift(p)
+   return p
+end
+
+--- the following function is modified from jafontspec.lua (by K. Maeda).
+--- Instead of "%", we use U+FFFFF for suppressing spaces.
+utf = unicode.utf8
+function ltj.process_input_buffer(buffer)
+--     print(utf.byte(buffer, utf.len(buffer)))
+   if utf.len(buffer) > 0 
+        and ltj.is_ucs_in_japanese_char(utf.byte(buffer, utf.len(buffer))) then
+       buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
+   end
+   return buffer
+end
+
+
+---------- Hyphenate
+
+-- 
+function ltj.suppress_hyphenate_ja(head)
+   local p=head
+   while p do 
+      if node.type(p.id)=='glyph' and  ltj.is_ucs_in_japanese_char(p.char) then
+        local v = node.has_attribute(p,luatexbase.attributes['luatexja@curjfnt'])
+        if v then p.font=v end
+        v=node.has_attribute(p,luatexbase.attributes['luatexja@ykblshift'])
+        if v then 
+           node.set_attribute(p,luatexbase.attributes['luatexja@yablshift'],v)
+        else
+           node.unset_attribute(p,luatexbase.attributes['luatexja@yablshift'])
+        end
+        p.lang=ltj.ja_lang_number
+      end
+      p=node.next(p)
+   end
+   lang.hyphenate(head) 
+end
+
+-- callback
+luatexbase.add_to_callback('process_input_buffer', 
+   function (buffer)
+     return ltj.process_input_buffer(buffer)
+   end,'ltj.process_input_buffer')
+luatexbase.add_to_callback('pre_linebreak_filter', 
+   function (head,groupcode)
+     return ltj.main_process(head)
+   end,'ltj.pre_linebreak_filter')
+luatexbase.add_to_callback('hpack_filter', 
+  function (head,groupcode,size,packtype)
+     return ltj.main_process(ltj.replace_ja_font(head))
+  end,'ltj.hpack_filter')
+luatexbase.add_to_callback('hyphenate', 
+ function (head,tail)
+    return ltj.suppress_hyphenate_ja(head)
+ end,'ltj.hyphenate')
diff --git a/src/luatexja-core.sty b/src/luatexja-core.sty
new file mode 100644 (file)
index 0000000..19769fa
--- /dev/null
@@ -0,0 +1,83 @@
+\input luaotfload.sty
+\catcode`\@=11
+\catcode"FFFFF=14 %"
+
+\ifdefined\luatexja@loaded\endinput\fi
+\def\luatexja@loaded{hoge}
+
+\newcount\luatexja@tempcnta
+\newdimen\luatexja@tempdima
+%\newcount\jcharwidowpenalty
+\newskip\kanjiskip\kanjiskip=0pt minus.4pt
+\newskip\xkanjiskip
+\newdimen\zw
+\newdimen\zh
+\newdimen\jQ \jQ=0.25mm
+\newdimen\jH \jH=0.25mm
+\newcount\luatexja@autospc
+\newcount\luatexja@autoxspc
+
+\directlua{%
+  ltj = {}
+  function ltj.loadlua(file)
+    local path = assert(kpse.find_file(file, 'tex'),
+      "File '"..file.."' no found")
+    texio.write_nl("("..path..")")
+    dofile(path)
+  end
+  ltj.loadlua('luatexja-core.lua')
+  ltj.loadlua('luatexja-core-aux.lua')
+}
+
+% Attributes for Japanese typesetting.
+\newluatexattribute\luatexja@curjfnt   % index for ``current Japanese font''
+\newluatexattribute\luatexja@yablshift % attribute for \yabaselineshift
+\newluatexattribute\luatexja@ykblshift % attribute for \ykbaselineshift
+
+% for italic correction
+\newluatexattribute\luatexja@icflag
+\let\luatexja@ic=\/
+\def\/{{\luatexja@icflag=1\luatexja@ic}}
+
+% for hyphenation
+\newlanguage\luatexja@japanese
+\directlua{ltj.ja_lang_number=\the\luatexja@japanese}
+
+
+% \jfont<font><metric name> : Regard <font> as a Japanese font.
+% <font> must be defined by \font primitive already, and <metric> must be a control 
+% sequence defined by \loadjfontmetric below.
+\def\jfont{\directlua{ltj.jfontdefA(true)}}
+\def\@jfont#1{\directlua{ltj.jfontdefB('#1')}}
+
+% \loadjfontmetric<metric name><filename> : 
+% load <filename> which contains a font metric for a Japanese font.
+\def\loadjfontmetric#1#2{% #1: key, #2: file name
+\directlua{
+  jfm.name='#1'; jfm.char_type={}; jfm.glue={}; jfm.kern={}
+  ltj.loadlua('luatj-#2.lua'); ltj.loadjfontmetric()}
+}
+
+% ybaselineshift
+\let\yabaselineshift=\luatexja@yablshift % 欧文文字
+\let\ykbaselineshift=\luatexja@ykblshift % 和文文字
+\luatexja@yablshift=0 \luatexja@ykblshift=0
+
+% \inhibitxspcode, \xspcode
+\def\inhibitxspcode#1#2{\directlua{ltj.set_inhibit_xsp_table(#1,#2)}}
+\let\xspcode=\inhibitxspcode
+% \prebreakpenalty, \postbreakpenalty
+\def\prebreakpenalty#1#2{\directlua{ltj.set_penalty_table('pre',#1,#2)}}
+\def\postbreakpenalty#1#2{\directlua{ltj.set_penalty_table('post',#1,#2)}}
+
+\def\autospacing{\luatexja@autospc=0 }
+\def\noautospacing{\luatexja@autospc=1 }
+\def\autoxspacing{\luatexja@autoxspc=0 }
+\def\noautoxspacing{\luatexja@autoxspc=1 }
+\autospacing\autoxspacing
+% \inhibitglue
+\def\inhibitglue{\directlua{ltj.create_ihb_node()}}
+
+\input luatexja-kinsoku.tex
+\catcode`\@=12
+\endinput
diff --git a/src/luatexja-kinsoku.tex b/src/luatexja-kinsoku.tex
new file mode 100644 (file)
index 0000000..d2cca2e
--- /dev/null
@@ -0,0 +1,352 @@
+%0}{0}
+\prebreakpenalty{33}{10000}
+\prebreakpenalty{34}{10000}
+\postbreakpenalty{35}{500}
+\postbreakpenalty{36}{500}
+\postbreakpenalty{37}{500}
+\postbreakpenalty{38}{500}
+\postbreakpenalty{96}{10000}
+\prebreakpenalty{39}{10000}
+\prebreakpenalty{41}{10000}
+\postbreakpenalty{40}{10000}
+\prebreakpenalty{42}{500}
+\prebreakpenalty{43}{500}
+\prebreakpenalty{45}{10000}
+\prebreakpenalty{46}{10000}
+\prebreakpenalty{44}{10000}
+\prebreakpenalty{47}{500}
+\prebreakpenalty{59}{10000}
+\prebreakpenalty{63}{10000}
+\prebreakpenalty{58}{10000}
+\prebreakpenalty{93}{10000}
+\postbreakpenalty{91}{10000}
+\prebreakpenalty{12289}{10000}
+\prebreakpenalty{12290}{10000}
+\prebreakpenalty{65292}{10000}
+\prebreakpenalty{65294}{10000}
+\prebreakpenalty{12539}{10000}
+\prebreakpenalty{65306}{10000}
+\prebreakpenalty{65307}{10000}
+\prebreakpenalty{65311}{10000}
+\prebreakpenalty{65281}{10000}
+\prebreakpenalty{12443}{10000}
+\prebreakpenalty{12444}{10000}
+\prebreakpenalty{180}{10000}
+\postbreakpenalty{65344}{10000}
+\prebreakpenalty{12293}{10000}
+\prebreakpenalty{8230}{250}
+\prebreakpenalty{8229}{250}
+\postbreakpenalty{8216}{10000}
+\prebreakpenalty{8217}{10000}
+\postbreakpenalty{8220}{10000}
+\prebreakpenalty{8221}{10000}
+\prebreakpenalty{65289}{10000}
+\postbreakpenalty{65288}{10000}
+\prebreakpenalty{65373}{10000}
+\postbreakpenalty{65371}{10000}
+\prebreakpenalty{65341}{10000}
+\postbreakpenalty{65339}{10000}
+\postbreakpenalty{12308}{10000}
+\prebreakpenalty{12309}{10000}
+\postbreakpenalty{12296}{10000}
+\prebreakpenalty{12297}{10000}
+\postbreakpenalty{12298}{10000}
+\prebreakpenalty{12299}{10000}
+\postbreakpenalty{12300}{10000}
+\prebreakpenalty{12301}{10000}
+\postbreakpenalty{12302}{10000}
+\prebreakpenalty{12303}{10000}
+\postbreakpenalty{12304}{10000}
+\prebreakpenalty{12305}{10000}
+\prebreakpenalty{12540}{10000}
+\prebreakpenalty{65291}{200}
+\prebreakpenalty{8722}{200}
+\prebreakpenalty{65293}{200}
+\prebreakpenalty{65309}{200}
+\postbreakpenalty{65283}{200}
+\postbreakpenalty{65284}{200}
+\postbreakpenalty{65285}{200}
+\postbreakpenalty{65286}{200}
+\prebreakpenalty{12353}{150}
+\prebreakpenalty{12355}{150}
+\prebreakpenalty{12357}{150}
+\prebreakpenalty{12359}{150}
+\prebreakpenalty{12361}{150}
+\prebreakpenalty{12387}{150}
+\prebreakpenalty{12419}{150}
+\prebreakpenalty{12421}{150}
+\prebreakpenalty{12423}{150}
+\prebreakpenalty{12430}{150}
+\prebreakpenalty{12449}{150}
+\prebreakpenalty{12451}{150}
+\prebreakpenalty{12453}{150}
+\prebreakpenalty{12455}{150}
+\prebreakpenalty{12457}{150}
+\prebreakpenalty{12483}{150}
+\prebreakpenalty{12515}{150}
+\prebreakpenalty{12517}{150}
+\prebreakpenalty{12519}{150}
+\prebreakpenalty{12526}{150}
+\prebreakpenalty{12533}{150}
+\prebreakpenalty{12534}{150}
+\prebreakpenalty{12541}{10000}
+\prebreakpenalty{12542}{10000}
+\prebreakpenalty{12445}{10000}
+\prebreakpenalty{12446}{10000}
+\prebreakpenalty{12339}{10000}
+\prebreakpenalty{12340}{10000}
+\prebreakpenalty{12341}{10000}
+\prebreakpenalty{12347}{10000}
+\postbreakpenalty{10629}{10000}
+\prebreakpenalty{10630}{10000}
+\postbreakpenalty{65375}{10000}
+\prebreakpenalty{65376}{10000}
+\postbreakpenalty{12312}{10000}
+\prebreakpenalty{12313}{10000}
+\postbreakpenalty{12310}{10000}
+\prebreakpenalty{12311}{10000}
+\postbreakpenalty{171}{10000}
+\prebreakpenalty{187}{10000}
+\postbreakpenalty{12317}{10000}
+\prebreakpenalty{12319}{10000}
+\prebreakpenalty{8252}{10000}
+\prebreakpenalty{8263}{10000}
+\prebreakpenalty{8264}{10000}
+\prebreakpenalty{8265}{10000}
+\postbreakpenalty{161}{10000}
+\postbreakpenalty{191}{10000}
+\prebreakpenalty{720}{10000}
+\prebreakpenalty{170}{10000}
+\prebreakpenalty{186}{10000}
+\prebreakpenalty{185}{10000}
+\prebreakpenalty{178}{10000}
+\prebreakpenalty{179}{10000}
+\postbreakpenalty{8364}{10000}
+\prebreakpenalty{12437}{150}
+\prebreakpenalty{12438}{150}
+\prebreakpenalty{12784}{150}
+\prebreakpenalty{12785}{150}
+\prebreakpenalty{12786}{150}
+\prebreakpenalty{12787}{150}
+\prebreakpenalty{12788}{150}
+\prebreakpenalty{12789}{150}
+\prebreakpenalty{12790}{150}
+\prebreakpenalty{12791}{150}
+\prebreakpenalty{12792}{150}
+\prebreakpenalty{12793}{150}
+\prebreakpenalty{12794}{150}
+\prebreakpenalty{12795}{150}
+\prebreakpenalty{12796}{150}
+\prebreakpenalty{12797}{150}
+\prebreakpenalty{12798}{150}
+\prebreakpenalty{12799}{150}
+\prebreakpenalty{8482}{10000}
+\prebreakpenalty{65377}{10000}
+\prebreakpenalty{65380}{10000}
+\prebreakpenalty{65438}{10000}
+\prebreakpenalty{65439}{10000}
+\prebreakpenalty{65379}{10000}
+\postbreakpenalty{65378}{10000}
+\xspcode{40}{1}
+\xspcode{41}{2}
+\xspcode{91}{1}
+\xspcode{93}{2}
+\xspcode{96}{1}
+\xspcode{39}{2}
+\xspcode{59}{2}
+\xspcode{44}{2}
+\xspcode{46}{2}
+\xspcode{128}{3}
+\xspcode{129}{3}
+\xspcode{130}{3}
+\xspcode{131}{3}
+\xspcode{132}{3}
+\xspcode{133}{3}
+\xspcode{134}{3}
+\xspcode{135}{3}
+\xspcode{136}{3}
+\xspcode{137}{3}
+\xspcode{138}{3}
+\xspcode{139}{3}
+\xspcode{140}{3}
+\xspcode{141}{3}
+\xspcode{142}{3}
+\xspcode{143}{3}
+\xspcode{144}{3}
+\xspcode{145}{3}
+\xspcode{146}{3}
+\xspcode{147}{3}
+\xspcode{148}{3}
+\xspcode{149}{3}
+\xspcode{150}{3}
+\xspcode{151}{3}
+\xspcode{152}{3}
+\xspcode{153}{3}
+\xspcode{154}{3}
+\xspcode{155}{3}
+\xspcode{156}{3}
+\xspcode{157}{3}
+\xspcode{158}{3}
+\xspcode{159}{3}
+\xspcode{160}{3}
+\xspcode{161}{3}
+\xspcode{162}{3}
+\xspcode{163}{3}
+\xspcode{164}{3}
+\xspcode{165}{3}
+\xspcode{166}{3}
+\xspcode{167}{3}
+\xspcode{168}{3}
+\xspcode{169}{3}
+\xspcode{170}{3}
+\xspcode{171}{3}
+\xspcode{172}{3}
+\xspcode{173}{3}
+\xspcode{174}{3}
+\xspcode{175}{3}
+\xspcode{176}{3}
+\xspcode{177}{3}
+\xspcode{178}{3}
+\xspcode{179}{3}
+\xspcode{180}{3}
+\xspcode{181}{3}
+\xspcode{182}{3}
+\xspcode{183}{3}
+\xspcode{184}{3}
+\xspcode{185}{3}
+\xspcode{186}{3}
+\xspcode{187}{3}
+\xspcode{188}{3}
+\xspcode{189}{3}
+\xspcode{190}{3}
+\xspcode{191}{3}
+\xspcode{192}{3}
+\xspcode{193}{3}
+\xspcode{194}{3}
+\xspcode{195}{3}
+\xspcode{196}{3}
+\xspcode{197}{3}
+\xspcode{198}{3}
+\xspcode{199}{3}
+\xspcode{200}{3}
+\xspcode{201}{3}
+\xspcode{202}{3}
+\xspcode{203}{3}
+\xspcode{204}{3}
+\xspcode{205}{3}
+\xspcode{206}{3}
+\xspcode{207}{3}
+\xspcode{208}{3}
+\xspcode{209}{3}
+\xspcode{210}{3}
+\xspcode{211}{3}
+\xspcode{212}{3}
+\xspcode{213}{3}
+\xspcode{214}{3}
+\xspcode{215}{3}
+\xspcode{216}{3}
+\xspcode{217}{3}
+\xspcode{218}{3}
+\xspcode{219}{3}
+\xspcode{220}{3}
+\xspcode{221}{3}
+\xspcode{222}{3}
+\xspcode{223}{3}
+\xspcode{224}{3}
+\xspcode{225}{3}
+\xspcode{226}{3}
+\xspcode{227}{3}
+\xspcode{228}{3}
+\xspcode{229}{3}
+\xspcode{230}{3}
+\xspcode{231}{3}
+\xspcode{232}{3}
+\xspcode{233}{3}
+\xspcode{234}{3}
+\xspcode{235}{3}
+\xspcode{236}{3}
+\xspcode{237}{3}
+\xspcode{238}{3}
+\xspcode{239}{3}
+\xspcode{240}{3}
+\xspcode{241}{3}
+\xspcode{242}{3}
+\xspcode{243}{3}
+\xspcode{244}{3}
+\xspcode{245}{3}
+\xspcode{246}{3}
+\xspcode{247}{3}
+\xspcode{248}{3}
+\xspcode{249}{3}
+\xspcode{250}{3}
+\xspcode{251}{3}
+\xspcode{252}{3}
+\xspcode{253}{3}
+\xspcode{254}{3}
+\xspcode{255}{3}
+\inhibitxspcode{12289}{1}
+\inhibitxspcode{12290}{1}
+\inhibitxspcode{65292}{1}
+\inhibitxspcode{65294}{1}
+\inhibitxspcode{65307}{1}
+\inhibitxspcode{65311}{1}
+\inhibitxspcode{65289}{1}
+\inhibitxspcode{65288}{2}
+\inhibitxspcode{65341}{1}
+\inhibitxspcode{65339}{2}
+\inhibitxspcode{65373}{1}
+\inhibitxspcode{65371}{2}
+\inhibitxspcode{8216}{2}
+\inhibitxspcode{8217}{1}
+\inhibitxspcode{8220}{2}
+\inhibitxspcode{8221}{1}
+\inhibitxspcode{12308}{2}
+\inhibitxspcode{12309}{1}
+\inhibitxspcode{12296}{2}
+\inhibitxspcode{12297}{1}
+\inhibitxspcode{12298}{2}
+\inhibitxspcode{12299}{1}
+\inhibitxspcode{12300}{2}
+\inhibitxspcode{12301}{1}
+\inhibitxspcode{12302}{2}
+\inhibitxspcode{12303}{1}
+\inhibitxspcode{12304}{2}
+\inhibitxspcode{12305}{1}
+\inhibitxspcode{8212}{0}
+\inhibitxspcode{8213}{0}
+\inhibitxspcode{12316}{0}
+\inhibitxspcode{65374}{0}
+\inhibitxspcode{8230}{0}
+\inhibitxspcode{165}{0}
+\inhibitxspcode{65509}{0}
+\inhibitxspcode{176}{1}
+\inhibitxspcode{8242}{1}
+\inhibitxspcode{8243}{1}
+\inhibitxspcode{10629}{2}
+\inhibitxspcode{10630}{1}
+\inhibitxspcode{65375}{2}
+\inhibitxspcode{65376}{1}
+\inhibitxspcode{12312}{2}
+\inhibitxspcode{12313}{1}
+\inhibitxspcode{12310}{2}
+\inhibitxspcode{12311}{1}
+\inhibitxspcode{171}{2}
+\inhibitxspcode{187}{1}
+\inhibitxspcode{12317}{2}
+\inhibitxspcode{12319}{1}
+\inhibitxspcode{8252}{1}
+\inhibitxspcode{8263}{1}
+\inhibitxspcode{8264}{1}
+\inhibitxspcode{8265}{1}
+\inhibitxspcode{161}{2}
+\inhibitxspcode{191}{2}
+\inhibitxspcode{170}{1}
+\inhibitxspcode{186}{1}
+\inhibitxspcode{185}{1}
+\inhibitxspcode{178}{1}
+\inhibitxspcode{179}{1}
+\inhibitxspcode{8364}{2}
+\inhibitxspcode{8482}{1}
+\inhibitxspcode{65377}{1}
+\inhibitxspcode{65380}{1}
+\inhibitxspcode{65378}{2}
diff --git a/src/luatexja-kinsoku_make.tex b/src/luatexja-kinsoku_make.tex
new file mode 100644 (file)
index 0000000..b517369
--- /dev/null
@@ -0,0 +1,17 @@
+\parindent0pt
+\output={\shipout\box255}
+\tt\catcode`\_=12
+\def\{{\char'173 }\def\}{\char'175}
+\toks0={\%}
+\def\postbreakpenalty{\out\toks0={\string\postbreakpenalty\{}\count600 }%
+\def\prebreakpenalty{\out\toks0={\string\prebreakpenalty\{}\count600 }%
+\def\inhibitxspcode{\out\toks0={\string\inhibitxspcode\{}\count600 }%
+\def\xspcode{\out\toks0={\string\xspcode\{}\count600 }%
+\catcode`\=13
+\def={\count601 }%\
+\def\out{\par\the\toks0 \the\count600\}\{\the\count601\}}
+\input ukinsoku
+\end
+
+% euptex pte-kinsoku-make ; dvitype -output-level=1 pte-kinsoku-make
+% | grep "\[" | sed "s/\[\(.*\)\]/\1/" > pte-kinsoku.tex
\ No newline at end of file
diff --git a/src/luatj-mono.lua b/src/luatj-mono.lua
new file mode 100644 (file)
index 0000000..d927903
--- /dev/null
@@ -0,0 +1,3 @@
+jfm.dir = 'yoko'
+jfm.zw= 1.0; jfm.zh = 1.0
+jfm.define_type_dim(0, 0.0 , 1.0 , 0.88, 0.12, 0.0)
\ No newline at end of file
diff --git a/src/luatj-ujis.lua b/src/luatj-ujis.lua
new file mode 100644 (file)
index 0000000..9fc6c0a
--- /dev/null
@@ -0,0 +1,70 @@
+-- A sample of Japanese font metric for pluatex
+-- The unit of <height>, <depth>: 
+-- The unit of other dimension: the design size
+
+jfm.dir = 'yoko'
+-- 'yoko'
+
+jfm.zw= 1.0; jfm.zh = 1.0
+-- amount of ``1zw'' and ``1zh'' (these units are used in pTeX)
+
+
+-- character type
+-- jfm.define_char_type(<type>, <letters>)
+jfm.define_char_type(1, {
+  0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016, 
+  0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F
+                    })
+jfm.define_char_type(2, {
+  0x2019, 0x201D, 0x3001, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015, 
+  0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60
+                    })
+jfm.define_char_type(3, {0x30FB, 0xFF1A, 0xFF1B})
+jfm.define_char_type(4, {0x3002, 0xFF0E})
+jfm.define_char_type(5, {0x2015, 0x2025, 0x2026})
+jfm.define_char_type(6, {'boxbdd'})
+
+-- 'boxbdd' matches 
+--       o the beginning of paragraphs and hboxes
+--       o the ending of paragraphs and hboxes
+--       o just after the hbox created by \parindent
+
+-- 'jcharbdd' matches the boundary between two Japanese characters whose metrics (or sizes) 
+--            are different.
+
+-- 'diffmet' matches the boundary between a Japanese character 
+--           and a material which is not a Japanese character.
+
+-- dimension
+-- jfm.define_type_dim(<type>, <left>, <width>, <height>, <depth>, <italic correction>)
+jfm.define_type_dim(0, 0.0 , 1.0 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(1, 0.5 , 0.5 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(2, 0.0 , 0.5 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(3, 0.25, 0.5 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(4, 0.0 , 0.5 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(5, 0.0 , 1.0 , 0.88, 0.12, 0.0)
+-- jfm.define_type_dim(6, 0.0 , 1.0 , 0.88, 0.12, 0.0): does not needed
+
+-- glue/kern
+-- jfm.define_glue(<btype>, <atype>, <width>, <stretch>, <shrink>)
+-- jfm.define_kern(<btype>, <atype>, <width>)
+jfm.define_glue(0,1, 0.5 , 0.0, 0.5 )
+jfm.define_glue(0,3, 0.25, 0.0, 0.25)
+jfm.define_glue(1,3, 0.25, 0.0, 0.25)
+jfm.define_glue(2,0, 0.5 , 0.0, 0.5 )
+jfm.define_glue(2,1, 0.5 , 0.0, 0.5 )
+jfm.define_glue(2,3, 0.25, 0.0, 0.25)
+jfm.define_glue(2,5, 0.5 , 0.0, 0.5 )
+jfm.define_glue(3,0, 0.25, 0.0, 0.25)
+jfm.define_glue(3,1, 0.25, 0.0, 0.25)
+jfm.define_glue(3,2, 0.25, 0.0, 0.25)
+jfm.define_glue(3,3, 0.5 , 0.0, 0.5 )
+jfm.define_glue(3,4, 0.25, 0.0, 0.25)
+jfm.define_glue(3,5, 0.25, 0.0, 0.25)
+jfm.define_glue(4,0, 0.5 , 0.0, 0.0 )
+jfm.define_glue(4,1, 0.5 , 0.0, 0.0 )
+jfm.define_glue(4,3, 0.75, 0.0, 0.25)
+jfm.define_glue(4,5, 0.5 , 0.0, 0.0 )
+jfm.define_glue(5,1, 0.5 , 0.0, 0.5 )
+jfm.define_glue(5,3, 0.25, 0.0, 0.25)
+jfm.define_kern(5,5, 0.0)
\ No newline at end of file