• R/O
  • HTTP
  • SSH
  • HTTPS

luatexja: コミット

ソースコードの管理場所


コミットメタ情報

リビジョン48a5e4f90be30f875b41cdad85d902525fe88ac7 (tree)
日時2011-04-17 17:17:55
作者Hironori Kitagawa <h_kitagawa2001@yaho...>
コミッターHironori Kitagawa

ログメッセージ

Fixed the insertion process of \xkanjiskip around ligatures,
and several parameters (e.g. prebreakpenalty) can be changed locally.

変更サマリ

差分

--- a/doc/s1sty.tex
+++ b/doc/s1sty.tex
@@ -25,6 +25,7 @@
2525 \def\minfnt{psft:Ryumin-Light:jfm=ujis }
2626 \def\gothfnt{psft:GothicBBB-Medium:jfm=ujis }
2727 \jfont\eightmc=\minfnt at 10.5\jQ
28+\jfont\eightjtt={psft:GothicBBB-Medium:jfm=mono} at 10.5\jQ
2829 \jfont\eightgt=\gothfnt at 10.5\jQ
2930 \let\tenmc=\tenmin
3031 \jfont\tenjtt={psft:GothicBBB-Medium:jfm=mono} at 13.5\jQ
@@ -76,12 +77,13 @@
7677 \chardef\other=12
7778 \newbox\vspbox
7879 \setbox\vspbox=\hbox{\tt\char32}
79-{\catcode`\ =\active%\catcode`\%=\active
80+{\catcode`\ =\active\catcode`\_=\active%\catcode`\%=\active
8081 \gdef\ttverbatim{\begingroup\xkanjiskip=0pt
8182 \catcode`\ =\active\let =~\catcode`\%=\other
8283 \catcode`\\=\other\catcode`\{=\other\catcode`\}=\other
8384 \catcode`\$=\other\catcode`\&=\other\catcode`\#=\other\catcode`\~=\other
84-\catcode`\_=\other\catcode`\^=\other\catcode"FFFFF=12%" <- needed
85+\catcode`\_=\active\catcode`\^=\other\catcode"FFFFF=12%" <- needed
86+\let_=\_%
8587 \obeyspaces\obeylines\tt}}
8688
8789 \abovedisplayskip=\medskipamount
@@ -97,8 +99,10 @@
9799 \catcode`\|=\active
98100 {\obeylines \gdef|{\ttverbatim \spaceskip.5em\let^^M=\ \let|=\endgroup}}
99101
100-\catcode`\<=\active
101-\def<#1>{{\it$\langle$#1$\rangle$}}
102+{\catcode`\_=\active \global\catcode`\<=\active
103+\gdef<{\begingroup\catcode`\_=\active\let_=\_\it\@arg}
104+\gdef\@arg#1>{$\langle$#1$\rangle$\endgroup}
105+}
102106
103107 % itemize
104108 \newcount\enumi\enumi=0
@@ -108,5 +112,6 @@
108112 \def\enum{\par\medskip\advance\enumi1\leftskip=3\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss\the\enumi.\kern0.5\zw}}
109113 \def\enditem{\medskip\par\enumi=0\leftskip=0pt\parskip=0pt\noindent}
110114
115+\setjaparameter{cjkxspmode={`★,0}}
111116
112117 \endinput
Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ
--- a/doc/sample1.tex
+++ b/doc/sample1.tex
@@ -27,7 +27,7 @@
2727
2828 \beginparagraph 特徴
2929
30-\item 欧文フォント/和文フォントの内部独立管理.
30+\item 欧文フォント/和文フォントの外部独立管理.
3131 \item 違う和文フォントでも「メトリックが同じ」なら,字間に空白を挿入する際には同じものとして扱う.
3232 {\bf 例}: 「ほげほげ){\gt (ふがふが}」は以下の出力より得られた:
3333 \begintt
@@ -40,10 +40,9 @@
4040 \beginparagraph 制限
4141
4242 \item 全体的にテスト不足です.
43-\item 合字の前後の和欧文間空白の挿入処理は適当{\small(合字でない場合の処理をそのまま流用)\inhibitglue}.
44-\item {\bf 現時点で\LaTeX での使用は殆ど考慮されていません.``plain Lua\TeX''で使ってください.}
45-\item |\accent|を和文文字に対して使うことはできません.これは「フォントを後で置換する」という実装上,
46-仕方のないことだと思われます.
43+\item {\bf 現時点で\LaTeX での使用は殆ど考慮されていません.今は``plain Lua\TeX''で使ってください.}
44+\item |\accent|を和文文字に対して使うことはできません.
45+これは「フォントを後で置換する」という実装上,仕方のないことだと思われます.
4746 \item 数式中の日本語は想定していません.|\hbox|か何かで囲ってください.
4847 \item p\TeX にあった以下の機能はまだ実装していません.
4948 \itemitem |\euc|, |\jis|, |\sjis|, |\kuten|といった,コード変換プリミティブ.
@@ -63,12 +62,13 @@
6362 \item {\tt luatexja-core.lua}: コア部分に使われるLuaコード.
6463 \item {\tt luatexja-jfont.lua}: 和文フォント定義部のLuaコード.
6564 \item {\tt luatexja-rmlgbm-data.lua}: 非埋込和文フォント用のデータ(小塚明朝Pr6N R由来).
66-\item {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト(小塚明朝を{\tt luaotfload}で読み込んだ時のキャッシュが必要).
65+\item {\tt luatexja-rmlgbm.lua}: 非埋込和文フォント (Ryumin-Light etc.) 定義部.
66+\item {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト
67+{\small(小塚明朝を{\tt luaotfload}で読み込んだ時のキャッシュが必要)\inhibitglue}.
6768 \item {\tt luatexja-kinsoku.tex}: 禁則用ペナルティ等のパラメータを書いたファイル.
6869 下のファイルによって{\tt ukinsoku.tex} (in up\TeX-0.30) から自動生成されたもの.
69-\item {\tt luatexja-kinsoku\_make.tex}: 上の{\tt luatexja-kinsoku.tex}製作用ファイル.
70-\item {\tt luatj-ujis.lua}: up\TeX-0.30の{\tt ujis.tfm}ベースのメトリックサンプル.
71-\item {\tt luatj-mono.lua}: 「全文字が全角幅」のメトリックサンプル.
70+\item {\tt jfm-ujis.lua}: up\TeX-0.30の{\tt ujis.tfm}ベースのメトリックサンプル.
71+\item {\tt jfm-mono.lua}: 「全文字が全角幅」のメトリックサンプル.
7272 \enditem
7373
7474 \beginsection 使用方法
@@ -139,20 +139,20 @@ JFM は和文文字の幅や,和文文字間の空白の入り方などを規
139139 \TeX の|\font| primitiveと同様の書式を持った次の命令を用いて和文フォントを定義する:
140140
141141 \begintt
142- \jfont<font>={<fontname>:<features>} <size> % local に定義
143- \gjfont<font>={<fontname>:<features>} <size> % global に定義
142+ \jfont<font>={<font_name>:<features>} <size> % local に定義
143+ \gjfont<font>={<font_name>:<features>} <size> % global に定義
144144 \endtt
145145
146146
147-\item {\bf <fontname> の指定について}\par\noindent
147+\item {\bf <font_name> の指定について}\par\noindent
148148 内部でluaotfloadパッケージを読み込んでいる.大きくわけて,以下の4種類がある.
149149 このうち,前の2つはluaotfloadパッケージの機能である.
150-\itemitem |file:<filename>|\par\noindent
151-TrueType/OpenTypeフォントをファイル名<filename>で指定.
152-\itemitem |name:<fontname>|\par\noindent
153-システム内のフォント名を<fontname>に指定することも可能.
154-\itemitem |psft:<PSfontname>|\par\noindent
155-PSフォント名<PSfontname>を直接指定することもでき,
150+\itemitem |file:<file_name>|\par\noindent
151+TrueType/OpenTypeフォントをファイル名<file_name>で指定.
152+\itemitem |name:<font_name>|\par\noindent
153+システム内のフォント名を<font_name>に指定することも可能.
154+\itemitem |psft:<PSfont_name>|\par\noindent
155+PSフォント名<PSfont_name>を直接指定することもでき,
156156 この場合はフォントは名前だけ(非埋込)となる.
157157 例えば,本文章では,
158158 \begintt
@@ -163,7 +163,7 @@ PSフォント名<PSfontname>を直接指定することもでき,
163163 %\itemitem |vf:<vfname>|
164164
165165 \item {\bf JFMの指定}:<features>欄に次を指定する.\par\noindent
166-\itemitem |jfm=<jfmfile>|: JFMとして|jfm-<jfmfile>.lua|を用いることを示す.必須.
166+\itemitem |jfm=<jfm_file>|: JFMとして|jfm-<jfm_file>.lua|を用いることを示す.必須.
167167 \itemitem |jfmvar=<varkey>|\par\noindent
168168 和文文字間の空白の挿入処理は,使用するJFMと,この<varkey>の値とのペアによって行われる.
169169
@@ -171,7 +171,8 @@ PSフォント名<PSfontname>を直接指定することもでき,
171171 \begintt
172172 \jfont\tenipam={file:ipaexm.ttf:script=latn;+jp90;jfm=mt}
173173 \endtt
174-なお,非埋込の場合は,GSUB/GPOSテーブルとして小塚明朝 Pr6N Rのものが用いられる.
174+なお,非埋込の場合は,GSUB/GPOSテーブルとして小塚明朝 Pr6N Rのものが用いられる
175+(|test01-noembed.pdf|を参照).
175176 \enditem
176177
177178 \beginparagraph 組版パラメタの調整
@@ -188,27 +189,27 @@ PSフォント名<PSfontname>を直接指定することもでき,
188189
189190 \enum ◎がついているものは,自動的にglobalな代入となってしまうもの.
190191
191-\item |prebreakpenalty={<chrcode>, <penalty>}|★◎\par\noindent
192+\item |prebreakpenalty={<chr_code>, <penalty>}|★\par\noindent
192193 p\TeX の|\prebreakpenalty|に対応した設定項目である.
193-\itemitem <chrcode>: 文字コードを指定する.一旦補助カウンタに代入されるので,
194+\itemitem <chr_code>: 文字コードを指定する.一旦補助カウンタに代入されるので,
194195 16進法での数値の指定 (|"abcd|) や,%"
195196 文字トークンによる指定 (|`あ|) も可能である.
196197 \itemitem <penalty>: penalty の値を0から10000までの自然数で指定する
197198 {\small(範囲外でも可能だが)\inhibitglue}.
198199
199-\item |postbreakpenalty={<chrcode>, <penalty>}|★◎\par\noindent
200+\item |postbreakpenalty={<chr_code>, <penalty>}|★\par\noindent
200201 同様に,p\TeX の|\postbreakpenalty|に対応した設定項目である.
201202 p\TeX では,同一文字に対して|\prebreakpenalty|, |\postbreakpenalty|の両方を定義する
202203 ことはできなかったが,Lua\TeX-jaでは可能である.
203204
204-\item |cjkxspmode={<chrcode>, <mode>}|★◎\par\noindent
205+\item |cjkxspmode={<chr_code>, <mode>}|★\par\noindent
205206 p\TeX の|\inhibitxspcode|に対応した設定項目である.<mode>で許される値は,
206207 \itemitem 0, 1, 2, 3: p\TeX の対応するprimitiveと同じ意味.
207208 \itemitem |inhibit|: 前後の欧文文字との間の|\xkanjiskip|自動挿入を禁止.
208209 \itemitem |preonly|: 前の欧文文字との間の|\xkanjiskip|自動挿入のみを許可.
209210 \itemitem |postonly|: 後の欧文文字との間の|\xkanjiskip|自動挿入のみを許可.
210211 \itemitem |allow|: 前後の欧文文字との間の|\xkanjiskip|自動挿入を許可.
211-\item |asciixspmode={<chrcode>, <mode>}|★◎\par\noindent
212+\item |asciixspmode={<chr_code>, <mode>}|★\par\noindent
212213 同様に,p\TeX の|\xspcode|に対応した設定項目である.
213214 \item |yabaselineshift=<dimen>|:
214215 欧文文字のベースライン補正量をdimensionで指定する.
@@ -218,8 +219,10 @@ p\TeX の|\inhibitxspcode|に対応した設定項目である.<mode>で許さ
218219 \item |xkanjiskip=<skip>|★\inhibitglue: |\xkanjiskip=<skip>|と同じ意味.
219220 \item |jcharwidowpenalty=<penalty>|★\inhibitglue: |\jcharwidowpenalty=<penalty>|と同じ意味.
220221 \item |autospacing[=<bool>]|★◎\par\noindent
222+%\item |autospacing[=<bool>]|★\par\noindent
221223 和文文字間のglue(|\kanjiskip|)の自動挿入をするかしないかを制御.
222224 \item |autoxspacing[=<bool>]|★◎\par\noindent
225+%\item |autoxspacing[=<bool>]|★\par\noindent
223226 和欧文間のglue(|\xkanjiskip|)の自動挿入をするかしないかを制御.
224227
225228 \item |differentjfm=(large/small/average/both)|★◎\par\noindent
@@ -296,8 +299,11 @@ p\TeX の|adjust_hlist| procedureとほぼ同様の処理を用いて,
296299 挿入する.
297300 \itemitem 数式境界 (|math_node|) との間に|\xkanjiskip|を自動挿入するかの決定は,
298301 p\TeX では数字{\tt 0}との間に挿入するかどうかで判定していたが,Lua\TeX-jaでは
299-「文字コード|'math'|の文字」で判定している.
300-
302+「文字コード$-1$の文字」で判定している.
303+\itemitem 合字の周囲の空白挿入については,構成要素の文字列を通じて判断している.例えば,
304+「漢ffi字」という文字列に対して,
305+\itemT 「漢」と「ffi」間の空白挿入:「漢」と「f」間に入るかで判断
306+\itemT 「ffi」と「字」間の空白挿入:「i」と「字」間に入るかで判断
301307
302308 \item ベースライン補正: |pre_linebreak_filter|, |hpack_filter|
303309
--- a/src/luatexja-core.lua
+++ b/src/luatexja-core.lua
@@ -3,52 +3,113 @@ function ltj.error(s,t)
33 tex.error('LuaTeX-ja error: ' .. s ,t)
44 end
55
6+-- Three aux. functions, bollowed from tex.web
7+local unity=65536
8+local function print_scaled(s)
9+ local out=''
10+ local delta=10
11+ if s<0 then
12+ out=out..'-'; s=-s
13+ end
14+ out=out..tostring(math.floor(s/unity)) .. '.'
15+ s=10*(s%unity)+5
16+ repeat
17+ if delta>unity then s=s+32768-50000 end
18+ out=out .. tostring(math.floor(s/unity))
19+ s=10*(s%unity)
20+ delta=delta*10
21+ until s<=delta
22+ return out
23+end
24+
25+local function print_glue(d,order)
26+ local out=print_scaled(d)
27+ if order>0 then
28+ out=out..'fi'
29+ while order>1 do
30+ out=out..'l'; order=order-1
31+ end
32+ else
33+ out=out..'pt'
34+ end
35+ return out
36+end
37+
38+local function print_spec(p)
39+ local out=print_scaled(p.width)..'pt'
40+ if p.stretch~=0 then
41+ out=out..' plus '..print_glue(p.stretch,p.stretch_order)
42+ end
43+ if p.shrink~=0 then
44+ out=out..' minus '..print_glue(p.shrink,p.shrink_order)
45+ end
46+return out
47+end
48+
649 -- return true if and only if p is a Japanese character node
750 function ltj.is_japanese_glyph_node(p)
851 return p and (node.type(p.id)=='glyph')
952 and (p.font==node.has_attribute(p,luatexbase.attributes['luatexja@curjfnt']))
1053 end
1154
12----------- Kinsoku
13-----------
14-ltj.penalty_table = {}
15-function ltj.set_penalty_table(m,c,p)
16- if not ltj.penalty_table[c] then ltj.penalty_table[c]={} end
17- if m=='pre' then
18- ltj.penalty_table[c].pre=p
19- elseif m=='post' then
20- ltj.penalty_table[c].post=p
21- end
55+---------- Stack table
56+---- ltj.stack_ch_table [stack_level] : 情報を格納したテーブル
57+---- .auto_spacing, .auto_xspacing: \autospacing etc.
58+---- [chr_code].pre, [chr_code].post, [chr_code].xsp
59+
60+ltj.stack_ch_table={}; ltj.stack_ch_table[0]={}
61+
62+function ltj.new_stack_level()
63+ local i = tex.getcount('ltj@stack@pbp')
64+ if tex.currentgrouplevel > tex.getcount('ltj@group@level@pbp') then
65+ i = i+1 -- new stack level
66+ tex.setcount('ltj@group@level@pbp', tex.currentgrouplevel)
67+ for j,v in pairs(ltj.stack_ch_table) do -- clear the stack above i
68+ if j>=i then ltj.stack_ch_table[j]=nil end
69+ end
70+ ltj.stack_ch_table[i] = table.fastcopy(ltj.stack_ch_table[i-1])
71+ tex.setcount('ltj@stack@pbp', i)
72+ end
73+ return i
74+end
75+function ltj.set_ch_table(g,m,c,p)
76+ local i = ltj.new_stack_level()
77+ if not ltj.stack_ch_table[i][c] then ltj.stack_ch_table[i][c] = {} end
78+ ltj.stack_ch_table[i][c][m] = p
79+ if g=='global' then
80+ for j,v in pairs(ltj.stack_ch_table) do
81+ if not ltj.stack_ch_table[j][c] then ltj.stack_ch_table[j][c] = {} end
82+ ltj.stack_ch_table[j][c][m] = p
83+ end
84+ end
2285 end
86+
2387 function ltj.get_penalty_table(m,c)
24- local i=ltj.penalty_table[c]
25- if i then
26- i=(ltj.penalty_table[c])[m]
27- end
28- if not i then i=0 end
29- tex.write(i)
88+ local i = tex.getcount('ltj@stack@pbp')
89+ i = ltj.stack_ch_table[i][c]
90+ if i then i=i[m] end
91+ return i or 0
3092 end
3193
32-ltj.inhibit_xsp_table = {}
33-function ltj.set_inhibit_xsp_table(c,p)
34- ltj.inhibit_xsp_table[c]=p
35-end
3694 function ltj.get_inhibit_xsp_table(c)
37- return ltj.inhibit_xsp_table[c] or 3
95+ local i = tex.getcount('ltj@stack@pbp')
96+ i = ltj.stack_ch_table[i][c]
97+ if i then i=i.xsp end
98+ return i or 3
3899 end
39100
40101 --------
41102 function ltj.out_ja_parameter_one(k)
42103 if k == 'yabaselineshift' then
43- tex.write(tex.getattribute('luatexja@yablshift')/65536 .. 'pt')
104+ tex.write(print_scaled(tex.getattribute('luatexja@yablshift'))..'pt')
44105 elseif k == 'ykbaselineshift' then
45- tex.write(tex.getattribute('luatexja@ykblshift')/65536 .. 'pt')
106+ tex.write(print_scaled(tex.getattribute('luatexja@ykblshift'))..'pt')
46107 elseif k == 'kanjiskip' then
47- tex.sprint('\\the\\kanjiskip')
108+ tex.write(print_spec(tex.getskip('kanjiskip')))
48109 elseif k == 'xkanjiskip' then
49- tex.sprint('\\the\\xkanjiskip')
110+ tex.write(print_spec(tex.getskip('xkanjiskip')))
50111 elseif k == 'jcharwidowpenalty' then
51- tex.write(tex.getattribute('jcharwidowpenalty'))
112+ tex.write(tex.getcount('jcharwidowpenalty'))
52113 elseif k == 'autospacing' then
53114 tex.write(tostring(ltj.auto_spacing))
54115 elseif k == 'autoxspacing' then
@@ -62,14 +123,13 @@ function ltj.out_ja_parameter_one(k)
62123 tex.write('average')
63124 elseif ltj.calc_between_two_jchar_aux==ltj.calc_between_two_jchar_aux_both then
64125 tex.write('both')
65- else
126+ else -- This can't happen.
66127 tex.write('???')
67128 end
68129 end
69130 end
70131
71132 function ltj.out_ja_parameter_two(k,c)
72- print(k,c)
73133 if k == 'prebreakpenalty' then
74134 tex.write(ltj.get_penalty_table('pre',c))
75135 elseif k == 'postbreakpenalty' then
@@ -206,25 +266,26 @@ end
206266
207267 function ltj.add_kinsoku_penalty(head,p)
208268 local c = p.char
209- if not ltj.penalty_table[c] then return false; end
210- if ltj.penalty_table[c].pre then
269+ local e = ltj.get_penalty_table('pre',c)
270+ if e~=0 then
211271 local q = node.prev(p)
212272 if q and node.type(q.id)=='penalty' then
213- q.penalty=q.penalty+ltj.penalty_table[c].pre
273+ q.penalty=q.penalty+e
214274 else
215275 q=node.new(node.id('penalty'))
216- q.penalty=ltj.penalty_table[c].pre
276+ q.penalty=e
217277 node.insert_before(head,p,q)
218278 end
219279 end
220- if ltj.penalty_table[c].post then
280+ e = ltj.get_penalty_table('post',c)
281+ if e~=0 then
221282 local q = node.next(p)
222283 if q and node.type(q.id)=='penalty' then
223- q.penalty=q.penalty+ltj.penalty_table[c].post
284+ q.penalty=q.penalty+e
224285 return false
225286 else
226287 q=node.new(node.id('penalty'))
227- q.penalty=ltj.penalty_table[c].post
288+ q.penalty=e
228289 node.insert_after(head,p,q)
229290 return true
230291 end
@@ -243,7 +304,7 @@ function ltj.insert_jfm_glue(head)
243304 end
244305 while p and ltj.is_parindent_box(p) do p=node.next(p) end
245306 while p do
246- if node.type(p.id)=='whatsit' and p.subtype==44
307+ if node.type(p.id)=='whatsit' and p.subtype==node.subtype('user_defined')
247308 and p.user_id==30111 then
248309 g=p; p=node.next(p);
249310 ihb_flag=true; head,p=node.remove(head, g)
@@ -265,9 +326,7 @@ function ltj.insert_jfm_glue(head)
265326 end
266327 -- Insert skip after the last node
267328 g=ltj.calc_between_two_jchar(q,nil)
268- if g then
269- h = node.insert_after(head,q,g)
270- end
329+ if g then h = node.insert_after(head,q,g) end
271330 return head
272331 end
273332
@@ -276,28 +335,29 @@ end
276335 -- Insert \xkanjiskip at the boundaries between Japanese characters
277336 -- and non-Japanese characters.
278337 -- We also insert \kanjiskip between Kanji in this function.
279-ltj.kanji_skip={}
280-ltj.xkanji_skip={}
281-ltj.insert_skip=0
282-ltj.cx = nil
283- -- 0: ``no_skip'', 1: ``after_schar'', 2: ``after_wchar''
284--- These variables are ``global'', because we want to avoid to write one large function.
338+local kanji_skip={}
339+local xkanji_skip={}
340+local cx = nil
341+local no_skip=0
342+local after_schar=1
343+local after_wchar=2
344+local insert_skip=no_skip
285345 function ltj.insert_kanji_skip(head)
286346 if ltj.auto_spacing then
287- ltj.kanji_skip=tex.skip['kanjiskip']
347+ kanji_skip=tex.skip['kanjiskip']
288348 else
289- ltj.kanji_skip=node.new(node.id('glue_spec'))
290- ltj.kanji_skip.width=0; ltj.kanji_skip.stretch=0; ltj.kanji_skip.shrink=0
349+ kanji_skip=node.new(node.id('glue_spec'))
350+ kanji_skip.width=0; kanji_skip.stretch=0; kanji_skip.shrink=0
291351 end
292352 if ltj.auto_xspacing then
293- ltj.xkanji_skip=tex.skip['xkanjiskip']
353+ xkanji_skip=tex.skip['xkanjiskip']
294354 else
295- ltj.xkanji_skip=node.new(node.id('glue_spec'))
296- ltj.xkanji_skip.width=0; ltj.xkanji_skip.stretch=0; ltj.xkanji_skip.shrink=0
355+ xkanji_skip=node.new(node.id('glue_spec'))
356+ xkanji_skip.width=0; xkanji_skip.stretch=0; xkanji_skip.shrink=0
297357 end
298358 local p=head -- 「現在のnode」
299359 local q=nil -- pの一つ前
300- ltj.insert_skip=0
360+ insert_skip=no_skip
301361 while p do
302362 if node.type(p.id)=='glyph' then
303363 repeat
@@ -320,7 +380,7 @@ function ltj.insert_kanji_skip(head)
320380 p=p
321381 else
322382 -- rule, disc, glue, margin_kern
323- ltj.insert_skip=0
383+ insert_skip=no_skip
324384 end
325385 q=p; p=node.next(p)
326386 end
@@ -328,70 +388,80 @@ function ltj.insert_kanji_skip(head)
328388 return head
329389 end
330390
391+function ltj.set_insert_skip_after_achar(p)
392+ local c=p.char
393+ while p.components and p.subtype
394+ and math.floor(p.subtype/2)%2==1 do
395+ p=node.tail(p.components); c = p.char
396+ end
397+ if ltj.get_inhibit_xsp_table(c)>=2 then
398+ insert_skip=after_schar
399+ else
400+ insert_skip=no_skip
401+ end
402+end
403+
331404 -- Insert \xkanjiskip before p, a glyph node
332--- TODO; ligature
333405 function ltj.insks_around_char(head,q,p)
334406 local a=ltj.get_inhibit_xsp_table(p.char)
335407 if ltj.is_japanese_glyph_node(p) then
336- ltj.cx=p.char
408+ cx=p.char
337409 if ltj.is_japanese_glyph_node(q) then
338410 local g = node.new(node.id('glue'))
339- g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
411+ g.subtype=0; g.spec=node.copy(kanji_skip)
340412 node.insert_before(head,p,g)
341- elseif ltj.insert_skip==1 then
413+ elseif insert_skip==after_schar then
342414 ltj.insert_akxsp(head,q)
343415 end
344- ltj.insert_skip=2
416+ insert_skip=after_wchar
345417 else
346- if ltj.insert_skip==2 then
347- ltj.insert_kaxsp(head,q,a)
348- end
349- if a>=2 then
350- ltj.insert_skip=1
351- else
352- ltj.insert_skip=0
418+ if insert_skip==after_wchar then
419+ ltj.insert_kaxsp(head,q,p)
353420 end
421+ ltj.set_insert_skip_after_achar(p)
354422 end
355423 end
356424
425+-- In the next two function, cx is the Kanji code.
357426 function ltj.insert_akxsp(head,q)
358- local f = ltj.get_inhibit_xsp_table(ltj.cx)
359- local g
360- if f<=1 then return end
361- g = node.new(node.id('glue'))
362- g.subtype=0; g.spec=node.copy(ltj.xkanji_skip)
427+ if ltj.get_inhibit_xsp_table(cx)<=1 then return end
428+ local g = node.new(node.id('glue'))
429+ g.subtype=0; g.spec=node.copy(xkanji_skip)
363430 node.insert_after(head,q,g)
364431 end
365432
366-function ltj.insert_kaxsp(head,q,a)
433+function ltj.insert_kaxsp(head,q,p)
367434 local g=true
368- local f=ltj.get_inhibit_xsp_table(ltj.cx)
369- if a%2 == 1 then
370- if f%2==0 then g=false end
435+ local c=p.char
436+ while p.components and p.subtype
437+ and math.floor(p.subtype/2)%2==1 do
438+ p=p.components; c = p.char
439+ end
440+ if ltj.get_inhibit_xsp_table(c)%2 == 1 then
441+ if ltj.get_inhibit_xsp_table(cx)%2==0 then g=false end
371442 else
372443 g=false
373444 end
374445 if g then
375446 g = node.new(node.id('glue'))
376- g.subtype=0; g.spec=node.copy(ltj.xkanji_skip)
447+ g.subtype=0; g.spec=node.copy(xkanji_skip)
377448 node.insert_after(head,q,g)
378449 end
379450 end
380451
381452 -- Return first and last glyph nodes in a hbox
382-ltj.first_char = nil
383-ltj.last_char = nil
384-ltj.find_first_char = nil
453+local first_char = nil
454+local last_char = nil
455+local find_first_char = nil
385456 function ltj.check_box(bp)
386- local p, flag
387- p=bp; flag=false
457+ local p = bp; local flag = false
388458 while p do
389459 if node.type(p.id)=='glyph' then
390460 repeat
391- if ltj.find_first_char then
392- ltj.first_char=p; ltj.find_first_char=false
461+ if find_first_char then
462+ first_char=p; find_first_char=false
393463 end
394- ltj.last_char=p; flag=true; p=node.next(p)
464+ last_char=p; flag=true; p=node.next(p)
395465 if not p then return flag end
396466 until node.type(p.id)~='glyph'
397467 end
@@ -399,10 +469,10 @@ function ltj.check_box(bp)
399469 flag=true
400470 if p.shift==0 then
401471 if ltj.check_box(p.head) then flag=true end
402- else if ltj.find_first_char then
403- ltj.find_first_char=false
472+ else if find_first_char then
473+ find_first_char=false
404474 else
405- ltj.last_char=nil
475+ last_char=nil
406476 end
407477 end
408478 elseif node.type(p.id) == 'ins' or node.type(p.id) == 'mark'
@@ -411,10 +481,10 @@ function ltj.check_box(bp)
411481 p=p
412482 else
413483 flag=true
414- if ltj.find_first_char then
415- ltj.find_first_char=false
484+ if find_first_char then
485+ find_first_char=false
416486 else
417- ltj.last_char=nil
487+ last_char=nil
418488 end
419489 end
420490 p=node.next(p)
@@ -425,52 +495,41 @@ end
425495 -- Insert \xkanjiskip around p, an hbox
426496 function ltj.insks_around_hbox(head,q,p)
427497 if p.shift==0 then
428- ltj.find_first_char=true; ltj.first_char=nil; ltj.last_char=nil
498+ find_first_char=true; first_char=nil; last_char=nil
429499 if ltj.check_box(p.head) then
430500 -- first char
431- if ltj.is_japanese_glyph_node(ltj.first_char) then
432- ltj.cx=ltj.first_char.char
433- if ltj.insert_skip==1 then
501+ if ltj.is_japanese_glyph_node(first_char) then
502+ cx=first_char.char
503+ if insert_skip==after_schar then
434504 ltj.insert_akxsp(head,q)
435- elseif ltj.insert_skip==2 then
505+ elseif insert_skip==after_wchar then
436506 local g = node.new(node.id('glue'))
437- g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
507+ g.subtype=0; g.spec=node.copy(kanji_skip)
438508 node.insert_before(head,p,g)
439509 end
440- ltj.insert_skip=2
441- elseif ltj.first_char then
442- local a=ltj.get_inhibit_xsp_table(ltj.first_char.char)
443- if ltj.insert_skip==2 then
444- local g = node.new(node.id('glue'))
445- g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
446- node.insert_after(head,q,g)
447- end
448- if a>=2 then
449- ltj.insert_skip=1
450- else
451- ltj.insert_skip=0
510+ insert_skip=after_wchar
511+ elseif first_char then
512+ cx=first_char.char
513+ if insert_skip==after_wchar then
514+ ltj.insert_kaxsp(head,q,first_char)
452515 end
516+ ltj.set_insert_skip_after_achar(first_char)
453517 end
454518 -- last char
455- if ltj.is_japanese_glyph_node(ltj.last_char) then
519+ if ltj.is_japanese_glyph_node(last_char) then
456520 if ltj.is_japanese_glyph_node(node.next(p)) then
457521 local g = node.new(node.id('glue'))
458- g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
522+ g.subtype=0; g.spec=node.copy(kanji_skip)
459523 node.insert_after(head,p,g)
460524 end
461- ltj.insert_skip=2
462- elseif ltj.last_char then
463- local a=ltj.get_inhibit_xsp_table(ltj.last_char.char)
464- if a>=2 then
465- ltj.insert_skip=1
466- else
467- ltj.insert_skip=0
468- end
469- else ltj.insert_skip=0
525+ insert_skip=after_wchar
526+ elseif last_char then
527+ ltj.set_insert_skip_after_achar(last_char)
528+ else insert_skip=no_skip
470529 end
471- else ltj.insert_skip=0
530+ else insert_skip=no_skip
472531 end
473- else ltj.insert_skip=0
532+ else insert_skip=no_skip
474533 end
475534 end
476535
@@ -478,27 +537,22 @@ end
478537 function ltj.insks_around_penalty(head,q,p)
479538 local r=node.next(p)
480539 if r and node.type(r.id)=='glyph' then
481- local a=ltj.get_inhibit_xsp_table(r.char)
482540 if ltj.is_japanese_glyph_node(r) then
483- ltj.cx=r.char
541+ cx=r.char
484542 if ltj.is_japanese_glyph_node(p) then
485543 local g = node.new(node.id('glue'))
486- g.subtype=0; g.spec=node.copy(ltj.kanji_skip)
544+ g.subtype=0; g.spec=node.copy(kanji_skip)
487545 node.insert_before(head,r,g)
488- elseif ltj.insert_skip==1 then
546+ elseif insert_skip==insert_schar then
489547 ltj.insert_akxsp(head,p)
490548 end
491549 q=p; p=node.next(p)
492- ltj.insert_skip=2
550+ insert_skip=after_wchar
493551 else
494- if ltj.insert_skip==2 then
495- ltj.insert_kaxsp(head,p,a)
496- end
497- if a>=2 then
498- ltj.insert_skip=1
499- else
500- ltj.insert_skip=0
552+ if insert_skip==after_wchar then
553+ ltj.insert_kaxsp(head,p,r)
501554 end
555+ ltj.set_insert_skip_after_achar(r)
502556 end
503557 end
504558 end
@@ -509,7 +563,7 @@ function ltj.insks_around_kern(head,q,p)
509563 if node.has_attribute(p,luatexbase.attributes['luatexja@icflag']) then
510564 p=p -- p is a kern from \/: do nothing
511565 else
512- ltj.insert_skip=0
566+ insert_skip=no_skip
513567 end
514568 elseif p.subtype==2 then -- \accent: We ignore the accent character.
515569 local v = node.next(node.next(node.next(p)))
@@ -521,12 +575,12 @@ end
521575
522576 -- Insert \xkanjiskip around p, a math_node
523577 function ltj.insks_around_math(head,q,p)
524- local a=ltj.get_inhibit_xsp_table('math')
525- if (p.subtype==0) and (ltj.insert_skip==2) then
526- ltj.insert_kaxsp(head,q,a)
527- ltj.insert_skip=0
578+ local g = { char = -1 }
579+ if (p.subtype==0) and (insert_skip==after_wchar) then
580+ ltj.insert_kaxsp(head,q,g)
581+ insert_skip=no_skip
528582 else
529- ltj.insert_skip=1
583+ ltj.set_insert_skip_after_achar(g)
530584 end
531585 end
532586
@@ -566,73 +620,27 @@ function ltj.main_process(head)
566620 return p
567621 end
568622
569--- TeX's \hss
570-function ltj.get_hss()
571- local hss = node.new(node.id("glue"))
572- local hss_spec = node.new(node.id("glue_spec"))
573- hss_spec.width = 0
574- hss_spec.stretch = 65536
575- hss_spec.stretch_order = 2
576- hss_spec.shrink = 65536
577- hss_spec.shrink_order = 2
578- hss.spec = hss_spec
579- return hss
580-end
581-
582-function ltj.set_ja_width(head)
583- local p = head
584- local t,s,th, g, q,a
585- while p do
586- if ltj.is_japanese_glyph_node(p) then
587- t=ltj.metrics[ltj.font_metric_table[p.font].jfm]
588- s=t.char_type[node.has_attribute(p,luatexbase.attributes['luatexja@charclass'])]
589- if not(s.left==0.0 and s.down==0.0
590- and tex.round(s.width*ltj.font_metric_table[p.font].size)==p.width) then
591- -- must be encapsuled by a \hbox
592- head, q = node.remove(head,p)
593- p.next=nil
594- p.yoffset=tex.round(p.yoffset-ltj.font_metric_table[p.font].size*s.down)
595- p.xoffset=tex.round(p.xoffset-ltj.font_metric_table[p.font].size*s.left)
596- node.insert_after(p,p,ltj.get_hss())
597- g=node.hpack(p, tex.round(ltj.font_metric_table[p.font].size*s.width)
598- , 'exactly')
599- g.height=tex.round(ltj.font_metric_table[p.font].size*s.height)
600- g.depth=tex.round(ltj.font_metric_table[p.font].size*s.depth)
601- head,p = node.insert_before(head,q,g)
602- p=q
603- else p=node.next(p)
604- end
605- else p=node.next(p)
606- end
607- end
608- return head
609-end
610-
611623 -- debug
612-ltj.depth=""
613-function ltj.to_pt(a)
614- return math.floor(a/65536*100000)/100000
615-end
624+local depth=""
616625 function ltj.show_node_list(head)
617- local p =head
618- local k=ltj.depth
619- ltj.depth=ltj.depth .. '.'
626+ local p =head; local k = depth; local s
627+ depth=depth .. '.'
620628 while p do
621- local s=node.type(p.id)
629+ s=node.type(p.id)
622630 if s == 'glyph' then
623- print(ltj.depth .. ' glyph', p.subtype, utf.char(p.char), p.font)
631+ print(depth .. ' glyph', p.subtype, utf.char(p.char), p.font)
624632 elseif s=='hlist' then
625- print(ltj.depth .. ' hlist', p.subtype, '(' .. ltj.to_pt(p.height)
626- .. '+' .. ltj.to_pt(p.depth)
627- .. ')x' .. ltj.to_pt(p.width) )
633+ print(depth .. ' hlist', p.subtype, '(' .. print_scaled(p.height)
634+ .. '+' .. print_scaled(p.depth)
635+ .. ')x' .. print_scaled(p.width) )
628636 ltj.show_node_list(p.head)
629- ltj.depth=k
637+ depth=k
630638 elseif s=='whatsit' then
631- print(ltj.depth .. ' whatsit', p.subtype)
639+ print(depth .. ' whatsit', p.subtype)
632640 elseif s=='glue' then
633- print(ltj.depth .. ' glue', p.subtype, ltj.to_pt(p.spec.width))
641+ print(depth .. ' glue', p.subtype, print_spec(p.spec))
634642 else
635- print(ltj.depth .. ' ' .. s, s.subtype)
643+ print(depth .. ' ' .. s, s.subtype)
636644 end
637645 p=node.next(p)
638646 end
--- a/src/luatexja-core.sty
+++ b/src/luatexja-core.sty
@@ -34,7 +34,8 @@
3434 texio.write_nl("("..path..")")
3535 dofile(path)
3636 end
37- ltj.loadlua('luatexja-rmlgbm.lua')
37+ require('lualibs')
38+ ltj.loadlua('luatexja-rmlgbm.lua')
3839 % This file must be read before luatexja-jfont.lua. For Ryumin-Light and GothicBBB-Medium.
3940 ltj.loadlua('luatexja-core.lua')
4041 ltj.loadlua('luatexja-jfont.lua')
@@ -64,6 +65,8 @@
6465 \def\inhibitglue{\directlua{ltj.create_ihb_node()}}
6566
6667 %%%%%%%% \setjaparameter
68+\newcount\ltj@stack@pbp\newcount\ltj@group@level@pbp
69+\ltj@group@level@pbp=0 \ltj@stack@pbp=0
6770
6871 % prebreakpenalty = {<char_code>, <penalty>}
6972 \define@key[ltj]{japaram}{prebreakpenalty}{%
@@ -73,7 +76,7 @@
7376 \def\luatexja@setbp#1,#2:#3{
7477 \luatexja@tempcnta=#1\relax
7578 \luatexja@tempcntb=#2\relax
76- \directlua{ltj.set_penalty_table(\asluastring{#3},
79+ \directlua{ltj.set_ch_table(ltj.isglobal, \asluastring{#3},
7780 tex.getcount('luatexja@tempcnta'),tex.getcount('luatexja@tempcntb'))}}
7881
7982 % yabaselineshift = <dimen>
@@ -100,7 +103,7 @@
100103 \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
101104 \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
102105 \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
103- \directlua{ltj.set_inhibit_xsp_table(tex.getcount('luatexja@tempcnta'),
106+ \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
104107 tex.getcount('luatexja@tempcntb'))}}
105108
106109 % asciixspmode = {<char_code>, <mode>}
@@ -115,7 +118,7 @@
115118 \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
116119 \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
117120 \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
118- \directlua{ltj.set_inhibit_xsp_table(tex.getcount('luatexja@tempcnta'),
121+ \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
119122 tex.getcount('luatexja@tempcntb'))}}
120123
121124 % autospacing = <bool> (default: true)
--- a/src/luatexja-jfont.lua
+++ b/src/luatexja-jfont.lua
@@ -129,3 +129,48 @@ function ltj.extract_metric(name)
129129 end
130130 return
131131 end
132+
133+
134+--====== Adjust the width of Japanese glyphs
135+
136+-- TeX's \hss
137+function ltj.get_hss()
138+ local hss = node.new(node.id("glue"))
139+ local hss_spec = node.new(node.id("glue_spec"))
140+ hss_spec.width = 0
141+ hss_spec.stretch = 65536
142+ hss_spec.stretch_order = 2
143+ hss_spec.shrink = 65536
144+ hss_spec.shrink_order = 2
145+ hss.spec = hss_spec
146+ return hss
147+end
148+
149+function ltj.set_ja_width(head)
150+ local p = head
151+ local t,s,th, g, q,a
152+ while p do
153+ if ltj.is_japanese_glyph_node(p) then
154+ t=ltj.metrics[ltj.font_metric_table[p.font].jfm]
155+ s=t.char_type[node.has_attribute(p,luatexbase.attributes['luatexja@charclass'])]
156+ if not(s.left==0.0 and s.down==0.0
157+ and tex.round(s.width*ltj.font_metric_table[p.font].size)==p.width) then
158+ -- must be encapsuled by a \hbox
159+ head, q = node.remove(head,p)
160+ p.next=nil
161+ p.yoffset=tex.round(p.yoffset-ltj.font_metric_table[p.font].size*s.down)
162+ p.xoffset=tex.round(p.xoffset-ltj.font_metric_table[p.font].size*s.left)
163+ node.insert_after(p,p,ltj.get_hss())
164+ g=node.hpack(p, tex.round(ltj.font_metric_table[p.font].size*s.width)
165+ , 'exactly')
166+ g.height=tex.round(ltj.font_metric_table[p.font].size*s.height)
167+ g.depth=tex.round(ltj.font_metric_table[p.font].size*s.depth)
168+ head,p = node.insert_before(head,q,g)
169+ p=q
170+ else p=node.next(p)
171+ end
172+ else p=node.next(p)
173+ end
174+ end
175+ return head
176+end
--- a/src/luatexja-plain.tex
+++ b/src/luatexja-plain.tex
@@ -14,7 +14,7 @@
1414 xkanjiskip=.25\zw plus 1pt minus 1pt,
1515 autospacing, autoxspacing,
1616 yabaselineshift=0pt, ykbaselineshift=0pt,
17- jcharwidowpenalty=500
17+ jcharwidowpenalty=500, differentjfm=average
1818 }
1919
2020 \input luatexja-kinsoku.tex
Binary files a/test/test01-noembed.pdf and b/test/test01-noembed.pdf differ
Binary files a/test/test01.pdf and b/test/test01.pdf differ
Binary files a/test/test02-latex.pdf and b/test/test02-latex.pdf differ
Binary files a/test/test03-after.pdf and b/test/test03-after.pdf differ
--- a/test/test03-after.tex
+++ b/test/test03-after.tex
@@ -45,4 +45,16 @@ a\inhibitglue (a)\inhibitglue aあa〜a
4545 \getjaparameter{asciixspmode}{`a},
4646 \getjaparameter{asciixspmode}{`b}
4747
48+{\setjaparameter{kanjiskip=0pt plus 1fi minus 1fil}\getjaparameter{kanjiskip}\par}
49+{x\setjaparameter{kanjiskip=0pt plus 1fill minus 1filll}\getjaparameter{kanjiskip}\par}
50+
51+\tenrm
52+{\setjaparameter{asciixspmode={`i,preonly},ykbaselineshift=0pt}
53+あiあfiあffiあ\par}
54+
55+{\setjaparameter{asciixspmode={`f,postonly},ykbaselineshift=0pt}
56+あfあfiあffiあ\par}
57+
58+\setjaparameter{asciixspmode={-1,inhibit}}
59+あ$a$あ
4860 \end
Binary files /dev/null and b/test/test04-jfm.pdf differ
--- /dev/null
+++ b/test/test04-jfm.tex
@@ -0,0 +1,14 @@
1+%#!luatex
2+\input luatexja-core.sty
3+
4+\jfont\rml={psft:Ryumin-Light:jfm=ujis} at 10pt
5+\rml あ\inhibitglue\char"201Cあ←Ryumin-Light
6+
7+\jfont\rml={file:ipam.ttf:jfm=ujis} at 10pt
8+\rml あ\inhibitglue\char"201Cあ←ipam
9+
10+\jfont\rml={file:KozMinPr6N-Regular.otf:jfm=ujis} at 10pt
11+\rml あ\inhibitglue\char"201Cあ←KozMinPr6N-Regular
12+
13+あ\discretionary{.\inhibitglue\kern-1\zw}{}{.}あ
14+\end
旧リポジトリブラウザで表示