• R/O
  • HTTP
  • SSH
  • HTTPS

luatexja: コミット

ソースコードの管理場所


コミットメタ情報

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

ログメッセージ

Rewrite the main process (inserting JFM glue/kern and \[x]kanjiskip) and so on.
- Re-defined \/ for italic corrections of Japanese characters.
- "Character 'lineend'" is now allowed in JFM file (for hanging punct.)
- Modified the internal data structure of JFM for speed up.
- Renamed TeX control sequences, and Lua functions.

変更サマリ

差分

--- a/doc/s1sty.tex
+++ b/doc/s1sty.tex
@@ -55,7 +55,7 @@
5555 \let\sc=\eightsc \def\tt{\eighttt\eightjtt}%
5656 \let\mc=\eightmc \let\gt=\eightgt%
5757 \rm\mc\xkanjiskip=0.25\zw plus 1pt minus 1pt%
58- \setjaparameter{ykbaselineshift=-0.76pt, yabaselineshift=-0.76pt}
58+ \ltjsetparameter{ykbaselineshift=-0.76pt, yabaselineshift=-0.76pt}
5959 }
6060
6161
@@ -117,6 +117,6 @@
117117 \def\enum{\par\medskip\advance\enumi1\leftskip=2\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss\the\enumi.\kern0.5\zw}}
118118 \def\enditem{\medskip\par\enumi=0\leftskip=0pt\parskip=0pt\noindent}
119119
120-\setjaparameter{cjkxspmode={`★,0}}
120+\ltjsetparameter{cjkxspmode={`★,0}}
121121
122122 \endinput
Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ
--- a/doc/sample1.tex
+++ b/doc/sample1.tex
@@ -1,7 +1,6 @@
11 %#! time luatex sample1
22 \input s1sty.tex % style file
33
4-\message{BB}
54 \overfullrule=0pt
65 \def\LaTeX{L\kern-.36em\setbox0=\hbox{T}\vbox to\ht0{\hbox{\sx A}\vss}\kern-.15em\TeX}
76 \font\mff=manfnt at 10pt
@@ -17,13 +16,11 @@
1716 \centerline{\big Lua\TeX-jaパッケージ}\bigskip
1817 \centerline{\large\the\year/\the\month/\the\day}\medskip
1918
20-\message{AA}
2119 \bigskip
2220
2321 本パッケージは,(最低でもp\TeX と同等の水準の)日本語組版をLua\TeX 上で実現させることを
2422 目標としたマクロである.まだまだ足りないところはあるが,とりあえず動くようになった?ので公開する.
2523
26-%{\showboxdepth=10000\showboxbreadth=10000\tracingonline=1\scrollmode\showlists}\end
2724
2825 \beginparagraph 特徴
2926
@@ -43,6 +40,7 @@
4340 \item {\bf 現時点で\LaTeX での使用は殆ど考慮されていません.今は``plain Lua\TeX''で使ってください.}
4441 \item |\accent|を和文文字に対して使うことはできません.
4542 これは「フォントを後で置換する」という実装上,仕方のないことだと思われます.
43+{\small|\/|を試験的に日本語にも対応させました.|make_accent|の処理をLuaコードで書けば可能だと思われます.}
4644 \item 数式中の日本語は想定していません.|\hbox|か何かで囲ってください.
4745 \item p\TeX にあった以下の機能はまだ実装していません.
4846 \itemitem |\euc|, |\jis|, |\sjis|, |\kuten|といった,コード変換プリミティブ.
@@ -61,6 +59,7 @@
6159 {\bf 現時点で\LaTeX での使用は全く考慮されていない.}
6260 \item {\tt luatexja-core.lua}: コア部分に使われるLuaコード.
6361 \item {\tt luatexja-jfont.lua}: 和文フォント定義部のLuaコード.
62+\item {\tt luatexja-xkanji.lua}: |\[x]kanjiskip|自動挿入処理のLuaコード.
6463 \item {\tt luatexja-rmlgbm-data.lua}: 非埋込和文フォント用のデータ(小塚明朝Pr6N R由来).
6564 \item {\tt luatexja-rmlgbm.lua}: 非埋込和文フォント (Ryumin-Light etc.) 定義部.
6665 \item {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト
@@ -146,13 +145,13 @@ PSフォント名<PSfont_name>を直接指定することもでき,
146145 \item デフォルトでは,|U+0100|以降の文字は全部和文扱いであり,さらに文字範囲として,
147146 \begintt
148147 \defcharrange{1}{"80-"FF}
149- \setjaparameter{jcharrange={-1}}
148+ \ltjsetparameter{jcharrange={-1}}
150149 \endtt
151150 と指定している{\small(つまりLatin-1 Supplementの範囲は欧文扱い)\inhibitglue}.
152151
153-TODO: 「{\setjaparameter{jcharrange={1}}× (|U+00D7|)}」等,ISO 8859-1領域
152+TODO: 「{\ltjsetparameter{jcharrange={1}}× (|U+00D7|)}」等,ISO 8859-1領域
154153 にマッピングされた文字の扱い.
155-「{\setjaparameter{jcharrange={1}}¢ (|U+00A2|)}」はHalfwidth and
154+「{\ltjsetparameter{jcharrange={1}}¢ (|U+00A2|)}」はHalfwidth and
156155 Fullwidth Formsに全角形(\char"FFE0)があるから%"
157156 luaotfloadの置換処理に割り込めばよいが…….
158157 \enditem
@@ -162,8 +161,8 @@ luaotfloadの置換処理に割り込めばよいが…….
162161
163162 日本語組版用の各種パラメタの調整には,次の命令を用いる.
164163 \begintt
165- \setjaparameter{<key>=<value>, ...} % local に変更
166- \globalsetjaparameter{<key>=<value>, ...} % global に変更
164+ \ltjsetparameter{<key>=<value>, ...} % local に変更
165+ \globalltjsetparameter{<key>=<value>, ...} % global に変更
167166 \endtt
168167
169168 <key> に許される値は次の通りである.
@@ -256,11 +255,11 @@ $\lvert\hbox{<range_num>}\rvert$番の文字範囲の文字を和文扱いする
256255
257256 日本語組版用の各種パラメタの取得には,次の命令を用いる.
258257 \begintt
259- \getjaparameter{<key>} or \getjaparameter{<key>}{<chr_code>}
258+ \ltjgetparameter{<key>} or \ltjgetparameter{<key>}{<chr_code>}
260259 \endtt
261260 戻り値は全て「空白は|\catcode=10|,それ以外の文字は全て|\catcode=12|」の文字列である.
262261
263-<key>に指定できる値は,説明がない限りは|\setjaparameter|で指定できる<key>と同じで,次の通りである,
262+<key>に指定できる値は,説明がない限りは|\ltjsetparameter|で指定できる<key>と同じで,次の通りである,
264263
265264 \item |kanjiskip|, |xkanjiskip|, |yabaselineshift|, |ykbaselineshift|, |jcharwidowpenalty|%
266265 \par\noindent
@@ -313,9 +312,17 @@ p\TeX 用{\tt JFM}で言うところの「文字クラス」を定義する.
313312 \itemitem <class>は文字クラスを表す1以上$\hbox{\tt0x800}=2048$未満の整数.
314313 \itemitem <chars>には,<class>に属する「文字」達のUnicodeにおけるコード番号を
315314 リストの形|{...}|で記述する.
315+\itemitem どの文字クラスにも属さなかった文字は,自動的に0番の文字クラスに属するとみなされる.
316316
317317 また,このリストには,以下の「仮想的な文字」も指定可能である.
318318 \itemT |'lineend'|: 行末.
319+この「文字」を0以外の文字クラスに設定することで,ぶら下げ組のような組版も可能になる.
320+例えば,句点類の文字クラスが2のとき,
321+\begintt
322+ jfm.define_char_type(8,{'linebdd'}})
323+ jfm.define_kern(2, 8, -0.5)
324+\endtt
325+と指定すればよい.
319326 \itemT |'boxbdd'|: 水平ボックスの先頭/末尾,段落の先頭/末尾.
320327 \itemT |'jcharbdd'|: 和文文字達の連続とそれ以外のもの(例えば欧文文字)との境界.
321328 \itemT |'diffmet'|: 異なるメトリックの和文文字間に入るglueの計算に使われる.
@@ -376,18 +383,32 @@ $p$は「現在の和文フォント」の番号もattribute |\luatexja@curjfnt|
376383
377384 \item {\bf JFM由来glue/kernの挿入: |pre_linebreak_filter|, |hpack_filter|}
378385
379-ここで,メトリックに由来する和文文字間のglue/kernを挿入する.
380-基本的には連続する和文文字間に挿入するが,
386+ここで,JFMに由来する和文文字間のglue/kernを挿入する.
387+基本的には連続する和文文字(を表すnode)間に挿入するが,
381388 \itemitem 水平ボックスの先頭/末尾,段落の先頭/末尾には「文字コード|'boxbdd'|の文字」があると
382389 見做して空白を挿入する.
383390 \itemitem 和文文字とそうでないもの(欧文文字,ボックス等)の間に関しては,
384391 和文文字でない方は「文字コード|'jcharbdd'|の文字」であると見做す.
385392 \itemitem フォントの異なる2つの和文文字においても,
386-両者のフォントのmetric keyとsizeが一致した場合は,
393+両者のフォントのJFMとsizeが一致した場合は,
387394 挿入処理においては「同じフォント」であるかのように扱う.
388395 \itemitem そうでない場合は,両者の間に「文字コード|'diffmet'|の文字」があると見做して,
389396 両和文文字からそれぞれglue/kern |gb|, |ga|を計算し,そこから実際に入るglue/kernを
390-計算している(|\setjaparameter|中の|differentjfm|キーを参照).
397+計算している(|\ltjsetparameter|中の|differentjfm|キーを参照).
398+\itemitem もうちょっと詳しく書くと,本処理前において,和文文字を表す
399+2つの連続した|glyph_node| $Q$, $P$の間には,次のnode達が挿入される:
400+$$
401+ \ldots,\ Q,\ (\hbox{|\kern|}\ w\,{\rm pt}),\ (\hbox{|\penalty|}\ p),\
402+(\hbox{|\kern|}\ (k-w)\,{\rm pt})
403+,\ P,\ \ldots
404+$$
405+上に書いた全てのnodeが挿入されるとは限らず,また4つめのkernもglueに変わる可能性がある.
406+上に出てきた量の意味は次の通りである:
407+\itemT $w$: $Q$が行末にきたときに,行末からどれだけずらすかを指定した量.
408+\itemT $p$: $Q$の行末禁則用penaltyと$P$の行頭禁則用penaltyの合計値.ウィドウ防止用の
409+|\jcharwidowpenalty|が挿入される時は,値はここに加算される.
410+\itemT |\kern| $k$: 本来の$Q$と$P$の間に入る空き(glueであることも).
411+$w$のために自然長を補正している.
391412
392413 \item {\bf |\kanjiskip|, |\xkanjiskip|の挿入: |pre_linebreak_filter|, |hpack_filter|}
393414
--- a/src/luatexja-core.lua
+++ b/src/luatexja-core.lua
@@ -1,20 +1,45 @@
11 local node_type = node.type
2+local node_new = node.new
3+local node_prev = node.prev
4+local node_next = node.next
25 local has_attr = node.has_attribute
36 local node_insert_before = node.insert_before
47 local node_insert_after = node.insert_after
58 local node_hpack = node.hpack
69 local round = tex.round
7-local node_new = node.new
10+
811 local id_penalty = node.id('penalty')
912 local id_glyph = node.id('glyph')
1013 local id_glue_spec = node.id('glue_spec')
1114 local id_glue = node.id('glue')
15+local id_kern = node.id('kern')
16+local id_hlist = node.id('hlist')
17+local id_vlist = node.id('vlist')
18+local id_rule = node.id('rule')
19+local id_math = node.id('math')
1220 local id_whatsit = node.id('whatsit')
13-local next_node = node.next
21+
1422 local attr_jchar_class = luatexbase.attributes['luatexja@charclass']
1523 local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
1624 local attr_yablshift = luatexbase.attributes['luatexja@yablshift']
25+local attr_ykblshift = luatexbase.attributes['luatexja@ykblshift']
1726 local attr_icflag = luatexbase.attributes['luatexja@icflag']
27+-- attr_icflag: 1: kern from \/, 2: 'lineend' kern from JFM
28+
29+local lang_ja_token = token.create('luatexja@japanese')
30+local lang_ja = lang_ja_token[2]
31+
32+--
33+local rgjc_get_range_setting = ltj.int_get_range_setting
34+local rgjc_char_to_range = ltj.int_char_to_range
35+local rgjc_is_ucs_in_japanese_char = ltj.int_is_ucs_in_japanese_char
36+local ljfm_find_char_class = ltj.int_find_char_class
37+
38+------------------------------------------------------------------------
39+-- naming:
40+-- ltj.ext_... : called from \directlua{}
41+-- ltj.int_... : called from other Lua codes, but not from \directlua{}
42+-- (other) : only called from this file
1843
1944 -- error messages
2045 function ltj.error(s,t)
@@ -70,63 +95,71 @@ local function is_japanese_glyph_node(p)
7095 and (p.font==has_attr(p,attr_curjfnt))
7196 end
7297
73----------- Stack table
74----- ltj.stack_ch_table [stack_level] : 情報を格納したテーブル
75----- .auto_spacing, .auto_xspacing: \autospacing etc.
76----- [chr_code].pre, [chr_code].post, [chr_code].xsp
7798
78-ltj.stack_ch_table={}; ltj.stack_ch_table[0]={}
99+------------------------------------------------------------------------
100+-- CODE FOR STACK TABLE FOR CHARACTER PROPERTIES (prefix: cstb)
101+------------------------------------------------------------------------
79102
80-local function get_stack_level()
81- local i = tex.getcount('ltj@stack@pbp')
82- if tex.currentgrouplevel > tex.getcount('ltj@group@level@pbp') then
103+---- table: charprop_stack_table [stack_level][chr_code].{pre|post|xsp}
104+local charprop_stack_table={}; charprop_stack_table[0]={}
105+
106+local function cstb_get_stack_level()
107+ local i = tex.getcount('ltj@@stack')
108+ if tex.currentgrouplevel > tex.getcount('ltj@@group@level') then
83109 i = i+1 -- new stack level
84- tex.setcount('ltj@group@level@pbp', tex.currentgrouplevel)
85- for j,v in pairs(ltj.stack_ch_table) do -- clear the stack above i
86- if j>=i then ltj.stack_ch_table[j]=nil end
110+ tex.setcount('ltj@@group@level', tex.currentgrouplevel)
111+ for j,v in pairs(charprop_stack_table) do -- clear the stack above i
112+ if j>=i then charprop_stack_table[j]=nil end
87113 end
88- ltj.stack_ch_table[i] = table.fastcopy(ltj.stack_ch_table[i-1])
89- tex.setcount('ltj@stack@pbp', i)
114+ charprop_stack_table[i] = table.fastcopy(charprop_stack_table[i-1])
115+ tex.setcount('ltj@@stack', i)
90116 end
91117 return i
92118 end
93-function ltj.set_ch_table(g,m,c,p,lb,ub)
94- local i = get_stack_level()
119+
120+-- EXT
121+function ltj.ext_set_stack_table(g,m,c,p,lb,ub)
122+ local i = cstb_get_stack_level()
95123 if p<lb or p>ub then
96124 ltj.error('Invalid code (' .. p .. '), should in the range '
97125 .. tostring(lb) .. '..' .. tostring(ub) .. '.',
98126 {"I'm going to use 0 instead of that illegal code value."})
99127 p=0
100- elseif c<0 or c>0x10FFFF then
128+ elseif c<-1 or c>0x10FFFF then
101129 ltj.error('Invalid character code (' .. p
102- .. '), should in the range 0.."10FFFF.',{})
130+ .. '), should in the range -1.."10FFFF.',{})
103131 return
104- elseif not ltj.stack_ch_table[i][c] then
105- ltj.stack_ch_table[i][c] = {}
132+ elseif not charprop_stack_table[i][c] then
133+ charprop_stack_table[i][c] = {}
106134 end
107- ltj.stack_ch_table[i][c][m] = p
135+ charprop_stack_table[i][c][m] = p
108136 if g=='global' then
109- for j,v in pairs(ltj.stack_ch_table) do
110- if not ltj.stack_ch_table[j][c] then ltj.stack_ch_table[j][c] = {} end
111- ltj.stack_ch_table[j][c][m] = p
137+ for j,v in pairs(charprop_stack_table) do
138+ if not charprop_stack_table[j][c] then charprop_stack_table[j][c] = {} end
139+ charprop_stack_table[j][c][m] = p
112140 end
113141 end
114142 end
115143
116-local function get_penalty_table(m,c)
117- local i = ltj.stack_ch_table[tex.getcount('ltj@stack@pbp')][c]
144+local function cstb_get_penalty_table(m,c)
145+ local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
118146 if i then i=i[m] end
119147 return i or 0
120148 end
121149
122-local function get_inhibit_xsp_table(c)
123- local i = ltj.stack_ch_table[tex.getcount('ltj@stack@pbp')][c]
150+local function cstb_get_inhibit_xsp_table(c)
151+ local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
124152 if i then i=i.xsp end
125153 return i or 3
126154 end
155+ltj.int_get_inhibit_xsp_table = cstb_get_inhibit_xsp_table
127156
128---------
129-function ltj.out_ja_parameter_one(k)
157+------------------------------------------------------------------------
158+-- CODE FOR GETTING/SETTING PARAMETERS
159+------------------------------------------------------------------------
160+
161+-- EXT: print parameters that don't need arguments
162+function ltj.ext_get_parameter_unary(k)
130163 if k == 'yabaselineshift' then
131164 tex.write(print_scaled(tex.getattribute('luatexja@yablshift'))..'pt')
132165 elseif k == 'ykbaselineshift' then
@@ -156,12 +189,11 @@ function ltj.out_ja_parameter_one(k)
156189 end
157190 end
158191
159-
160-
161-function ltj.out_ja_parameter_two(k,c)
192+-- EXT: print parameters that need arguments
193+function ltj.ext_get_parameter_binary(k,c)
162194 if k == 'jcharrange' then
163195 if c<0 or c>216 then c=0 end
164- tex.write(ltj.get_jcr_setting(c))
196+ tex.write(rgjc_get_range_setting(c))
165197 else
166198 if c<0 or c>0x10FFFF then
167199 ltj.error('Invalid character code (' .. c
@@ -170,33 +202,94 @@ function ltj.out_ja_parameter_two(k,c)
170202 c=0
171203 end
172204 if k == 'prebreakpenalty' then
173- tex.write(get_penalty_table('pre',c))
205+ tex.write(cstb_get_penalty_table('pre',c))
174206 elseif k == 'postbreakpenalty' then
175- tex.write(get_penalty_table('post',c))
207+ tex.write(cstb_get_penalty_table('post',c))
176208 elseif k == 'kcatcode' then
177- tex.write(get_penalty_table('kcat',c))
209+ tex.write(cstb_get_penalty_table('kcat',c))
178210 elseif k == 'chartorange' then
179- tex.write(ltj.get_char_jcrnumber(c))
211+ tex.write(rgjc_char_to_range(c))
180212 elseif k == 'cjkxspmode' or k == 'asciixspmode' then
181- tex.write(get_inhibit_xsp_table(c))
213+ tex.write(cstb_get_inhibit_xsp_table(c))
182214 end
183215 end
184216 end
185217
186-
187----------
188-function ltj.print_global()
218+-- EXT: print \global if necessary
219+function ltj.ext_print_global()
189220 if ltj.isglobal=='global' then tex.sprint('\\global') end
190221 end
191222
192-function ltj.create_ihb_node()
223+
224+------------------------------------------------------------------------
225+-- MAIN PROCESS STEP 1: replace fonts (prefix: main1)
226+------------------------------------------------------------------------
227+
228+--- the following function is modified from jafontspec.lua (by K. Maeda).
229+--- Instead of "%", we use U+FFFFF for suppressing spaces.
230+local function main1_process_input_buffer(buffer)
231+ local c = utf.byte(buffer, utf.len(buffer))
232+ local p = node_new(id_glyph)
233+ p.char = c
234+ if utf.len(buffer) > 0
235+ and rgjc_is_ucs_in_japanese_char(p) then
236+ buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
237+ end
238+ return buffer
239+end
240+
241+local function main1_suppress_hyphenate_ja(head)
242+ local p
243+ for p in node.traverse(head) do
244+ if p.id == id_glyph then
245+ if rgjc_is_ucs_in_japanese_char(p) then
246+ local v = has_attr(p, attr_curjfnt)
247+ if v then
248+ p.font = v
249+ node.set_attribute(p,attr_jchar_class,
250+ ljfm_find_char_class(p.char, ltj.font_metric_table[v].jfm))
251+ end
252+ v = has_attr(p, attr_ykblshift)
253+ if v then
254+ node.set_attribute(p, attr_yablshift, v)
255+ else
256+ node.unset_attribute(p, attr_yablshift)
257+ end
258+ p.lang=lang_ja
259+ end
260+ end
261+ end
262+ lang.hyphenate(head)
263+ return head -- 共通化のため値を返す
264+end
265+
266+-- CALLBACKS
267+luatexbase.add_to_callback('process_input_buffer',
268+ function (buffer)
269+ return main1_process_input_buffer(buffer)
270+ end,'ltj.process_input_buffer')
271+luatexbase.add_to_callback('hpack_filter',
272+ function (head,groupcode,size,packtype)
273+ return main1_suppress_hyphenate_ja(head)
274+ end,'ltj.hpack_filter_pre',0)
275+luatexbase.add_to_callback('hyphenate',
276+ function (head,tail)
277+ return main1_suppress_hyphenate_ja(head)
278+ end,'ltj.hyphenate')
279+
280+
281+------------------------------------------------------------------------
282+-- MAIN PROCESS STEP 2: insert glue/kerns from JFM (prefix: main2)
283+------------------------------------------------------------------------
284+
285+-- EXT: for \inhibitglue
286+function ltj.ext_create_inhibitglue_node()
193287 local g=node_new(id_whatsit, node.subtype('user_defined'))
194- g.user_id=30111; g.type=number; g.value=1
195- node.write(g)
288+ g.user_id=30111; g.type=number; g.value=1; node.write(g)
196289 end
197290
198291
199-local function find_size_metric(px)
292+local function main2_find_size_metric(px)
200293 if is_japanese_glyph_node(px) then
201294 return ltj.font_metric_table[px.font].size, ltj.font_metric_table[px.font].jfm
202295 else
@@ -204,94 +297,130 @@ local function find_size_metric(px)
204297 end
205298 end
206299
207-local function new_jfm_glue(size,mt,bc,ac)
300+local function main2_new_jfm_glue(size,mt,bc,ac)
208301 -- mt: metric key, bc, ac: char classes
209302 local g=nil
210- local h
211303 local w=bc*0x800+ac
212- if ltj.metrics[mt].glue[w] then
213- h=node_new(id_glue_spec)
214- h.width =round(size*ltj.metrics[mt].glue[w].width)
215- h.stretch=round(size*ltj.metrics[mt].glue[w].stretch)
216- h.shrink =round(size*ltj.metrics[mt].glue[w].shrink)
304+ local z = ltj.metrics[mt]
305+ if z.glue[w] then
306+ local h = node_new(id_glue_spec)
307+ h.width = round(size*z.glue[w][0])
308+ h.stretch = round(size*z.glue[w][1])
309+ h.shrink = round(size*z.glue[w][2])
217310 h.stretch_order=0; h.shrink_order=0
218- g=node_new(id_glue)
219- g.subtype=0; g.spec=h; return g
220- elseif ltj.metrics[mt].kern[w] then
221- g=node_new(node.id('kern'))
222- g.subtype=0; g.kern=round(size*ltj.metrics[mt].kern[w]); return g
223- else
224- return nil
311+ g = node_new(id_glue)
312+ g.subtype = 0; g.spec = h
313+ elseif z.kern[w] then
314+ g = node_new(id_kern)
315+ g.subtype = 1; g.kern = round(size*z.kern[w])
225316 end
317+ return g
226318 end
227319
228-
229-function calc_between_two_jchar(q,p)
320+-- return value: g (glue/kern from JFM), w (width of 'lineend' kern)
321+local function main2_calc(qs,qm,q,p,last,ihb_flag)
230322 -- q, p: node (possibly null)
231- local ps,pm,qs,qm,g,h
232- if (not p) or (p.id==id_glue and p.subtype==15) then
323+ local ps, pm, g, h
324+ local w = 0
325+ if (not p) or p==last then
233326 -- q is the last node
234- -- (p is nil or \parfillskip)
235- qs, qm = find_size_metric(q)
236327 if not qm then
237- return nil
238- else
239- g=new_jfm_glue(qs,qm,
328+ return nil, 0
329+ elseif not ihb_flag then
330+ g=main2_new_jfm_glue(qs,qm,
240331 has_attr(q,attr_jchar_class),
241- ltj.find_char_type('boxbdd',qm))
332+ ljfm_find_char_class('boxbdd',qm))
242333 end
243- elseif not q then
334+ elseif qs==0 then
244335 -- p is the first node etc.
245- ps, pm = find_size_metric(p)
336+ ps, pm = main2_find_size_metric(p)
246337 if not pm then
247- return nil
248- else
249- g=new_jfm_glue(ps,pm,
250- ltj.find_char_type('boxbdd',pm),
338+ return nil, 0
339+ elseif not ihb_flag then
340+ g=main2_new_jfm_glue(ps,pm,
341+ ljfm_find_char_class('boxbdd',pm),
251342 has_attr(p,attr_jchar_class))
252343 end
253344 else -- p and q are not nil
254- qs, qm = find_size_metric(q)
255- ps, pm = find_size_metric(p)
256- if (not pm) and (not qm) then
257- -- Both p and q are NOT Japanese glyph node
258- return nil
345+ ps, pm = main2_find_size_metric(p)
346+ if ihb_flag or ((not pm) and (not qm)) then
347+ g = nil
259348 elseif (qs==ps) and (qm==pm) then
260- -- Both p and q are Japanese glyph node, and same metric and size
261- g=new_jfm_glue(ps,pm,
262- has_attr(q,attr_jchar_class),
263- has_attr(p,attr_jchar_class))
349+ -- Both p and q are Japanese glyph nodes, and same metric and size
350+ g = main2_new_jfm_glue(ps,pm,
351+ has_attr(q,attr_jchar_class),
352+ has_attr(p,attr_jchar_class))
264353 elseif not qm then
265- -- q is not Japanese glyph node
266- g=new_jfm_glue(ps,pm,
267- ltj.find_char_type('jcharbdd',pm),
268- has_attr(p,attr_jchar_class))
354+ -- q is not a Japanese glyph node
355+ g = main2_new_jfm_glue(ps,pm,
356+ ljfm_find_char_class('jcharbdd',pm),
357+ has_attr(p,attr_jchar_class))
269358 elseif not pm then
270- -- p is not Japanese glyph node
271- g=new_jfm_glue(qs,qm,
272- has_attr(q,attr_jchar_class),
273- ltj.find_char_type('jcharbdd',qm))
359+ -- p is not a Japanese glyph node
360+ g = main2_new_jfm_glue(qs,qm,
361+ has_attr(q,attr_jchar_class),
362+ ljfm_find_char_class('jcharbdd',qm))
274363 else
275- g=new_jfm_glue(qs,qm,
276- has_attr(q,attr_jchar_class),
277- ltj.find_char_type('diffmet',qm))
278- h=new_jfm_glue(ps,pm,
279- ltj.find_char_type('diffmet',pm),
280- has_attr(p,attr_jchar_class))
281- g=ltj.calc_between_two_jchar_aux(g,h)
364+ g = main2_new_jfm_glue(qs,qm,
365+ has_attr(q,attr_jchar_class),
366+ ljfm_find_char_class('diffmet',qm))
367+ h = main2_new_jfm_glue(ps,pm,
368+ ljfm_find_char_class('diffmet',pm),
369+ has_attr(p,attr_jchar_class))
370+ g = ltj.calc_between_two_jchar_aux(g,h)
282371 end
283372 end
284- if g then node.set_attribute(g,attr_icflag,2) end
285- return g
373+ if g then node.set_attribute(g, attr_icflag, 3) end
374+ if qm then
375+ local x = ljfm_find_char_class('lineend', qm)
376+ if x~=0 then
377+ x = has_attr(q,attr_jchar_class)*0x800 + x
378+ if ltj.metrics[qm].kern[x] then
379+ w = round(qs*ltj.metrics[qm].kern[x])
380+ end
381+ end
382+ end
383+
384+ return g, w
286385 end
287386
387+local function main2_between_two_char(head,q,p,p_bp,ihb_flag,last)
388+ local qs = 0; local g, w
389+ local qm = nil
390+ if q then
391+ qs, qm = main2_find_size_metric(q)
392+ end
393+ g, w = main2_calc(qs, qm, q, p, last, ihb_flag)
394+ if w~=0 and (not p_bp) then
395+ p_bp = node_new(id_penalty); p_bp.penalty = 0
396+ head = node_insert_before(head, p, p_bp)
397+ end
398+ if g then
399+ if g.id==id_kern then
400+ g.kern = round(g.kern - w)
401+ else
402+ g.spec.width = round(g.spec.width - w)
403+ end
404+ head = node_insert_before(head, p, g)
405+ elseif w~=0 then
406+ g = node_new(id_kern); g.kern = -w; g.subtype = 1
407+ node.set_attribute(g,attr_icflag,2)
408+ head = node_insert_before(head, p, g)
409+ -- this g might be replaced by \[x]kanjiskip in step 3.
410+ end
411+ if w~=0 then
412+ g = node_new(id_kern); g.kern = w; g.subtype = 0
413+ head = node_insert_before(head, p_bp, g)
414+ end
415+return head, p_bp
416+end
288417
289--- In the beginning of a hbox created by line breaking, there are the followings:
290--- o a hbox by \parindent
291--- o a whatsit node which contains local paragraph materials.
418+-- In the beginning of a hlist created by line breaking, there are the followings:
419+-- - a hbox by \parindent
420+-- - a whatsit node which contains local paragraph materials.
292421 -- When we insert jfm glues, we ignore these nodes.
293-local function parindent_box(p)
294- if node_type(p.id)=='hlist' then
422+local function main2_is_parindent_box(p)
423+ if p.id==id_hlist then
295424 return (p.subtype==3)
296425 -- hlist (subtype=3) is a box by \parindent
297426 elseif p.id==id_whatsit then
@@ -299,50 +428,49 @@ local function parindent_box(p)
299428 end
300429 end
301430
302-local function add_kinsoku_penalty(head,p)
431+-- next three functions deal with inserting penalty by kinsoku.
432+local function main2_add_penalty_before(head,p,p_bp,pen)
433+ if p_bp then
434+ p_bp.penalty = p_bp.penalty + pen
435+ else -- we must create a new penalty node
436+ local g = node_new(id_penalty); g.penalty = pen
437+ local q = node_prev(p)
438+ if q then
439+ if has_attr(q, attr_icflag) ~= 3 then
440+ q = p
441+ end
442+ return node_insert_before(head, q, g)
443+ end
444+ end
445+ return head
446+end
447+
448+local function main2_add_kinsoku_penalty(head,p,p_bp)
303449 local c = p.char
304- local e = get_penalty_table('pre',c)
450+ local e = cstb_get_penalty_table('pre',c)
305451 if e~=0 then
306- local q = node.prev(p)
307- if q and q.id==id_penalty then
308- q.penalty=q.penalty+e
309- else
310- q=node_new(id_penalty)
311- q.penalty=e
312- node_insert_before(head,p,q)
313- end
452+ head = main2_add_penalty_before(head, p, p_bp, e)
314453 end
315- e = get_penalty_table('post',c)
454+ e = cstb_get_penalty_table('post',c)
316455 if e~=0 then
317- local q = next_node(p)
456+ local q = node_next(p)
318457 if q and q.id==id_penalty then
319- q.penalty=q.penalty+e
458+ q.penalty = q.penalty + e
320459 return false
321460 else
322- q=node_new(id_penalty)
323- q.penalty=e
461+ q = node_new(id_penalty); q.penalty = e
324462 node_insert_after(head,p,q)
325463 return true
326464 end
327465 end
328466 end
329467
330-local function insert_widow_penalty(head,jq)
331- if not jq then
332- return head
333- end
334- local p = node.prev(jq)
335- local jwp=tex.getcount('jcharwidowpenalty')
336- if p and has_attr(p,attr_icflag)==2 then
337- jq=p -- the case where jq has the non-zero \prebreakpenalty.
338- end
339- if jq.id==id_penalty then
340- jq.penalty=jq.penalty + jwp
468+local function main2_add_widow_penalty(head,widow_node,widow_bp)
469+ if not widow_node then
341470 return head
342471 else
343- local g = node.new(id_penalty)
344- g.penalty=jwp
345- return node_insert_before(head,jq,g)
472+ return main2_add_penalty_before(head, widow_node,
473+ widow_bp, tex.getcount('jcharwidowpenalty'))
346474 end
347475 end
348476
@@ -350,473 +478,180 @@ local depth=""
350478
351479 -- Insert jfm glue: main routine
352480 -- mode = true iff insert_jfm_glue is called from pre_linebreak_filter
353-local function insert_jfm_glue(head, mode)
481+local function main2_insert_jfm_glue(head, mode)
354482 local p = head
483+ local p_bp = nil -- p と直前の文字の間の penalty node
355484 local q = nil -- the previous node of p
356- local jq = nil -- 最後の「句読点扱いでない」和文文字
485+ local widow_node = nil -- 最後の「句読点扱いでない」和文文字
486+ local widow_bp = nil -- \jcharwidowpenalty 挿入位置
487+ local last -- the sentinel
488+ local ihb_flag = false -- is \inhibitglue specified?
357489 local g
358- local ihb_flag = false
359- local pn = nil
490+ -- initialization
360491 if not p then return head
361492 elseif mode then
362- while p and parindent_box(p) do p=next_node(p) end
363- pn=node.tail(head)
364- if pn and pn.id==id_glue and pn.subtype==15 then
365- pn=node.prev(pn)
366- while (pn and pn.id==id_penalty) do pn=node.prev(pn) end
493+ while p and main2_is_parindent_box(p) do p=node_next(p) end
494+ last=node.tail(head)
495+ if last and last.id==id_glue and last.subtype==15 then
496+ last=node.prev(last)
497+ while (last and last.id==id_penalty) do last=node.prev(last) end
367498 end
368- if pn then pn=next_node(pn) end
499+ if last then last=node_next(last) end
500+ else -- 番人を挿入
501+ last=node.tail(head); g = node_new('kern')
502+ node_insert_after(head,last,g); last = g
369503 end
370- while p~=pn do
504+ -- main loop
505+ while q~=last do
371506 if p.id==id_whatsit and p.subtype==node.subtype('user_defined')
372507 and p.user_id==30111 then
373- g=p; p=next_node(p);
374- ihb_flag=true; head,p=node.remove(head, g)
508+ g = p; p = node_next(p)
509+ ihb_flag = true; head, p = node.remove(head, g)
375510 else
376- g=calc_between_two_jchar(q,p)
377- if g and (not ihb_flag) then
378- h = node_insert_before(head,p,g)
379- if not q then head=h end
380- -- If p is the first node (=head), the skip is inserted
381- -- before head. So we must change head.
382- end
383- q=p; ihb_flag=false;
511+ head, p_bp = main2_between_two_char(head, q, p, p_bp, ihb_flag, last)
512+ q=p; ihb_flag=false
384513 if is_japanese_glyph_node(p) then
385- if get_penalty_table('kcat',p.char)%2~=1 then
386- jq=p
514+ if cstb_get_penalty_table('kcat',p.char)%2~=1 then
515+ widow_node = p; widow_bp = p_bp
387516 end
388- if add_kinsoku_penalty(head,p) then
389- p=next_node(p)
517+ if main2_add_kinsoku_penalty(head, p, p_bp) then
518+ p_bp = node_next(p); p = p_bp
519+ else p_bp = nil
390520 end
521+ else p_bp = nil
391522 end
392- p=next_node(p)
523+ p=node_next(p)
393524 end
394525 end
395- -- Insert skip after the last node
396- g=calc_between_two_jchar(q,nil)
397- if g then h = node_insert_after(head,q,g) end
398-
399526 if mode then
400527 -- Insert \jcharwidowpenalty
401- head = insert_widow_penalty(head,jq)
402- end
403- return head
404-end
405-
406-
407-
408--- Insert \xkanjiskip at the boundaries between Japanese characters
409--- and non-Japanese characters.
410--- We also insert \kanjiskip between Kanji in this function.
411-local kanji_skip={}
412-local xkanji_skip={}
413-local cx = nil
414-local no_skip=0
415-local after_schar=1
416-local after_wchar=2
417-local insert_skip=no_skip
418-
419-
420--- In the next two function, cx is the Kanji code.
421-local function insert_akxsp(head,q)
422- if get_inhibit_xsp_table(cx)<=1 then return end
423- local g = node_new(id_glue)
424- g.subtype=0; g.spec=node.copy(xkanji_skip)
425- node_insert_after(head,q,g)
426-end
427-
428-local function insert_kaxsp(head,q,p)
429- local g=true
430- local c=p.char
431- while p.components and p.subtype
432- and math.floor(p.subtype/2)%2==1 do
433- p=p.components; c = p.char
434- end
435- if get_inhibit_xsp_table(c)%2 == 1 then
436- if get_inhibit_xsp_table(cx)%2==0 then g=false end
437- else
438- g=false
439- end
440- if g then
441- g = node_new(id_glue)
442- g.subtype=0; g.spec=node.copy(xkanji_skip)
443- node_insert_after(head,q,g)
444- end
445-end
446-
447-
448-local function set_insert_skip_after_achar(p)
449- local c=p.char
450- while p.components and p.subtype
451- and math.floor(p.subtype/2)%2==1 do
452- p=node.tail(p.components); c = p.char
453- end
454- if get_inhibit_xsp_table(c)>=2 then
455- insert_skip=after_schar
456- else
457- insert_skip=no_skip
458- end
459-end
460-
461--- Insert \xkanjiskip before p, a glyph node
462-local function insks_around_char(head,q,p)
463- if is_japanese_glyph_node(p) then
464- cx=p.char
465- if is_japanese_glyph_node(q) then
466- local g = node_new(id_glue)
467- g.subtype=0; g.spec=node.copy(kanji_skip)
468- node_insert_before(head,p,g)
469- elseif insert_skip==after_schar then
470- insert_akxsp(head,q)
528+ head = main2_add_widow_penalty(head, widow_node, widow_bp)
529+ -- cleanup
530+ p = node_prev(last)
531+ if p and p.id==id_kern and has_attr(p,attr_icflag)==2 then
532+ head = node.remove(head, p)
471533 end
472- insert_skip=after_wchar
473534 else
474- if insert_skip==after_wchar then
475- insert_kaxsp(head,q,p)
476- end
477- set_insert_skip_after_achar(p)
478- end
479-end
480-
481--- Return first and last glyph nodes in a hbox
482-local first_char = nil
483-local last_char = nil
484-local find_first_char = nil
485-local function check_box(bp)
486- local p = bp; local flag = false
487- while p do
488- local pt = node_type(p.id)
489- if pt=='glyph' then
490- repeat
491- if find_first_char then
492- first_char=p; find_first_char=false
493- end
494- last_char=p; flag=true; p=next_node(p)
495- if not p then return flag end
496- until p.id~=id_glyph
497- end
498- if pt=='hlist' then
499- flag=true
500- if p.shift==0 then
501- if check_box(p.head) then flag=true end
502- else if find_first_char then
503- find_first_char=false
504- else
505- last_char=nil
506- end
507- end
508- elseif pt == 'ins' or pt == 'mark'
509- or pt == 'adjust'
510- or pt == 'whatsit' or pt == 'penalty' then
511- p=p
512- else
513- flag=true
514- if find_first_char then
515- find_first_char=false
516- else
517- last_char=nil
518- end
519- end
520- p=next_node(p)
521- end
522- return flag
523-end
524-
525--- Insert \xkanjiskip around p, an hbox
526-local function insks_around_hbox(head,q,p)
527- if p.shift==0 then
528- find_first_char=true; first_char=nil; last_char=nil
529- if check_box(p.head) then
530- -- first char
531- if is_japanese_glyph_node(first_char) then
532- cx=first_char.char
533- if insert_skip==after_schar then
534- insert_akxsp(head,q)
535- elseif insert_skip==after_wchar then
536- local g = node_new(id_glue)
537- g.subtype=0; g.spec=node.copy(kanji_skip)
538- node_insert_before(head,p,g)
539- end
540- insert_skip=after_wchar
541- elseif first_char then
542- cx=first_char.char
543- if insert_skip==after_wchar then
544- insert_kaxsp(head,q,first_char)
545- end
546- set_insert_skip_after_achar(first_char)
547- end
548- -- last char
549- if is_japanese_glyph_node(last_char) then
550- if is_japanese_glyph_node(next_node(p)) then
551- local g = node_new(id_glue)
552- g.subtype=0; g.spec=node.copy(kanji_skip)
553- node_insert_after(head,p,g)
554- end
555- insert_skip=after_wchar
556- elseif last_char then
557- set_insert_skip_after_achar(last_char)
558- else insert_skip=no_skip
559- end
560- else insert_skip=no_skip
561- end
562- else insert_skip=no_skip
563- end
564-end
565-
566--- Insert \xkanjiskip around p, a penalty
567-local function insks_around_penalty(head,q,p)
568- local r=next_node(p)
569- if r and r.id==id_glyph then
570- if is_japanese_glyph_node(r) then
571- cx=r.char
572- if is_japanese_glyph_node(q) then
573- local g = node_new(id_glue)
574- g.subtype=0; g.spec=node.copy(kanji_skip)
575- node_insert_before(head,r,g)
576- elseif insert_skip==insert_schar then
577- insert_akxsp(head,p)
578- end
579- q=p; p=next_node(p)
580- insert_skip=after_wchar
581- else
582- if insert_skip==after_wchar then
583- insert_kaxsp(head,p,r)
584- end
585- set_insert_skip_after_achar(r)
586- end
587- end
588-end
589-
590--- Insert \xkanjiskip around p, a kern
591-local function insks_around_kern(head,q,p)
592- if p.subtype==1 then -- \kern or \/
593- if not has_attr(p,attr_icflag) then
594- insert_skip=no_skip
595- end
596- elseif p.subtype==2 then -- \accent: We ignore the accent character.
597- local v = next_node(next_node(next_node(p)))
598- if v and v.id==id_glyph then
599- insks_around_char(head,q,v)
600- end
601- end
602-end
603-
604--- Insert \xkanjiskip around p, a math_node
605-local function insks_around_math(head,q,p)
606- local g = { char = -1 }
607- if (p.subtype==0) and (insert_skip==after_wchar) then
608- insert_kaxsp(head,q,g)
609- insert_skip=no_skip
610- else
611- set_insert_skip_after_achar(g)
612- end
613-end
614-
615-local function insert_kanji_skip(head)
616- if ltj.auto_spacing then
617- kanji_skip=tex.skip['kanjiskip']
618- else
619- kanji_skip=node_new(id_glue_spec)
620- kanji_skip.width=0; kanji_skip.stretch=0; kanji_skip.shrink=0
621- end
622- if ltj.auto_xspacing then
623- xkanji_skip=tex.skip['xkanjiskip']
624- else
625- xkanji_skip=node_new(id_glue_spec)
626- xkanji_skip.width=0; xkanji_skip.stretch=0; xkanji_skip.shrink=0
627- end
628- local p=head -- 「現在のnode」
629- local q=nil -- pの一つ前
630- insert_skip=no_skip
631- while p do
632- local pt = node_type(p.id)
633- if pt=='glyph' then
634- repeat
635- insks_around_char(head,q,p)
636- q=p; p=next_node(p)
637- until (not p) or p.id~=id_glyph
638- else
639- if pt == 'hlist' then
640- insks_around_hbox(head,q,p)
641- elseif pt == 'penalty' then
642- insks_around_penalty(head,q,p)
643- elseif pt == 'kern' then
644- insks_around_kern(head,q,p)
645- elseif pt == 'math' then
646- insks_around_math(head,q,p)
647- elseif pt == 'ins' or pt == 'mark'
648- or pt == 'adjust'
649- or pt == 'whatsit' then
650- -- do nothing
651- p=p
652- else
653- -- rule, disc, glue, margin_kern
654- insert_skip=no_skip
655- end
656- q=p; p=next_node(p)
657- end
535+ head = node.remove(head, last)
658536 end
659537 return head
660538 end
661539
662--- Shift baseline
663-local function baselineshift(head)
664- local p=head
665- local m=false -- is in math mode?
666- while p do
667- local v=has_attr(p,attr_yablshift)
668- if v then
669- local pt = node_type(p.id)
670- if pt=='glyph' then
671- p.yoffset=p.yoffset-v
672- elseif pt=='math' then
673- m=(p.subtype==0)
674- end
675- if m then -- boxes and rules are shifted only in math mode
676- if pt=='hlist' or pt=='vlist' then
677- p.shift=p.shift+v
678- elseif pt=='rule' then
679- p.height=p.height-v; p.depth=p.depth+v
680- end
681- end
682- end
683- p=next_node(p)
684- end
685- return head
686-end
687540
688-
689---====== Adjust the width of Japanese glyphs
541+------------------------------------------------------------------------
542+-- MAIN PROCESS STEP 4: width of japanese chars (prefix: main4)
543+------------------------------------------------------------------------
690544
691545 -- TeX's \hss
692-local function get_hss()
546+local function main4_get_hss()
693547 local hss = node_new(id_glue)
694- local hss_spec = node_new(id_glue_spec)
695- hss_spec.width = 0
696- hss_spec.stretch = 65536
697- hss_spec.stretch_order = 2
698- hss_spec.shrink = 65536
699- hss_spec.shrink_order = 2
700- hss.spec = hss_spec
548+ local fil_spec = node_new(id_glue_spec)
549+ fil_spec.width = 0
550+ fil_spec.stretch = 65536
551+ fil_spec.stretch_order = 2
552+ fil_spec.shrink = 65536
553+ fil_spec.shrink_order = 2
554+ hss.spec = fil_spec
701555 return hss
702556 end
703557
704-local function set_ja_width(head)
558+local function main4_set_ja_width(head)
705559 local p = head
706- local t,s,th, g, q,a
560+ local met_tb, t, s, g, th, q, a
561+ local m = false -- is in math mode?
707562 while p do
708- if is_japanese_glyph_node(p) then
709- t=ltj.metrics[ltj.font_metric_table[p.font].jfm]
710- s=t.char_type[has_attr(p,attr_jchar_class)]
711- if not(s.left==0.0 and s.down==0.0
712- and round(s.width*ltj.font_metric_table[p.font].size)==p.width) then
713- -- must be encapsuled by a \hbox
714- head, q = node.remove(head,p)
715- p.next=nil
716- p.yoffset=round(p.yoffset-ltj.font_metric_table[p.font].size*s.down)
717- p.xoffset=round(p.xoffset-ltj.font_metric_table[p.font].size*s.left)
718- node_insert_after(p,p,get_hss())
719- g=node_hpack(p, round(ltj.font_metric_table[p.font].size*s.width)
720- , 'exactly')
721- g.height=round(ltj.font_metric_table[p.font].size*s.height)
722- g.depth=round(ltj.font_metric_table[p.font].size*s.depth)
723- head,p = node_insert_before(head,q,g)
724- p=q
725- else p=next_node(p)
563+ local v=has_attr(p,attr_yablshift) or 0
564+ if p.id==id_glyph then
565+ p.yoffset = p.yoffset-v
566+ if is_japanese_glyph_node(p) then
567+ met_tb = ltj.font_metric_table[p.font]
568+ t = ltj.metrics[met_tb.jfm]
569+ s = t.char_type[has_attr(p,attr_jchar_class)]
570+ if not(s.left==0.0 and s.down==0.0
571+ and round(s.width*met_tb.size)==p.width) then
572+ -- must be encapsuled by a \hbox
573+ head, q = node.remove(head,p)
574+ p.next=nil
575+ p.yoffset=round(p.yoffset-met_tb.size*s.down)
576+ p.xoffset=round(p.xoffset-met_tb.size*s.left)
577+ node_insert_after(p, p, main4_get_hss())
578+ g = node_hpack(p, round(met_tb.size*s.width), 'exactly')
579+ g.height = round(met_tb.size*s.height)
580+ g.depth = round(met_tb.size*s.depth)
581+ head, p = node_insert_before(head, q, g)
582+ p = q
583+ else p=node_next(p)
584+ end
585+ else p=node_next(p)
726586 end
727- else p=next_node(p)
587+ elseif p.id==id_math then
588+ m=(p.subtype==0); p=node_next(p)
589+ else
590+ if m then
591+ if p.id==id_hlist or p.id==id_vlist then
592+ p.shift=p.shift+v
593+ elseif p.id==id_rule then
594+ p.height=p.height-v; p.depth=p.depth+v
595+ end
596+ end
597+ p=node_next(p)
728598 end
729599 end
730- return head
600+return head
731601 end
732602
733603 -- main process
734604 -- mode = true iff main_process is called from pre_linebreak_filter
735605 local function main_process(head, mode)
736606 local p = head
737- p = insert_jfm_glue(p,mode)
738- p = insert_kanji_skip(p)
739- p = baselineshift(p)
740- p = set_ja_width(p)
607+ p = main2_insert_jfm_glue(p,mode)
608+ p = ltj.int_insert_kanji_skip(p)
609+ p = main4_set_ja_width(p)
741610 return p
742611 end
743612
613+
744614 -- debug
745-function ltj.show_node_list(head)
746- local p =head; local k = depth
747- depth=depth .. '.'
615+local debug_depth
616+function ltj.ext_show_node_list(head,depth,print_fn)
617+ debug_depth = depth
618+ if head then
619+ debug_show_node_list_X(head, print_fn)
620+ else
621+ print_fn(debug_depth .. ' (null list)')
622+ end
623+end
624+function debug_show_node_list_X(p,print_fn)
625+ debug_depth=debug_depth.. '.'
626+ local k = debug_depth
748627 while p do
749628 local pt=node_type(p.id)
750629 if pt == 'glyph' then
751- print(depth .. ' glyph', p.subtype, utf.char(p.char), p.font)
630+ print_fn(debug_depth.. ' glyph ', p.subtype, utf.char(p.char), p.font)
752631 elseif pt=='hlist' then
753- print(depth .. ' hlist', p.subtype, '(' .. print_scaled(p.height)
632+ print_fn(debug_depth.. ' hlist ', p.subtype, '(' .. print_scaled(p.height)
754633 .. '+' .. print_scaled(p.depth)
755634 .. ')x' .. print_scaled(p.width) )
756- ltj.show_node_list(p.head)
757- depth=k
635+ debug_show_node_list_X(p.head,print_fn)
636+ debug_depth=k
758637 elseif pt == 'whatsit' then
759- print(depth .. ' whatsit', p.subtype)
638+ print_fn(debug_depth.. ' whatsit', p.subtype)
760639 elseif pt == 'glue' then
761- print(depth .. ' glue', p.subtype, print_spec(p.spec))
640+ print_fn(debug_depth.. ' glue ', p.subtype, print_spec(p.spec))
641+ elseif pt == 'kern' then
642+ print_fn(debug_depth.. ' kern ', p.subtype, print_scaled(p.kern) .. 'pt')
762643 elseif pt == 'penalty' then
763- print(depth .. ' penalty', p.penalty)
644+ print_fn(debug_depth.. ' penalty', p.penalty)
764645 else
765- print(depth .. ' ' .. node.type(p.id), p.subtype)
646+ print_fn(debug_depth.. ' ' .. node.type(p.id), p.subtype)
766647 end
767- p=next_node(p)
768- end
769-end
770-
771-
772-
773---- the following function is modified from jafontspec.lua (by K. Maeda).
774---- Instead of "%", we use U+FFFFF for suppressing spaces.
775-local function process_input_buffer(buffer)
776- local c = utf.byte(buffer, utf.len(buffer))
777- local p = node.new(id_glyph)
778- p.char = c
779- if utf.len(buffer) > 0
780- and ltj.is_ucs_in_japanese_char(p) then
781- buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
648+ p=node_next(p)
782649 end
783- return buffer
784650 end
785651
786652
787----------- Hyphenate
788-local function suppress_hyphenate_ja(head)
789- local p
790- for p in node.traverse(head) do
791- if p.id == id_glyph then
792- local pc=p.char
793- if ltj.is_ucs_in_japanese_char(p) then
794- local v = has_attr(p,attr_curjfnt)
795- if v then
796- p.font=v
797- local l=ltj.find_char_type(pc,ltj.font_metric_table[v].jfm) or 0
798- node.set_attribute(p,attr_jchar_class,l)
799- end
800- v=has_attr(p,luatexbase.attributes['luatexja@ykblshift'])
801- if v then
802- node.set_attribute(p,attr_yablshift,v)
803- else
804- node.unset_attribute(p,attr_yablshift)
805- end
806- p.lang=ltj.ja_lang_number
807- end
808- end
809- end
810- lang.hyphenate(head)
811- return head -- 共通化のため値を返す
812-end
813653
814654 -- callbacks
815-luatexbase.add_to_callback('process_input_buffer',
816- function (buffer)
817- return process_input_buffer(buffer)
818- end,'ltj.process_input_buffer')
819-
820655 luatexbase.add_to_callback('pre_linebreak_filter',
821656 function (head,groupcode)
822657 return main_process(head, true)
@@ -825,13 +660,3 @@ luatexbase.add_to_callback('hpack_filter',
825660 function (head,groupcode,size,packtype)
826661 return main_process(head, false)
827662 end,'ltj.hpack_filter',2)
828-
829---insert before callbacks from luaotfload
830-luatexbase.add_to_callback('hpack_filter',
831- function (head,groupcode,size,packtype)
832- return suppress_hyphenate_ja(head)
833- end,'ltj.hpack_filter_pre',0)
834-luatexbase.add_to_callback('hyphenate',
835- function (head,tail)
836- return suppress_hyphenate_ja(head)
837- end,'ltj.hyphenate')
--- a/src/luatexja-core.sty
+++ b/src/luatexja-core.sty
@@ -46,10 +46,10 @@
4646 require('lualibs')
4747 ltj.loadlua('luatexja-rmlgbm.lua')
4848 % For Ryumin-Light and GothicBBB-Medium.
49- ltj.loadlua('luatexja-core.lua')
5049 ltj.loadlua('luatexja-jfont.lua')
50+ ltj.loadlua('luatexja-core.lua')
51+ ltj.loadlua('luatexja-xkanji.lua')
5152 ltj.loadlua('luatexja-core-aux.lua')
52- ltj.ja_lang_number=\the\luatexja@japanese
5353 }
5454
5555
@@ -66,24 +66,25 @@
6666 \def\asluastring#1{'\luaescapestring{\detokenize{#1}}'}
6767
6868 %%%%%%%% Redefine \/
69-\let\luatexja@ic=\/ \protected\def\/{{\luatexja@icflag=1\luatexja@ic}}
69+%\let\luatexja@ic=\/ \protected\def\/{{\luatexja@icflag=1\luatexja@ic}}
70+\protected\def\/{\directlua{ltj.ext_append_italic()}}
7071
7172 %%%%%%%% \jfont\CS={...:...;jfm=metric;...}, \gjfont
72-\def\jfont{\afterassignment\@jfont\directlua{ltj.jfontdefX('false')}}
73-\def\gjfont{\afterassignment\@jfont\directlua{ltj.jfontdefX('true')}}
74-\def\@jfont{\directlua{ltj.jfontdefY()}}
73+\def\jfont{\afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(false)}}
74+\def\gjfont{\afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(true)}}
75+\def\ltj@@jfont{\directlua{ltj.ext_jfontdefY()}}
7576
7677 %%%%%%%% \inhibitglue
77-\def\inhibitglue{\directlua{ltj.create_ihb_node()}}
78+\def\inhibitglue{\directlua{ltj.ext_create_inhibitglue_node()}}
7879
79-%%%%%%%% \defcharrange<name>{100-200,3000-,5000,...}
80-\def\defcharrange#1#2{%
81- \ltj@tempcntc=#1 \expandafter\ltj@dcrange#2,,\ignorespaces}
82-\def\ltj@dcrange#1,{\def\ltj@temp{#1}%
80+%%%%%%%% \ltjdefcharrange<name>{100-200,3000-,5000,...}
81+\def\ltjdefcharrange#1#2{%
82+ \luatexja@tempcntc=#1 \expandafter\ltj@@dcrange#2,,\ignorespaces}
83+\def\ltj@@dcrange#1,{\def\ltj@temp{#1}%
8384 \ifx\ltj@temp\empty\let\@next=\relax\else
84- \ltj@@dcrange{#1}\let\@next=\ltj@dcrange\fi\@next}
85-\def\ltj@@dcrange#1{\ltj@enexist#1--\@nil}
86-\def\ltj@enexist#1-#2-#3\@nil{\def\ltj@temp{#3}%
85+ \ltj@@dcrangeA{#1}\let\@next=\ltj@@dcrange\fi\@next}
86+\def\ltj@@dcrangeA#1{\ltj@@dcrangeB#1--\@nil}
87+\def\ltj@@dcrangeB#1-#2-#3\@nil{\def\ltj@temp{#3}%
8788 \ifx\ltj@temp\empty
8889 \luatexja@tempcnta=#1 \luatexja@tempcntb=\luatexja@tempcnta
8990 \else
@@ -92,26 +93,25 @@
9293 \def\ltj@temp{#2}%
9394 \ifx\ltj@temp\empty\luatexja@tempcntb="10FFFF \else\luatexja@tempcntb=#2 \fi%"
9495 \fi
95- \directlua{ltj.def_char_range(\the\luatexja@tempcnta,\the\luatexja@tempcntb,
96+ \directlua{ltj.ext_add_char_range(\the\luatexja@tempcnta,\the\luatexja@tempcntb,
9697 \the\luatexja@tempcntc)}%
9798 }
9899
99-%%%%%%%% \setjaparameter
100-\newcount\ltj@stack@pbp\newcount\ltj@group@level@pbp
101-\ltj@group@level@pbp=0 \ltj@stack@pbp=0
100+%%%%%%%% \ltjsetparameter
101+\newcount\ltj@@stack \newcount\ltj@@group@level
102+\ltj@@group@level=0 \ltj@@stack=0
102103
103104 % prebreakpenalty = {<char_code>, <penalty>}
104105 \define@key[ltj]{japaram}{kcatcode}{%
105- \expandafter\luatexja@setbp#1:{kcat}{0}{0x7FFFFFFF}}
106+ \expandafter\ltj@@set@stack#1:{kcat}{0}{0x7FFFFFFF}}
106107 \define@key[ltj]{japaram}{prebreakpenalty}{%
107- \expandafter\luatexja@setbp#1:{pre}{-10000}{10000}}
108+ \expandafter\ltj@@set@stack#1:{pre}{-10000}{10000}}
108109 \define@key[ltj]{japaram}{postbreakpenalty}{%
109- \expandafter\luatexja@setbp#1:{post}{-10000}{10000}}
110-\def\luatexja@setbp#1,#2:#3#4#5{
111- \luatexja@tempcnta=#1\relax
112- \luatexja@tempcntb=#2\relax
113- \directlua{ltj.set_ch_table(ltj.isglobal, \asluastring{#3},
114- tex.getcount('luatexja@tempcnta'),tex.getcount('luatexja@tempcntb'),#4,#5)}}
110+ \expandafter\ltj@@set@stack#1:{post}{-10000}{10000}}
111+\def\ltj@@set@stack#1,#2:#3#4#5{%
112+ \luatexja@tempcnta=#1\relax \luatexja@tempcntb=#2\relax
113+ \directlua{ltj.ext_set_stack_table(ltj.isglobal, \asluastring{#3},
114+ \the\luatexja@tempcnta,tex.getcount('luatexja@tempcntb'),#4,#5)}}
115115
116116 % yabaselineshift = <dimen>
117117 \define@key[ltj]{japaram}{yabaselineshift}{%
@@ -129,31 +129,31 @@
129129 % mode: inhibit, preonly, postonly, allow
130130 % or 0 2 1 3
131131 \define@key[ltj]{japaram}{cjkxspmode}{% \inhibitxspcode
132- \expandafter\luatexja@setjxspmode#1:\relax}
133-\def\luatexja@setjxspmode#1,#2:{%
132+ \expandafter\ltj@set@cjkxspmode#1:\relax}
133+\def\ltj@set@cjkxspmode#1,#2:{%
134134 \lowercase{\edef\ltj@temp{#2}}%
135135 \def\ltj@tempa{inhibit}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{0}\fi
136136 \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
137137 \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
138138 \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
139139 \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
140- \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
141- tex.getcount('luatexja@tempcntb'),0,3)}}
140+ \directlua{ltj.ext_set_stack_table(ltj.isglobal, 'xsp', \the\luatexja@tempcnta,
141+ \the\luatexja@tempcntb,0,3)}}
142142
143143 % asciixspmode = {<char_code>, <mode>}
144144 % mode: inhibit, preonly, postonly, allow
145145 % or 0 1 2 3
146146 \define@key[ltj]{japaram}{asciixspmode}{% \inhibitxspcode
147- \expandafter\luatexja@setaxspmode#1:\relax}
148-\def\luatexja@setaxspmode#1,#2:{%
147+ \expandafter\ltj@set@asciixspmode#1:\relax}
148+\def\ltj@set@asciixspmode#1,#2:{%
149149 \lowercase{\edef\ltj@temp{#2}}%
150150 \def\ltj@tempa{inhibit}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{0}\fi
151151 \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
152152 \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
153153 \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
154154 \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
155- \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
156- tex.getcount('luatexja@tempcntb'),0,3)}}
155+ \directlua{ltj.ext_set_stack_table(ltj.isglobal, 'xsp', \the\luatexja@tempcnta,
156+ \the\luatexja@tempcntb,0,3)}}
157157
158158 % autospacing = <bool> (default: true)
159159 \define@boolkey[ltj]{japaram}{autospacing}[true]{%
@@ -174,16 +174,16 @@
174174 }
175175
176176 \define@key[ltj]{japaram}{kanjiskip}{% % SKIP
177- \directlua{ltj.print_global()}\kanjiskip=#1 }
177+ \directlua{ltj.ext_print_global()}\kanjiskip=#1 }
178178 \define@key[ltj]{japaram}{xkanjiskip}{% % SKIP
179- \directlua{ltj.print_global()}\xkanjiskip=#1 }
179+ \directlua{ltj.ext_print_global()}\xkanjiskip=#1 }
180180 \define@key[ltj]{japaram}{jcharwidowpenalty}{% %COUNT
181- \directlua{ltj.print_global()}\jcharwidowpenalty=#1 }
181+ \directlua{ltj.ext_print_global()}\jcharwidowpenalty=#1 }
182182
183183 % differentjfm = { large | small | average | both }
184-\define@choicekey*+[ltj]{japaram}{differentjfm}[\ltj@temp\ltj@result]%
184+\define@choicekey*+[ltj]{japaram}{differentjfm}[\ltj@temp\ltj@tempr]%
185185 {large,small,average,both}{%
186- \ifcase\ltj@result
186+ \ifcase\ltj@tempr
187187 \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_large}\or
188188 \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_small}\or
189189 \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_average}\or
@@ -194,12 +194,12 @@
194194
195195
196196 % jcharrange = { +-<range_number> }
197-\define@key[ltj]{japaram}{jcharrange}{\expandafter\@setjcharrange#1,,}
198-\def\@setjcharrange#1,{%
197+\define@key[ltj]{japaram}{jcharrange}{\expandafter\ltj@@scrange#1,,}
198+\def\ltj@@scrange#1,{%
199199 \edef\ltj@temp{#1}%
200- \ifx\ltj@temp\empty\let\next=\relax\else\let\next=\@setjcharrange
201- \luatexja@tempcnta=#1 \directlua{ltj.set_jchar_range(%
202- ltj.is_global,tex.getcount('luatexja@tempcnta'))}%
200+ \ifx\ltj@temp\empty\let\next=\relax\else\let\next=\ltj@@scrange
201+ \luatexja@tempcnta=#1 \directlua{ltj.ext_toggle_char_range(%
202+ ltj.is_global,\the\luatexja@tempcnta)}%
203203 \fi\next
204204 }
205205
@@ -207,43 +207,31 @@
207207
208208
209209
210-\def\setjaparameter#1{\directlua{ltj.isglobal=''}%
210+\def\ltjsetparameter#1{\directlua{ltj.isglobal=''}%
211211 \setkeys[ltj]{japaram}{#1}\ignorespaces}
212-\def\globalsetjaparameter#1{\directlua{ltj.isglobal='global'}%
212+\def\globalltjsetparameter#1{\directlua{ltj.isglobal='global'}%
213213 \setkeys[ltj]{japaram}{#1}\ignorespaces}
214214
215215 %%%%%%%%
216-\def\getjaparameter#1{%
217- \lowercase{\edef\ltj@temp{#1}}\let\@next=\getjaparameter@one%
218- \def\ltj@tempa{prebreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
219- \def\ltj@tempa{postbreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
220- \def\ltj@tempa{cjkxspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
221- \def\ltj@tempa{asciixspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
222- \def\ltj@tempa{kcatcode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
223- \def\ltj@tempa{jcharrange}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
224- \def\ltj@tempa{chartorange}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
216+\def\ltjgetparameter#1{%
217+ \lowercase{\edef\ltj@temp{#1}}\let\@next=\ltj@@getparam@one%
218+ \def\ltj@tempa{prebreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
219+ \def\ltj@tempa{postbreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
220+ \def\ltj@tempa{cjkxspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
221+ \def\ltj@tempa{asciixspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
222+ \def\ltj@tempa{kcatcode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
223+ \def\ltj@tempa{jcharrange}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
224+ \def\ltj@tempa{chartorange}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
225225 \@next
226226 }
227-\def\getjaparameter@one{\directlua{ltj.out_ja_parameter_one('\ltj@temp')}}
228-\def\getjaparameter@two#1{%
227+\def\ltj@@getparam@one{\directlua{ltj.ext_get_parameter_unary('\ltj@temp')}}
228+\def\ltj@@getparam@two#1{%
229229 \luatexja@tempcnta=#1
230- \directlua{ltj.out_ja_parameter_two('\ltj@temp', tex.getcount('luatexja@tempcnta'))}
230+ \directlua{ltj.ext_get_parameter_binary('\ltj@temp', \the\luatexja@tempcnta)}
231231 }
232232
233233
234234
235-%%%%%%%% commands for ``compatibility''
236-% \def\setinhibitxspcode#1#2{\setjaparameter{cjkxspmode={#1,#2}}}
237-% \def\setxspcode#1#2{\setjaparameter{asciixspmode={#1,#2}}}
238-% \def\setprebreakpenalty#1#2{\setjaparameter{prebreakpenalty={#1,#2}}}
239-% \def\setpostbreakpenalty#1#2{\setjaparameter{prebreakpenalty={#1,#2}}}
240-% \def\getprebreakpenalty#1{\directlua{ltj.get_penalty_table('pre',#1)}\luatexja@tempcnta}
241-% \def\getpostbreakpenalty#1{\directlua{ltj.get_penalty_table('post',#1)}\luatexja@tempcnta}
242-% \def\autospacing{\luatexja@autospc=0 }
243-% \def\noautospacing{\luatexja@autospc=1 }
244-% \def\autoxspacing{\luatexja@autoxspc=0 }
245-% \def\noautoxspacing{\luatexja@autoxspc=1 }
246-
247235 \def\ltj@temp{plain}
248236 \ifx\fmtname\ltj@temp
249237 \message{plain format: loading luatexja-plain.tex}
--- a/src/luatexja-jfont.lua
+++ b/src/luatexja-jfont.lua
@@ -1,12 +1,37 @@
1+local node_new = node.new
12 local has_attr = node.has_attribute
2-local jfmfname
3+local floor = math.floor
4+local round = tex.round
35
4---====== METRIC
5-jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}
6+local attr_icflag = luatexbase.attributes['luatexja@icflag']
7+local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
8+local id_glyph = node.id('glyph')
9+local id_kern = node.id('kern')
10+
11+------------------------------------------------------------------------
12+-- LOADING JFM (prefix: ljfm)
13+------------------------------------------------------------------------
14+
15+ltj.metrics={} -- this table stores all metric informations
16+ltj.font_metric_table={} -- [font number] -> jfm_name, jfm_var, size
17+
18+jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {}
19+
20+local ljfm_jfm_cons
21+local jfm_file_name, jfm_var
622
723 function jfm.define_char_type(t,lt)
824 if not jfm.char_type[t] then jfm.char_type[t]={} end
925 jfm.char_type[t].chars=lt
26+ for i,v in pairs(lt) do
27+ if v == 'linebdd' then
28+ if #lt ~= 1 then ljfm_jfm_cons = false; return end
29+ elseif not jfm.chars[v] then
30+ jfm.chars[v] = t
31+ else
32+ ljfm_jfm_cons = false ; return
33+ end
34+ end
1035 end
1136 function jfm.define_type_dim(t,l,x,w,h,d,i)
1237 if not jfm.char_type[t] then jfm.char_type[t]={} end
@@ -17,184 +42,158 @@ end
1742 function jfm.define_glue(b,a,w,st,sh)
1843 local j=b*0x800+a
1944 if not jfm.glue[j] then jfm.glue[j]={} end
20- jfm.glue[j].width=w; jfm.glue[j].stretch=st;
21- jfm.glue[j].shrink=sh
45+ jfm.glue[j][0]=w; jfm.glue[j][1]=st;
46+ jfm.glue[j][2]=sh
2247 end
2348 function jfm.define_kern(b,a,w)
2449 local j=b*0x800+a
2550 if not jfm.kern[j] then jfm.kern[j]=w end
2651 end
2752
28--- procedures for \loadjfontmetric
29-ltj.metrics={} -- this table stores all metric informations
30-ltj.font_metric_table={}
31-
32-local function search_metric(key)
33- for i,v in ipairs(ltj.metrics) do
34- if v.name==key then return i end
35- end
36- return nil
37-end
38-
3953 -- return nil iff ltj.metrics[ind] is a bad metric
40-local function consistency_check(ind)
54+local function ljfm_consistency_check(ind)
4155 local t = ltj.metrics[ind]
42- local r = ind
56+ local r = nil
57+ if ljfm_jfm_cons then r = ind end
4358 if t.dir~='yoko' then -- TODO: tate?
4459 r=nil
4560 elseif type(t.zw)~='number' or type(t.zh)~='number' then
4661 r=nil -- .zw, .zh must be present
47- else
48- local lbt = ltj.find_char_type('lindend',ind)
49- if lbt~=0 and t.char_type[lbt].chars~={'linebdd'} then
50- r=nil -- 'linebdd' must be isolated char_type
51- end
5262 end
5363 if not r then ltj.metrics[ind] = nil end
5464 return r
5565 end
5666
57-function ltj.load_jfont_metric()
58- if jfmfname=='' then
67+local function ljfm_find_char_class(c,m)
68+-- c: character code, m
69+ if not ltj.metrics[m] then return 0 end
70+ return ltj.metrics[m].chars[c] or 0
71+end
72+ltj.int_find_char_class = ljfm_find_char_class
73+
74+local function ljfm_load_jfont_metric()
75+ if jfm_file_name=='' then
5976 ltj.error('no JFM specified',
6077 {[1]='To load and define a Japanese font, the name of JFM must be specified.',
6178 [2]="The JFM 'ujis' will be used for now."})
62- jfmfname='ujis'
79+ jfm_file_name='ujis'
80+ end
81+ local name=jfm_file_name .. ':' .. jfm_var
82+ local i = nil
83+ for j,v in ipairs(ltj.metrics) do
84+ if v.name==name then i=j; break end
6385 end
64- jfm.name=jfmfname .. ':' .. ltj.jfmvar
65- local i = search_metric(jfm.name)
6686 local t = {}
6787 if i then return i end
68- jfm.char_type={}; jfm.glue={}; jfm.kern={}
69- ltj.loadlua('jfm-' .. jfmfname .. '.lua')
70- t.name=jfm.name
88+ jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {}
89+ ljfm_jfm_cons = true
90+ ltj.loadlua('jfm-' .. jfm_file_name .. '.lua')
91+ t.name=name
7192 t.dir=jfm.dir; t.zw=jfm.zw; t.zh=jfm.zh
72- t.char_type=jfm.char_type
93+ t.char_type=jfm.char_type; t.chars=jfm.chars
7394 t.glue=jfm.glue; t.kern=jfm.kern
7495 table.insert(ltj.metrics,t)
75- return consistency_check(#ltj.metrics)
96+ return ljfm_consistency_check(#ltj.metrics)
7697 end
7798
78-function ltj.find_char_type(c,m)
79--- c: character code, m
80- if not ltj.metrics[m] then return 0 end
81- for i, v in pairs(ltj.metrics[m].char_type) do
82- if i~=0 then
83- for j,w in pairs(v.chars) do
84- if w==c then return i end
85- end
86- end
87- end
88- return 0
89-end
9099
100+------------------------------------------------------------------------
101+-- LOADING JAPANESE FONTS (prefix: ljft)
102+------------------------------------------------------------------------
103+local cstemp
91104
92---====== \setjfont\CS={...:...;jfm=metric;...}
93-
94-function ltj.jfontdefX(g)
105+-- EXT
106+function ltj.ext_jfontdefX(g)
95107 local t = token.get_next()
96- ltj.cstemp=token.csname_name(t)
108+ cstemp=token.csname_name(t)
97109 if g then ltj.is_global = '\\global' else ltj.is_global = '' end
98- tex.sprint('\\expandafter\\font\\csname ' .. ltj.cstemp .. '\\endcsname')
110+ tex.sprint('\\expandafter\\font\\csname ' .. cstemp .. '\\endcsname')
99111 end
100112
101-function ltj.jfontdefY() -- for horizontal font
102- local j=ltj.load_jfont_metric()
103- local fn=font.id(ltj.cstemp)
113+-- EXT
114+function ltj.ext_jfontdefY() -- for horizontal font
115+ local j = ljfm_load_jfont_metric()
116+ local fn = font.id(cstemp)
104117 local f = font.fonts[fn]
105118 if not j then
106- ltj.error("bad JFM '" .. jfmfname .. "'",
119+ ltj.error("bad JFM '" .. jfm_file_name .. "'",
107120 {[1]='The JFM file you specified is not valid JFM file.',
108121 [2]='Defining Japanese font is cancelled.'})
109122 tex.sprint(ltj.is_global .. '\\expandafter\\let\\csname '
110- .. ltj.cstemp .. '\\endcsname=\\relax')
123+ .. cstemp .. '\\endcsname=\\relax')
111124 return
112125 end
113126 ltj.font_metric_table[fn]={}
114127 ltj.font_metric_table[fn].jfm=j; ltj.font_metric_table[fn].size=f.size
115128 tex.sprint(ltj.is_global .. '\\protected\\expandafter\\def\\csname '
116- .. ltj.cstemp .. '\\endcsname'
129+ .. cstemp .. '\\endcsname'
117130 .. '{\\csname luatexja@curjfnt\\endcsname=' .. fn
118131 .. ' \\zw=' .. tex.round(f.size*ltj.metrics[j].zw) .. 'sp'
119132 .. '\\zh=' .. tex.round(f.size*ltj.metrics[j].zh) .. 'sp\\relax}')
120133 end
121134
122-local dr_orig = fonts.define.read
123-function fonts.define.read(name, size, id)
124- ltj.extract_metric(name)
125- -- In the present imple., we don't remove "jfm=..." from name.
126- local fontdata = dr_orig(name, size, id)
127- return fontdata
128-end
129-
130--- extract jfmfname and ltj.jfmvar
131-function ltj.extract_metric(name)
135+-- extract jfm_file_name and jfm_var
136+local function ljft_extract_metric(name)
132137 local basename=name
133138 local tmp = utf.sub(basename, 1, 5)
134- jfmfname = ''
135- ltj.jfmvar = ''
139+ jfm_file_name = ''; jfm_var = ''
136140 if tmp == 'file:' or tmp == 'name:' or tmp == 'psft:' then
137141 basename = utf.sub(basename, 6)
138142 end
139-
140143 local p = utf.find(basename, ":")
141144 if p then
142145 basename = utf.sub(basename, p+1)
143146 else return
144147 end
145-
148+ -- now basename contains 'features' only.
146149 p=1
147150 while p do
148- local q= utf.find(basename, ";",p+1) or utf.len(basename)+1
149- if utf.sub(basename,p,p+3)=='jfm=' and q>p+4 then
150- jfmfname = utf.sub(basename,p+4,q-1)
151- elseif utf.sub(basename,p,p+6)=='jfmvar=' and q>p+6 then
152- ltj.jfmvar = utf.sub(basename,p+7,q-1)
151+ local q = utf.find(basename, ";", p+1) or utf.len(basename)+1
152+ if utf.sub(basename, p, p+3)=='jfm=' and q>p+4 then
153+ jfm_file_name = utf.sub(basename, p+4, q-1)
154+ elseif utf.sub(basename, p, p+6)=='jfmvar=' and q>p+6 then
155+ jfm_var = utf.sub(basename, p+7, q-1)
153156 end
154- if utf.len(basename)+1==q then p=nil else p=q+1 end
157+ if utf.len(basename)+1==q then p = nil else p = q + 1 end
155158 end
156159 return
157160 end
158161
162+-- replace fonts.define.read()
163+local ljft_dr_orig = fonts.define.read
164+function fonts.define.read(name, size, id)
165+ ljft_extract_metric(name)
166+ -- In the present imple., we don't remove "jfm=..." from name.
167+ return ljft_dr_orig(name, size, id)
168+end
159169
160---====== Range of Japanese characters.
170+------------------------------------------------------------------------
171+-- MANAGING THE RANGE OF JAPANESE CHARACTERS (prefix: rgjc)
172+------------------------------------------------------------------------
161173 -- jcr_table_main[chr_code] = index
162174 -- index : internal 0, 1, 2, ..., 216 0: 'other'
163175 -- external 1 2 216, (out of range): 'other'
164176
165--- init:
166-local ucs_out = 0x110000
177+-- initialize
167178 local jcr_table_main = {}
168-local jcr_cjk = 0
169-local jcr_noncjk = 1
179+local jcr_cjk = 0; local jcr_noncjk = 1; local ucs_out = 0x110000
170180
171-for i=0x80,0xFF do
172- jcr_table_main[i]=1
173-end
174-for i=0x100,ucs_out-1 do
175- jcr_table_main[i]=0
176-end
181+for i=0x80 ,0xFF do jcr_table_main[i]=1 end
182+for i=0x100,ucs_out-1 do jcr_table_main[i]=0 end
177183
178-function ltj.def_char_range(b,e,ind) -- ind: external range number
184+-- EXT: add characters to a range
185+function ltj.ext_add_char_range(b,e,ind) -- ind: external range number
179186 if ind<0 or ind>216 then
180- ltj.error('Invalid range number (' .. ind .. '), should be in the range 1..216.',
181- {}); return
187+ ltj.error('Invalid range number (' .. ind ..
188+ '), should be in the range 1..216.',
189+ {}); return
182190 end
183191 for i=math.max(0x80,b),math.min(ucs_out-1,e) do
184192 jcr_table_main[i]=ind
185193 end
186194 end
187195
188-local function get_char_jcrcode(p) -- for internal use
189- local i
190- local c = p.char
191- if c<0x80 then return jcr_noncjk else i=jcr_table_main[c] end
192- return math.floor(has_attr(p,
193- luatexbase.attributes['luatexja@kcat'..math.floor(i/31)])
194- /math.pow(2, i%31))%2
195-end
196-
197-function ltj.get_char_jcrnumber(c) -- return the (external) range number
196+local function rgjc_char_to_range(c) -- return the (external) range number
198197 if c<0x80 or c>=ucs_out then return -1
199198 else
200199 local i = jcr_table_main[c] or 0
@@ -202,25 +201,61 @@ function ltj.get_char_jcrnumber(c) -- return the (external) range number
202201 end
203202 end
204203
205-function ltj.get_jcr_setting(i) -- i: internal range number
206- return math.floor(tex.getattribute(luatexbase.attributes['luatexja@kcat'..math.floor(i/31)])
207- /math.pow(2, i%31))%2
204+local function rgjc_get_range_setting(i) -- i: internal range number
205+ return floor(tex.getattribute(
206+ luatexbase.attributes['luatexja@kcat'..floor(i/31)])
207+ /math.pow(2, i%31))%2
208208 end
209+ltj.int_get_range_setting = rgjc_get_range_setting
210+ltj.int_char_to_range = rgjc_char_to_range
209211
210--- 和文文字と認識する unicode の範囲
211-function ltj.is_ucs_in_japanese_char(p)
212- return (get_char_jcrcode(p)~=jcr_noncjk)
212+-- glyph_node p は和文文字か?
213+local function rgjc_is_ucs_in_japanese_char(p)
214+ local c = p.char
215+ if c<0x80 then return false
216+ else
217+ local i=jcr_table_main[c]
218+ return (floor(
219+ has_attr(p, luatexbase.attributes['luatexja@kcat'..floor(i/31)])
220+ /math.pow(2, i%31))%2 ~= jcr_noncjk)
221+ end
213222 end
223+ltj.int_is_ucs_in_japanese_char = rgjc_is_ucs_in_japanese_char
214224
215-function ltj.set_jchar_range(g, i) -- i: external range number
225+-- EXT
226+function ltj.ext_toggle_char_range(g, i) -- i: external range number
216227 if i==0 then return
217228 else
218229 local kc
219230 if i>0 then kc=0 else kc=1; i=-i end
220231 if i>216 then i=0 end
221- local attr = luatexbase.attributes['luatexja@kcat'..math.floor(i/31)]
232+ local attr = luatexbase.attributes['luatexja@kcat'..floor(i/31)]
222233 local a = tex.getattribute(attr)
223234 local k = math.pow(2, i%31)
224- tex.setattribute(g,attr,(math.floor(a/k/2)*2+kc)*k+a%k)
235+ tex.setattribute(g,attr,(floor(a/k/2)*2+kc)*k+a%k)
236+ end
237+end
238+
239+------------------------------------------------------------------------
240+-- MISC
241+------------------------------------------------------------------------
242+
243+-- EXT: italic correction
244+function ltj.ext_append_italic()
245+ local p = tex.nest[tex.nest.ptr].tail
246+ if p and p.id==id_glyph then
247+ local f = p.font
248+ local g = node_new(id_kern)
249+ g.subtype = 1; node.set_attribute(g, attr_icflag, 1)
250+ if rgjc_is_ucs_in_japanese_char(p) then
251+ f = has_attr(p, attr_curjfnt)
252+ print(f, p.char)
253+ local j = ltj.font_metric_table[f]
254+ local c = ljfm_find_char_class(p.char, j.jfm)
255+ g.kern = round(j.size * ltj.metrics[j.jfm].char_type[c].italic)
256+ else
257+ g.kern = font.fonts[f].characters[p.char].italic
258+ end
259+ node.write(g)
225260 end
226261 end
\ No newline at end of file
--- a/src/luatexja-kinsoku.tex
+++ b/src/luatexja-kinsoku.tex
@@ -2,405 +2,405 @@
22 % 行頭、行末禁則パラメータ
33 %
44 % 1byte characters
5-\setjaparameter{prebreakpenalty={`!,10000}}
6-\setjaparameter{prebreakpenalty={`",10000}}
7-\setjaparameter{postbreakpenalty={`\#,500}}
8-\setjaparameter{postbreakpenalty={`\$,500}}
9-\setjaparameter{postbreakpenalty={`\%,500}}
10-\setjaparameter{postbreakpenalty={`\&,500}}
11-\setjaparameter{postbreakpenalty={`\`,10000}}
12-\setjaparameter{prebreakpenalty={`',10000}}
13-\setjaparameter{prebreakpenalty={`),10000}}
14-\setjaparameter{postbreakpenalty={`(,10000}}
15-\setjaparameter{prebreakpenalty={`*,500}}
16-\setjaparameter{prebreakpenalty={`+,500}}
17-\setjaparameter{prebreakpenalty={`-,10000}}
18-\setjaparameter{prebreakpenalty={`.,10000}}
19-\setjaparameter{prebreakpenalty={47,10000}}
20-\setjaparameter{prebreakpenalty={`/,500}}
21-\setjaparameter{prebreakpenalty={`;,10000}}
22-\setjaparameter{prebreakpenalty={`?,10000}}
23-\setjaparameter{prebreakpenalty={`:,10000}}
24-\setjaparameter{prebreakpenalty={`],10000}}
25-\setjaparameter{postbreakpenalty={`[,10000}}
5+\ltjsetparameter{prebreakpenalty={`!,10000}}
6+\ltjsetparameter{prebreakpenalty={`",10000}}
7+\ltjsetparameter{postbreakpenalty={`\#,500}}
8+\ltjsetparameter{postbreakpenalty={`\$,500}}
9+\ltjsetparameter{postbreakpenalty={`\%,500}}
10+\ltjsetparameter{postbreakpenalty={`\&,500}}
11+\ltjsetparameter{postbreakpenalty={`\`,10000}}
12+\ltjsetparameter{prebreakpenalty={`',10000}}
13+\ltjsetparameter{prebreakpenalty={`),10000}}
14+\ltjsetparameter{postbreakpenalty={`(,10000}}
15+\ltjsetparameter{prebreakpenalty={`*,500}}
16+\ltjsetparameter{prebreakpenalty={`+,500}}
17+\ltjsetparameter{prebreakpenalty={`-,10000}}
18+\ltjsetparameter{prebreakpenalty={`.,10000}}
19+\ltjsetparameter{prebreakpenalty={47,10000}}
20+\ltjsetparameter{prebreakpenalty={`/,500}}
21+\ltjsetparameter{prebreakpenalty={`;,10000}}
22+\ltjsetparameter{prebreakpenalty={`?,10000}}
23+\ltjsetparameter{prebreakpenalty={`:,10000}}
24+\ltjsetparameter{prebreakpenalty={`],10000}}
25+\ltjsetparameter{postbreakpenalty={`[,10000}}
2626 %全角文字
27-\setjaparameter{prebreakpenalty={`、,10000}}
28-\setjaparameter{prebreakpenalty={`。,10000}}
29-\setjaparameter{prebreakpenalty={`,,10000}}
30-\setjaparameter{prebreakpenalty={`.,10000}}
31-\setjaparameter{prebreakpenalty={`・,10000}}
32-\setjaparameter{prebreakpenalty={`:,10000}}
33-\setjaparameter{prebreakpenalty={`;,10000}}
34-\setjaparameter{prebreakpenalty={`?,10000}}
35-\setjaparameter{prebreakpenalty={`!,10000}}
36-\setjaparameter{prebreakpenalty={`゛,10000}}%\jis"212B
37-\setjaparameter{prebreakpenalty={`゜,10000}}%\jis"212C
38-\setjaparameter{prebreakpenalty={`´,10000}}%\jis"212D
39-\setjaparameter{postbreakpenalty={``,10000}}%\jis"212E
40-\setjaparameter{prebreakpenalty={`々,10000}}%\jis"2139
41-\setjaparameter{prebreakpenalty={`…,250}}%\jis"2144
42-\setjaparameter{prebreakpenalty={`‥,250}}%\jis"2145
43-\setjaparameter{postbreakpenalty={`‘,10000}}%\jis"2146
44-\setjaparameter{prebreakpenalty={`’,10000}}%\jis"2147
45-\setjaparameter{postbreakpenalty={`“,10000}}%\jis"2148
46-\setjaparameter{prebreakpenalty={`”,10000}}%\jis"2149
47-\setjaparameter{prebreakpenalty={`),10000}}
48-\setjaparameter{postbreakpenalty={`(,10000}}
49-\setjaparameter{prebreakpenalty={`},10000}}
50-\setjaparameter{postbreakpenalty={`{,10000}}
51-\setjaparameter{prebreakpenalty={`],10000}}
52-\setjaparameter{postbreakpenalty={`[,10000}}
53-%\setjaparameter{postbreakpenalty={`‘,10000}}
54-%\setjaparameter{prebreakpenalty={`’,10000}}
55-\setjaparameter{postbreakpenalty={`〔,10000}}%\jis"214C
56-\setjaparameter{prebreakpenalty={`〕,10000}}%\jis"214D
57-\setjaparameter{postbreakpenalty={`〈,10000}}%\jis"2152
58-\setjaparameter{prebreakpenalty={`〉,10000}}%\jis"2153
59-\setjaparameter{postbreakpenalty={`《,10000}}%\jis"2154
60-\setjaparameter{prebreakpenalty={`》,10000}}%\jis"2155
61-\setjaparameter{postbreakpenalty={`「,10000}}%\jis"2156
62-\setjaparameter{prebreakpenalty={`」,10000}}%\jis"2157
63-\setjaparameter{postbreakpenalty={`『,10000}}%\jis"2158
64-\setjaparameter{prebreakpenalty={`』,10000}}%\jis"2159
65-\setjaparameter{postbreakpenalty={`【,10000}}%\jis"215A
66-\setjaparameter{prebreakpenalty={`】,10000}}%\jis"215B
67-\setjaparameter{prebreakpenalty={`ー,10000}}
68-\setjaparameter{prebreakpenalty={`+,200}}
69-\setjaparameter{prebreakpenalty={`−,200}}% U+2212 MINUS SIGN
70-\setjaparameter{prebreakpenalty={`-,200}}% U+FF0D FULLWIDTH HYPHEN-MINUS
71-\setjaparameter{prebreakpenalty={`=,200}}
72-\setjaparameter{postbreakpenalty={`#,200}}
73-\setjaparameter{postbreakpenalty={`$,200}}
74-\setjaparameter{postbreakpenalty={`%,200}}
75-\setjaparameter{postbreakpenalty={`&,200}}
76-\setjaparameter{prebreakpenalty={`ぁ,150}}
77-\setjaparameter{prebreakpenalty={`ぃ,150}}
78-\setjaparameter{prebreakpenalty={`ぅ,150}}
79-\setjaparameter{prebreakpenalty={`ぇ,150}}
80-\setjaparameter{prebreakpenalty={`ぉ,150}}
81-\setjaparameter{prebreakpenalty={`っ,150}}
82-\setjaparameter{prebreakpenalty={`ゃ,150}}
83-\setjaparameter{prebreakpenalty={`ゅ,150}}
84-\setjaparameter{prebreakpenalty={`ょ,150}}
85-\setjaparameter{prebreakpenalty={`ゎ,150}}%\jis"246E
86-\setjaparameter{prebreakpenalty={`ァ,150}}
87-\setjaparameter{prebreakpenalty={`ィ,150}}
88-\setjaparameter{prebreakpenalty={`ゥ,150}}
89-\setjaparameter{prebreakpenalty={`ェ,150}}
90-\setjaparameter{prebreakpenalty={`ォ,150}}
91-\setjaparameter{prebreakpenalty={`ッ,150}}
92-\setjaparameter{prebreakpenalty={`ャ,150}}
93-\setjaparameter{prebreakpenalty={`ュ,150}}
94-\setjaparameter{prebreakpenalty={`ョ,150}}
95-\setjaparameter{prebreakpenalty={`ヮ,150}}%\jis"256E
96-\setjaparameter{prebreakpenalty={`ヵ,150}}%\jis"2575
97-\setjaparameter{prebreakpenalty={`ヶ,150}}%\jis"2576
27+\ltjsetparameter{prebreakpenalty={`、,10000}}
28+\ltjsetparameter{prebreakpenalty={`。,10000}}
29+\ltjsetparameter{prebreakpenalty={`,,10000}}
30+\ltjsetparameter{prebreakpenalty={`.,10000}}
31+\ltjsetparameter{prebreakpenalty={`・,10000}}
32+\ltjsetparameter{prebreakpenalty={`:,10000}}
33+\ltjsetparameter{prebreakpenalty={`;,10000}}
34+\ltjsetparameter{prebreakpenalty={`?,10000}}
35+\ltjsetparameter{prebreakpenalty={`!,10000}}
36+\ltjsetparameter{prebreakpenalty={`゛,10000}}%\jis"212B
37+\ltjsetparameter{prebreakpenalty={`゜,10000}}%\jis"212C
38+\ltjsetparameter{prebreakpenalty={`´,10000}}%\jis"212D
39+\ltjsetparameter{postbreakpenalty={``,10000}}%\jis"212E
40+\ltjsetparameter{prebreakpenalty={`々,10000}}%\jis"2139
41+\ltjsetparameter{prebreakpenalty={`…,250}}%\jis"2144
42+\ltjsetparameter{prebreakpenalty={`‥,250}}%\jis"2145
43+\ltjsetparameter{postbreakpenalty={`‘,10000}}%\jis"2146
44+\ltjsetparameter{prebreakpenalty={`’,10000}}%\jis"2147
45+\ltjsetparameter{postbreakpenalty={`“,10000}}%\jis"2148
46+\ltjsetparameter{prebreakpenalty={`”,10000}}%\jis"2149
47+\ltjsetparameter{prebreakpenalty={`),10000}}
48+\ltjsetparameter{postbreakpenalty={`(,10000}}
49+\ltjsetparameter{prebreakpenalty={`},10000}}
50+\ltjsetparameter{postbreakpenalty={`{,10000}}
51+\ltjsetparameter{prebreakpenalty={`],10000}}
52+\ltjsetparameter{postbreakpenalty={`[,10000}}
53+%\ltjsetparameter{postbreakpenalty={`‘,10000}}
54+%\ltjsetparameter{prebreakpenalty={`’,10000}}
55+\ltjsetparameter{postbreakpenalty={`〔,10000}}%\jis"214C
56+\ltjsetparameter{prebreakpenalty={`〕,10000}}%\jis"214D
57+\ltjsetparameter{postbreakpenalty={`〈,10000}}%\jis"2152
58+\ltjsetparameter{prebreakpenalty={`〉,10000}}%\jis"2153
59+\ltjsetparameter{postbreakpenalty={`《,10000}}%\jis"2154
60+\ltjsetparameter{prebreakpenalty={`》,10000}}%\jis"2155
61+\ltjsetparameter{postbreakpenalty={`「,10000}}%\jis"2156
62+\ltjsetparameter{prebreakpenalty={`」,10000}}%\jis"2157
63+\ltjsetparameter{postbreakpenalty={`『,10000}}%\jis"2158
64+\ltjsetparameter{prebreakpenalty={`』,10000}}%\jis"2159
65+\ltjsetparameter{postbreakpenalty={`【,10000}}%\jis"215A
66+\ltjsetparameter{prebreakpenalty={`】,10000}}%\jis"215B
67+\ltjsetparameter{prebreakpenalty={`ー,10000}}
68+\ltjsetparameter{prebreakpenalty={`+,200}}
69+\ltjsetparameter{prebreakpenalty={`−,200}}% U+2212 MINUS SIGN
70+\ltjsetparameter{prebreakpenalty={`-,200}}% U+FF0D FULLWIDTH HYPHEN-MINUS
71+\ltjsetparameter{prebreakpenalty={`=,200}}
72+\ltjsetparameter{postbreakpenalty={`#,200}}
73+\ltjsetparameter{postbreakpenalty={`$,200}}
74+\ltjsetparameter{postbreakpenalty={`%,200}}
75+\ltjsetparameter{postbreakpenalty={`&,200}}
76+\ltjsetparameter{prebreakpenalty={`ぁ,150}}
77+\ltjsetparameter{prebreakpenalty={`ぃ,150}}
78+\ltjsetparameter{prebreakpenalty={`ぅ,150}}
79+\ltjsetparameter{prebreakpenalty={`ぇ,150}}
80+\ltjsetparameter{prebreakpenalty={`ぉ,150}}
81+\ltjsetparameter{prebreakpenalty={`っ,150}}
82+\ltjsetparameter{prebreakpenalty={`ゃ,150}}
83+\ltjsetparameter{prebreakpenalty={`ゅ,150}}
84+\ltjsetparameter{prebreakpenalty={`ょ,150}}
85+\ltjsetparameter{prebreakpenalty={`ゎ,150}}%\jis"246E
86+\ltjsetparameter{prebreakpenalty={`ァ,150}}
87+\ltjsetparameter{prebreakpenalty={`ィ,150}}
88+\ltjsetparameter{prebreakpenalty={`ゥ,150}}
89+\ltjsetparameter{prebreakpenalty={`ェ,150}}
90+\ltjsetparameter{prebreakpenalty={`ォ,150}}
91+\ltjsetparameter{prebreakpenalty={`ッ,150}}
92+\ltjsetparameter{prebreakpenalty={`ャ,150}}
93+\ltjsetparameter{prebreakpenalty={`ュ,150}}
94+\ltjsetparameter{prebreakpenalty={`ョ,150}}
95+\ltjsetparameter{prebreakpenalty={`ヮ,150}}%\jis"256E
96+\ltjsetparameter{prebreakpenalty={`ヵ,150}}%\jis"2575
97+\ltjsetparameter{prebreakpenalty={`ヶ,150}}%\jis"2576
9898 % kinsoku JIS X 0208 additional
99-\setjaparameter{prebreakpenalty={`ヽ,10000}}
100-\setjaparameter{prebreakpenalty={`ヾ,10000}}
101-\setjaparameter{prebreakpenalty={`ゝ,10000}}
102-\setjaparameter{prebreakpenalty={`ゞ,10000}}
99+\ltjsetparameter{prebreakpenalty={`ヽ,10000}}
100+\ltjsetparameter{prebreakpenalty={`ヾ,10000}}
101+\ltjsetparameter{prebreakpenalty={`ゝ,10000}}
102+\ltjsetparameter{prebreakpenalty={`ゞ,10000}}
103103
104104 %
105105 % kinsoku JIS X 0213
106106 %
107-\setjaparameter{prebreakpenalty={`〳,10000}}
108-\setjaparameter{prebreakpenalty={`〴,10000}}
109-\setjaparameter{prebreakpenalty={`〵,10000}}
110-\setjaparameter{prebreakpenalty={`〻,10000}}
111-\setjaparameter{postbreakpenalty={`⦅,10000}}
112-\setjaparameter{prebreakpenalty={`⦆,10000}}
113-\setjaparameter{postbreakpenalty={`⦅,10000}}
114-\setjaparameter{prebreakpenalty={`⦆,10000}}
115-\setjaparameter{postbreakpenalty={`〘,10000}}
116-\setjaparameter{prebreakpenalty={`〙,10000}}
117-\setjaparameter{postbreakpenalty={`〖,10000}}
118-\setjaparameter{prebreakpenalty={`〗,10000}}
119-\setjaparameter{postbreakpenalty={`«,10000}}
120-\setjaparameter{prebreakpenalty={`»,10000}}
121-\setjaparameter{postbreakpenalty={`〝,10000}}
122-\setjaparameter{prebreakpenalty={`〟,10000}}
123-\setjaparameter{prebreakpenalty={`‼,10000}}
124-\setjaparameter{prebreakpenalty={`⁇,10000}}
125-\setjaparameter{prebreakpenalty={`⁈,10000}}
126-\setjaparameter{prebreakpenalty={`⁉,10000}}
127-\setjaparameter{postbreakpenalty={`¡,10000}}
128-\setjaparameter{postbreakpenalty={`¿,10000}}
129-\setjaparameter{prebreakpenalty={`ː,10000}}
130-\setjaparameter{prebreakpenalty={`ª,10000}}
131-\setjaparameter{prebreakpenalty={`º,10000}}
132-\setjaparameter{prebreakpenalty={`¹,10000}}
133-\setjaparameter{prebreakpenalty={`²,10000}}
134-\setjaparameter{prebreakpenalty={`³,10000}}
135-\setjaparameter{postbreakpenalty={`€,10000}}
136-\setjaparameter{prebreakpenalty={`ゕ,150}}
137-\setjaparameter{prebreakpenalty={`ゖ,150}}
138-\setjaparameter{prebreakpenalty={`ㇰ,150}}
139-\setjaparameter{prebreakpenalty={`ㇱ,150}}
140-\setjaparameter{prebreakpenalty={`ㇲ,150}}
141-\setjaparameter{prebreakpenalty={`ㇳ,150}}
142-\setjaparameter{prebreakpenalty={`ㇴ,150}}
143-\setjaparameter{prebreakpenalty={`ㇵ,150}}
144-\setjaparameter{prebreakpenalty={`ㇶ,150}}
145-\setjaparameter{prebreakpenalty={`ㇷ,150}}
146-\setjaparameter{prebreakpenalty={`ㇸ,150}}
147-\setjaparameter{prebreakpenalty={`ㇹ,150}}
148-%\setjaparameter{prebreakpenalty={`ㇷ゚,150}}
149-\setjaparameter{prebreakpenalty={`ㇺ,150}}
150-\setjaparameter{prebreakpenalty={`ㇻ,150}}
151-\setjaparameter{prebreakpenalty={`ㇼ,150}}
152-\setjaparameter{prebreakpenalty={`ㇽ,150}}
153-\setjaparameter{prebreakpenalty={`ㇾ,150}}
154-\setjaparameter{prebreakpenalty={`ㇿ,150}}
107+\ltjsetparameter{prebreakpenalty={`〳,10000}}
108+\ltjsetparameter{prebreakpenalty={`〴,10000}}
109+\ltjsetparameter{prebreakpenalty={`〵,10000}}
110+\ltjsetparameter{prebreakpenalty={`〻,10000}}
111+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
112+\ltjsetparameter{prebreakpenalty={`⦆,10000}}
113+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
114+\ltjsetparameter{prebreakpenalty={`⦆,10000}}
115+\ltjsetparameter{postbreakpenalty={`〘,10000}}
116+\ltjsetparameter{prebreakpenalty={`〙,10000}}
117+\ltjsetparameter{postbreakpenalty={`〖,10000}}
118+\ltjsetparameter{prebreakpenalty={`〗,10000}}
119+\ltjsetparameter{postbreakpenalty={`«,10000}}
120+\ltjsetparameter{prebreakpenalty={`»,10000}}
121+\ltjsetparameter{postbreakpenalty={`〝,10000}}
122+\ltjsetparameter{prebreakpenalty={`〟,10000}}
123+\ltjsetparameter{prebreakpenalty={`‼,10000}}
124+\ltjsetparameter{prebreakpenalty={`⁇,10000}}
125+\ltjsetparameter{prebreakpenalty={`⁈,10000}}
126+\ltjsetparameter{prebreakpenalty={`⁉,10000}}
127+\ltjsetparameter{postbreakpenalty={`¡,10000}}
128+\ltjsetparameter{postbreakpenalty={`¿,10000}}
129+\ltjsetparameter{prebreakpenalty={`ː,10000}}
130+\ltjsetparameter{prebreakpenalty={`ª,10000}}
131+\ltjsetparameter{prebreakpenalty={`º,10000}}
132+\ltjsetparameter{prebreakpenalty={`¹,10000}}
133+\ltjsetparameter{prebreakpenalty={`²,10000}}
134+\ltjsetparameter{prebreakpenalty={`³,10000}}
135+\ltjsetparameter{postbreakpenalty={`€,10000}}
136+\ltjsetparameter{prebreakpenalty={`ゕ,150}}
137+\ltjsetparameter{prebreakpenalty={`ゖ,150}}
138+\ltjsetparameter{prebreakpenalty={`ㇰ,150}}
139+\ltjsetparameter{prebreakpenalty={`ㇱ,150}}
140+\ltjsetparameter{prebreakpenalty={`ㇲ,150}}
141+\ltjsetparameter{prebreakpenalty={`ㇳ,150}}
142+\ltjsetparameter{prebreakpenalty={`ㇴ,150}}
143+\ltjsetparameter{prebreakpenalty={`ㇵ,150}}
144+\ltjsetparameter{prebreakpenalty={`ㇶ,150}}
145+\ltjsetparameter{prebreakpenalty={`ㇷ,150}}
146+\ltjsetparameter{prebreakpenalty={`ㇸ,150}}
147+\ltjsetparameter{prebreakpenalty={`ㇹ,150}}
148+%\ltjsetparameter{prebreakpenalty={`ㇷ゚,150}}
149+\ltjsetparameter{prebreakpenalty={`ㇺ,150}}
150+\ltjsetparameter{prebreakpenalty={`ㇻ,150}}
151+\ltjsetparameter{prebreakpenalty={`ㇼ,150}}
152+\ltjsetparameter{prebreakpenalty={`ㇽ,150}}
153+\ltjsetparameter{prebreakpenalty={`ㇾ,150}}
154+\ltjsetparameter{prebreakpenalty={`ㇿ,150}}
155155 %
156156 % kinsoku JIS X 0212
157157 %
158-%\setjaparameter{postbreakpenalty={`¡,10000}}
159-%\setjaparameter{postbreakpenalty={`¿,10000}}
160-%\setjaparameter{prebreakpenalty={`º,10000}}
161-%\setjaparameter{prebreakpenalty={`ª,10000}}
162-\setjaparameter{prebreakpenalty={`™,10000}}
158+%\ltjsetparameter{postbreakpenalty={`¡,10000}}
159+%\ltjsetparameter{postbreakpenalty={`¿,10000}}
160+%\ltjsetparameter{prebreakpenalty={`º,10000}}
161+%\ltjsetparameter{prebreakpenalty={`ª,10000}}
162+\ltjsetparameter{prebreakpenalty={`™,10000}}
163163 %
164164 % kinsoku 半角片仮名
165165 %
166-\setjaparameter{prebreakpenalty={`。,10000}}
167-\setjaparameter{prebreakpenalty={`、,10000}}
168-\setjaparameter{prebreakpenalty={`゙,10000}}
169-\setjaparameter{prebreakpenalty={`゚,10000}}
170-\setjaparameter{prebreakpenalty={`」,10000}}
171-\setjaparameter{postbreakpenalty={`「,10000}}
166+\ltjsetparameter{prebreakpenalty={`。,10000}}
167+\ltjsetparameter{prebreakpenalty={`、,10000}}
168+\ltjsetparameter{prebreakpenalty={`゙,10000}}
169+\ltjsetparameter{prebreakpenalty={`゚,10000}}
170+\ltjsetparameter{prebreakpenalty={`」,10000}}
171+\ltjsetparameter{postbreakpenalty={`「,10000}}
172172 %
173173 % xspcode
174-\setjaparameter{asciixspmode={`(,preonly}}
175-\setjaparameter{asciixspmode={`),postonly}}
176-\setjaparameter{asciixspmode={`[,preonly}}
177-\setjaparameter{asciixspmode={`],postonly}}
178-\setjaparameter{asciixspmode={``,preonly}}
179-\setjaparameter{asciixspmode={`',postonly}}
180-\setjaparameter{asciixspmode={`;,postonly}}
181-\setjaparameter{asciixspmode={47,postonly}}
182-\setjaparameter{asciixspmode={`.,postonly}}
174+\ltjsetparameter{asciixspmode={`(,preonly}}
175+\ltjsetparameter{asciixspmode={`),postonly}}
176+\ltjsetparameter{asciixspmode={`[,preonly}}
177+\ltjsetparameter{asciixspmode={`],postonly}}
178+\ltjsetparameter{asciixspmode={``,preonly}}
179+\ltjsetparameter{asciixspmode={`',postonly}}
180+\ltjsetparameter{asciixspmode={`;,postonly}}
181+\ltjsetparameter{asciixspmode={47,postonly}}
182+\ltjsetparameter{asciixspmode={`.,postonly}}
183183 % for 8bit Latin
184-\setjaparameter{asciixspmode={"80,allow}}
185-\setjaparameter{asciixspmode={"81,allow}}
186-\setjaparameter{asciixspmode={"82,allow}}
187-\setjaparameter{asciixspmode={"83,allow}}
188-\setjaparameter{asciixspmode={"84,allow}}
189-\setjaparameter{asciixspmode={"85,allow}}
190-\setjaparameter{asciixspmode={"86,allow}}
191-\setjaparameter{asciixspmode={"87,allow}}
192-\setjaparameter{asciixspmode={"88,allow}}
193-\setjaparameter{asciixspmode={"89,allow}}
194-\setjaparameter{asciixspmode={"8A,allow}}
195-\setjaparameter{asciixspmode={"8B,allow}}
196-\setjaparameter{asciixspmode={"8C,allow}}
197-\setjaparameter{asciixspmode={"8D,allow}}
198-\setjaparameter{asciixspmode={"8E,allow}}
199-\setjaparameter{asciixspmode={"8F,allow}}
200-\setjaparameter{asciixspmode={"90,allow}}
201-\setjaparameter{asciixspmode={"91,allow}}
202-\setjaparameter{asciixspmode={"92,allow}}
203-\setjaparameter{asciixspmode={"93,allow}}
204-\setjaparameter{asciixspmode={"94,allow}}
205-\setjaparameter{asciixspmode={"95,allow}}
206-\setjaparameter{asciixspmode={"96,allow}}
207-\setjaparameter{asciixspmode={"97,allow}}
208-\setjaparameter{asciixspmode={"98,allow}}
209-\setjaparameter{asciixspmode={"99,allow}}
210-\setjaparameter{asciixspmode={"9A,allow}}
211-\setjaparameter{asciixspmode={"9B,allow}}
212-\setjaparameter{asciixspmode={"9C,allow}}
213-\setjaparameter{asciixspmode={"9D,allow}}
214-\setjaparameter{asciixspmode={"9E,allow}}
215-\setjaparameter{asciixspmode={"9F,allow}}
216-\setjaparameter{asciixspmode={"A0,allow}}
217-\setjaparameter{asciixspmode={"A1,allow}}
218-\setjaparameter{asciixspmode={"A2,allow}}
219-\setjaparameter{asciixspmode={"A3,allow}}
220-\setjaparameter{asciixspmode={"A4,allow}}
221-\setjaparameter{asciixspmode={"A5,allow}}
222-\setjaparameter{asciixspmode={"A6,allow}}
223-\setjaparameter{asciixspmode={"A7,allow}}
224-\setjaparameter{asciixspmode={"A8,allow}}
225-\setjaparameter{asciixspmode={"A9,allow}}
226-\setjaparameter{asciixspmode={"AA,allow}}
227-\setjaparameter{asciixspmode={"AB,allow}}
228-\setjaparameter{asciixspmode={"AC,allow}}
229-\setjaparameter{asciixspmode={"AD,allow}}
230-\setjaparameter{asciixspmode={"AE,allow}}
231-\setjaparameter{asciixspmode={"AF,allow}}
232-\setjaparameter{asciixspmode={"B0,allow}}
233-\setjaparameter{asciixspmode={"B1,allow}}
234-\setjaparameter{asciixspmode={"B2,allow}}
235-\setjaparameter{asciixspmode={"B3,allow}}
236-\setjaparameter{asciixspmode={"B4,allow}}
237-\setjaparameter{asciixspmode={"B5,allow}}
238-\setjaparameter{asciixspmode={"B6,allow}}
239-\setjaparameter{asciixspmode={"B7,allow}}
240-\setjaparameter{asciixspmode={"B8,allow}}
241-\setjaparameter{asciixspmode={"B9,allow}}
242-\setjaparameter{asciixspmode={"BA,allow}}
243-\setjaparameter{asciixspmode={"BB,allow}}
244-\setjaparameter{asciixspmode={"BC,allow}}
245-\setjaparameter{asciixspmode={"BD,allow}}
246-\setjaparameter{asciixspmode={"BE,allow}}
247-\setjaparameter{asciixspmode={"BF,allow}}
248-\setjaparameter{asciixspmode={"C0,allow}}
249-\setjaparameter{asciixspmode={"C1,allow}}
250-\setjaparameter{asciixspmode={"C2,allow}}
251-\setjaparameter{asciixspmode={"C3,allow}}
252-\setjaparameter{asciixspmode={"C4,allow}}
253-\setjaparameter{asciixspmode={"C5,allow}}
254-\setjaparameter{asciixspmode={"C6,allow}}
255-\setjaparameter{asciixspmode={"C7,allow}}
256-\setjaparameter{asciixspmode={"C8,allow}}
257-\setjaparameter{asciixspmode={"C9,allow}}
258-\setjaparameter{asciixspmode={"CA,allow}}
259-\setjaparameter{asciixspmode={"CB,allow}}
260-\setjaparameter{asciixspmode={"CC,allow}}
261-\setjaparameter{asciixspmode={"CD,allow}}
262-\setjaparameter{asciixspmode={"CE,allow}}
263-\setjaparameter{asciixspmode={"CF,allow}}
264-\setjaparameter{asciixspmode={"D0,allow}}
265-\setjaparameter{asciixspmode={"D1,allow}}
266-\setjaparameter{asciixspmode={"D2,allow}}
267-\setjaparameter{asciixspmode={"D3,allow}}
268-\setjaparameter{asciixspmode={"D4,allow}}
269-\setjaparameter{asciixspmode={"D5,allow}}
270-\setjaparameter{asciixspmode={"D6,allow}}
271-\setjaparameter{asciixspmode={"D7,allow}}
272-\setjaparameter{asciixspmode={"D8,allow}}
273-\setjaparameter{asciixspmode={"D9,allow}}
274-\setjaparameter{asciixspmode={"DA,allow}}
275-\setjaparameter{asciixspmode={"DB,allow}}
276-\setjaparameter{asciixspmode={"DC,allow}}
277-\setjaparameter{asciixspmode={"DD,allow}}
278-\setjaparameter{asciixspmode={"DE,allow}}
279-\setjaparameter{asciixspmode={"DF,allow}}
280-\setjaparameter{asciixspmode={"E0,allow}}
281-\setjaparameter{asciixspmode={"E1,allow}}
282-\setjaparameter{asciixspmode={"E2,allow}}
283-\setjaparameter{asciixspmode={"E3,allow}}
284-\setjaparameter{asciixspmode={"E4,allow}}
285-\setjaparameter{asciixspmode={"E5,allow}}
286-\setjaparameter{asciixspmode={"E6,allow}}
287-\setjaparameter{asciixspmode={"E7,allow}}
288-\setjaparameter{asciixspmode={"E8,allow}}
289-\setjaparameter{asciixspmode={"E9,allow}}
290-\setjaparameter{asciixspmode={"EA,allow}}
291-\setjaparameter{asciixspmode={"EB,allow}}
292-\setjaparameter{asciixspmode={"EC,allow}}
293-\setjaparameter{asciixspmode={"ED,allow}}
294-\setjaparameter{asciixspmode={"EE,allow}}
295-\setjaparameter{asciixspmode={"EF,allow}}
296-\setjaparameter{asciixspmode={"F0,allow}}
297-\setjaparameter{asciixspmode={"F1,allow}}
298-\setjaparameter{asciixspmode={"F2,allow}}
299-\setjaparameter{asciixspmode={"F3,allow}}
300-\setjaparameter{asciixspmode={"F4,allow}}
301-\setjaparameter{asciixspmode={"F5,allow}}
302-\setjaparameter{asciixspmode={"F6,allow}}
303-\setjaparameter{asciixspmode={"F7,allow}}
304-\setjaparameter{asciixspmode={"F8,allow}}
305-\setjaparameter{asciixspmode={"F9,allow}}
306-\setjaparameter{asciixspmode={"FA,allow}}
307-\setjaparameter{asciixspmode={"FB,allow}}
308-\setjaparameter{asciixspmode={"FC,allow}}
309-\setjaparameter{asciixspmode={"FD,allow}}
310-\setjaparameter{asciixspmode={"FE,allow}}
311-\setjaparameter{asciixspmode={"FF,allow}}
184+\ltjsetparameter{asciixspmode={"80,allow}}
185+\ltjsetparameter{asciixspmode={"81,allow}}
186+\ltjsetparameter{asciixspmode={"82,allow}}
187+\ltjsetparameter{asciixspmode={"83,allow}}
188+\ltjsetparameter{asciixspmode={"84,allow}}
189+\ltjsetparameter{asciixspmode={"85,allow}}
190+\ltjsetparameter{asciixspmode={"86,allow}}
191+\ltjsetparameter{asciixspmode={"87,allow}}
192+\ltjsetparameter{asciixspmode={"88,allow}}
193+\ltjsetparameter{asciixspmode={"89,allow}}
194+\ltjsetparameter{asciixspmode={"8A,allow}}
195+\ltjsetparameter{asciixspmode={"8B,allow}}
196+\ltjsetparameter{asciixspmode={"8C,allow}}
197+\ltjsetparameter{asciixspmode={"8D,allow}}
198+\ltjsetparameter{asciixspmode={"8E,allow}}
199+\ltjsetparameter{asciixspmode={"8F,allow}}
200+\ltjsetparameter{asciixspmode={"90,allow}}
201+\ltjsetparameter{asciixspmode={"91,allow}}
202+\ltjsetparameter{asciixspmode={"92,allow}}
203+\ltjsetparameter{asciixspmode={"93,allow}}
204+\ltjsetparameter{asciixspmode={"94,allow}}
205+\ltjsetparameter{asciixspmode={"95,allow}}
206+\ltjsetparameter{asciixspmode={"96,allow}}
207+\ltjsetparameter{asciixspmode={"97,allow}}
208+\ltjsetparameter{asciixspmode={"98,allow}}
209+\ltjsetparameter{asciixspmode={"99,allow}}
210+\ltjsetparameter{asciixspmode={"9A,allow}}
211+\ltjsetparameter{asciixspmode={"9B,allow}}
212+\ltjsetparameter{asciixspmode={"9C,allow}}
213+\ltjsetparameter{asciixspmode={"9D,allow}}
214+\ltjsetparameter{asciixspmode={"9E,allow}}
215+\ltjsetparameter{asciixspmode={"9F,allow}}
216+\ltjsetparameter{asciixspmode={"A0,allow}}
217+\ltjsetparameter{asciixspmode={"A1,allow}}
218+\ltjsetparameter{asciixspmode={"A2,allow}}
219+\ltjsetparameter{asciixspmode={"A3,allow}}
220+\ltjsetparameter{asciixspmode={"A4,allow}}
221+\ltjsetparameter{asciixspmode={"A5,allow}}
222+\ltjsetparameter{asciixspmode={"A6,allow}}
223+\ltjsetparameter{asciixspmode={"A7,allow}}
224+\ltjsetparameter{asciixspmode={"A8,allow}}
225+\ltjsetparameter{asciixspmode={"A9,allow}}
226+\ltjsetparameter{asciixspmode={"AA,allow}}
227+\ltjsetparameter{asciixspmode={"AB,allow}}
228+\ltjsetparameter{asciixspmode={"AC,allow}}
229+\ltjsetparameter{asciixspmode={"AD,allow}}
230+\ltjsetparameter{asciixspmode={"AE,allow}}
231+\ltjsetparameter{asciixspmode={"AF,allow}}
232+\ltjsetparameter{asciixspmode={"B0,allow}}
233+\ltjsetparameter{asciixspmode={"B1,allow}}
234+\ltjsetparameter{asciixspmode={"B2,allow}}
235+\ltjsetparameter{asciixspmode={"B3,allow}}
236+\ltjsetparameter{asciixspmode={"B4,allow}}
237+\ltjsetparameter{asciixspmode={"B5,allow}}
238+\ltjsetparameter{asciixspmode={"B6,allow}}
239+\ltjsetparameter{asciixspmode={"B7,allow}}
240+\ltjsetparameter{asciixspmode={"B8,allow}}
241+\ltjsetparameter{asciixspmode={"B9,allow}}
242+\ltjsetparameter{asciixspmode={"BA,allow}}
243+\ltjsetparameter{asciixspmode={"BB,allow}}
244+\ltjsetparameter{asciixspmode={"BC,allow}}
245+\ltjsetparameter{asciixspmode={"BD,allow}}
246+\ltjsetparameter{asciixspmode={"BE,allow}}
247+\ltjsetparameter{asciixspmode={"BF,allow}}
248+\ltjsetparameter{asciixspmode={"C0,allow}}
249+\ltjsetparameter{asciixspmode={"C1,allow}}
250+\ltjsetparameter{asciixspmode={"C2,allow}}
251+\ltjsetparameter{asciixspmode={"C3,allow}}
252+\ltjsetparameter{asciixspmode={"C4,allow}}
253+\ltjsetparameter{asciixspmode={"C5,allow}}
254+\ltjsetparameter{asciixspmode={"C6,allow}}
255+\ltjsetparameter{asciixspmode={"C7,allow}}
256+\ltjsetparameter{asciixspmode={"C8,allow}}
257+\ltjsetparameter{asciixspmode={"C9,allow}}
258+\ltjsetparameter{asciixspmode={"CA,allow}}
259+\ltjsetparameter{asciixspmode={"CB,allow}}
260+\ltjsetparameter{asciixspmode={"CC,allow}}
261+\ltjsetparameter{asciixspmode={"CD,allow}}
262+\ltjsetparameter{asciixspmode={"CE,allow}}
263+\ltjsetparameter{asciixspmode={"CF,allow}}
264+\ltjsetparameter{asciixspmode={"D0,allow}}
265+\ltjsetparameter{asciixspmode={"D1,allow}}
266+\ltjsetparameter{asciixspmode={"D2,allow}}
267+\ltjsetparameter{asciixspmode={"D3,allow}}
268+\ltjsetparameter{asciixspmode={"D4,allow}}
269+\ltjsetparameter{asciixspmode={"D5,allow}}
270+\ltjsetparameter{asciixspmode={"D6,allow}}
271+\ltjsetparameter{asciixspmode={"D7,allow}}
272+\ltjsetparameter{asciixspmode={"D8,allow}}
273+\ltjsetparameter{asciixspmode={"D9,allow}}
274+\ltjsetparameter{asciixspmode={"DA,allow}}
275+\ltjsetparameter{asciixspmode={"DB,allow}}
276+\ltjsetparameter{asciixspmode={"DC,allow}}
277+\ltjsetparameter{asciixspmode={"DD,allow}}
278+\ltjsetparameter{asciixspmode={"DE,allow}}
279+\ltjsetparameter{asciixspmode={"DF,allow}}
280+\ltjsetparameter{asciixspmode={"E0,allow}}
281+\ltjsetparameter{asciixspmode={"E1,allow}}
282+\ltjsetparameter{asciixspmode={"E2,allow}}
283+\ltjsetparameter{asciixspmode={"E3,allow}}
284+\ltjsetparameter{asciixspmode={"E4,allow}}
285+\ltjsetparameter{asciixspmode={"E5,allow}}
286+\ltjsetparameter{asciixspmode={"E6,allow}}
287+\ltjsetparameter{asciixspmode={"E7,allow}}
288+\ltjsetparameter{asciixspmode={"E8,allow}}
289+\ltjsetparameter{asciixspmode={"E9,allow}}
290+\ltjsetparameter{asciixspmode={"EA,allow}}
291+\ltjsetparameter{asciixspmode={"EB,allow}}
292+\ltjsetparameter{asciixspmode={"EC,allow}}
293+\ltjsetparameter{asciixspmode={"ED,allow}}
294+\ltjsetparameter{asciixspmode={"EE,allow}}
295+\ltjsetparameter{asciixspmode={"EF,allow}}
296+\ltjsetparameter{asciixspmode={"F0,allow}}
297+\ltjsetparameter{asciixspmode={"F1,allow}}
298+\ltjsetparameter{asciixspmode={"F2,allow}}
299+\ltjsetparameter{asciixspmode={"F3,allow}}
300+\ltjsetparameter{asciixspmode={"F4,allow}}
301+\ltjsetparameter{asciixspmode={"F5,allow}}
302+\ltjsetparameter{asciixspmode={"F6,allow}}
303+\ltjsetparameter{asciixspmode={"F7,allow}}
304+\ltjsetparameter{asciixspmode={"F8,allow}}
305+\ltjsetparameter{asciixspmode={"F9,allow}}
306+\ltjsetparameter{asciixspmode={"FA,allow}}
307+\ltjsetparameter{asciixspmode={"FB,allow}}
308+\ltjsetparameter{asciixspmode={"FC,allow}}
309+\ltjsetparameter{asciixspmode={"FD,allow}}
310+\ltjsetparameter{asciixspmode={"FE,allow}}
311+\ltjsetparameter{asciixspmode={"FF,allow}}
312312 %
313313 % inhibitxspcode
314-\setjaparameter{cjkxspmode={`、,postonly}}
315-\setjaparameter{cjkxspmode={`。,postonly}}
316-\setjaparameter{cjkxspmode={`,,postonly}}
317-\setjaparameter{cjkxspmode={`.,postonly}}
318-\setjaparameter{cjkxspmode={`;,postonly}}
319-\setjaparameter{cjkxspmode={`?,postonly}}
320-\setjaparameter{cjkxspmode={`),postonly}}
321-\setjaparameter{cjkxspmode={`(,preonly}}
322-\setjaparameter{cjkxspmode={`],postonly}}
323-\setjaparameter{cjkxspmode={`[,preonly}}
324-\setjaparameter{cjkxspmode={`},postonly}}
325-\setjaparameter{cjkxspmode={`{,preonly}}
326-\setjaparameter{cjkxspmode={`‘,preonly}}
327-\setjaparameter{cjkxspmode={`’,postonly}}
328-\setjaparameter{cjkxspmode={`“,preonly}}
329-\setjaparameter{cjkxspmode={`”,postonly}}
330-\setjaparameter{cjkxspmode={`〔,preonly}}
331-\setjaparameter{cjkxspmode={`〕,postonly}}
332-\setjaparameter{cjkxspmode={`〈,preonly}}
333-\setjaparameter{cjkxspmode={`〉,postonly}}
334-\setjaparameter{cjkxspmode={`《,preonly}}
335-\setjaparameter{cjkxspmode={`》,postonly}}
336-\setjaparameter{cjkxspmode={`「,preonly}}
337-\setjaparameter{cjkxspmode={`」,postonly}}
338-\setjaparameter{cjkxspmode={`『,preonly}}
339-\setjaparameter{cjkxspmode={`』,postonly}}
340-\setjaparameter{cjkxspmode={`【,preonly}}
341-\setjaparameter{cjkxspmode={`】,postonly}}
342-\setjaparameter{cjkxspmode={`—,inhibit}}% U+2014 EM DASH
343-\setjaparameter{cjkxspmode={`―,inhibit}}% U+2015 HORIZONTAL BAR
344-\setjaparameter{cjkxspmode={`〜,inhibit}}% U+301C WAVE DASH
345-\setjaparameter{cjkxspmode={`~,inhibit}}% U+FF5E FULLWIDTH TILDE
346-\setjaparameter{cjkxspmode={`…,inhibit}}
347-\setjaparameter{cjkxspmode={`¥,inhibit}}% U+00A5 YEN SIGN
348-\setjaparameter{cjkxspmode={`¥,inhibit}}% U+FFE5 FULLWIDTH YEN SIGN
349-\setjaparameter{cjkxspmode={`°,postonly}}
350-\setjaparameter{cjkxspmode={`′,postonly}}
351-\setjaparameter{cjkxspmode={`″,postonly}}
314+\ltjsetparameter{cjkxspmode={`、,postonly}}
315+\ltjsetparameter{cjkxspmode={`。,postonly}}
316+\ltjsetparameter{cjkxspmode={`,,postonly}}
317+\ltjsetparameter{cjkxspmode={`.,postonly}}
318+\ltjsetparameter{cjkxspmode={`;,postonly}}
319+\ltjsetparameter{cjkxspmode={`?,postonly}}
320+\ltjsetparameter{cjkxspmode={`),postonly}}
321+\ltjsetparameter{cjkxspmode={`(,preonly}}
322+\ltjsetparameter{cjkxspmode={`],postonly}}
323+\ltjsetparameter{cjkxspmode={`[,preonly}}
324+\ltjsetparameter{cjkxspmode={`},postonly}}
325+\ltjsetparameter{cjkxspmode={`{,preonly}}
326+\ltjsetparameter{cjkxspmode={`‘,preonly}}
327+\ltjsetparameter{cjkxspmode={`’,postonly}}
328+\ltjsetparameter{cjkxspmode={`“,preonly}}
329+\ltjsetparameter{cjkxspmode={`”,postonly}}
330+\ltjsetparameter{cjkxspmode={`〔,preonly}}
331+\ltjsetparameter{cjkxspmode={`〕,postonly}}
332+\ltjsetparameter{cjkxspmode={`〈,preonly}}
333+\ltjsetparameter{cjkxspmode={`〉,postonly}}
334+\ltjsetparameter{cjkxspmode={`《,preonly}}
335+\ltjsetparameter{cjkxspmode={`》,postonly}}
336+\ltjsetparameter{cjkxspmode={`「,preonly}}
337+\ltjsetparameter{cjkxspmode={`」,postonly}}
338+\ltjsetparameter{cjkxspmode={`『,preonly}}
339+\ltjsetparameter{cjkxspmode={`』,postonly}}
340+\ltjsetparameter{cjkxspmode={`【,preonly}}
341+\ltjsetparameter{cjkxspmode={`】,postonly}}
342+\ltjsetparameter{cjkxspmode={`—,inhibit}}% U+2014 EM DASH
343+\ltjsetparameter{cjkxspmode={`―,inhibit}}% U+2015 HORIZONTAL BAR
344+\ltjsetparameter{cjkxspmode={`〜,inhibit}}% U+301C WAVE DASH
345+\ltjsetparameter{cjkxspmode={`~,inhibit}}% U+FF5E FULLWIDTH TILDE
346+\ltjsetparameter{cjkxspmode={`…,inhibit}}
347+\ltjsetparameter{cjkxspmode={`¥,inhibit}}% U+00A5 YEN SIGN
348+\ltjsetparameter{cjkxspmode={`¥,inhibit}}% U+FFE5 FULLWIDTH YEN SIGN
349+\ltjsetparameter{cjkxspmode={`°,postonly}}
350+\ltjsetparameter{cjkxspmode={`′,postonly}}
351+\ltjsetparameter{cjkxspmode={`″,postonly}}
352352 %
353353 % inhibitxspcode JIS X 0213
354354 %
355-\setjaparameter{cjkxspmode={`⦅,preonly}}
356-\setjaparameter{cjkxspmode={`⦆,postonly}}
357-\setjaparameter{cjkxspmode={`⦅,preonly}}
358-\setjaparameter{cjkxspmode={`⦆,postonly}}
359-\setjaparameter{cjkxspmode={`〘,preonly}}
360-\setjaparameter{cjkxspmode={`〙,postonly}}
361-\setjaparameter{cjkxspmode={`〖,preonly}}
362-\setjaparameter{cjkxspmode={`〗,postonly}}
363-\setjaparameter{cjkxspmode={`«,preonly}}
364-\setjaparameter{cjkxspmode={`»,postonly}}
365-\setjaparameter{cjkxspmode={`〝,preonly}}
366-\setjaparameter{cjkxspmode={`〟,postonly}}
367-\setjaparameter{cjkxspmode={`‼,postonly}}
368-\setjaparameter{cjkxspmode={`⁇,postonly}}
369-\setjaparameter{cjkxspmode={`⁈,postonly}}
370-\setjaparameter{cjkxspmode={`⁉,postonly}}
371-\setjaparameter{cjkxspmode={`¡,preonly}}
372-\setjaparameter{cjkxspmode={`¿,preonly}}
373-\setjaparameter{cjkxspmode={`ª,postonly}}
374-\setjaparameter{cjkxspmode={`º,postonly}}
375-\setjaparameter{cjkxspmode={`¹,postonly}}
376-\setjaparameter{cjkxspmode={`²,postonly}}
377-\setjaparameter{cjkxspmode={`³,postonly}}
378-\setjaparameter{cjkxspmode={`€,preonly}}
355+\ltjsetparameter{cjkxspmode={`⦅,preonly}}
356+\ltjsetparameter{cjkxspmode={`⦆,postonly}}
357+\ltjsetparameter{cjkxspmode={`⦅,preonly}}
358+\ltjsetparameter{cjkxspmode={`⦆,postonly}}
359+\ltjsetparameter{cjkxspmode={`〘,preonly}}
360+\ltjsetparameter{cjkxspmode={`〙,postonly}}
361+\ltjsetparameter{cjkxspmode={`〖,preonly}}
362+\ltjsetparameter{cjkxspmode={`〗,postonly}}
363+\ltjsetparameter{cjkxspmode={`«,preonly}}
364+\ltjsetparameter{cjkxspmode={`»,postonly}}
365+\ltjsetparameter{cjkxspmode={`〝,preonly}}
366+\ltjsetparameter{cjkxspmode={`〟,postonly}}
367+\ltjsetparameter{cjkxspmode={`‼,postonly}}
368+\ltjsetparameter{cjkxspmode={`⁇,postonly}}
369+\ltjsetparameter{cjkxspmode={`⁈,postonly}}
370+\ltjsetparameter{cjkxspmode={`⁉,postonly}}
371+\ltjsetparameter{cjkxspmode={`¡,preonly}}
372+\ltjsetparameter{cjkxspmode={`¿,preonly}}
373+\ltjsetparameter{cjkxspmode={`ª,postonly}}
374+\ltjsetparameter{cjkxspmode={`º,postonly}}
375+\ltjsetparameter{cjkxspmode={`¹,postonly}}
376+\ltjsetparameter{cjkxspmode={`²,postonly}}
377+\ltjsetparameter{cjkxspmode={`³,postonly}}
378+\ltjsetparameter{cjkxspmode={`€,preonly}}
379379 %
380380 % inhibitxspcode JIS X 0212
381381 %
382-%\setjaparameter{cjkxspmode={`¡,postonly}}
383-%\setjaparameter{cjkxspmode={`¿,postonly}}
384-%\setjaparameter{cjkxspmode={`º,postonly}}
385-%\setjaparameter{cjkxspmode={`ª,postonly}}
386-\setjaparameter{cjkxspmode={`™,postonly}}
382+%\ltjsetparameter{cjkxspmode={`¡,postonly}}
383+%\ltjsetparameter{cjkxspmode={`¿,postonly}}
384+%\ltjsetparameter{cjkxspmode={`º,postonly}}
385+%\ltjsetparameter{cjkxspmode={`ª,postonly}}
386+\ltjsetparameter{cjkxspmode={`™,postonly}}
387387 %
388388 % inhibitxspcode 半角片仮名
389389 %
390-\setjaparameter{cjkxspmode={`。,postonly}}
391-\setjaparameter{cjkxspmode={`、,postonly}}
392-\setjaparameter{cjkxspmode={`「,preonly}}
393-\setjaparameter{cjkxspmode={`」,postonly}}
390+\ltjsetparameter{cjkxspmode={`。,postonly}}
391+\ltjsetparameter{cjkxspmode={`、,postonly}}
392+\ltjsetparameter{cjkxspmode={`「,preonly}}
393+\ltjsetparameter{cjkxspmode={`」,postonly}}
394394
395395 \endinput
396396 cat `locate ukinsoku.tex` \
397- | sed "s/prebreakpenalty\(.*\)=\([0-9]*\)/setjaparameter{prebreakpenalty={\1,\2}}/" \
398- | sed "s/postbreakpenalty\(.*\)=\([0-9]*\)/setjaparameter{postbreakpenalty={\1,\2}}/" \
399- | sed "s/inhibitxspcode\(.*\)=0/setjaparameter{cjkxspmode={\1,inhibit}}/" \
400- | sed "s/inhibitxspcode\(.*\)=1/setjaparameter{cjkxspmode={\1,postonly}}/" \
401- | sed "s/inhibitxspcode\(.*\)=2/setjaparameter{cjkxspmode={\1,preonly}}/" \
402- | sed "s/inhibitxspcode\(.*\)=3/setjaparameter{cjkxspmode={\1,allow}}/" \
403- | sed "s/xspcode\(.*\)=0/setjaparameter{asciixspmode={\1,inhibit}}/" \
404- | sed "s/xspcode\(.*\)=2/setjaparameter{asciixspmode={\1,postonly}}/" \
405- | sed "s/xspcode\(.*\)=1/setjaparameter{asciixspmode={\1,preonly}}/" \
406- | sed "s/xspcode\(.*\)=3/setjaparameter{asciixspmode={\1,allow}}/" > luatexja-kinsoku.tex
\ No newline at end of file
397+ | sed "s/prebreakpenalty\(.*\)=\([0-9]*\)/ltjsetparameter{prebreakpenalty={\1,\2}}/" \
398+ | sed "s/postbreakpenalty\(.*\)=\([0-9]*\)/ltjsetparameter{postbreakpenalty={\1,\2}}/" \
399+ | sed "s/inhibitxspcode\(.*\)=0/ltjsetparameter{cjkxspmode={\1,inhibit}}/" \
400+ | sed "s/inhibitxspcode\(.*\)=1/ltjsetparameter{cjkxspmode={\1,postonly}}/" \
401+ | sed "s/inhibitxspcode\(.*\)=2/ltjsetparameter{cjkxspmode={\1,preonly}}/" \
402+ | sed "s/inhibitxspcode\(.*\)=3/ltjsetparameter{cjkxspmode={\1,allow}}/" \
403+ | sed "s/xspcode\(.*\)=0/ltjsetparameter{asciixspmode={\1,inhibit}}/" \
404+ | sed "s/xspcode\(.*\)=2/ltjsetparameter{asciixspmode={\1,postonly}}/" \
405+ | sed "s/xspcode\(.*\)=1/ltjsetparameter{asciixspmode={\1,preonly}}/" \
406+ | sed "s/xspcode\(.*\)=3/ltjsetparameter{asciixspmode={\1,allow}}/" > luatexja-kinsoku.tex
\ No newline at end of file
--- a/src/luatexja-plain.tex
+++ b/src/luatexja-plain.tex
@@ -10,7 +10,7 @@
1010 \let\mc=\tenmin
1111 \let\gt=\tengt
1212 \mc
13-\setjaparameter{kanjiskip=0pt plus 0.4pt minus 0.4pt,
13+\ltjsetparameter{kanjiskip=0pt plus 0.4pt minus 0.4pt,
1414 xkanjiskip=.25\zw plus 1pt minus 1pt,
1515 autospacing, autoxspacing, jcharrange={-1},
1616 yabaselineshift=0pt, ykbaselineshift=0pt,
@@ -21,19 +21,19 @@
2121
2222 \luatexja@tempcnta="2000%"
2323 \loop\ifnum\luatexja@tempcnta<"2070%"
24- \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
24+ \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
2525 \advance\luatexja@tempcnta by1
2626 \repeat
2727
2828 \luatexja@tempcnta="3000%"
2929 \loop\ifnum\luatexja@tempcnta<"3040%"
30- \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
30+ \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
3131 \advance\luatexja@tempcnta by1
3232 \repeat
3333
3434 \luatexja@tempcnta="FF00%"
3535 \loop\ifnum\luatexja@tempcnta<"FFF0%"
36- \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
36+ \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
3737 \advance\luatexja@tempcnta by1
3838 \repeat
3939 \endinput
\ No newline at end of file
--- /dev/null
+++ b/src/luatexja-xkanji.lua
@@ -0,0 +1,267 @@
1+------------------------------------------------------------------------
2+-- MAIN PROCESS STEP 3: insert \xkanjiskip (prefix: none)
3+------------------------------------------------------------------------
4+
5+local node_type = node.type
6+local node_new = node.new
7+local node_prev = node.prev
8+local node_next = node.next
9+local has_attr = node.has_attribute
10+local node_insert_before = node.insert_before
11+local node_insert_after = node.insert_after
12+local node_hpack = node.hpack
13+
14+local id_penalty = node.id('penalty')
15+local id_glyph = node.id('glyph')
16+local id_glue = node.id('glue')
17+local id_glue_spec = node.id('glue_spec')
18+local id_kern = node.id('kern')
19+local id_hlist = node.id('hlist')
20+local id_ins = node.id('ins')
21+local id_mark = node.id('mark')
22+local id_adjust = node.id('adjust')
23+local id_math = node.id('math')
24+local id_whatsit = node.id('whatsit')
25+
26+local attr_icflag = luatexbase.attributes['luatexja@icflag']
27+local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
28+
29+local kanji_skip
30+local xkanji_skip
31+local no_skip = 0
32+local after_schar = 1
33+local after_wchar = 2
34+local insert_skip = no_skip
35+
36+-- (glyph_node nr) ... (node nq) <GLUE> ,,, (node np)
37+local np, nq, nrc
38+local no_skip = 0
39+local after_schar = 1
40+local after_wchar = 2 -- nr is a Japanese glyph_node
41+local insert_skip = no_skip
42+
43+local cstb_get_inhibit_xsp_table = ltj.int_get_inhibit_xsp_table
44+
45+local function is_japanese_glyph_node(p)
46+ return p and (p.id==id_glyph)
47+ and (p.font==has_attr(p,attr_curjfnt))
48+end
49+
50+-- the following 2 functions are the lowest part.
51+-- cx: the Kanji code of np
52+local function insert_ascii_kanji_xkskip(head,q,cx)
53+ if cstb_get_inhibit_xsp_table(cx)<=1 then return end
54+ local g = node_new(id_glue)
55+ g.subtype = 0; g.spec = node.copy(xkanji_skip)
56+ node_insert_after(head, q, g)
57+end
58+
59+local function insert_kanji_ascii_xkskip(head,q,p)
60+ local g=true
61+ local c = p.char
62+ while p.components and p.subtype
63+ and math.floor(p.subtype/2)%2==1 do
64+ p = p.components; c = p.char
65+ end
66+ if cstb_get_inhibit_xsp_table(c)%2 == 1 then
67+ if cstb_get_inhibit_xsp_table(nrc)%2 == 0 then g = false end
68+ else g = false
69+ end
70+ if g then
71+ g = node_new(id_glue)
72+ g.subtype = 0; g.spec = node.copy(xkanji_skip)
73+ node_insert_after(head, q, g)
74+ end
75+end
76+
77+
78+local function set_insert_skip_after_achar(p)
79+ local c = p.char
80+ while p.components and p.subtype
81+ and math.floor(p.subtype/2)%2 == 1 do
82+ p=node.tail(p.components); c = p.char
83+ end
84+ if cstb_get_inhibit_xsp_table(c)>=2 then
85+ insert_skip = after_schar
86+ else
87+ insert_skip = no_skip
88+ end
89+end
90+
91+-- When p is a glyph_node ...
92+local function insks_around_char(head)
93+ if is_japanese_glyph_node(np) then
94+ if insert_skip==after_wchar then
95+ local g = node_new(id_glue)
96+ g.subtype=0; g.spec=node.copy(kanji_skip)
97+ node_insert_before(head, np, g)
98+ elseif insert_skip==after_schar then
99+ insert_ascii_kanji_xkskip(head, nq, np.char)
100+ end
101+ insert_skip=after_wchar; nrc = np.char
102+ else
103+ if insert_skip==after_wchar then
104+ insert_kanji_ascii_xkskip(head, nq, np)
105+ end
106+ set_insert_skip_after_achar(np)
107+ end
108+ nq = np
109+end
110+
111+-- Return first and last glyph nodes in a hbox
112+local first_char = nil
113+local last_char = nil
114+local find_first_char = nil
115+local function check_box(box_ptr)
116+ local p = box_ptr; local found_visible_node = false
117+ while p do
118+ if p.id==id_glyph then
119+ repeat
120+ if find_first_char then
121+ first_char = p; find_first_char = false
122+ end
123+ last_char = p; found_visible_node = true; p=node_next(p)
124+ if not p then return found_visible_node end
125+ until p.id~=id_glyph
126+ end
127+ if p.id==id_hlist then
128+ found_visible_node = true
129+ if p.shift==0 then
130+ if check_box(p.head) then found_visible_node = true end
131+ else if find_first_char then
132+ find_first_char = false
133+ else
134+ last_char = nil
135+ end
136+ end
137+ elseif p.id==id_ins or p.id==id_mark
138+ or p.id==id_adjust or p.id==id_whatsit
139+ or p.id==id_penalty then
140+ p=p
141+ else
142+ found_visible_node = true
143+ if find_first_char then
144+ find_first_char = false
145+ else
146+ last_char = nil
147+ end
148+ end
149+ p = node_next(p)
150+ end
151+ return found_visible_node
152+end
153+
154+-- When np is a hlist_node ...
155+local function insks_around_hbox(head)
156+ if np.shift==0 then
157+ find_first_char = true; first_char = nil; last_char = nil
158+ if check_box(np.head) then
159+ -- first char
160+ if is_japanese_glyph_node(first_char) then
161+ nrc = first_char.char
162+ if insert_skip==after_schar then
163+ insert_ascii_kanji_xkskip(head, nq, first_char.char)
164+ elseif insert_skip==after_wchar then
165+ local g = node_new(id_glue)
166+ g.subtype = 0; g.spec = node.copy(kanji_skip)
167+ node_insert_before(head, np, g)
168+ end
169+ insert_skip = after_wchar
170+ elseif first_char then
171+ if insert_skip==after_wchar then
172+ insert_kanji_ascii_xkskip(head, nq, first_char)
173+ end
174+ set_insert_skip_after_achar(first_char)
175+ end
176+ -- last char
177+ if is_japanese_glyph_node(last_char) then
178+ if is_japanese_glyph_node(node_next(np)) then
179+ local g = node_new(id_glue)
180+ g.subtype = 0; g.spec = node.copy(kanji_skip)
181+ node_insert_after(head, np, g)
182+ end
183+ insert_skip = after_wchar; nrc = last_char.char
184+ elseif last_char then
185+ set_insert_skip_after_achar(last_char)
186+ else insert_skip = no_skip
187+ end
188+ else insert_skip = no_skip
189+ end
190+ else insert_skip = no_skip
191+ end
192+ nq = np
193+end
194+
195+-- When np is a penalty ...
196+local function insks_around_penalty(head)
197+ nq = np
198+end
199+
200+-- When np is a kern ...
201+--
202+local function insks_around_kern(head)
203+ if np.subtype==1 then -- \kern or \/
204+ local i = has_attr(np, attr_icflag)
205+ if not i then -- \kern
206+ insert_skip = no_skip
207+ elseif i==1 then
208+ nq = np
209+ end
210+ elseif np.subtype==2 then
211+ -- (np = kern from \accent) .. (accent char) .. (kern from \accent) .. (glyph)
212+ np = node_next(node_next(np))
213+ end
214+end
215+
216+-- When np is a math_node ...
217+local function insks_around_math(head)
218+ local g = { char = -1 }
219+ if (np.subtype==0) and (insert_skip==after_wchar) then
220+ insert_kanji_ascii_xkskip(head, nq, g)
221+ insert_skip = no_skip
222+ else
223+ nq = np; set_insert_skip_after_achar(g)
224+ end
225+end
226+
227+function ltj.int_insert_kanji_skip(head)
228+ if ltj.auto_spacing then
229+ kanji_skip=tex.skip['kanjiskip']
230+ else
231+ kanji_skip=node_new(id_glue_spec)
232+ kanji_skip.width=0; kanji_skip.stretch=0; kanji_skip.shrink=0
233+ end
234+ if ltj.auto_xspacing then
235+ xkanji_skip=tex.skip['xkanjiskip']
236+ else
237+ xkanji_skip=node_new(id_glue_spec)
238+ xkanji_skip.width=0; xkanji_skip.stretch=0; xkanji_skip.shrink=0
239+ end
240+ np = head; nq = nil; insert_skip = no_skip
241+ while np do
242+ if np.id==id_glyph then
243+ repeat
244+ insks_around_char(head); np=node_next(np)
245+ until (not np) or np.id~=id_glyph
246+ else
247+ if np.id==id_hlist then
248+ insks_around_hbox(head)
249+ elseif np.id==id_penalty then
250+ insks_around_penalty(head)
251+ elseif np.id==id_kern then
252+ insks_around_kern(head)
253+ elseif np.id==id_math then
254+ insks_around_math(head)
255+ elseif np.id==id_ins or np.id==id_mark
256+ or np.id==id_adjust or np.id==id_whatsit then
257+ -- do nothing
258+ np = np
259+ else
260+ -- rule, disc, glue, margin_kern
261+ insert_skip = no_skip
262+ end
263+ np = node_next(np)
264+ end
265+ end
266+ return head
267+end
--- /dev/null
+++ b/test/jfm-hang.lua
@@ -0,0 +1,34 @@
1+
2+jfm.dir = 'yoko'
3+-- 'yoko'
4+
5+jfm.zw= 1.0; jfm.zh = 1.0
6+-- amount of ``1zw'' and ``1zh'' (these units are used in pTeX)
7+
8+
9+-- character type
10+-- jfm.define_char_type(<type>, <letters>)
11+jfm.define_char_type(1, {
12+ 0x3042
13+})
14+jfm.define_char_type(2, {
15+ 0x3044
16+})
17+jfm.define_char_type(3, {
18+ 0x3048
19+})
20+jfm.define_char_type(4, {
21+ 0x304A
22+})
23+jfm.define_char_type(8, {'lineend'})
24+
25+
26+jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
27+jfm.define_type_dim(1, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
28+jfm.define_type_dim(2, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
29+jfm.define_type_dim(3, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
30+jfm.define_type_dim(4, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.50)
31+
32+jfm.define_kern(1,8, -0.5)
33+jfm.define_glue(2,3, 0.25, 0.25, 0.25)
34+jfm.define_glue(1,3, 0.25, 0.0, 0.25)
\ No newline at end of file
Binary files a/test/test01-noembed.pdf and b/test/test01-noembed.pdf differ
--- a/test/test01-noembed.tex
+++ b/test/test01-noembed.tex
@@ -72,19 +72,19 @@
7272
7373 {\noindent\bf\tengt {\tt differentjfm=small}(小さい方)}
7474
75-\setjaparameter{differentjfm=small}\djtest
75+\ltjsetparameter{differentjfm=small}\djtest
7676
7777 {\noindent\bf\tengt {\tt differentjfm=large}(大きい方)}
7878
79-\setjaparameter{differentjfm=LARGE}\djtest
79+\ltjsetparameter{differentjfm=LARGE}\djtest
8080
8181 {\noindent\bf\tengt {\tt differentjfm=average}(default,平均)}
8282
83-\setjaparameter{differentjfm=AVERAGE}\djtest
83+\ltjsetparameter{differentjfm=AVERAGE}\djtest
8484
8585 {\noindent\bf\tengt {\tt differentjfm=both}(両方挿入)}
8686
87-\setjaparameter{differentjfm=Both}\djtest
87+\ltjsetparameter{differentjfm=Both}\djtest
8888
8989
9090 \end
Binary files a/test/test01.pdf and b/test/test01.pdf differ
--- a/test/test01.tex
+++ b/test/test01.tex
@@ -68,19 +68,19 @@
6868
6969 {\noindent\bf\tengt {\tt differentjfm=small}(小さい方)}
7070
71-\setjaparameter{differentjfm=small}\djtest
71+\ltjsetparameter{differentjfm=small}\djtest
7272
7373 {\noindent\bf\tengt {\tt differentjfm=large}(大きい方)}
7474
75-\setjaparameter{differentjfm=LARGE}\djtest
75+\ltjsetparameter{differentjfm=LARGE}\djtest
7676
7777 {\noindent\bf\tengt {\tt differentjfm=average}(default,平均)}
7878
79-\setjaparameter{differentjfm=AVERAGE}\djtest
79+\ltjsetparameter{differentjfm=AVERAGE}\djtest
8080
8181 {\noindent\bf\tengt {\tt differentjfm=both}(両方挿入)}
8282
83-\setjaparameter{differentjfm=Both}\djtest
83+\ltjsetparameter{differentjfm=Both}\djtest
8484
8585
8686 \end
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
@@ -7,64 +7,64 @@
77
88 \catcode`\@=11
99 \the\luatexja@ykblshift
10-\setjaparameter{ykbaselineshift=\maxdimen,autoxspacing=false}
10+\ltjsetparameter{ykbaselineshift=\maxdimen,autoxspacing=false}
1111 \the\luatexja@ykblshift\
12-\getjaparameter{ykbaselineshift}
12+\ltjgetparameter{ykbaselineshift}
1313
14-\getjaparameter{kanjiskip},
15-\getjaparameter{xkanjiskip}
14+\ltjgetparameter{kanjiskip},
15+\ltjgetparameter{xkanjiskip}
1616
17-\getjaparameter{autospacing},
18-\getjaparameter{autoxspacing}
17+\ltjgetparameter{autospacing},
18+\ltjgetparameter{autoxspacing}
1919
20-\getjaparameter{differentjfm}.
21-\setjaparameter{ykbaselineshift=0pt,autoxspacing=true}
20+\ltjgetparameter{differentjfm}.
21+\ltjsetparameter{ykbaselineshift=0pt,autoxspacing=true}
2222
2323
24-あいうえお{\setjaparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: local
24+あいうえお{\ltjsetparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: local
2525
26-あいうえお{\globalsetjaparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: global
26+あいうえお{\globalltjsetparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: global
2727
28-\getjaparameter{prebreakpenalty}{`(},
29-\getjaparameter{prebreakpenalty}{`)},
30-\getjaparameter{prebreakpenalty}{`あ}
28+\ltjgetparameter{prebreakpenalty}{`(},
29+\ltjgetparameter{prebreakpenalty}{`)},
30+\ltjgetparameter{prebreakpenalty}{`あ}
3131
3232
33-\getjaparameter{postbreakpenalty}{`(},
34-\getjaparameter{postbreakpenalty}{`)},
35-\getjaparameter{postbreakpenalty}{`あ}
33+\ltjgetparameter{postbreakpenalty}{`(},
34+\ltjgetparameter{postbreakpenalty}{`)},
35+\ltjgetparameter{postbreakpenalty}{`あ}
3636
3737 a\inhibitglue (a)\inhibitglue aあa〜a
3838
3939 \medskip
4040 xspmode
4141
42-\getjaparameter{cjkxspmode}{`(},
43-\getjaparameter{cjkxspmode}{`)},
44-\getjaparameter{cjkxspmode}{`あ},
45-\getjaparameter{cjkxspmode}{`〜}
42+\ltjgetparameter{cjkxspmode}{`(},
43+\ltjgetparameter{cjkxspmode}{`)},
44+\ltjgetparameter{cjkxspmode}{`あ},
45+\ltjgetparameter{cjkxspmode}{`〜}
4646
47-\setjaparameter{asciixspmode={`\b,inhibit}}
47+\ltjsetparameter{asciixspmode={`\b,inhibit}}
4848 あ[あ]あaあbあ
4949
50-\getjaparameter{asciixspmode}{`[},
51-\getjaparameter{asciixspmode}{`]},
52-\getjaparameter{asciixspmode}{`a},
53-\getjaparameter{asciixspmode}{`b}
50+\ltjgetparameter{asciixspmode}{`[},
51+\ltjgetparameter{asciixspmode}{`]},
52+\ltjgetparameter{asciixspmode}{`a},
53+\ltjgetparameter{asciixspmode}{`b}
5454
55-{\setjaparameter{kanjiskip=0pt plus 1fi minus 1fil}\getjaparameter{kanjiskip}\par}
56-{x\setjaparameter{kanjiskip=0pt plus 1fill minus 1filll}\getjaparameter{kanjiskip}\par}
55+{\ltjsetparameter{kanjiskip=0pt plus 1fi minus 1fil}\ltjgetparameter{kanjiskip}\par}
56+{x\ltjsetparameter{kanjiskip=0pt plus 1fill minus 1filll}\ltjgetparameter{kanjiskip}\par}
5757
5858 \medskip
5959 {\tengt ■合字テスト}
6060
6161 \tenrm
62-{\setjaparameter{asciixspmode={`i,preonly},ykbaselineshift=0pt}
62+{\ltjsetparameter{asciixspmode={`i,preonly},ykbaselineshift=0pt}
6363 あiあfiあffiあ\par}
6464
65-{\setjaparameter{asciixspmode={`f,postonly},ykbaselineshift=0pt}
65+{\ltjsetparameter{asciixspmode={`f,postonly},ykbaselineshift=0pt}
6666 あfあfiあffiあ\par}
6767
68-\setjaparameter{asciixspmode={0,inhibit}}
68+\ltjsetparameter{asciixspmode={-1,inhibit}}
6969 あ$a$あ
7070 \end
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
--- a/test/test04-jfm.tex
+++ b/test/test04-jfm.tex
@@ -1,6 +1,7 @@
11 %#!luatex
22 \input luatexja-core.sty
33
4+\def\head#1{\medskip\noindent{\bf\tengt ■ #1}\par}
45 \jfont\rml={psft:Ryumin-Light:jfm=ujis} at 10pt
56 \rml あ\inhibitglue\char"201Cあ←Ryumin-Light
67
@@ -10,9 +11,11 @@
1011 \jfont\rml={file:KozMinPr6N-Regular.otf:jfm=ujis} at 10pt
1112 \rml あ\inhibitglue\char"201Cあ←KozMinPr6N-Regular
1213
13-\scrollmode
14-\jfont\rml={psft:GothicBBB-Medium:jfm=bad} at 10pt % must be error
14+{\scrollmode
15+\gjfont\rml={psft:GothicBBB-Medium:jfm=bad} at 10pt % must be error
16+}
1517 \rml あ123 % \rml は未定義となる
18+{\tt\meaning\rml}
1619
1720 \bigskip
1821 \font\rml={file:ipaexg.ttf} at 10pt\rml
@@ -20,34 +23,66 @@
2023 ここからは,欧文文字フォントはIPA EXゴシック
2124
2225
23-\medskip{\tengt 文字範囲の代入/取得テスト}
26+\head{文字範囲の代入/取得テスト}
2427
25-\defcharrange{2}{`あ,"E0-"FF}
28+\ltjdefcharrange{2}{`あ,"E0-"FF}
2629 「\char"F4」は2番の文字範囲なので,和文扱いのはず
2730
28-{iso8859-1 和文扱い:\setjaparameter{jcharrange={1}}%
29-\getjaparameter{jcharrange}{1}%
31+{iso8859-1 和文扱い:\ltjsetparameter{jcharrange={1}}%
32+\ltjgetparameter{jcharrange}{1}%
3033 § ¶ ° £ ¥ \char"F4}
3134
32-{iso8859-1 欧文扱い:\setjaparameter{jcharrange={-1}}%
33-\getjaparameter{jcharrange}{1}%
35+{iso8859-1 欧文扱い:\ltjsetparameter{jcharrange={-1}}%
36+\ltjgetparameter{jcharrange}{1}%
3437 § ¶ ° £ ¥ \char"F4}
3538
3639
37-\medskip{\tengt 文字範囲の状況取得}
38-\getjaparameter{jcharrange}{0}
39-\getjaparameter{jcharrange}{1}
40-\getjaparameter{jcharrange}{2}
40+\head{文字範囲の状況取得}
41+\ltjgetparameter{jcharrange}{0}
42+\ltjgetparameter{jcharrange}{1}
43+\ltjgetparameter{jcharrange}{2}
4144
42-\medskip{\tengt 文字コード→文字範囲}
43-\getjaparameter{chartorange}{`い} % must be 217
44-\getjaparameter{chartorange}{`§} % must be 1
45-\getjaparameter{chartorange}{"F7} % must be 2
46-\getjaparameter{chartorange}{-1} % must be -1
45+\head{文字コード→文字範囲}
46+\ltjgetparameter{chartorange}{`い} % must be 217
47+\ltjgetparameter{chartorange}{`§} % must be 1
48+\ltjgetparameter{chartorange}{"F7} % must be 2
49+\ltjgetparameter{chartorange}{-1} % must be error "
4750
4851 \medskip
49-\setjaparameter{jcharrange={-217}}
52+\ltjsetparameter{jcharrange={-217}}
5053 ほとんど欧文扱い.2番は別(「あ」)
51-\setjaparameter{jcharrange={218}}
54+\ltjsetparameter{jcharrange={218}}
5255 和文扱いにもどる
56+
57+\vfill\eject
58+\jfont\rmlh={psft:Ryumin-Light:jfm=hang} at 10pt
59+\head{‘lineend’検証}
60+\jfont\sixgt={psft:GothicBBB-Medium:jfm=ujis} at 6pt
61+\font\sixtt=cmtt10 at 6pt
62+
63+
64+\def\dumplist#1{\par\noindent\leavevmode
65+\hbox to 0.2\hsize{\copy#1\hss}%
66+\vbox{\hsize=0.6\hsize\sixtt\baselineskip=7.2pt\sixgt\let\\=\relax
67+\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par', tex.print)}\hrule}}
68+
69+\setbox0=\hbox{\rmlh あえあいえ}
70+\dumplist0
71+
72+\medskip
73+\ltjsetparameter{postbreakpenalty={`あ,100}}
74+\ltjsetparameter{postbreakpenalty={`い,100}}
75+\ltjsetparameter{postbreakpenalty={`う,100}}
76+\ltjsetparameter{postbreakpenalty={`え,100}}
77+\setbox0=\hbox{\rmlh あえあいえ}
78+\dumplist0
79+
80+\head{italic correction}
81+
82+\setbox0=\hbox{x{\rmlh お\/}({\rmlh お\/}あ}
83+\dumplist0
84+
85+\setbox0=\hbox{x{\it f\/}({\it g\/}あ}
86+\dumplist0
87+
5388 \end
Binary files /dev/null and b/test/test05-speed.pdf differ
--- /dev/null
+++ b/test/test05-speed.tex
@@ -0,0 +1,18 @@
1+%#! time luatex test05-speed.tex
2+\input luatexja-core.sty
3+
4+\newcount\cnt\newcount\cnta
5+\cnt=0
6+\long\def\loop#1\repeat{\def\body{#1}\iterate}
7+\loop\ifnum\cnt<10 % <= this value
8+ \cnta=0 \message{\the\cnt:}\par
9+ {\loop\ifnum\cnta<500 あ.「い,うえお・か(き)く)(けこ\advance\cnta1\repeat}
10+ \advance\cnt1
11+\repeat
12+
13+\end
14+
15+% real time:
16+% 20: 14.373s
17+% 10: 8.476s
18+% env: C2D E7300, Mem 4GB, LuaTeX 0.66.0pre, Gentoo amd64 unstable
\ No newline at end of file
旧リポジトリブラウザで表示