OSDN Git Service

Rewrite the main process (inserting JFM glue/kern and \[x]kanjiskip) and so on.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 27 Apr 2011 08:40:19 +0000 (17:40 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 27 Apr 2011 08:40:19 +0000 (17:40 +0900)
- 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.

21 files changed:
doc/s1sty.tex
doc/sample1.pdf
doc/sample1.tex
src/luatexja-core.lua
src/luatexja-core.sty
src/luatexja-jfont.lua
src/luatexja-kinsoku.tex
src/luatexja-plain.tex
src/luatexja-xkanji.lua [new file with mode: 0644]
test/jfm-hang.lua [new file with mode: 0644]
test/test01-noembed.pdf
test/test01-noembed.tex
test/test01.pdf
test/test01.tex
test/test02-latex.pdf
test/test03-after.pdf
test/test03-after.tex
test/test04-jfm.pdf
test/test04-jfm.tex
test/test05-speed.pdf [new file with mode: 0644]
test/test05-speed.tex [new file with mode: 0644]

index f57cca1..ef7b53d 100644 (file)
@@ -55,7 +55,7 @@
   \let\sc=\eightsc \def\tt{\eighttt\eightjtt}%
   \let\mc=\eightmc \let\gt=\eightgt%
   \rm\mc\xkanjiskip=0.25\zw plus 1pt minus 1pt%
-  \setjaparameter{ykbaselineshift=-0.76pt, yabaselineshift=-0.76pt}
+  \ltjsetparameter{ykbaselineshift=-0.76pt, yabaselineshift=-0.76pt}
 }
 
 
 \def\enum{\par\medskip\advance\enumi1\leftskip=2\zw\noindent\hskip-1\zw\hbox to 1\zw{\hss\the\enumi.\kern0.5\zw}}
 \def\enditem{\medskip\par\enumi=0\leftskip=0pt\parskip=0pt\noindent}
 
-\setjaparameter{cjkxspmode={`★,0}}
+\ltjsetparameter{cjkxspmode={`★,0}}
 
 \endinput
index cfa0514..91d5a02 100644 (file)
Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ
index 34970a6..05f18ec 100644 (file)
@@ -1,7 +1,6 @@
 %#! time luatex sample1
 \input s1sty.tex % style file
 
-\message{BB}
 \overfullrule=0pt
 \def\LaTeX{L\kern-.36em\setbox0=\hbox{T}\vbox to\ht0{\hbox{\sx A}\vss}\kern-.15em\TeX}
 \font\mff=manfnt at 10pt
 \centerline{\big Lua\TeX-jaパッケージ}\bigskip
 \centerline{\large\the\year/\the\month/\the\day}\medskip
 
-\message{AA}
 \bigskip
 
 本パッケージは,(最低でもp\TeX と同等の水準の)日本語組版をLua\TeX 上で実現させることを
 目標としたマクロである.まだまだ足りないところはあるが,とりあえず動くようになった?ので公開する. 
 
-%{\showboxdepth=10000\showboxbreadth=10000\tracingonline=1\scrollmode\showlists}\end
 
 \beginparagraph 特徴
 
@@ -43,6 +40,7 @@
 \item {\bf 現時点で\LaTeX での使用は殆ど考慮されていません.今は``plain Lua\TeX''で使ってください.}
 \item |\accent|を和文文字に対して使うことはできません.
 これは「フォントを後で置換する」という実装上,仕方のないことだと思われます.
+{\small|\/|を試験的に日本語にも対応させました.|make_accent|の処理をLuaコードで書けば可能だと思われます.}
 \item 数式中の日本語は想定していません.|\hbox|か何かで囲ってください.
 \item p\TeX にあった以下の機能はまだ実装していません.
 \itemitem |\euc|, |\jis|, |\sjis|, |\kuten|といった,コード変換プリミティブ.
@@ -61,6 +59,7 @@
 {\bf 現時点で\LaTeX での使用は全く考慮されていない.}
 \item {\tt luatexja-core.lua}: コア部分に使われるLuaコード.
 \item {\tt luatexja-jfont.lua}: 和文フォント定義部のLuaコード.
+\item {\tt luatexja-xkanji.lua}: |\[x]kanjiskip|自動挿入処理のLuaコード.
 \item {\tt luatexja-rmlgbm-data.lua}: 非埋込和文フォント用のデータ(小塚明朝Pr6N R由来).
 \item {\tt luatexja-rmlgbm.lua}: 非埋込和文フォント (Ryumin-Light etc.) 定義部.
 \item {\tt mk-rmlgbm-data.tex}: {\tt luatexja-rmlgbm-data.lua}作成用スクリプト
@@ -146,13 +145,13 @@ PSフォント名<PSfont_name>を直接指定することもでき,
 \item デフォルトでは,|U+0100|以降の文字は全部和文扱いであり,さらに文字範囲として,
 \begintt
   \defcharrange{1}{"80-"FF}
-  \setjaparameter{jcharrange={-1}}
+  \ltjsetparameter{jcharrange={-1}}
 \endtt
 と指定している{\small(つまりLatin-1 Supplementの範囲は欧文扱い)\inhibitglue}.
 
-TODO: 「{\setjaparameter{jcharrange={1}}× (|U+00D7|)}」等,ISO 8859-1領域
+TODO: 「{\ltjsetparameter{jcharrange={1}}× (|U+00D7|)}」等,ISO 8859-1領域
 にマッピングされた文字の扱い.
-「{\setjaparameter{jcharrange={1}}¢ (|U+00A2|)}」はHalfwidth and
+「{\ltjsetparameter{jcharrange={1}}¢ (|U+00A2|)}」はHalfwidth and
 Fullwidth Formsに全角形(\char"FFE0)があるから%"
 luaotfloadの置換処理に割り込めばよいが…….
 \enditem
@@ -162,8 +161,8 @@ luaotfloadの置換処理に割り込めばよいが…….
 
 日本語組版用の各種パラメタの調整には,次の命令を用いる.
 \begintt
-  \setjaparameter{<key>=<value>, ...}       % local に変更
-  \globalsetjaparameter{<key>=<value>, ...} % global に変更
+  \ltjsetparameter{<key>=<value>, ...}       % local に変更
+  \globalltjsetparameter{<key>=<value>, ...} % global に変更
 \endtt
 
 <key> に許される値は次の通りである.
@@ -256,11 +255,11 @@ $\lvert\hbox{<range_num>}\rvert$番の文字範囲の文字を和文扱いする
 
 日本語組版用の各種パラメタの取得には,次の命令を用いる.
 \begintt
-  \getjaparameter{<key>} or \getjaparameter{<key>}{<chr_code>}
+  \ltjgetparameter{<key>} or \ltjgetparameter{<key>}{<chr_code>}
 \endtt
 戻り値は全て「空白は|\catcode=10|,それ以外の文字は全て|\catcode=12|」の文字列である.
 
-<key>に指定できる値は,説明がない限りは|\setjaparameter|で指定できる<key>と同じで,次の通りである,
+<key>に指定できる値は,説明がない限りは|\ltjsetparameter|で指定できる<key>と同じで,次の通りである,
 
 \item |kanjiskip|, |xkanjiskip|, |yabaselineshift|, |ykbaselineshift|, |jcharwidowpenalty|%
 \par\noindent
@@ -313,9 +312,17 @@ p\TeX 用{\tt JFM}で言うところの「文字クラス」を定義する.
 \itemitem <class>は文字クラスを表す1以上$\hbox{\tt0x800}=2048$未満の整数.
 \itemitem <chars>には,<class>に属する「文字」達のUnicodeにおけるコード番号を
 リストの形|{...}|で記述する.
+\itemitem どの文字クラスにも属さなかった文字は,自動的に0番の文字クラスに属するとみなされる.
 
 また,このリストには,以下の「仮想的な文字」も指定可能である.
 \itemT |'lineend'|: 行末.
+この「文字」を0以外の文字クラスに設定することで,ぶら下げ組のような組版も可能になる.
+例えば,句点類の文字クラスが2のとき,
+\begintt
+  jfm.define_char_type(8,{'linebdd'}})
+  jfm.define_kern(2, 8, -0.5)
+\endtt
+と指定すればよい.
 \itemT |'boxbdd'|: 水平ボックスの先頭/末尾,段落の先頭/末尾.
 \itemT |'jcharbdd'|: 和文文字達の連続とそれ以外のもの(例えば欧文文字)との境界.
 \itemT |'diffmet'|: 異なるメトリックの和文文字間に入るglueの計算に使われる.
@@ -376,18 +383,32 @@ $p$は「現在の和文フォント」の番号もattribute |\luatexja@curjfnt|
 
 \item {\bf JFM由来glue/kernの挿入: |pre_linebreak_filter|, |hpack_filter|}
 
-ここで,メトリックに由来する和文文字間のglue/kernを挿入する.
-基本的には連続する和文文字間に挿入するが,
+ここで,JFMに由来する和文文字間のglue/kernを挿入する.
+基本的には連続する和文文字(を表すnode)間に挿入するが,
 \itemitem 水平ボックスの先頭/末尾,段落の先頭/末尾には「文字コード|'boxbdd'|の文字」があると
 見做して空白を挿入する.
 \itemitem 和文文字とそうでないもの(欧文文字,ボックス等)の間に関しては,
 和文文字でない方は「文字コード|'jcharbdd'|の文字」であると見做す.
 \itemitem フォントの異なる2つの和文文字においても,
-両者のフォントのmetric keyとsizeが一致した場合は,
+両者のフォントのJFMとsizeが一致した場合は,
 挿入処理においては「同じフォント」であるかのように扱う.
 \itemitem  そうでない場合は,両者の間に「文字コード|'diffmet'|の文字」があると見做して,
 両和文文字からそれぞれglue/kern |gb|, |ga|を計算し,そこから実際に入るglue/kernを
-計算している(|\setjaparameter|中の|differentjfm|キーを参照).
+計算している(|\ltjsetparameter|中の|differentjfm|キーを参照).
+\itemitem もうちょっと詳しく書くと,本処理前において,和文文字を表す
+2つの連続した|glyph_node| $Q$, $P$の間には,次のnode達が挿入される:
+$$
+ \ldots,\ Q,\ (\hbox{|\kern|}\ w\,{\rm pt}),\ (\hbox{|\penalty|}\ p),\ 
+(\hbox{|\kern|}\ (k-w)\,{\rm pt})
+,\ P,\ \ldots
+$$
+上に書いた全てのnodeが挿入されるとは限らず,また4つめのkernもglueに変わる可能性がある.
+上に出てきた量の意味は次の通りである:
+\itemT $w$: $Q$が行末にきたときに,行末からどれだけずらすかを指定した量.
+\itemT $p$: $Q$の行末禁則用penaltyと$P$の行頭禁則用penaltyの合計値.ウィドウ防止用の
+|\jcharwidowpenalty|が挿入される時は,値はここに加算される.
+\itemT |\kern| $k$: 本来の$Q$と$P$の間に入る空き(glueであることも).
+$w$のために自然長を補正している.
 
 \item {\bf |\kanjiskip|, |\xkanjiskip|の挿入: |pre_linebreak_filter|, |hpack_filter|}
 
index 6dca1a8..a2c43db 100644 (file)
@@ -1,20 +1,45 @@
 local node_type = node.type
+local node_new = node.new
+local node_prev = node.prev
+local node_next = node.next
 local has_attr = node.has_attribute
 local node_insert_before = node.insert_before
 local node_insert_after = node.insert_after
 local node_hpack = node.hpack
 local round = tex.round
-local node_new = node.new
+
 local id_penalty = node.id('penalty')
 local id_glyph = node.id('glyph')
 local id_glue_spec = node.id('glue_spec')
 local id_glue = node.id('glue')
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_rule = node.id('rule')
+local id_math = node.id('math')
 local id_whatsit = node.id('whatsit')
-local next_node = node.next
+
 local attr_jchar_class = luatexbase.attributes['luatexja@charclass']
 local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
 local attr_yablshift = luatexbase.attributes['luatexja@yablshift']
+local attr_ykblshift = luatexbase.attributes['luatexja@ykblshift']
 local attr_icflag = luatexbase.attributes['luatexja@icflag']
+-- attr_icflag: 1: kern from \/, 2: 'lineend' kern from JFM
+
+local lang_ja_token = token.create('luatexja@japanese')
+local lang_ja = lang_ja_token[2]
+
+-- 
+local rgjc_get_range_setting = ltj.int_get_range_setting 
+local rgjc_char_to_range     = ltj.int_char_to_range
+local rgjc_is_ucs_in_japanese_char = ltj.int_is_ucs_in_japanese_char
+local ljfm_find_char_class = ltj.int_find_char_class
+
+------------------------------------------------------------------------
+-- naming:
+--    ltj.ext_... : called from \directlua{}
+--    ltj.int_... : called from other Lua codes, but not from \directlua{}
+--    (other)     : only called from this file
 
 -- error messages
 function ltj.error(s,t)
@@ -70,63 +95,71 @@ local function is_japanese_glyph_node(p)
    and (p.font==has_attr(p,attr_curjfnt))
 end
 
----------- Stack table
----- ltj.stack_ch_table [stack_level] : 情報を格納したテーブル
-----   .auto_spacing, .auto_xspacing: \autospacing etc.
-----   [chr_code].pre, [chr_code].post, [chr_code].xsp
 
-ltj.stack_ch_table={}; ltj.stack_ch_table[0]={}
+------------------------------------------------------------------------
+-- CODE FOR STACK TABLE FOR CHARACTER PROPERTIES (prefix: cstb)
+------------------------------------------------------------------------
 
-local function get_stack_level()
-  local i = tex.getcount('ltj@stack@pbp')
-  if tex.currentgrouplevel > tex.getcount('ltj@group@level@pbp') then
+---- table: charprop_stack_table [stack_level][chr_code].{pre|post|xsp}
+local charprop_stack_table={}; charprop_stack_table[0]={}
+
+local function cstb_get_stack_level()
+  local i = tex.getcount('ltj@@stack')
+  if tex.currentgrouplevel > tex.getcount('ltj@@group@level') then
     i = i+1 -- new stack level
-    tex.setcount('ltj@group@level@pbp', tex.currentgrouplevel)
-    for j,v in pairs(ltj.stack_ch_table) do -- clear the stack above i
-      if j>=i then ltj.stack_ch_table[j]=nil end
+    tex.setcount('ltj@@group@level', tex.currentgrouplevel)
+    for j,v in pairs(charprop_stack_table) do -- clear the stack above i
+      if j>=i then charprop_stack_table[j]=nil end
     end
-    ltj.stack_ch_table[i] = table.fastcopy(ltj.stack_ch_table[i-1])
-    tex.setcount('ltj@stack@pbp', i)
+    charprop_stack_table[i] = table.fastcopy(charprop_stack_table[i-1])
+    tex.setcount('ltj@@stack', i)
   end
   return i
 end
-function ltj.set_ch_table(g,m,c,p,lb,ub)
-  local i = get_stack_level()
+
+-- EXT
+function ltj.ext_set_stack_table(g,m,c,p,lb,ub)
+  local i = cstb_get_stack_level()
   if p<lb or p>ub then 
      ltj.error('Invalid code (' .. p .. '), should in the range '
               .. tostring(lb) .. '..' .. tostring(ub) .. '.',
            {"I'm going to use 0 instead of that illegal code value."})
      p=0
-  elseif c<0 or c>0x10FFFF then
+  elseif c<-1 or c>0x10FFFF then
      ltj.error('Invalid character code (' .. p 
-              .. '), should in the range 0.."10FFFF.',{})
+              .. '), should in the range -1.."10FFFF.',{})
      return 
-  elseif not ltj.stack_ch_table[i][c] then 
-     ltj.stack_ch_table[i][c] = {} 
+  elseif not charprop_stack_table[i][c] then 
+     charprop_stack_table[i][c] = {} 
   end
-  ltj.stack_ch_table[i][c][m] = p
+  charprop_stack_table[i][c][m] = p
   if g=='global' then
-    for j,v in pairs(ltj.stack_ch_table) do 
-      if not ltj.stack_ch_table[j][c] then ltj.stack_ch_table[j][c] = {} end
-      ltj.stack_ch_table[j][c][m] = p
+    for j,v in pairs(charprop_stack_table) do 
+      if not charprop_stack_table[j][c] then charprop_stack_table[j][c] = {} end
+      charprop_stack_table[j][c][m] = p
     end
   end
 end
 
-local function get_penalty_table(m,c)
-  local i = ltj.stack_ch_table[tex.getcount('ltj@stack@pbp')][c]
+local function cstb_get_penalty_table(m,c)
+  local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
   if i then i=i[m] end
   return i or 0
 end
 
-local function get_inhibit_xsp_table(c)
-  local i = ltj.stack_ch_table[tex.getcount('ltj@stack@pbp')][c]
+local function cstb_get_inhibit_xsp_table(c)
+  local i = charprop_stack_table[tex.getcount('ltj@@stack')][c]
   if i then i=i.xsp end
   return i or 3
 end
+ltj.int_get_inhibit_xsp_table = cstb_get_inhibit_xsp_table
 
---------
-function ltj.out_ja_parameter_one(k)
+------------------------------------------------------------------------
+-- CODE FOR GETTING/SETTING PARAMETERS 
+------------------------------------------------------------------------
+
+-- EXT: print parameters that don't need arguments
+function ltj.ext_get_parameter_unary(k)
    if k == 'yabaselineshift' then
       tex.write(print_scaled(tex.getattribute('luatexja@yablshift'))..'pt')
    elseif k == 'ykbaselineshift' then
@@ -156,12 +189,11 @@ function ltj.out_ja_parameter_one(k)
    end
 end
 
-
-
-function ltj.out_ja_parameter_two(k,c)
+-- EXT: print parameters that need arguments
+function ltj.ext_get_parameter_binary(k,c)
    if k == 'jcharrange' then
       if c<0 or c>216 then c=0 end
-      tex.write(ltj.get_jcr_setting(c))
+      tex.write(rgjc_get_range_setting(c))
    else
       if c<0 or c>0x10FFFF then
         ltj.error('Invalid character code (' .. c 
@@ -170,33 +202,94 @@ function ltj.out_ja_parameter_two(k,c)
         c=0
       end
       if k == 'prebreakpenalty' then
-        tex.write(get_penalty_table('pre',c))
+        tex.write(cstb_get_penalty_table('pre',c))
       elseif k == 'postbreakpenalty' then
-        tex.write(get_penalty_table('post',c))
+        tex.write(cstb_get_penalty_table('post',c))
       elseif k == 'kcatcode' then
-        tex.write(get_penalty_table('kcat',c))
+        tex.write(cstb_get_penalty_table('kcat',c))
       elseif k == 'chartorange' then 
-        tex.write(ltj.get_char_jcrnumber(c))
+        tex.write(rgjc_char_to_range(c))
       elseif k == 'cjkxspmode' or k == 'asciixspmode' then
-        tex.write(get_inhibit_xsp_table(c))
+        tex.write(cstb_get_inhibit_xsp_table(c))
       end
    end
 end
 
-
---------- 
-function ltj.print_global()
+-- EXT: print \global if necessary
+function ltj.ext_print_global()
   if ltj.isglobal=='global' then tex.sprint('\\global') end
 end
 
-function ltj.create_ihb_node()
+
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 1: replace fonts (prefix: main1)
+------------------------------------------------------------------------
+
+--- the following function is modified from jafontspec.lua (by K. Maeda).
+--- Instead of "%", we use U+FFFFF for suppressing spaces.
+local function main1_process_input_buffer(buffer)
+   local c = utf.byte(buffer, utf.len(buffer))
+   local p = node_new(id_glyph)
+   p.char = c
+   if utf.len(buffer) > 0 
+   and rgjc_is_ucs_in_japanese_char(p) then
+       buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
+   end
+   return buffer
+end
+
+local function main1_suppress_hyphenate_ja(head)
+   local p
+   for p in node.traverse(head) do
+      if p.id == id_glyph then
+        if rgjc_is_ucs_in_japanese_char(p) then
+           local v = has_attr(p, attr_curjfnt)
+           if v then 
+              p.font = v 
+              node.set_attribute(p,attr_jchar_class,
+                 ljfm_find_char_class(p.char, ltj.font_metric_table[v].jfm))
+           end
+           v = has_attr(p, attr_ykblshift)
+           if v then 
+              node.set_attribute(p, attr_yablshift, v)
+           else
+              node.unset_attribute(p, attr_yablshift)
+           end
+           p.lang=lang_ja
+        end
+      end
+   end
+   lang.hyphenate(head)
+   return head -- 共通化のため値を返す
+end
+
+-- CALLBACKS
+luatexbase.add_to_callback('process_input_buffer', 
+   function (buffer)
+     return main1_process_input_buffer(buffer)
+   end,'ltj.process_input_buffer')
+luatexbase.add_to_callback('hpack_filter', 
+  function (head,groupcode,size,packtype)
+     return main1_suppress_hyphenate_ja(head)
+  end,'ltj.hpack_filter_pre',0)
+luatexbase.add_to_callback('hyphenate', 
+ function (head,tail)
+    return main1_suppress_hyphenate_ja(head)
+ end,'ltj.hyphenate')
+
+
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 2: insert glue/kerns from JFM (prefix: main2)
+------------------------------------------------------------------------
+
+-- EXT: for \inhibitglue
+function ltj.ext_create_inhibitglue_node()
    local g=node_new(id_whatsit, node.subtype('user_defined'))
-   g.user_id=30111; g.type=number; g.value=1
-   node.write(g)
+   g.user_id=30111; g.type=number; g.value=1; node.write(g)
 end
 
 
-local function find_size_metric(px)
+local function main2_find_size_metric(px)
    if is_japanese_glyph_node(px) then
       return ltj.font_metric_table[px.font].size, ltj.font_metric_table[px.font].jfm
    else 
@@ -204,94 +297,130 @@ local function find_size_metric(px)
    end
 end
 
-local function new_jfm_glue(size,mt,bc,ac)
+local function main2_new_jfm_glue(size,mt,bc,ac)
 -- mt: metric key, bc, ac: char classes
    local g=nil
-   local h
    local w=bc*0x800+ac
-   if ltj.metrics[mt].glue[w] then
-      h=node_new(id_glue_spec)
-      h.width  =round(size*ltj.metrics[mt].glue[w].width)
-      h.stretch=round(size*ltj.metrics[mt].glue[w].stretch)
-      h.shrink =round(size*ltj.metrics[mt].glue[w].shrink)
+   local z = ltj.metrics[mt]
+   if z.glue[w] then
+      local h = node_new(id_glue_spec)
+      h.width   = round(size*z.glue[w][0])
+      h.stretch = round(size*z.glue[w][1])
+      h.shrink  = round(size*z.glue[w][2])
       h.stretch_order=0; h.shrink_order=0
-      g=node_new(id_glue)
-      g.subtype=0; g.spec=h; return g
-   elseif ltj.metrics[mt].kern[w] then
-      g=node_new(node.id('kern'))
-      g.subtype=0; g.kern=round(size*ltj.metrics[mt].kern[w]); return g
-   else
-      return nil
+      g = node_new(id_glue)
+      g.subtype = 0; g.spec = h
+   elseif z.kern[w] then
+      g = node_new(id_kern)
+      g.subtype = 1; g.kern = round(size*z.kern[w])
    end
+   return g
 end
 
-
-function calc_between_two_jchar(q,p)
+-- return value: g (glue/kern from JFM), w (width of 'lineend' kern)
+local function main2_calc(qs,qm,q,p,last,ihb_flag)
    -- q, p: node (possibly null)
-   local ps,pm,qs,qm,g,h
-   if (not p) or (p.id==id_glue and p.subtype==15) then
+   local ps, pm, g, h
+   local w = 0
+   if (not p) or p==last then
       -- q is the last node
-      -- (p is nil or \parfillskip)
-      qs, qm = find_size_metric(q)
       if not qm then
-        return nil
-      else
-        g=new_jfm_glue(qs,qm,
+        return nil, 0
+      elseif not ihb_flag then 
+        g=main2_new_jfm_glue(qs,qm,
                            has_attr(q,attr_jchar_class),
-                               ltj.find_char_type('boxbdd',qm))
+                               ljfm_find_char_class('boxbdd',qm))
       end
-   elseif not q then
+   elseif qs==0 then
       -- p is the first node etc.
-      ps, pm = find_size_metric(p)
+      ps, pm = main2_find_size_metric(p)
       if not pm then
-        return nil
-      else
-        g=new_jfm_glue(ps,pm,
-                               ltj.find_char_type('boxbdd',pm),
+        return nil, 0
+      elseif not ihb_flag then 
+        g=main2_new_jfm_glue(ps,pm,
+                               ljfm_find_char_class('boxbdd',pm),
                                has_attr(p,attr_jchar_class))
       end
    else -- p and q are not nil
-      qs, qm = find_size_metric(q)
-      ps, pm = find_size_metric(p)
-      if (not pm) and (not qm) then 
-        -- Both p and q are NOT Japanese glyph node
-        return nil
+      ps, pm = main2_find_size_metric(p)
+      if ihb_flag or ((not pm) and (not qm)) then 
+        g = nil
       elseif (qs==ps) and (qm==pm) then 
-        -- Both p and q are Japanese glyph node, and same metric and size
-        g=new_jfm_glue(ps,pm,
-                           has_attr(q,attr_jchar_class),
-                           has_attr(p,attr_jchar_class))
+        -- Both p and q are Japanese glyph nodes, and same metric and size
+        g = main2_new_jfm_glue(ps,pm,
+                               has_attr(q,attr_jchar_class),
+                               has_attr(p,attr_jchar_class))
       elseif not qm then
-        -- q is not Japanese glyph node
-        g=new_jfm_glue(ps,pm,
-                           ltj.find_char_type('jcharbdd',pm),
-                           has_attr(p,attr_jchar_class))
+        -- q is not Japanese glyph node
+        g = main2_new_jfm_glue(ps,pm,
+                               ljfm_find_char_class('jcharbdd',pm),
+                               has_attr(p,attr_jchar_class))
       elseif not pm then
-        -- p is not Japanese glyph node
-        g=new_jfm_glue(qs,qm,
-                           has_attr(q,attr_jchar_class),
-                           ltj.find_char_type('jcharbdd',qm))
+        -- p is not Japanese glyph node
+        g = main2_new_jfm_glue(qs,qm,
+                               has_attr(q,attr_jchar_class),
+                               ljfm_find_char_class('jcharbdd',qm))
       else
-        g=new_jfm_glue(qs,qm,
-                           has_attr(q,attr_jchar_class),
-                           ltj.find_char_type('diffmet',qm))
-        h=new_jfm_glue(ps,pm,
-                           ltj.find_char_type('diffmet',pm),
-                           has_attr(p,attr_jchar_class))
-        g=ltj.calc_between_two_jchar_aux(g,h)
+        g = main2_new_jfm_glue(qs,qm,
+                               has_attr(q,attr_jchar_class),
+                               ljfm_find_char_class('diffmet',qm))
+        h = main2_new_jfm_glue(ps,pm,
+                               ljfm_find_char_class('diffmet',pm),
+                               has_attr(p,attr_jchar_class))
+        g = ltj.calc_between_two_jchar_aux(g,h)
       end
    end
-   if g then node.set_attribute(g,attr_icflag,2) end
-   return g
+   if g then node.set_attribute(g, attr_icflag, 3) end
+   if qm then
+      local x = ljfm_find_char_class('lineend', qm)
+      if x~=0  then
+        x = has_attr(q,attr_jchar_class)*0x800 + x
+        if ltj.metrics[qm].kern[x] then 
+           w = round(qs*ltj.metrics[qm].kern[x])
+        end
+      end
+   end
+
+   return g, w
 end
 
+local function main2_between_two_char(head,q,p,p_bp,ihb_flag,last)
+   local qs = 0; local g, w
+   local qm = nil
+   if q then
+      qs, qm = main2_find_size_metric(q)
+   end
+   g, w = main2_calc(qs, qm, q, p, last, ihb_flag)
+   if w~=0 and (not p_bp) then
+      p_bp = node_new(id_penalty); p_bp.penalty = 0
+      head = node_insert_before(head, p, p_bp)
+   end
+   if g then
+      if g.id==id_kern then 
+        g.kern = round(g.kern - w)
+      else
+        g.spec.width = round(g.spec.width - w)
+      end
+      head = node_insert_before(head, p, g)
+   elseif w~=0 then
+      g = node_new(id_kern); g.kern = -w; g.subtype = 1
+      node.set_attribute(g,attr_icflag,2)
+      head = node_insert_before(head, p, g)
+      -- this g might be replaced by \[x]kanjiskip in step 3.
+   end
+   if w~=0 then
+      g = node_new(id_kern); g.kern = w; g.subtype = 0
+      head = node_insert_before(head, p_bp, g)
+   end
+return head, p_bp
+end
 
--- In the beginning of a hbox created by line breaking, there are the followings:
---   o a hbox by \parindent
---   o a whatsit node which contains local paragraph materials.
+-- In the beginning of a hlist created by line breaking, there are the followings:
+--   - a hbox by \parindent
+--   - a whatsit node which contains local paragraph materials.
 -- When we insert jfm glues, we ignore these nodes.
-local function parindent_box(p)
-   if node_type(p.id)=='hlist' then 
+local function main2_is_parindent_box(p)
+   if p.id==id_hlist then 
       return (p.subtype==3)
       -- hlist (subtype=3) is a box by \parindent
    elseif p.id==id_whatsit then 
@@ -299,50 +428,49 @@ local function parindent_box(p)
    end
 end
 
-local function add_kinsoku_penalty(head,p)
+-- next three functions deal with inserting penalty by kinsoku.
+local function main2_add_penalty_before(head,p,p_bp,pen)
+   if p_bp then
+      p_bp.penalty = p_bp.penalty + pen
+   else -- we must create a new penalty node
+      local g = node_new(id_penalty); g.penalty = pen
+      local q = node_prev(p)
+      if q then
+        if has_attr(q, attr_icflag) ~= 3 then
+           q = p
+        end
+        return node_insert_before(head, q, g)
+      end
+   end
+   return head
+end
+
+local function main2_add_kinsoku_penalty(head,p,p_bp)
    local c = p.char
-   local e = get_penalty_table('pre',c)
+   local e = cstb_get_penalty_table('pre',c)
    if e~=0 then
-      local q = node.prev(p)
-      if q and q.id==id_penalty then
-        q.penalty=q.penalty+e
-      else 
-        q=node_new(id_penalty)
-        q.penalty=e
-        node_insert_before(head,p,q)
-      end
+      head = main2_add_penalty_before(head, p, p_bp, e)
    end
-   e = get_penalty_table('post',c)
+   e = cstb_get_penalty_table('post',c)
    if e~=0 then
-      local q = next_node(p)
+      local q = node_next(p)
       if q and q.id==id_penalty then
-        q.penalty=q.penalty+e
+        q.penalty = q.penalty + e
         return false
       else 
-        q=node_new(id_penalty)
-        q.penalty=e
+        q = node_new(id_penalty); q.penalty = e
         node_insert_after(head,p,q)
         return true
       end
    end
 end
 
-local function insert_widow_penalty(head,jq)
-   if not jq then 
-      return head 
-   end
-   local p = node.prev(jq)
-   local jwp=tex.getcount('jcharwidowpenalty')
-   if p and has_attr(p,attr_icflag)==2 then
-      jq=p -- the case where jq has the non-zero \prebreakpenalty.
-   end
-   if jq.id==id_penalty then
-      jq.penalty=jq.penalty + jwp
+local function main2_add_widow_penalty(head,widow_node,widow_bp)
+   if not widow_node then 
       return head
    else
-      local g = node.new(id_penalty)
-      g.penalty=jwp
-      return node_insert_before(head,jq,g)
+      return main2_add_penalty_before(head, widow_node,
+                 widow_bp, tex.getcount('jcharwidowpenalty'))
    end
 end
 
@@ -350,473 +478,180 @@ local depth=""
 
 -- Insert jfm glue: main routine
 -- mode = true iff insert_jfm_glue is called from pre_linebreak_filter
-local function insert_jfm_glue(head, mode)
+local function main2_insert_jfm_glue(head, mode)
    local p = head
+   local p_bp = nil -- p と直前の文字の間の penalty node
    local q = nil  -- the previous node of p
-   local jq = nil -- 最後の「句読点扱いでない」和文文字
+   local widow_node = nil -- 最後の「句読点扱いでない」和文文字
+   local widow_bp = nil -- \jcharwidowpenalty 挿入位置
+   local last -- the sentinel 
+   local ihb_flag = false -- is \inhibitglue specified?
    local g
-   local ihb_flag = false
-   local pn = nil
+   -- initialization
    if not p then return head 
    elseif mode then
-      while p and  parindent_box(p) do p=next_node(p) end
-      pn=node.tail(head)
-      if pn and pn.id==id_glue and pn.subtype==15 then
-        pn=node.prev(pn)
-        while (pn and pn.id==id_penalty) do pn=node.prev(pn) end
+      while p and main2_is_parindent_box(p) do p=node_next(p) end
+      last=node.tail(head)
+      if last and last.id==id_glue and last.subtype==15 then
+        last=node.prev(last)
+        while (last and last.id==id_penalty) do last=node.prev(last) end
       end
-      if pn then pn=next_node(pn) end
+      if last then last=node_next(last) end
+   else -- 番人を挿入
+      last=node.tail(head); g = node_new('kern')
+      node_insert_after(head,last,g); last = g
    end
-   while p~=pn do
+   -- main loop
+   while q~=last do
       if p.id==id_whatsit and p.subtype==node.subtype('user_defined')
          and p.user_id==30111 then
-        g=p; p=next_node(p); 
-        ihb_flag=true; head,p=node.remove(head, g)
+        g = p; p = node_next(p)
+        ihb_flag = true; head, p = node.remove(head, g)
       else
-        g=calc_between_two_jchar(q,p)
-        if g and (not ihb_flag) then
-           h = node_insert_before(head,p,g)
-           if not q then head=h end 
-           -- If p is the first node (=head), the skip is inserted
-           -- before head. So we must change head.
-        end
-        q=p; ihb_flag=false; 
+        head, p_bp = main2_between_two_char(head, q, p, p_bp, ihb_flag, last)
+        q=p; ihb_flag=false
         if is_japanese_glyph_node(p) then
-           if get_penalty_table('kcat',p.char)%2~=1 then
-              jq=p
+           if cstb_get_penalty_table('kcat',p.char)%2~=1 then
+              widow_node = p; widow_bp = p_bp
            end
-           if add_kinsoku_penalty(head,p) then
-              p=next_node(p)
+           if main2_add_kinsoku_penalty(head, p, p_bp) then
+              p_bp = node_next(p); p = p_bp
+           else p_bp = nil
            end
+        else p_bp = nil
         end
-        p=next_node(p)
+        p=node_next(p)
       end
    end
-   -- Insert skip after the last node
-   g=calc_between_two_jchar(q,nil)
-   if g then h = node_insert_after(head,q,g) end
-
    if mode then
       -- Insert \jcharwidowpenalty
-      head = insert_widow_penalty(head,jq)
-   end
-   return head
-end
-
-
-
--- Insert \xkanjiskip at the boundaries between Japanese characters 
--- and non-Japanese characters. 
--- We also insert \kanjiskip between Kanji in this function.
-local kanji_skip={}
-local xkanji_skip={}
-local cx = nil
-local no_skip=0
-local after_schar=1
-local after_wchar=2
-local insert_skip=no_skip
-
-
--- In the next two function, cx is the Kanji code.
-local function insert_akxsp(head,q)
-   if get_inhibit_xsp_table(cx)<=1 then return end
-   local g = node_new(id_glue)
-   g.subtype=0; g.spec=node.copy(xkanji_skip)
-   node_insert_after(head,q,g)
-end
-
-local function insert_kaxsp(head,q,p)
-   local g=true
-   local c=p.char
-   while p.components and p.subtype 
-      and math.floor(p.subtype/2)%2==1 do
-      p=p.components; c = p.char
-   end
-   if get_inhibit_xsp_table(c)%2 == 1 then
-      if get_inhibit_xsp_table(cx)%2==0 then g=false end
-   else 
-      g=false
-   end
-   if g then
-      g = node_new(id_glue)
-      g.subtype=0; g.spec=node.copy(xkanji_skip)
-      node_insert_after(head,q,g)
-   end
-end
-
-
-local function set_insert_skip_after_achar(p)
-   local c=p.char
-   while p.components and p.subtype 
-      and math.floor(p.subtype/2)%2==1 do
-      p=node.tail(p.components); c = p.char
-   end
-  if get_inhibit_xsp_table(c)>=2 then
-     insert_skip=after_schar
-  else
-     insert_skip=no_skip
-  end
-end
-
--- Insert \xkanjiskip before p, a glyph node
-local function insks_around_char(head,q,p)
-   if is_japanese_glyph_node(p) then
-      cx=p.char
-      if is_japanese_glyph_node(q)  then
-        local g = node_new(id_glue)
-        g.subtype=0; g.spec=node.copy(kanji_skip)
-        node_insert_before(head,p,g)
-      elseif insert_skip==after_schar then
-        insert_akxsp(head,q)
+      head = main2_add_widow_penalty(head, widow_node, widow_bp)
+      -- cleanup
+      p = node_prev(last)
+      if p and p.id==id_kern and has_attr(p,attr_icflag)==2 then
+        head = node.remove(head, p)
       end
-      insert_skip=after_wchar
    else
-      if insert_skip==after_wchar then
-        insert_kaxsp(head,q,p)
-      end
-      set_insert_skip_after_achar(p)
-   end
-end
-
--- Return first and last glyph nodes in a hbox
-local first_char = nil
-local last_char = nil
-local find_first_char = nil
-local function check_box(bp)
-   local p = bp; local  flag = false
-   while p do
-      local pt = node_type(p.id)
-      if pt=='glyph' then
-        repeat 
-           if find_first_char then
-              first_char=p; find_first_char=false
-           end
-           last_char=p; flag=true; p=next_node(p)
-           if not p then return flag end
-        until p.id~=id_glyph
-      end
-      if pt=='hlist' then
-        flag=true
-        if p.shift==0 then
-           if check_box(p.head) then flag=true end
-        else if find_first_char then 
-              find_first_char=false
-           else 
-              last_char=nil
-           end
-        end
-      elseif pt == 'ins' or pt == 'mark'
-         or pt == 'adjust' 
-         or pt == 'whatsit' or pt == 'penalty' then
-        p=p
-      else
-        flag=true
-        if find_first_char then 
-           find_first_char=false
-        else 
-           last_char=nil
-        end
-      end
-      p=next_node(p)
-   end
-   return flag
-end 
-
--- Insert \xkanjiskip around p, an hbox
-local function insks_around_hbox(head,q,p)
-   if p.shift==0 then
-      find_first_char=true; first_char=nil; last_char=nil
-      if check_box(p.head) then
-        -- first char
-        if is_japanese_glyph_node(first_char) then
-           cx=first_char.char
-           if insert_skip==after_schar then 
-              insert_akxsp(head,q)
-           elseif insert_skip==after_wchar then
-              local g = node_new(id_glue)
-              g.subtype=0; g.spec=node.copy(kanji_skip)
-              node_insert_before(head,p,g)
-           end
-           insert_skip=after_wchar
-        elseif first_char then
-           cx=first_char.char
-           if insert_skip==after_wchar then
-              insert_kaxsp(head,q,first_char)
-           end
-           set_insert_skip_after_achar(first_char)
-        end
-        -- last char
-        if is_japanese_glyph_node(last_char) then
-           if is_japanese_glyph_node(next_node(p)) then
-              local g = node_new(id_glue)
-              g.subtype=0; g.spec=node.copy(kanji_skip)
-              node_insert_after(head,p,g)
-           end
-           insert_skip=after_wchar
-        elseif last_char then
-           set_insert_skip_after_achar(last_char)
-        else insert_skip=no_skip
-        end
-      else insert_skip=no_skip
-      end
-   else insert_skip=no_skip
-   end
-end
-
--- Insert \xkanjiskip around p, a penalty
-local function insks_around_penalty(head,q,p)
-   local r=next_node(p)
-   if r  and r.id==id_glyph then
-      if is_japanese_glyph_node(r) then
-        cx=r.char
-        if is_japanese_glyph_node(q)  then
-           local g = node_new(id_glue)
-           g.subtype=0; g.spec=node.copy(kanji_skip)
-           node_insert_before(head,r,g)
-        elseif insert_skip==insert_schar then
-           insert_akxsp(head,p)
-        end
-        q=p; p=next_node(p)
-        insert_skip=after_wchar
-      else
-        if insert_skip==after_wchar then
-           insert_kaxsp(head,p,r)
-        end
-        set_insert_skip_after_achar(r)
-      end
-   end
-end
-
--- Insert \xkanjiskip around p, a kern
-local function insks_around_kern(head,q,p)
-   if p.subtype==1 then -- \kern or \/
-      if not has_attr(p,attr_icflag) then
-        insert_skip=no_skip
-      end
-   elseif p.subtype==2 then -- \accent: We ignore the accent character.
-      local v = next_node(next_node(next_node(p)))
-      if v and v.id==id_glyph then
-        insks_around_char(head,q,v)
-      end
-   end
-end
-
--- Insert \xkanjiskip around p, a math_node
-local function insks_around_math(head,q,p)
-   local g = { char = -1 }
-   if (p.subtype==0) and (insert_skip==after_wchar) then
-      insert_kaxsp(head,q,g)
-      insert_skip=no_skip
-   else
-      set_insert_skip_after_achar(g)
-   end
-end
-
-local function insert_kanji_skip(head)
-   if ltj.auto_spacing then
-      kanji_skip=tex.skip['kanjiskip']
-   else
-      kanji_skip=node_new(id_glue_spec)
-      kanji_skip.width=0;  kanji_skip.stretch=0; kanji_skip.shrink=0
-   end
-   if ltj.auto_xspacing then
-      xkanji_skip=tex.skip['xkanjiskip']
-   else
-      xkanji_skip=node_new(id_glue_spec)
-      xkanji_skip.width=0;  xkanji_skip.stretch=0; xkanji_skip.shrink=0
-   end
-   local p=head -- 「現在のnode」
-   local q=nil  -- pの一つ前 
-   insert_skip=no_skip
-   while p do
-      local pt = node_type(p.id)
-      if pt=='glyph' then
-        repeat 
-           insks_around_char(head,q,p)
-           q=p; p=next_node(p)
-        until (not p) or p.id~=id_glyph
-      else
-        if pt == 'hlist' then
-           insks_around_hbox(head,q,p)
-        elseif pt == 'penalty' then
-           insks_around_penalty(head,q,p)
-        elseif pt == 'kern' then
-           insks_around_kern(head,q,p)
-        elseif pt == 'math' then
-           insks_around_math(head,q,p)
-        elseif pt == 'ins' or pt == 'mark'
-            or pt == 'adjust'
-            or pt == 'whatsit' then
-           -- do nothing
-           p=p
-        else
-           -- rule, disc, glue, margin_kern
-           insert_skip=no_skip
-        end
-        q=p; p=next_node(p)
-      end
+      head = node.remove(head, last)
    end
    return head
 end
 
--- Shift baseline
-local function baselineshift(head)
-   local p=head
-   local m=false -- is in math mode?
-   while p do 
-      local v=has_attr(p,attr_yablshift)
-      if v then
-        local pt = node_type(p.id)
-        if pt=='glyph' then
-           p.yoffset=p.yoffset-v
-        elseif pt=='math' then
-           m=(p.subtype==0)
-        end
-        if m then -- boxes and rules are shifted only in math mode
-           if pt=='hlist' or pt=='vlist' then
-              p.shift=p.shift+v
-           elseif pt=='rule' then
-              p.height=p.height-v; p.depth=p.depth+v 
-           end
-        end
-      end
-      p=next_node(p)
-   end
-   return head
-end
 
-
---====== Adjust the width of Japanese glyphs
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 4: width of japanese chars (prefix: main4)
+------------------------------------------------------------------------
 
 -- TeX's \hss
-local function get_hss()
+local function main4_get_hss()
    local hss = node_new(id_glue)
-   local hss_spec = node_new(id_glue_spec)
-   hss_spec.width = 0
-   hss_spec.stretch = 65536
-   hss_spec.stretch_order = 2
-   hss_spec.shrink = 65536
-   hss_spec.shrink_order = 2
-   hss.spec = hss_spec
+   local fil_spec = node_new(id_glue_spec)
+   fil_spec.width = 0
+   fil_spec.stretch = 65536
+   fil_spec.stretch_order = 2
+   fil_spec.shrink = 65536
+   fil_spec.shrink_order = 2
+   hss.spec = fil_spec
    return hss
 end
 
-local function set_ja_width(head)
+local function main4_set_ja_width(head)
    local p = head
-   local t,s,th, g, q,a
+   local met_tb, t, s, g, th, q, a
+   local m = false -- is in math mode?
    while p do
-      if is_japanese_glyph_node(p) then
-        t=ltj.metrics[ltj.font_metric_table[p.font].jfm]
-        s=t.char_type[has_attr(p,attr_jchar_class)]
-        if not(s.left==0.0 and s.down==0.0 
-               and round(s.width*ltj.font_metric_table[p.font].size)==p.width) then
-           -- must be encapsuled by a \hbox
-           head, q = node.remove(head,p)
-           p.next=nil
-           p.yoffset=round(p.yoffset-ltj.font_metric_table[p.font].size*s.down)
-           p.xoffset=round(p.xoffset-ltj.font_metric_table[p.font].size*s.left)
-           node_insert_after(p,p,get_hss())
-           g=node_hpack(p, round(ltj.font_metric_table[p.font].size*s.width)
-                        , 'exactly')
-           g.height=round(ltj.font_metric_table[p.font].size*s.height)
-           g.depth=round(ltj.font_metric_table[p.font].size*s.depth)
-           head,p = node_insert_before(head,q,g)
-           p=q
-        else p=next_node(p)
+      local v=has_attr(p,attr_yablshift) or 0
+      if p.id==id_glyph then
+        p.yoffset = p.yoffset-v
+        if is_japanese_glyph_node(p) then
+           met_tb = ltj.font_metric_table[p.font]
+           t = ltj.metrics[met_tb.jfm]
+           s = t.char_type[has_attr(p,attr_jchar_class)]
+           if not(s.left==0.0 and s.down==0.0 
+                  and round(s.width*met_tb.size)==p.width) then
+              -- must be encapsuled by a \hbox
+              head, q = node.remove(head,p)
+              p.next=nil
+              p.yoffset=round(p.yoffset-met_tb.size*s.down)
+              p.xoffset=round(p.xoffset-met_tb.size*s.left)
+              node_insert_after(p, p, main4_get_hss())
+              g = node_hpack(p, round(met_tb.size*s.width), 'exactly')
+              g.height = round(met_tb.size*s.height)
+              g.depth = round(met_tb.size*s.depth)
+              head, p = node_insert_before(head, q, g)
+              p = q
+           else p=node_next(p)
+           end
+        else p=node_next(p)
         end
-      else p=next_node(p)
+      elseif p.id==id_math then
+        m=(p.subtype==0); p=node_next(p)
+      else
+        if m then
+           if p.id==id_hlist or p.id==id_vlist then
+              p.shift=p.shift+v
+           elseif p.id==id_rule then
+              p.height=p.height-v; p.depth=p.depth+v 
+           end
+        end
+        p=node_next(p)
       end
    end
-   return head
+return head
 end
 
 -- main process
 -- mode = true iff main_process is called from pre_linebreak_filter
 local function main_process(head, mode)
    local p = head
-   p = insert_jfm_glue(p,mode)
-   p = insert_kanji_skip(p)
-   p = baselineshift(p)
-   p = set_ja_width(p)
+   p = main2_insert_jfm_glue(p,mode)
+   p = ltj.int_insert_kanji_skip(p)
+   p = main4_set_ja_width(p)
    return p
 end
 
+
 -- debug
-function ltj.show_node_list(head)
-   local p =head; local k = depth
-   depth=depth .. '.'
+local debug_depth
+function ltj.ext_show_node_list(head,depth,print_fn)
+   debug_depth = depth
+   if head then
+      debug_show_node_list_X(head, print_fn)
+   else
+      print_fn(debug_depth .. ' (null list)')
+   end
+end
+function debug_show_node_list_X(p,print_fn)
+   debug_depth=debug_depth.. '.'
+   local k = debug_depth
    while p do
       local pt=node_type(p.id)
       if pt == 'glyph' then
-        print(depth .. ' glyph', p.subtype, utf.char(p.char), p.font)
+        print_fn(debug_depth.. ' glyph  ', p.subtype, utf.char(p.char), p.font)
       elseif pt=='hlist' then
-        print(depth .. ' hlist', p.subtype, '(' .. print_scaled(p.height)
+        print_fn(debug_depth.. ' hlist  ', p.subtype, '(' .. print_scaled(p.height)
            .. '+' .. print_scaled(p.depth)
         .. ')x' .. print_scaled(p.width) )
-        ltj.show_node_list(p.head)
-        depth=k
+        debug_show_node_list_X(p.head,print_fn)
+        debug_depth=k
       elseif pt == 'whatsit' then
-        print(depth .. ' whatsit', p.subtype)
+        print_fn(debug_depth.. ' whatsit', p.subtype)
       elseif pt == 'glue' then
-        print(depth .. ' glue', p.subtype, print_spec(p.spec))
+        print_fn(debug_depth.. ' glue   ', p.subtype, print_spec(p.spec))
+      elseif pt == 'kern' then
+        print_fn(debug_depth.. ' kern   ', p.subtype, print_scaled(p.kern) .. 'pt')
       elseif pt == 'penalty' then
-        print(depth .. ' penalty', p.penalty)
+        print_fn(debug_depth.. ' penalty', p.penalty)
       else
-        print(depth .. ' ' .. node.type(p.id), p.subtype)
+        print_fn(debug_depth.. ' ' .. node.type(p.id), p.subtype)
       end
-      p=next_node(p)
-   end
-end
-
-
-
---- the following function is modified from jafontspec.lua (by K. Maeda).
---- Instead of "%", we use U+FFFFF for suppressing spaces.
-local function process_input_buffer(buffer)
-   local c = utf.byte(buffer, utf.len(buffer))
-   local p = node.new(id_glyph)
-   p.char = c
-   if utf.len(buffer) > 0 
-   and ltj.is_ucs_in_japanese_char(p) then
-       buffer = buffer .. string.char(0xF3,0xBF,0xBF,0xBF) -- U+FFFFF
+      p=node_next(p)
    end
-   return buffer
 end
 
 
----------- Hyphenate
-local function suppress_hyphenate_ja(head)
-   local p
-   for p in node.traverse(head) do
-      if p.id == id_glyph then
-        local pc=p.char
-        if ltj.is_ucs_in_japanese_char(p) then
-           local v = has_attr(p,attr_curjfnt)
-           if v then 
-              p.font=v 
-              local l=ltj.find_char_type(pc,ltj.font_metric_table[v].jfm) or 0
-              node.set_attribute(p,attr_jchar_class,l)
-           end
-           v=has_attr(p,luatexbase.attributes['luatexja@ykblshift'])
-           if v then 
-              node.set_attribute(p,attr_yablshift,v)
-           else
-              node.unset_attribute(p,attr_yablshift)
-           end
-           p.lang=ltj.ja_lang_number
-        end
-      end
-   end
-   lang.hyphenate(head)
-   return head -- 共通化のため値を返す
-end
 
 -- callbacks
-luatexbase.add_to_callback('process_input_buffer', 
-   function (buffer)
-     return process_input_buffer(buffer)
-   end,'ltj.process_input_buffer')
-
 luatexbase.add_to_callback('pre_linebreak_filter', 
    function (head,groupcode)
      return main_process(head, true)
@@ -825,13 +660,3 @@ luatexbase.add_to_callback('hpack_filter',
   function (head,groupcode,size,packtype)
      return main_process(head, false)
   end,'ltj.hpack_filter',2)
-
---insert before callbacks from luaotfload
-luatexbase.add_to_callback('hpack_filter', 
-  function (head,groupcode,size,packtype)
-     return suppress_hyphenate_ja(head)
-  end,'ltj.hpack_filter_pre',0)
-luatexbase.add_to_callback('hyphenate', 
- function (head,tail)
-    return suppress_hyphenate_ja(head)
- end,'ltj.hyphenate')
index 1c1880a..83fd352 100644 (file)
   require('lualibs')
   ltj.loadlua('luatexja-rmlgbm.lua') 
     % For Ryumin-Light and GothicBBB-Medium.
-  ltj.loadlua('luatexja-core.lua')
   ltj.loadlua('luatexja-jfont.lua')
+  ltj.loadlua('luatexja-core.lua')
+  ltj.loadlua('luatexja-xkanji.lua')
   ltj.loadlua('luatexja-core-aux.lua')
-  ltj.ja_lang_number=\the\luatexja@japanese
 }
 
 
 \def\asluastring#1{'\luaescapestring{\detokenize{#1}}'}
 
 %%%%%%%% Redefine \/
-\let\luatexja@ic=\/ \protected\def\/{{\luatexja@icflag=1\luatexja@ic}}
+%\let\luatexja@ic=\/ \protected\def\/{{\luatexja@icflag=1\luatexja@ic}}
+\protected\def\/{\directlua{ltj.ext_append_italic()}}
 
 %%%%%%%% \jfont\CS={...:...;jfm=metric;...}, \gjfont
-\def\jfont{\afterassignment\@jfont\directlua{ltj.jfontdefX('false')}}
-\def\gjfont{\afterassignment\@jfont\directlua{ltj.jfontdefX('true')}}
-\def\@jfont{\directlua{ltj.jfontdefY()}}
+\def\jfont{\afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(false)}}
+\def\gjfont{\afterassignment\ltj@@jfont\directlua{ltj.ext_jfontdefX(true)}}
+\def\ltj@@jfont{\directlua{ltj.ext_jfontdefY()}}
 
 %%%%%%%% \inhibitglue
-\def\inhibitglue{\directlua{ltj.create_ihb_node()}}
+\def\inhibitglue{\directlua{ltj.ext_create_inhibitglue_node()}}
 
-%%%%%%%% \defcharrange<name>{100-200,3000-,5000,...}
-\def\defcharrange#1#2{%
-  \ltj@tempcntc=#1 \expandafter\ltj@dcrange#2,,\ignorespaces}
-\def\ltj@dcrange#1,{\def\ltj@temp{#1}%
+%%%%%%%% \ltjdefcharrange<name>{100-200,3000-,5000,...}
+\def\ltjdefcharrange#1#2{%
+  \luatexja@tempcntc=#1 \expandafter\ltj@@dcrange#2,,\ignorespaces}
+\def\ltj@@dcrange#1,{\def\ltj@temp{#1}%
   \ifx\ltj@temp\empty\let\@next=\relax\else
-  \ltj@@dcrange{#1}\let\@next=\ltj@dcrange\fi\@next}
-\def\ltj@@dcrange#1{\ltj@enexist#1--\@nil}
-\def\ltj@enexist#1-#2-#3\@nil{\def\ltj@temp{#3}%
+  \ltj@@dcrangeA{#1}\let\@next=\ltj@@dcrange\fi\@next}
+\def\ltj@@dcrangeA#1{\ltj@@dcrangeB#1--\@nil}
+\def\ltj@@dcrangeB#1-#2-#3\@nil{\def\ltj@temp{#3}%
   \ifx\ltj@temp\empty
     \luatexja@tempcnta=#1 \luatexja@tempcntb=\luatexja@tempcnta
   \else
     \def\ltj@temp{#2}%
     \ifx\ltj@temp\empty\luatexja@tempcntb="10FFFF \else\luatexja@tempcntb=#2 \fi%"
   \fi
-  \directlua{ltj.def_char_range(\the\luatexja@tempcnta,\the\luatexja@tempcntb,
+  \directlua{ltj.ext_add_char_range(\the\luatexja@tempcnta,\the\luatexja@tempcntb,
     \the\luatexja@tempcntc)}%
   }
 
-%%%%%%%% \setjaparameter
-\newcount\ltj@stack@pbp\newcount\ltj@group@level@pbp
-\ltj@group@level@pbp=0 \ltj@stack@pbp=0
+%%%%%%%% \ltjsetparameter
+\newcount\ltj@@stack \newcount\ltj@@group@level
+\ltj@@group@level=0 \ltj@@stack=0
 
 % prebreakpenalty = {<char_code>, <penalty>}
 \define@key[ltj]{japaram}{kcatcode}{%
-  \expandafter\luatexja@setbp#1:{kcat}{0}{0x7FFFFFFF}}
+  \expandafter\ltj@@set@stack#1:{kcat}{0}{0x7FFFFFFF}}
 \define@key[ltj]{japaram}{prebreakpenalty}{%
-  \expandafter\luatexja@setbp#1:{pre}{-10000}{10000}}
+  \expandafter\ltj@@set@stack#1:{pre}{-10000}{10000}}
 \define@key[ltj]{japaram}{postbreakpenalty}{%
-  \expandafter\luatexja@setbp#1:{post}{-10000}{10000}}
-\def\luatexja@setbp#1,#2:#3#4#5{
-  \luatexja@tempcnta=#1\relax
-  \luatexja@tempcntb=#2\relax
-  \directlua{ltj.set_ch_table(ltj.isglobal, \asluastring{#3},
-    tex.getcount('luatexja@tempcnta'),tex.getcount('luatexja@tempcntb'),#4,#5)}}
+  \expandafter\ltj@@set@stack#1:{post}{-10000}{10000}}
+\def\ltj@@set@stack#1,#2:#3#4#5{%
+  \luatexja@tempcnta=#1\relax \luatexja@tempcntb=#2\relax
+  \directlua{ltj.ext_set_stack_table(ltj.isglobal, \asluastring{#3},
+    \the\luatexja@tempcnta,tex.getcount('luatexja@tempcntb'),#4,#5)}}
 
 % yabaselineshift = <dimen>
 \define@key[ltj]{japaram}{yabaselineshift}{%
 % mode: inhibit, preonly, postonly, allow
 %    or       0        2         1      3
 \define@key[ltj]{japaram}{cjkxspmode}{%        \inhibitxspcode
-  \expandafter\luatexja@setjxspmode#1:\relax}
-\def\luatexja@setjxspmode#1,#2:{%
+  \expandafter\ltj@set@cjkxspmode#1:\relax}
+\def\ltj@set@cjkxspmode#1,#2:{%
   \lowercase{\edef\ltj@temp{#2}}%
   \def\ltj@tempa{inhibit}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{0}\fi
   \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
   \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
   \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
   \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
-  \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
-    tex.getcount('luatexja@tempcntb'),0,3)}}
+  \directlua{ltj.ext_set_stack_table(ltj.isglobal, 'xsp', \the\luatexja@tempcnta,
+    \the\luatexja@tempcntb,0,3)}}
 
 % asciixspmode = {<char_code>, <mode>}
 % mode: inhibit, preonly, postonly, allow
 %    or       0        1         2      3
 \define@key[ltj]{japaram}{asciixspmode}{%        \inhibitxspcode
-  \expandafter\luatexja@setaxspmode#1:\relax}
-\def\luatexja@setaxspmode#1,#2:{%
+  \expandafter\ltj@set@asciixspmode#1:\relax}
+\def\ltj@set@asciixspmode#1,#2:{%
   \lowercase{\edef\ltj@temp{#2}}%
   \def\ltj@tempa{inhibit}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{0}\fi
   \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
   \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
   \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
   \luatexja@tempcnta=#1\relax\luatexja@tempcntb=\ltj@temp\relax
-  \directlua{ltj.set_ch_table(ltj.isglobal, 'xsp', tex.getcount('luatexja@tempcnta'),
-    tex.getcount('luatexja@tempcntb'),0,3)}}
+  \directlua{ltj.ext_set_stack_table(ltj.isglobal, 'xsp', \the\luatexja@tempcnta,
+    \the\luatexja@tempcntb,0,3)}}
 
 % autospacing = <bool> (default: true)
 \define@boolkey[ltj]{japaram}{autospacing}[true]{%
   }
 
 \define@key[ltj]{japaram}{kanjiskip}{%              % SKIP
-  \directlua{ltj.print_global()}\kanjiskip=#1 }
+  \directlua{ltj.ext_print_global()}\kanjiskip=#1 }
 \define@key[ltj]{japaram}{xkanjiskip}{%             % SKIP
-  \directlua{ltj.print_global()}\xkanjiskip=#1 }
+  \directlua{ltj.ext_print_global()}\xkanjiskip=#1 }
 \define@key[ltj]{japaram}{jcharwidowpenalty}{%      %COUNT
-  \directlua{ltj.print_global()}\jcharwidowpenalty=#1 }
+  \directlua{ltj.ext_print_global()}\jcharwidowpenalty=#1 }
 
 % differentjfm = { large | small | average | both }
-\define@choicekey*+[ltj]{japaram}{differentjfm}[\ltj@temp\ltj@result]%
+\define@choicekey*+[ltj]{japaram}{differentjfm}[\ltj@temp\ltj@tempr]%
   {large,small,average,both}{%
-  \ifcase\ltj@result
+  \ifcase\ltj@tempr
     \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_large}\or
     \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_small}\or
     \directlua{ltj.calc_between_two_jchar_aux=ltj.calc_between_two_jchar_aux_average}\or
 
 
 % jcharrange = { +-<range_number> }
-\define@key[ltj]{japaram}{jcharrange}{\expandafter\@setjcharrange#1,,}
-\def\@setjcharrange#1,{%
+\define@key[ltj]{japaram}{jcharrange}{\expandafter\ltj@@scrange#1,,}
+\def\ltj@@scrange#1,{%
   \edef\ltj@temp{#1}%
-  \ifx\ltj@temp\empty\let\next=\relax\else\let\next=\@setjcharrange
-    \luatexja@tempcnta=#1 \directlua{ltj.set_jchar_range(%
-      ltj.is_global,tex.getcount('luatexja@tempcnta'))}%
+  \ifx\ltj@temp\empty\let\next=\relax\else\let\next=\ltj@@scrange
+    \luatexja@tempcnta=#1 \directlua{ltj.ext_toggle_char_range(%
+      ltj.is_global,\the\luatexja@tempcnta)}%
   \fi\next
 }
 
 
 
 
-\def\setjaparameter#1{\directlua{ltj.isglobal=''}%
+\def\ltjsetparameter#1{\directlua{ltj.isglobal=''}%
   \setkeys[ltj]{japaram}{#1}\ignorespaces}
-\def\globalsetjaparameter#1{\directlua{ltj.isglobal='global'}%
+\def\globalltjsetparameter#1{\directlua{ltj.isglobal='global'}%
   \setkeys[ltj]{japaram}{#1}\ignorespaces}
 
 %%%%%%%% 
-\def\getjaparameter#1{%
-  \lowercase{\edef\ltj@temp{#1}}\let\@next=\getjaparameter@one%
-  \def\ltj@tempa{prebreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{postbreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{cjkxspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{asciixspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{kcatcode}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{jcharrange}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
-  \def\ltj@tempa{chartorange}\ifx\ltj@temp\ltj@tempa\let\@next=\getjaparameter@two\fi
+\def\ltjgetparameter#1{%
+  \lowercase{\edef\ltj@temp{#1}}\let\@next=\ltj@@getparam@one%
+  \def\ltj@tempa{prebreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{postbreakpenalty}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{cjkxspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{asciixspmode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{kcatcode}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{jcharrange}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
+  \def\ltj@tempa{chartorange}\ifx\ltj@temp\ltj@tempa\let\@next=\ltj@@getparam@two\fi
   \@next
 }
-\def\getjaparameter@one{\directlua{ltj.out_ja_parameter_one('\ltj@temp')}}
-\def\getjaparameter@two#1{%
+\def\ltj@@getparam@one{\directlua{ltj.ext_get_parameter_unary('\ltj@temp')}}
+\def\ltj@@getparam@two#1{%
   \luatexja@tempcnta=#1
-  \directlua{ltj.out_ja_parameter_two('\ltj@temp', tex.getcount('luatexja@tempcnta'))}
+  \directlua{ltj.ext_get_parameter_binary('\ltj@temp', \the\luatexja@tempcnta)}
 }
 
 
 
-%%%%%%%% commands for ``compatibility''
-% \def\setinhibitxspcode#1#2{\setjaparameter{cjkxspmode={#1,#2}}}
-% \def\setxspcode#1#2{\setjaparameter{asciixspmode={#1,#2}}}
-% \def\setprebreakpenalty#1#2{\setjaparameter{prebreakpenalty={#1,#2}}}
-% \def\setpostbreakpenalty#1#2{\setjaparameter{prebreakpenalty={#1,#2}}}
-% \def\getprebreakpenalty#1{\directlua{ltj.get_penalty_table('pre',#1)}\luatexja@tempcnta}
-% \def\getpostbreakpenalty#1{\directlua{ltj.get_penalty_table('post',#1)}\luatexja@tempcnta}
-% \def\autospacing{\luatexja@autospc=0 }
-% \def\noautospacing{\luatexja@autospc=1 }
-% \def\autoxspacing{\luatexja@autoxspc=0 }
-% \def\noautoxspacing{\luatexja@autoxspc=1 }
-
 \def\ltj@temp{plain}
 \ifx\fmtname\ltj@temp
   \message{plain format: loading luatexja-plain.tex}
index def49ac..8f1fb33 100644 (file)
@@ -1,12 +1,37 @@
+local node_new = node.new
 local has_attr = node.has_attribute
-local jfmfname
+local floor = math.floor
+local round = tex.round
 
---====== METRIC
-jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}
+local attr_icflag = luatexbase.attributes['luatexja@icflag']
+local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
+local id_glyph = node.id('glyph')
+local id_kern = node.id('kern')
+
+------------------------------------------------------------------------
+-- LOADING JFM (prefix: ljfm)
+------------------------------------------------------------------------
+
+ltj.metrics={} -- this table stores all metric informations
+ltj.font_metric_table={} -- [font number] -> jfm_name, jfm_var, size
+
+jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {}
+
+local ljfm_jfm_cons
+local jfm_file_name, jfm_var
 
 function jfm.define_char_type(t,lt) 
    if not jfm.char_type[t] then jfm.char_type[t]={} end
    jfm.char_type[t].chars=lt 
+   for i,v in pairs(lt) do
+      if v == 'linebdd' then
+        if #lt ~= 1 then ljfm_jfm_cons = false; return end
+      elseif not jfm.chars[v] then 
+        jfm.chars[v] = t 
+      else 
+        ljfm_jfm_cons = false ; return
+      end
+   end
 end
 function jfm.define_type_dim(t,l,x,w,h,d,i)
    if not jfm.char_type[t] then jfm.char_type[t]={} end
@@ -17,184 +42,158 @@ end
 function jfm.define_glue(b,a,w,st,sh)
    local j=b*0x800+a
    if not jfm.glue[j] then jfm.glue[j]={} end
-   jfm.glue[j].width=w; jfm.glue[j].stretch=st; 
-   jfm.glue[j].shrink=sh
+   jfm.glue[j][0]=w; jfm.glue[j][1]=st; 
+   jfm.glue[j][2]=sh
 end
 function jfm.define_kern(b,a,w)
    local j=b*0x800+a
    if not jfm.kern[j] then jfm.kern[j]=w end
 end
 
--- procedures for \loadjfontmetric
-ltj.metrics={} -- this table stores all metric informations
-ltj.font_metric_table={}
-
-local function search_metric(key)
-   for i,v in ipairs(ltj.metrics) do 
-      if v.name==key then return i end
-   end
-   return nil
-end
-
 -- return nil iff ltj.metrics[ind] is a bad metric
-local function consistency_check(ind)
+local function ljfm_consistency_check(ind)
    local t = ltj.metrics[ind]
-   local r = ind
+   local r = nil
+   if ljfm_jfm_cons then r = ind end
    if t.dir~='yoko' then -- TODO: tate?
       r=nil
    elseif type(t.zw)~='number' or type(t.zh)~='number' then 
       r=nil -- .zw, .zh must be present
-   else
-      local lbt = ltj.find_char_type('lindend',ind)
-      if lbt~=0 and t.char_type[lbt].chars~={'linebdd'} then
-        r=nil -- 'linebdd' must be isolated char_type
-      end
    end
    if not r then ltj.metrics[ind] = nil end
    return r
 end
 
-function ltj.load_jfont_metric()
-   if jfmfname=='' then 
+local function ljfm_find_char_class(c,m)
+-- c: character code, m
+   if not ltj.metrics[m] then return 0 end
+   return ltj.metrics[m].chars[c] or 0
+end
+ltj.int_find_char_class = ljfm_find_char_class
+
+local function ljfm_load_jfont_metric()
+   if jfm_file_name=='' then 
       ltj.error('no JFM specified', 
                {[1]='To load and define a Japanese font, the name of JFM must be specified.',
                 [2]="The JFM 'ujis' will be  used for now."})
-      jfmfname='ujis'
+      jfm_file_name='ujis'
+   end
+   local name=jfm_file_name .. ':' .. jfm_var
+   local i = nil
+   for j,v in ipairs(ltj.metrics) do 
+      if v.name==name then i=j; break end
    end
-   jfm.name=jfmfname .. ':' .. ltj.jfmvar
-   local i = search_metric(jfm.name)
    local t = {}
    if i then  return i end
-   jfm.char_type={}; jfm.glue={}; jfm.kern={}
-   ltj.loadlua('jfm-' .. jfmfname .. '.lua')
-   t.name=jfm.name
+   jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {}
+   ljfm_jfm_cons = true
+   ltj.loadlua('jfm-' .. jfm_file_name .. '.lua')
+   t.name=name
    t.dir=jfm.dir; t.zw=jfm.zw; t.zh=jfm.zh
-   t.char_type=jfm.char_type
+   t.char_type=jfm.char_type; t.chars=jfm.chars
    t.glue=jfm.glue; t.kern=jfm.kern
    table.insert(ltj.metrics,t)
-   return consistency_check(#ltj.metrics)
+   return ljfm_consistency_check(#ltj.metrics)
 end
 
-function ltj.find_char_type(c,m)
--- c: character code, m
-   if not ltj.metrics[m] then return 0 end
-   for i, v in pairs(ltj.metrics[m].char_type) do
-      if i~=0 then
-        for j,w in pairs(v.chars) do
-           if w==c then return i end
-        end
-      end
-   end
-   return 0
-end
 
+------------------------------------------------------------------------
+-- LOADING JAPANESE FONTS (prefix: ljft)
+------------------------------------------------------------------------
+local cstemp
 
---====== \setjfont\CS={...:...;jfm=metric;...}
-
-function ltj.jfontdefX(g)
+-- EXT
+function ltj.ext_jfontdefX(g)
   local t = token.get_next()
-  ltj.cstemp=token.csname_name(t)
+  cstemp=token.csname_name(t)
   if g then ltj.is_global = '\\global' else ltj.is_global = '' end
-  tex.sprint('\\expandafter\\font\\csname ' .. ltj.cstemp .. '\\endcsname')
+  tex.sprint('\\expandafter\\font\\csname ' .. cstemp .. '\\endcsname')
 end
 
-function ltj.jfontdefY() -- for horizontal font
-   local j=ltj.load_jfont_metric()
-   local fn=font.id(ltj.cstemp)
+-- EXT
+function ltj.ext_jfontdefY() -- for horizontal font
+   local j = ljfm_load_jfont_metric()
+   local fn = font.id(cstemp)
    local f = font.fonts[fn]
    if not j then 
-     ltj.error("bad JFM '" .. jfmfname .. "'",
+     ltj.error("bad JFM '" .. jfm_file_name .. "'",
                {[1]='The JFM file you specified is not valid JFM file.',
                 [2]='Defining Japanese font is cancelled.'})
      tex.sprint(ltj.is_global .. '\\expandafter\\let\\csname '
-               .. ltj.cstemp .. '\\endcsname=\\relax')
+               .. cstemp .. '\\endcsname=\\relax')
      return 
    end
    ltj.font_metric_table[fn]={}
    ltj.font_metric_table[fn].jfm=j; ltj.font_metric_table[fn].size=f.size
    tex.sprint(ltj.is_global .. '\\protected\\expandafter\\def\\csname '
-              .. ltj.cstemp .. '\\endcsname'
+              .. cstemp .. '\\endcsname'
               .. '{\\csname luatexja@curjfnt\\endcsname=' .. fn
               .. ' \\zw=' .. tex.round(f.size*ltj.metrics[j].zw) .. 'sp'
               .. '\\zh=' .. tex.round(f.size*ltj.metrics[j].zh) .. 'sp\\relax}')
 end
 
-local dr_orig = fonts.define.read
-function fonts.define.read(name, size, id)
-   ltj.extract_metric(name)
-   -- In the present imple., we don't remove "jfm=..." from name.
-   local fontdata = dr_orig(name, size, id)
-   return fontdata
-end
-
--- extract jfmfname and ltj.jfmvar
-function ltj.extract_metric(name)
+-- extract jfm_file_name and jfm_var
+local function ljft_extract_metric(name)
    local basename=name
    local tmp = utf.sub(basename, 1, 5)
-   jfmfname = ''
-   ltj.jfmvar = ''
+   jfm_file_name = ''; jfm_var = ''
    if tmp == 'file:' or tmp == 'name:' or tmp == 'psft:' then
       basename = utf.sub(basename, 6)
    end
-
    local p = utf.find(basename, ":")
    if p then 
       basename = utf.sub(basename, p+1)
    else return 
    end
-
+   -- now basename contains 'features' only.
    p=1
    while p do
-      local q= utf.find(basename, ";",p+1) or utf.len(basename)+1
-      if utf.sub(basename,p,p+3)=='jfm=' and q>p+4 then
-        jfmfname = utf.sub(basename,p+4,q-1)
-      elseif utf.sub(basename,p,p+6)=='jfmvar=' and q>p+6 then
-        ltj.jfmvar = utf.sub(basename,p+7,q-1)
+      local q = utf.find(basename, ";", p+1) or utf.len(basename)+1
+      if utf.sub(basename, p, p+3)=='jfm=' and q>p+4 then
+        jfm_file_name = utf.sub(basename, p+4, q-1)
+      elseif utf.sub(basename, p, p+6)=='jfmvar=' and q>p+6 then
+        jfm_var = utf.sub(basename, p+7, q-1)
       end
-      if utf.len(basename)+1==q then p=nil else p=q+1 end
+      if utf.len(basename)+1==q then p = nil else p = q + 1 end
    end
    return
 end
 
+-- replace fonts.define.read()
+local ljft_dr_orig = fonts.define.read
+function fonts.define.read(name, size, id)
+   ljft_extract_metric(name)
+   -- In the present imple., we don't remove "jfm=..." from name.
+   return ljft_dr_orig(name, size, id)
+end
 
---====== Range of Japanese characters.
+------------------------------------------------------------------------
+-- MANAGING THE RANGE OF JAPANESE CHARACTERS (prefix: rgjc)
+------------------------------------------------------------------------
 -- jcr_table_main[chr_code] = index
 -- index : internal 0, 1, 2, ..., 216               0: 'other'
 --         external    1  2       216, (out of range): 'other'
 
--- init: 
-local ucs_out = 0x110000
+-- initialize 
 local jcr_table_main = {}
-local jcr_cjk = 0
-local jcr_noncjk = 1
+local jcr_cjk = 0; local jcr_noncjk = 1; local ucs_out = 0x110000
 
-for i=0x80,0xFF do
-   jcr_table_main[i]=1
-end
-for i=0x100,ucs_out-1 do
-   jcr_table_main[i]=0
-end
+for i=0x80 ,0xFF      do jcr_table_main[i]=1 end
+for i=0x100,ucs_out-1 do jcr_table_main[i]=0 end
 
-function ltj.def_char_range(b,e,ind) -- ind: external range number
+-- EXT: add characters to a range
+function ltj.ext_add_char_range(b,e,ind) -- ind: external range number
    if ind<0 or ind>216 then 
-      ltj.error('Invalid range number (' .. ind .. '), should be in the range 1..216.',
-               {}); return
+      ltj.error('Invalid range number (' .. ind ..
+               '), should be in the range 1..216.',
+            {}); return
    end
    for i=math.max(0x80,b),math.min(ucs_out-1,e) do
       jcr_table_main[i]=ind
    end
 end
 
-local function get_char_jcrcode(p) -- for internal use
-   local i
-   local c = p.char
-   if c<0x80 then return jcr_noncjk else i=jcr_table_main[c] end
-   return math.floor(has_attr(p,
-         luatexbase.attributes['luatexja@kcat'..math.floor(i/31)])
-         /math.pow(2, i%31))%2
-end
-
-function ltj.get_char_jcrnumber(c) -- return the (external) range number
+local function rgjc_char_to_range(c) -- return the (external) range number
    if c<0x80 or c>=ucs_out then return -1
    else 
       local i = jcr_table_main[c] or 0
@@ -202,25 +201,61 @@ function ltj.get_char_jcrnumber(c) -- return the (external) range number
    end
 end
 
-function ltj.get_jcr_setting(i) -- i: internal range number
-   return math.floor(tex.getattribute(luatexbase.attributes['luatexja@kcat'..math.floor(i/31)])
-         /math.pow(2, i%31))%2
+local function rgjc_get_range_setting(i) -- i: internal range number
+   return floor(tex.getattribute(
+                       luatexbase.attributes['luatexja@kcat'..floor(i/31)])
+                    /math.pow(2, i%31))%2
 end
+ltj.int_get_range_setting = rgjc_get_range_setting
+ltj.int_char_to_range = rgjc_char_to_range
 
---  和文文字と認識する unicode の範囲
-function ltj.is_ucs_in_japanese_char(p)
-   return (get_char_jcrcode(p)~=jcr_noncjk) 
+--  glyph_node p は和文文字か?
+local function rgjc_is_ucs_in_japanese_char(p)
+   local c = p.char
+   if c<0x80 then return false 
+   else 
+      local i=jcr_table_main[c] 
+      return (floor(
+                has_attr(p, luatexbase.attributes['luatexja@kcat'..floor(i/31)])
+                /math.pow(2, i%31))%2 ~= jcr_noncjk) 
+   end
 end
+ltj.int_is_ucs_in_japanese_char = rgjc_is_ucs_in_japanese_char
 
-function ltj.set_jchar_range(g, i) -- i: external range number
+-- EXT
+function ltj.ext_toggle_char_range(g, i) -- i: external range number
    if i==0 then return 
    else
       local kc
       if i>0 then kc=0 else kc=1; i=-i end
       if i>216 then i=0 end
-      local attr = luatexbase.attributes['luatexja@kcat'..math.floor(i/31)]
+      local attr = luatexbase.attributes['luatexja@kcat'..floor(i/31)]
       local a = tex.getattribute(attr)
       local k = math.pow(2, i%31)
-      tex.setattribute(g,attr,(math.floor(a/k/2)*2+kc)*k+a%k)
+      tex.setattribute(g,attr,(floor(a/k/2)*2+kc)*k+a%k)
+   end
+end
+
+------------------------------------------------------------------------
+-- MISC
+------------------------------------------------------------------------
+
+-- EXT: italic correction
+function ltj.ext_append_italic()
+   local p = tex.nest[tex.nest.ptr].tail
+   if p and p.id==id_glyph then
+      local f = p.font
+      local g = node_new(id_kern)
+      g.subtype = 1; node.set_attribute(g, attr_icflag, 1)
+      if rgjc_is_ucs_in_japanese_char(p) then
+        f = has_attr(p, attr_curjfnt)
+        print(f, p.char)
+        local j = ltj.font_metric_table[f]
+        local c = ljfm_find_char_class(p.char, j.jfm)
+        g.kern = round(j.size * ltj.metrics[j.jfm].char_type[c].italic)
+      else
+        g.kern = font.fonts[f].characters[p.char].italic
+      end
+      node.write(g)
    end
 end
\ No newline at end of file
index c26c0e6..c766e52 100644 (file)
 %      行頭、行末禁則パラメータ
 %
 % 1byte characters
-\setjaparameter{prebreakpenalty={`!,10000}}
-\setjaparameter{prebreakpenalty={`",10000}}
-\setjaparameter{postbreakpenalty={`\#,500}}
-\setjaparameter{postbreakpenalty={`\$,500}}
-\setjaparameter{postbreakpenalty={`\%,500}}
-\setjaparameter{postbreakpenalty={`\&,500}}
-\setjaparameter{postbreakpenalty={`\`,10000}}
-\setjaparameter{prebreakpenalty={`',10000}}
-\setjaparameter{prebreakpenalty={`),10000}}
-\setjaparameter{postbreakpenalty={`(,10000}}
-\setjaparameter{prebreakpenalty={`*,500}}
-\setjaparameter{prebreakpenalty={`+,500}}
-\setjaparameter{prebreakpenalty={`-,10000}}
-\setjaparameter{prebreakpenalty={`.,10000}}
-\setjaparameter{prebreakpenalty={47,10000}}
-\setjaparameter{prebreakpenalty={`/,500}}
-\setjaparameter{prebreakpenalty={`;,10000}}
-\setjaparameter{prebreakpenalty={`?,10000}}
-\setjaparameter{prebreakpenalty={`:,10000}}
-\setjaparameter{prebreakpenalty={`],10000}}
-\setjaparameter{postbreakpenalty={`[,10000}}
+\ltjsetparameter{prebreakpenalty={`!,10000}}
+\ltjsetparameter{prebreakpenalty={`",10000}}
+\ltjsetparameter{postbreakpenalty={`\#,500}}
+\ltjsetparameter{postbreakpenalty={`\$,500}}
+\ltjsetparameter{postbreakpenalty={`\%,500}}
+\ltjsetparameter{postbreakpenalty={`\&,500}}
+\ltjsetparameter{postbreakpenalty={`\`,10000}}
+\ltjsetparameter{prebreakpenalty={`',10000}}
+\ltjsetparameter{prebreakpenalty={`),10000}}
+\ltjsetparameter{postbreakpenalty={`(,10000}}
+\ltjsetparameter{prebreakpenalty={`*,500}}
+\ltjsetparameter{prebreakpenalty={`+,500}}
+\ltjsetparameter{prebreakpenalty={`-,10000}}
+\ltjsetparameter{prebreakpenalty={`.,10000}}
+\ltjsetparameter{prebreakpenalty={47,10000}}
+\ltjsetparameter{prebreakpenalty={`/,500}}
+\ltjsetparameter{prebreakpenalty={`;,10000}}
+\ltjsetparameter{prebreakpenalty={`?,10000}}
+\ltjsetparameter{prebreakpenalty={`:,10000}}
+\ltjsetparameter{prebreakpenalty={`],10000}}
+\ltjsetparameter{postbreakpenalty={`[,10000}}
 %全角文字
-\setjaparameter{prebreakpenalty={`、,10000}}
-\setjaparameter{prebreakpenalty={`。,10000}}
-\setjaparameter{prebreakpenalty={`,,10000}}
-\setjaparameter{prebreakpenalty={`.,10000}}
-\setjaparameter{prebreakpenalty={`・,10000}}
-\setjaparameter{prebreakpenalty={`:,10000}}
-\setjaparameter{prebreakpenalty={`;,10000}}
-\setjaparameter{prebreakpenalty={`?,10000}}
-\setjaparameter{prebreakpenalty={`!,10000}}
-\setjaparameter{prebreakpenalty={`゛,10000}}%\jis"212B
-\setjaparameter{prebreakpenalty={`゜,10000}}%\jis"212C
-\setjaparameter{prebreakpenalty={`´,10000}}%\jis"212D
-\setjaparameter{postbreakpenalty={``,10000}}%\jis"212E
-\setjaparameter{prebreakpenalty={`々,10000}}%\jis"2139
-\setjaparameter{prebreakpenalty={`…,250}}%\jis"2144
-\setjaparameter{prebreakpenalty={`‥,250}}%\jis"2145
-\setjaparameter{postbreakpenalty={`‘,10000}}%\jis"2146
-\setjaparameter{prebreakpenalty={`’,10000}}%\jis"2147
-\setjaparameter{postbreakpenalty={`“,10000}}%\jis"2148
-\setjaparameter{prebreakpenalty={`”,10000}}%\jis"2149
-\setjaparameter{prebreakpenalty={`),10000}}
-\setjaparameter{postbreakpenalty={`(,10000}}
-\setjaparameter{prebreakpenalty={`},10000}}
-\setjaparameter{postbreakpenalty={`{,10000}}
-\setjaparameter{prebreakpenalty={`],10000}}
-\setjaparameter{postbreakpenalty={`[,10000}}
-%\setjaparameter{postbreakpenalty={`‘,10000}}
-%\setjaparameter{prebreakpenalty={`’,10000}}
-\setjaparameter{postbreakpenalty={`〔,10000}}%\jis"214C
-\setjaparameter{prebreakpenalty={`〕,10000}}%\jis"214D
-\setjaparameter{postbreakpenalty={`〈,10000}}%\jis"2152
-\setjaparameter{prebreakpenalty={`〉,10000}}%\jis"2153
-\setjaparameter{postbreakpenalty={`《,10000}}%\jis"2154
-\setjaparameter{prebreakpenalty={`》,10000}}%\jis"2155
-\setjaparameter{postbreakpenalty={`「,10000}}%\jis"2156
-\setjaparameter{prebreakpenalty={`」,10000}}%\jis"2157
-\setjaparameter{postbreakpenalty={`『,10000}}%\jis"2158
-\setjaparameter{prebreakpenalty={`』,10000}}%\jis"2159
-\setjaparameter{postbreakpenalty={`【,10000}}%\jis"215A
-\setjaparameter{prebreakpenalty={`】,10000}}%\jis"215B
-\setjaparameter{prebreakpenalty={`ー,10000}}
-\setjaparameter{prebreakpenalty={`+,200}}
-\setjaparameter{prebreakpenalty={`−,200}}% U+2212 MINUS SIGN
-\setjaparameter{prebreakpenalty={`-,200}}% U+FF0D FULLWIDTH HYPHEN-MINUS 
-\setjaparameter{prebreakpenalty={`=,200}}
-\setjaparameter{postbreakpenalty={`#,200}}
-\setjaparameter{postbreakpenalty={`$,200}}
-\setjaparameter{postbreakpenalty={`%,200}}
-\setjaparameter{postbreakpenalty={`&,200}}
-\setjaparameter{prebreakpenalty={`ぁ,150}}
-\setjaparameter{prebreakpenalty={`ぃ,150}}
-\setjaparameter{prebreakpenalty={`ぅ,150}}
-\setjaparameter{prebreakpenalty={`ぇ,150}}
-\setjaparameter{prebreakpenalty={`ぉ,150}}
-\setjaparameter{prebreakpenalty={`っ,150}}
-\setjaparameter{prebreakpenalty={`ゃ,150}}
-\setjaparameter{prebreakpenalty={`ゅ,150}}
-\setjaparameter{prebreakpenalty={`ょ,150}}
-\setjaparameter{prebreakpenalty={`ゎ,150}}%\jis"246E
-\setjaparameter{prebreakpenalty={`ァ,150}}
-\setjaparameter{prebreakpenalty={`ィ,150}}
-\setjaparameter{prebreakpenalty={`ゥ,150}}
-\setjaparameter{prebreakpenalty={`ェ,150}}
-\setjaparameter{prebreakpenalty={`ォ,150}}
-\setjaparameter{prebreakpenalty={`ッ,150}}
-\setjaparameter{prebreakpenalty={`ャ,150}}
-\setjaparameter{prebreakpenalty={`ュ,150}}
-\setjaparameter{prebreakpenalty={`ョ,150}}
-\setjaparameter{prebreakpenalty={`ヮ,150}}%\jis"256E
-\setjaparameter{prebreakpenalty={`ヵ,150}}%\jis"2575
-\setjaparameter{prebreakpenalty={`ヶ,150}}%\jis"2576
+\ltjsetparameter{prebreakpenalty={`、,10000}}
+\ltjsetparameter{prebreakpenalty={`。,10000}}
+\ltjsetparameter{prebreakpenalty={`,,10000}}
+\ltjsetparameter{prebreakpenalty={`.,10000}}
+\ltjsetparameter{prebreakpenalty={`・,10000}}
+\ltjsetparameter{prebreakpenalty={`:,10000}}
+\ltjsetparameter{prebreakpenalty={`;,10000}}
+\ltjsetparameter{prebreakpenalty={`?,10000}}
+\ltjsetparameter{prebreakpenalty={`!,10000}}
+\ltjsetparameter{prebreakpenalty={`゛,10000}}%\jis"212B
+\ltjsetparameter{prebreakpenalty={`゜,10000}}%\jis"212C
+\ltjsetparameter{prebreakpenalty={`´,10000}}%\jis"212D
+\ltjsetparameter{postbreakpenalty={``,10000}}%\jis"212E
+\ltjsetparameter{prebreakpenalty={`々,10000}}%\jis"2139
+\ltjsetparameter{prebreakpenalty={`…,250}}%\jis"2144
+\ltjsetparameter{prebreakpenalty={`‥,250}}%\jis"2145
+\ltjsetparameter{postbreakpenalty={`‘,10000}}%\jis"2146
+\ltjsetparameter{prebreakpenalty={`’,10000}}%\jis"2147
+\ltjsetparameter{postbreakpenalty={`“,10000}}%\jis"2148
+\ltjsetparameter{prebreakpenalty={`”,10000}}%\jis"2149
+\ltjsetparameter{prebreakpenalty={`),10000}}
+\ltjsetparameter{postbreakpenalty={`(,10000}}
+\ltjsetparameter{prebreakpenalty={`},10000}}
+\ltjsetparameter{postbreakpenalty={`{,10000}}
+\ltjsetparameter{prebreakpenalty={`],10000}}
+\ltjsetparameter{postbreakpenalty={`[,10000}}
+%\ltjsetparameter{postbreakpenalty={`‘,10000}}
+%\ltjsetparameter{prebreakpenalty={`’,10000}}
+\ltjsetparameter{postbreakpenalty={`〔,10000}}%\jis"214C
+\ltjsetparameter{prebreakpenalty={`〕,10000}}%\jis"214D
+\ltjsetparameter{postbreakpenalty={`〈,10000}}%\jis"2152
+\ltjsetparameter{prebreakpenalty={`〉,10000}}%\jis"2153
+\ltjsetparameter{postbreakpenalty={`《,10000}}%\jis"2154
+\ltjsetparameter{prebreakpenalty={`》,10000}}%\jis"2155
+\ltjsetparameter{postbreakpenalty={`「,10000}}%\jis"2156
+\ltjsetparameter{prebreakpenalty={`」,10000}}%\jis"2157
+\ltjsetparameter{postbreakpenalty={`『,10000}}%\jis"2158
+\ltjsetparameter{prebreakpenalty={`』,10000}}%\jis"2159
+\ltjsetparameter{postbreakpenalty={`【,10000}}%\jis"215A
+\ltjsetparameter{prebreakpenalty={`】,10000}}%\jis"215B
+\ltjsetparameter{prebreakpenalty={`ー,10000}}
+\ltjsetparameter{prebreakpenalty={`+,200}}
+\ltjsetparameter{prebreakpenalty={`−,200}}% U+2212 MINUS SIGN
+\ltjsetparameter{prebreakpenalty={`-,200}}% U+FF0D FULLWIDTH HYPHEN-MINUS 
+\ltjsetparameter{prebreakpenalty={`=,200}}
+\ltjsetparameter{postbreakpenalty={`#,200}}
+\ltjsetparameter{postbreakpenalty={`$,200}}
+\ltjsetparameter{postbreakpenalty={`%,200}}
+\ltjsetparameter{postbreakpenalty={`&,200}}
+\ltjsetparameter{prebreakpenalty={`ぁ,150}}
+\ltjsetparameter{prebreakpenalty={`ぃ,150}}
+\ltjsetparameter{prebreakpenalty={`ぅ,150}}
+\ltjsetparameter{prebreakpenalty={`ぇ,150}}
+\ltjsetparameter{prebreakpenalty={`ぉ,150}}
+\ltjsetparameter{prebreakpenalty={`っ,150}}
+\ltjsetparameter{prebreakpenalty={`ゃ,150}}
+\ltjsetparameter{prebreakpenalty={`ゅ,150}}
+\ltjsetparameter{prebreakpenalty={`ょ,150}}
+\ltjsetparameter{prebreakpenalty={`ゎ,150}}%\jis"246E
+\ltjsetparameter{prebreakpenalty={`ァ,150}}
+\ltjsetparameter{prebreakpenalty={`ィ,150}}
+\ltjsetparameter{prebreakpenalty={`ゥ,150}}
+\ltjsetparameter{prebreakpenalty={`ェ,150}}
+\ltjsetparameter{prebreakpenalty={`ォ,150}}
+\ltjsetparameter{prebreakpenalty={`ッ,150}}
+\ltjsetparameter{prebreakpenalty={`ャ,150}}
+\ltjsetparameter{prebreakpenalty={`ュ,150}}
+\ltjsetparameter{prebreakpenalty={`ョ,150}}
+\ltjsetparameter{prebreakpenalty={`ヮ,150}}%\jis"256E
+\ltjsetparameter{prebreakpenalty={`ヵ,150}}%\jis"2575
+\ltjsetparameter{prebreakpenalty={`ヶ,150}}%\jis"2576
 % kinsoku  JIS X 0208 additional
-\setjaparameter{prebreakpenalty={`ヽ,10000}}
-\setjaparameter{prebreakpenalty={`ヾ,10000}}
-\setjaparameter{prebreakpenalty={`ゝ,10000}}
-\setjaparameter{prebreakpenalty={`ゞ,10000}}
+\ltjsetparameter{prebreakpenalty={`ヽ,10000}}
+\ltjsetparameter{prebreakpenalty={`ヾ,10000}}
+\ltjsetparameter{prebreakpenalty={`ゝ,10000}}
+\ltjsetparameter{prebreakpenalty={`ゞ,10000}}
 
 %
 % kinsoku  JIS X 0213
 %
-\setjaparameter{prebreakpenalty={`〳,10000}}
-\setjaparameter{prebreakpenalty={`〴,10000}}
-\setjaparameter{prebreakpenalty={`〵,10000}}
-\setjaparameter{prebreakpenalty={`〻,10000}}
-\setjaparameter{postbreakpenalty={`⦅,10000}}
-\setjaparameter{prebreakpenalty={`⦆,10000}}
-\setjaparameter{postbreakpenalty={`⦅,10000}}
-\setjaparameter{prebreakpenalty={`⦆,10000}}
-\setjaparameter{postbreakpenalty={`〘,10000}}
-\setjaparameter{prebreakpenalty={`〙,10000}}
-\setjaparameter{postbreakpenalty={`〖,10000}}
-\setjaparameter{prebreakpenalty={`〗,10000}}
-\setjaparameter{postbreakpenalty={`«,10000}}
-\setjaparameter{prebreakpenalty={`»,10000}}
-\setjaparameter{postbreakpenalty={`〝,10000}}
-\setjaparameter{prebreakpenalty={`〟,10000}}
-\setjaparameter{prebreakpenalty={`‼,10000}}
-\setjaparameter{prebreakpenalty={`⁇,10000}}
-\setjaparameter{prebreakpenalty={`⁈,10000}}
-\setjaparameter{prebreakpenalty={`⁉,10000}}
-\setjaparameter{postbreakpenalty={`¡,10000}}
-\setjaparameter{postbreakpenalty={`¿,10000}}
-\setjaparameter{prebreakpenalty={`ː,10000}}
-\setjaparameter{prebreakpenalty={`ª,10000}}
-\setjaparameter{prebreakpenalty={`º,10000}}
-\setjaparameter{prebreakpenalty={`¹,10000}}
-\setjaparameter{prebreakpenalty={`²,10000}}
-\setjaparameter{prebreakpenalty={`³,10000}}
-\setjaparameter{postbreakpenalty={`€,10000}}
-\setjaparameter{prebreakpenalty={`ゕ,150}}
-\setjaparameter{prebreakpenalty={`ゖ,150}}
-\setjaparameter{prebreakpenalty={`ㇰ,150}}
-\setjaparameter{prebreakpenalty={`ㇱ,150}}
-\setjaparameter{prebreakpenalty={`ㇲ,150}}
-\setjaparameter{prebreakpenalty={`ㇳ,150}}
-\setjaparameter{prebreakpenalty={`ㇴ,150}}
-\setjaparameter{prebreakpenalty={`ㇵ,150}}
-\setjaparameter{prebreakpenalty={`ㇶ,150}}
-\setjaparameter{prebreakpenalty={`ㇷ,150}}
-\setjaparameter{prebreakpenalty={`ㇸ,150}}
-\setjaparameter{prebreakpenalty={`ㇹ,150}}
-%\setjaparameter{prebreakpenalty={`ㇷ゚,150}}
-\setjaparameter{prebreakpenalty={`ㇺ,150}}
-\setjaparameter{prebreakpenalty={`ㇻ,150}}
-\setjaparameter{prebreakpenalty={`ㇼ,150}}
-\setjaparameter{prebreakpenalty={`ㇽ,150}}
-\setjaparameter{prebreakpenalty={`ㇾ,150}}
-\setjaparameter{prebreakpenalty={`ㇿ,150}}
+\ltjsetparameter{prebreakpenalty={`〳,10000}}
+\ltjsetparameter{prebreakpenalty={`〴,10000}}
+\ltjsetparameter{prebreakpenalty={`〵,10000}}
+\ltjsetparameter{prebreakpenalty={`〻,10000}}
+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
+\ltjsetparameter{prebreakpenalty={`⦆,10000}}
+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
+\ltjsetparameter{prebreakpenalty={`⦆,10000}}
+\ltjsetparameter{postbreakpenalty={`〘,10000}}
+\ltjsetparameter{prebreakpenalty={`〙,10000}}
+\ltjsetparameter{postbreakpenalty={`〖,10000}}
+\ltjsetparameter{prebreakpenalty={`〗,10000}}
+\ltjsetparameter{postbreakpenalty={`«,10000}}
+\ltjsetparameter{prebreakpenalty={`»,10000}}
+\ltjsetparameter{postbreakpenalty={`〝,10000}}
+\ltjsetparameter{prebreakpenalty={`〟,10000}}
+\ltjsetparameter{prebreakpenalty={`‼,10000}}
+\ltjsetparameter{prebreakpenalty={`⁇,10000}}
+\ltjsetparameter{prebreakpenalty={`⁈,10000}}
+\ltjsetparameter{prebreakpenalty={`⁉,10000}}
+\ltjsetparameter{postbreakpenalty={`¡,10000}}
+\ltjsetparameter{postbreakpenalty={`¿,10000}}
+\ltjsetparameter{prebreakpenalty={`ː,10000}}
+\ltjsetparameter{prebreakpenalty={`ª,10000}}
+\ltjsetparameter{prebreakpenalty={`º,10000}}
+\ltjsetparameter{prebreakpenalty={`¹,10000}}
+\ltjsetparameter{prebreakpenalty={`²,10000}}
+\ltjsetparameter{prebreakpenalty={`³,10000}}
+\ltjsetparameter{postbreakpenalty={`€,10000}}
+\ltjsetparameter{prebreakpenalty={`ゕ,150}}
+\ltjsetparameter{prebreakpenalty={`ゖ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇰ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇱ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇲ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇳ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇴ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇵ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇶ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇷ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇸ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇹ,150}}
+%\ltjsetparameter{prebreakpenalty={`ㇷ゚,150}}
+\ltjsetparameter{prebreakpenalty={`ㇺ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇻ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇼ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇽ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇾ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇿ,150}}
 %
 % kinsoku  JIS X 0212
 %
-%\setjaparameter{postbreakpenalty={`¡,10000}}
-%\setjaparameter{postbreakpenalty={`¿,10000}}
-%\setjaparameter{prebreakpenalty={`º,10000}}
-%\setjaparameter{prebreakpenalty={`ª,10000}}
-\setjaparameter{prebreakpenalty={`™,10000}}
+%\ltjsetparameter{postbreakpenalty={`¡,10000}}
+%\ltjsetparameter{postbreakpenalty={`¿,10000}}
+%\ltjsetparameter{prebreakpenalty={`º,10000}}
+%\ltjsetparameter{prebreakpenalty={`ª,10000}}
+\ltjsetparameter{prebreakpenalty={`™,10000}}
 %
 % kinsoku  半角片仮名
 %
-\setjaparameter{prebreakpenalty={`。,10000}}
-\setjaparameter{prebreakpenalty={`、,10000}}
-\setjaparameter{prebreakpenalty={`゙,10000}}
-\setjaparameter{prebreakpenalty={`゚,10000}}
-\setjaparameter{prebreakpenalty={`」,10000}}
-\setjaparameter{postbreakpenalty={`「,10000}}
+\ltjsetparameter{prebreakpenalty={`。,10000}}
+\ltjsetparameter{prebreakpenalty={`、,10000}}
+\ltjsetparameter{prebreakpenalty={`゙,10000}}
+\ltjsetparameter{prebreakpenalty={`゚,10000}}
+\ltjsetparameter{prebreakpenalty={`」,10000}}
+\ltjsetparameter{postbreakpenalty={`「,10000}}
 %
 % xspcode
-\setjaparameter{asciixspmode={`(,preonly}}
-\setjaparameter{asciixspmode={`),postonly}}
-\setjaparameter{asciixspmode={`[,preonly}}
-\setjaparameter{asciixspmode={`],postonly}}
-\setjaparameter{asciixspmode={``,preonly}}
-\setjaparameter{asciixspmode={`',postonly}}
-\setjaparameter{asciixspmode={`;,postonly}}
-\setjaparameter{asciixspmode={47,postonly}}
-\setjaparameter{asciixspmode={`.,postonly}}
+\ltjsetparameter{asciixspmode={`(,preonly}}
+\ltjsetparameter{asciixspmode={`),postonly}}
+\ltjsetparameter{asciixspmode={`[,preonly}}
+\ltjsetparameter{asciixspmode={`],postonly}}
+\ltjsetparameter{asciixspmode={``,preonly}}
+\ltjsetparameter{asciixspmode={`',postonly}}
+\ltjsetparameter{asciixspmode={`;,postonly}}
+\ltjsetparameter{asciixspmode={47,postonly}}
+\ltjsetparameter{asciixspmode={`.,postonly}}
 %  for 8bit Latin
-\setjaparameter{asciixspmode={"80,allow}}
-\setjaparameter{asciixspmode={"81,allow}}
-\setjaparameter{asciixspmode={"82,allow}}
-\setjaparameter{asciixspmode={"83,allow}}
-\setjaparameter{asciixspmode={"84,allow}}
-\setjaparameter{asciixspmode={"85,allow}}
-\setjaparameter{asciixspmode={"86,allow}}
-\setjaparameter{asciixspmode={"87,allow}}
-\setjaparameter{asciixspmode={"88,allow}}
-\setjaparameter{asciixspmode={"89,allow}}
-\setjaparameter{asciixspmode={"8A,allow}}
-\setjaparameter{asciixspmode={"8B,allow}}
-\setjaparameter{asciixspmode={"8C,allow}}
-\setjaparameter{asciixspmode={"8D,allow}}
-\setjaparameter{asciixspmode={"8E,allow}}
-\setjaparameter{asciixspmode={"8F,allow}}
-\setjaparameter{asciixspmode={"90,allow}}
-\setjaparameter{asciixspmode={"91,allow}}
-\setjaparameter{asciixspmode={"92,allow}}
-\setjaparameter{asciixspmode={"93,allow}}
-\setjaparameter{asciixspmode={"94,allow}}
-\setjaparameter{asciixspmode={"95,allow}}
-\setjaparameter{asciixspmode={"96,allow}}
-\setjaparameter{asciixspmode={"97,allow}}
-\setjaparameter{asciixspmode={"98,allow}}
-\setjaparameter{asciixspmode={"99,allow}}
-\setjaparameter{asciixspmode={"9A,allow}}
-\setjaparameter{asciixspmode={"9B,allow}}
-\setjaparameter{asciixspmode={"9C,allow}}
-\setjaparameter{asciixspmode={"9D,allow}}
-\setjaparameter{asciixspmode={"9E,allow}}
-\setjaparameter{asciixspmode={"9F,allow}}
-\setjaparameter{asciixspmode={"A0,allow}}
-\setjaparameter{asciixspmode={"A1,allow}}
-\setjaparameter{asciixspmode={"A2,allow}}
-\setjaparameter{asciixspmode={"A3,allow}}
-\setjaparameter{asciixspmode={"A4,allow}}
-\setjaparameter{asciixspmode={"A5,allow}}
-\setjaparameter{asciixspmode={"A6,allow}}
-\setjaparameter{asciixspmode={"A7,allow}}
-\setjaparameter{asciixspmode={"A8,allow}}
-\setjaparameter{asciixspmode={"A9,allow}}
-\setjaparameter{asciixspmode={"AA,allow}}
-\setjaparameter{asciixspmode={"AB,allow}}
-\setjaparameter{asciixspmode={"AC,allow}}
-\setjaparameter{asciixspmode={"AD,allow}}
-\setjaparameter{asciixspmode={"AE,allow}}
-\setjaparameter{asciixspmode={"AF,allow}}
-\setjaparameter{asciixspmode={"B0,allow}}
-\setjaparameter{asciixspmode={"B1,allow}}
-\setjaparameter{asciixspmode={"B2,allow}}
-\setjaparameter{asciixspmode={"B3,allow}}
-\setjaparameter{asciixspmode={"B4,allow}}
-\setjaparameter{asciixspmode={"B5,allow}}
-\setjaparameter{asciixspmode={"B6,allow}}
-\setjaparameter{asciixspmode={"B7,allow}}
-\setjaparameter{asciixspmode={"B8,allow}}
-\setjaparameter{asciixspmode={"B9,allow}}
-\setjaparameter{asciixspmode={"BA,allow}}
-\setjaparameter{asciixspmode={"BB,allow}}
-\setjaparameter{asciixspmode={"BC,allow}}
-\setjaparameter{asciixspmode={"BD,allow}}
-\setjaparameter{asciixspmode={"BE,allow}}
-\setjaparameter{asciixspmode={"BF,allow}}
-\setjaparameter{asciixspmode={"C0,allow}}
-\setjaparameter{asciixspmode={"C1,allow}}
-\setjaparameter{asciixspmode={"C2,allow}}
-\setjaparameter{asciixspmode={"C3,allow}}
-\setjaparameter{asciixspmode={"C4,allow}}
-\setjaparameter{asciixspmode={"C5,allow}}
-\setjaparameter{asciixspmode={"C6,allow}}
-\setjaparameter{asciixspmode={"C7,allow}}
-\setjaparameter{asciixspmode={"C8,allow}}
-\setjaparameter{asciixspmode={"C9,allow}}
-\setjaparameter{asciixspmode={"CA,allow}}
-\setjaparameter{asciixspmode={"CB,allow}}
-\setjaparameter{asciixspmode={"CC,allow}}
-\setjaparameter{asciixspmode={"CD,allow}}
-\setjaparameter{asciixspmode={"CE,allow}}
-\setjaparameter{asciixspmode={"CF,allow}}
-\setjaparameter{asciixspmode={"D0,allow}}
-\setjaparameter{asciixspmode={"D1,allow}}
-\setjaparameter{asciixspmode={"D2,allow}}
-\setjaparameter{asciixspmode={"D3,allow}}
-\setjaparameter{asciixspmode={"D4,allow}}
-\setjaparameter{asciixspmode={"D5,allow}}
-\setjaparameter{asciixspmode={"D6,allow}}
-\setjaparameter{asciixspmode={"D7,allow}}
-\setjaparameter{asciixspmode={"D8,allow}}
-\setjaparameter{asciixspmode={"D9,allow}}
-\setjaparameter{asciixspmode={"DA,allow}}
-\setjaparameter{asciixspmode={"DB,allow}}
-\setjaparameter{asciixspmode={"DC,allow}}
-\setjaparameter{asciixspmode={"DD,allow}}
-\setjaparameter{asciixspmode={"DE,allow}}
-\setjaparameter{asciixspmode={"DF,allow}}
-\setjaparameter{asciixspmode={"E0,allow}}
-\setjaparameter{asciixspmode={"E1,allow}}
-\setjaparameter{asciixspmode={"E2,allow}}
-\setjaparameter{asciixspmode={"E3,allow}}
-\setjaparameter{asciixspmode={"E4,allow}}
-\setjaparameter{asciixspmode={"E5,allow}}
-\setjaparameter{asciixspmode={"E6,allow}}
-\setjaparameter{asciixspmode={"E7,allow}}
-\setjaparameter{asciixspmode={"E8,allow}}
-\setjaparameter{asciixspmode={"E9,allow}}
-\setjaparameter{asciixspmode={"EA,allow}}
-\setjaparameter{asciixspmode={"EB,allow}}
-\setjaparameter{asciixspmode={"EC,allow}}
-\setjaparameter{asciixspmode={"ED,allow}}
-\setjaparameter{asciixspmode={"EE,allow}}
-\setjaparameter{asciixspmode={"EF,allow}}
-\setjaparameter{asciixspmode={"F0,allow}}
-\setjaparameter{asciixspmode={"F1,allow}}
-\setjaparameter{asciixspmode={"F2,allow}}
-\setjaparameter{asciixspmode={"F3,allow}}
-\setjaparameter{asciixspmode={"F4,allow}}
-\setjaparameter{asciixspmode={"F5,allow}}
-\setjaparameter{asciixspmode={"F6,allow}}
-\setjaparameter{asciixspmode={"F7,allow}}
-\setjaparameter{asciixspmode={"F8,allow}}
-\setjaparameter{asciixspmode={"F9,allow}}
-\setjaparameter{asciixspmode={"FA,allow}}
-\setjaparameter{asciixspmode={"FB,allow}}
-\setjaparameter{asciixspmode={"FC,allow}}
-\setjaparameter{asciixspmode={"FD,allow}}
-\setjaparameter{asciixspmode={"FE,allow}}
-\setjaparameter{asciixspmode={"FF,allow}}
+\ltjsetparameter{asciixspmode={"80,allow}}
+\ltjsetparameter{asciixspmode={"81,allow}}
+\ltjsetparameter{asciixspmode={"82,allow}}
+\ltjsetparameter{asciixspmode={"83,allow}}
+\ltjsetparameter{asciixspmode={"84,allow}}
+\ltjsetparameter{asciixspmode={"85,allow}}
+\ltjsetparameter{asciixspmode={"86,allow}}
+\ltjsetparameter{asciixspmode={"87,allow}}
+\ltjsetparameter{asciixspmode={"88,allow}}
+\ltjsetparameter{asciixspmode={"89,allow}}
+\ltjsetparameter{asciixspmode={"8A,allow}}
+\ltjsetparameter{asciixspmode={"8B,allow}}
+\ltjsetparameter{asciixspmode={"8C,allow}}
+\ltjsetparameter{asciixspmode={"8D,allow}}
+\ltjsetparameter{asciixspmode={"8E,allow}}
+\ltjsetparameter{asciixspmode={"8F,allow}}
+\ltjsetparameter{asciixspmode={"90,allow}}
+\ltjsetparameter{asciixspmode={"91,allow}}
+\ltjsetparameter{asciixspmode={"92,allow}}
+\ltjsetparameter{asciixspmode={"93,allow}}
+\ltjsetparameter{asciixspmode={"94,allow}}
+\ltjsetparameter{asciixspmode={"95,allow}}
+\ltjsetparameter{asciixspmode={"96,allow}}
+\ltjsetparameter{asciixspmode={"97,allow}}
+\ltjsetparameter{asciixspmode={"98,allow}}
+\ltjsetparameter{asciixspmode={"99,allow}}
+\ltjsetparameter{asciixspmode={"9A,allow}}
+\ltjsetparameter{asciixspmode={"9B,allow}}
+\ltjsetparameter{asciixspmode={"9C,allow}}
+\ltjsetparameter{asciixspmode={"9D,allow}}
+\ltjsetparameter{asciixspmode={"9E,allow}}
+\ltjsetparameter{asciixspmode={"9F,allow}}
+\ltjsetparameter{asciixspmode={"A0,allow}}
+\ltjsetparameter{asciixspmode={"A1,allow}}
+\ltjsetparameter{asciixspmode={"A2,allow}}
+\ltjsetparameter{asciixspmode={"A3,allow}}
+\ltjsetparameter{asciixspmode={"A4,allow}}
+\ltjsetparameter{asciixspmode={"A5,allow}}
+\ltjsetparameter{asciixspmode={"A6,allow}}
+\ltjsetparameter{asciixspmode={"A7,allow}}
+\ltjsetparameter{asciixspmode={"A8,allow}}
+\ltjsetparameter{asciixspmode={"A9,allow}}
+\ltjsetparameter{asciixspmode={"AA,allow}}
+\ltjsetparameter{asciixspmode={"AB,allow}}
+\ltjsetparameter{asciixspmode={"AC,allow}}
+\ltjsetparameter{asciixspmode={"AD,allow}}
+\ltjsetparameter{asciixspmode={"AE,allow}}
+\ltjsetparameter{asciixspmode={"AF,allow}}
+\ltjsetparameter{asciixspmode={"B0,allow}}
+\ltjsetparameter{asciixspmode={"B1,allow}}
+\ltjsetparameter{asciixspmode={"B2,allow}}
+\ltjsetparameter{asciixspmode={"B3,allow}}
+\ltjsetparameter{asciixspmode={"B4,allow}}
+\ltjsetparameter{asciixspmode={"B5,allow}}
+\ltjsetparameter{asciixspmode={"B6,allow}}
+\ltjsetparameter{asciixspmode={"B7,allow}}
+\ltjsetparameter{asciixspmode={"B8,allow}}
+\ltjsetparameter{asciixspmode={"B9,allow}}
+\ltjsetparameter{asciixspmode={"BA,allow}}
+\ltjsetparameter{asciixspmode={"BB,allow}}
+\ltjsetparameter{asciixspmode={"BC,allow}}
+\ltjsetparameter{asciixspmode={"BD,allow}}
+\ltjsetparameter{asciixspmode={"BE,allow}}
+\ltjsetparameter{asciixspmode={"BF,allow}}
+\ltjsetparameter{asciixspmode={"C0,allow}}
+\ltjsetparameter{asciixspmode={"C1,allow}}
+\ltjsetparameter{asciixspmode={"C2,allow}}
+\ltjsetparameter{asciixspmode={"C3,allow}}
+\ltjsetparameter{asciixspmode={"C4,allow}}
+\ltjsetparameter{asciixspmode={"C5,allow}}
+\ltjsetparameter{asciixspmode={"C6,allow}}
+\ltjsetparameter{asciixspmode={"C7,allow}}
+\ltjsetparameter{asciixspmode={"C8,allow}}
+\ltjsetparameter{asciixspmode={"C9,allow}}
+\ltjsetparameter{asciixspmode={"CA,allow}}
+\ltjsetparameter{asciixspmode={"CB,allow}}
+\ltjsetparameter{asciixspmode={"CC,allow}}
+\ltjsetparameter{asciixspmode={"CD,allow}}
+\ltjsetparameter{asciixspmode={"CE,allow}}
+\ltjsetparameter{asciixspmode={"CF,allow}}
+\ltjsetparameter{asciixspmode={"D0,allow}}
+\ltjsetparameter{asciixspmode={"D1,allow}}
+\ltjsetparameter{asciixspmode={"D2,allow}}
+\ltjsetparameter{asciixspmode={"D3,allow}}
+\ltjsetparameter{asciixspmode={"D4,allow}}
+\ltjsetparameter{asciixspmode={"D5,allow}}
+\ltjsetparameter{asciixspmode={"D6,allow}}
+\ltjsetparameter{asciixspmode={"D7,allow}}
+\ltjsetparameter{asciixspmode={"D8,allow}}
+\ltjsetparameter{asciixspmode={"D9,allow}}
+\ltjsetparameter{asciixspmode={"DA,allow}}
+\ltjsetparameter{asciixspmode={"DB,allow}}
+\ltjsetparameter{asciixspmode={"DC,allow}}
+\ltjsetparameter{asciixspmode={"DD,allow}}
+\ltjsetparameter{asciixspmode={"DE,allow}}
+\ltjsetparameter{asciixspmode={"DF,allow}}
+\ltjsetparameter{asciixspmode={"E0,allow}}
+\ltjsetparameter{asciixspmode={"E1,allow}}
+\ltjsetparameter{asciixspmode={"E2,allow}}
+\ltjsetparameter{asciixspmode={"E3,allow}}
+\ltjsetparameter{asciixspmode={"E4,allow}}
+\ltjsetparameter{asciixspmode={"E5,allow}}
+\ltjsetparameter{asciixspmode={"E6,allow}}
+\ltjsetparameter{asciixspmode={"E7,allow}}
+\ltjsetparameter{asciixspmode={"E8,allow}}
+\ltjsetparameter{asciixspmode={"E9,allow}}
+\ltjsetparameter{asciixspmode={"EA,allow}}
+\ltjsetparameter{asciixspmode={"EB,allow}}
+\ltjsetparameter{asciixspmode={"EC,allow}}
+\ltjsetparameter{asciixspmode={"ED,allow}}
+\ltjsetparameter{asciixspmode={"EE,allow}}
+\ltjsetparameter{asciixspmode={"EF,allow}}
+\ltjsetparameter{asciixspmode={"F0,allow}}
+\ltjsetparameter{asciixspmode={"F1,allow}}
+\ltjsetparameter{asciixspmode={"F2,allow}}
+\ltjsetparameter{asciixspmode={"F3,allow}}
+\ltjsetparameter{asciixspmode={"F4,allow}}
+\ltjsetparameter{asciixspmode={"F5,allow}}
+\ltjsetparameter{asciixspmode={"F6,allow}}
+\ltjsetparameter{asciixspmode={"F7,allow}}
+\ltjsetparameter{asciixspmode={"F8,allow}}
+\ltjsetparameter{asciixspmode={"F9,allow}}
+\ltjsetparameter{asciixspmode={"FA,allow}}
+\ltjsetparameter{asciixspmode={"FB,allow}}
+\ltjsetparameter{asciixspmode={"FC,allow}}
+\ltjsetparameter{asciixspmode={"FD,allow}}
+\ltjsetparameter{asciixspmode={"FE,allow}}
+\ltjsetparameter{asciixspmode={"FF,allow}}
 %
 % inhibitxspcode
-\setjaparameter{cjkxspmode={`、,postonly}}
-\setjaparameter{cjkxspmode={`。,postonly}}
-\setjaparameter{cjkxspmode={`,,postonly}}
-\setjaparameter{cjkxspmode={`.,postonly}}
-\setjaparameter{cjkxspmode={`;,postonly}}
-\setjaparameter{cjkxspmode={`?,postonly}}
-\setjaparameter{cjkxspmode={`),postonly}}
-\setjaparameter{cjkxspmode={`(,preonly}}
-\setjaparameter{cjkxspmode={`],postonly}}
-\setjaparameter{cjkxspmode={`[,preonly}}
-\setjaparameter{cjkxspmode={`},postonly}}
-\setjaparameter{cjkxspmode={`{,preonly}}
-\setjaparameter{cjkxspmode={`‘,preonly}}
-\setjaparameter{cjkxspmode={`’,postonly}}
-\setjaparameter{cjkxspmode={`“,preonly}}
-\setjaparameter{cjkxspmode={`”,postonly}}
-\setjaparameter{cjkxspmode={`〔,preonly}}
-\setjaparameter{cjkxspmode={`〕,postonly}}
-\setjaparameter{cjkxspmode={`〈,preonly}}
-\setjaparameter{cjkxspmode={`〉,postonly}}
-\setjaparameter{cjkxspmode={`《,preonly}}
-\setjaparameter{cjkxspmode={`》,postonly}}
-\setjaparameter{cjkxspmode={`「,preonly}}
-\setjaparameter{cjkxspmode={`」,postonly}}
-\setjaparameter{cjkxspmode={`『,preonly}}
-\setjaparameter{cjkxspmode={`』,postonly}}
-\setjaparameter{cjkxspmode={`【,preonly}}
-\setjaparameter{cjkxspmode={`】,postonly}}
-\setjaparameter{cjkxspmode={`—,inhibit}}% U+2014 EM DASH
-\setjaparameter{cjkxspmode={`―,inhibit}}% U+2015 HORIZONTAL BAR
-\setjaparameter{cjkxspmode={`〜,inhibit}}% U+301C WAVE DASH
-\setjaparameter{cjkxspmode={`~,inhibit}}% U+FF5E FULLWIDTH TILDE
-\setjaparameter{cjkxspmode={`…,inhibit}}
-\setjaparameter{cjkxspmode={`¥,inhibit}}% U+00A5 YEN SIGN
-\setjaparameter{cjkxspmode={`¥,inhibit}}% U+FFE5 FULLWIDTH YEN SIGN
-\setjaparameter{cjkxspmode={`°,postonly}}
-\setjaparameter{cjkxspmode={`′,postonly}}
-\setjaparameter{cjkxspmode={`″,postonly}}
+\ltjsetparameter{cjkxspmode={`、,postonly}}
+\ltjsetparameter{cjkxspmode={`。,postonly}}
+\ltjsetparameter{cjkxspmode={`,,postonly}}
+\ltjsetparameter{cjkxspmode={`.,postonly}}
+\ltjsetparameter{cjkxspmode={`;,postonly}}
+\ltjsetparameter{cjkxspmode={`?,postonly}}
+\ltjsetparameter{cjkxspmode={`),postonly}}
+\ltjsetparameter{cjkxspmode={`(,preonly}}
+\ltjsetparameter{cjkxspmode={`],postonly}}
+\ltjsetparameter{cjkxspmode={`[,preonly}}
+\ltjsetparameter{cjkxspmode={`},postonly}}
+\ltjsetparameter{cjkxspmode={`{,preonly}}
+\ltjsetparameter{cjkxspmode={`‘,preonly}}
+\ltjsetparameter{cjkxspmode={`’,postonly}}
+\ltjsetparameter{cjkxspmode={`“,preonly}}
+\ltjsetparameter{cjkxspmode={`”,postonly}}
+\ltjsetparameter{cjkxspmode={`〔,preonly}}
+\ltjsetparameter{cjkxspmode={`〕,postonly}}
+\ltjsetparameter{cjkxspmode={`〈,preonly}}
+\ltjsetparameter{cjkxspmode={`〉,postonly}}
+\ltjsetparameter{cjkxspmode={`《,preonly}}
+\ltjsetparameter{cjkxspmode={`》,postonly}}
+\ltjsetparameter{cjkxspmode={`「,preonly}}
+\ltjsetparameter{cjkxspmode={`」,postonly}}
+\ltjsetparameter{cjkxspmode={`『,preonly}}
+\ltjsetparameter{cjkxspmode={`』,postonly}}
+\ltjsetparameter{cjkxspmode={`【,preonly}}
+\ltjsetparameter{cjkxspmode={`】,postonly}}
+\ltjsetparameter{cjkxspmode={`—,inhibit}}% U+2014 EM DASH
+\ltjsetparameter{cjkxspmode={`―,inhibit}}% U+2015 HORIZONTAL BAR
+\ltjsetparameter{cjkxspmode={`〜,inhibit}}% U+301C WAVE DASH
+\ltjsetparameter{cjkxspmode={`~,inhibit}}% U+FF5E FULLWIDTH TILDE
+\ltjsetparameter{cjkxspmode={`…,inhibit}}
+\ltjsetparameter{cjkxspmode={`¥,inhibit}}% U+00A5 YEN SIGN
+\ltjsetparameter{cjkxspmode={`¥,inhibit}}% U+FFE5 FULLWIDTH YEN SIGN
+\ltjsetparameter{cjkxspmode={`°,postonly}}
+\ltjsetparameter{cjkxspmode={`′,postonly}}
+\ltjsetparameter{cjkxspmode={`″,postonly}}
 %
 % inhibitxspcode  JIS X 0213
 %
-\setjaparameter{cjkxspmode={`⦅,preonly}}
-\setjaparameter{cjkxspmode={`⦆,postonly}}
-\setjaparameter{cjkxspmode={`⦅,preonly}}
-\setjaparameter{cjkxspmode={`⦆,postonly}}
-\setjaparameter{cjkxspmode={`〘,preonly}}
-\setjaparameter{cjkxspmode={`〙,postonly}}
-\setjaparameter{cjkxspmode={`〖,preonly}}
-\setjaparameter{cjkxspmode={`〗,postonly}}
-\setjaparameter{cjkxspmode={`«,preonly}}
-\setjaparameter{cjkxspmode={`»,postonly}}
-\setjaparameter{cjkxspmode={`〝,preonly}}
-\setjaparameter{cjkxspmode={`〟,postonly}}
-\setjaparameter{cjkxspmode={`‼,postonly}}
-\setjaparameter{cjkxspmode={`⁇,postonly}}
-\setjaparameter{cjkxspmode={`⁈,postonly}}
-\setjaparameter{cjkxspmode={`⁉,postonly}}
-\setjaparameter{cjkxspmode={`¡,preonly}}
-\setjaparameter{cjkxspmode={`¿,preonly}}
-\setjaparameter{cjkxspmode={`ª,postonly}}
-\setjaparameter{cjkxspmode={`º,postonly}}
-\setjaparameter{cjkxspmode={`¹,postonly}}
-\setjaparameter{cjkxspmode={`²,postonly}}
-\setjaparameter{cjkxspmode={`³,postonly}}
-\setjaparameter{cjkxspmode={`€,preonly}}
+\ltjsetparameter{cjkxspmode={`⦅,preonly}}
+\ltjsetparameter{cjkxspmode={`⦆,postonly}}
+\ltjsetparameter{cjkxspmode={`⦅,preonly}}
+\ltjsetparameter{cjkxspmode={`⦆,postonly}}
+\ltjsetparameter{cjkxspmode={`〘,preonly}}
+\ltjsetparameter{cjkxspmode={`〙,postonly}}
+\ltjsetparameter{cjkxspmode={`〖,preonly}}
+\ltjsetparameter{cjkxspmode={`〗,postonly}}
+\ltjsetparameter{cjkxspmode={`«,preonly}}
+\ltjsetparameter{cjkxspmode={`»,postonly}}
+\ltjsetparameter{cjkxspmode={`〝,preonly}}
+\ltjsetparameter{cjkxspmode={`〟,postonly}}
+\ltjsetparameter{cjkxspmode={`‼,postonly}}
+\ltjsetparameter{cjkxspmode={`⁇,postonly}}
+\ltjsetparameter{cjkxspmode={`⁈,postonly}}
+\ltjsetparameter{cjkxspmode={`⁉,postonly}}
+\ltjsetparameter{cjkxspmode={`¡,preonly}}
+\ltjsetparameter{cjkxspmode={`¿,preonly}}
+\ltjsetparameter{cjkxspmode={`ª,postonly}}
+\ltjsetparameter{cjkxspmode={`º,postonly}}
+\ltjsetparameter{cjkxspmode={`¹,postonly}}
+\ltjsetparameter{cjkxspmode={`²,postonly}}
+\ltjsetparameter{cjkxspmode={`³,postonly}}
+\ltjsetparameter{cjkxspmode={`€,preonly}}
 %
 % inhibitxspcode  JIS X 0212
 %
-%\setjaparameter{cjkxspmode={`¡,postonly}}
-%\setjaparameter{cjkxspmode={`¿,postonly}}
-%\setjaparameter{cjkxspmode={`º,postonly}}
-%\setjaparameter{cjkxspmode={`ª,postonly}}
-\setjaparameter{cjkxspmode={`™,postonly}}
+%\ltjsetparameter{cjkxspmode={`¡,postonly}}
+%\ltjsetparameter{cjkxspmode={`¿,postonly}}
+%\ltjsetparameter{cjkxspmode={`º,postonly}}
+%\ltjsetparameter{cjkxspmode={`ª,postonly}}
+\ltjsetparameter{cjkxspmode={`™,postonly}}
 %
 % inhibitxspcode  半角片仮名
 %
-\setjaparameter{cjkxspmode={`。,postonly}}
-\setjaparameter{cjkxspmode={`、,postonly}}
-\setjaparameter{cjkxspmode={`「,preonly}}
-\setjaparameter{cjkxspmode={`」,postonly}}
+\ltjsetparameter{cjkxspmode={`。,postonly}}
+\ltjsetparameter{cjkxspmode={`、,postonly}}
+\ltjsetparameter{cjkxspmode={`「,preonly}}
+\ltjsetparameter{cjkxspmode={`」,postonly}}
 
 \endinput 
 cat `locate ukinsoku.tex` \
-  | sed "s/prebreakpenalty\(.*\)=\([0-9]*\)/setjaparameter{prebreakpenalty={\1,\2}}/" \
-  | sed "s/postbreakpenalty\(.*\)=\([0-9]*\)/setjaparameter{postbreakpenalty={\1,\2}}/" \
-  | sed "s/inhibitxspcode\(.*\)=0/setjaparameter{cjkxspmode={\1,inhibit}}/" \
-  | sed "s/inhibitxspcode\(.*\)=1/setjaparameter{cjkxspmode={\1,postonly}}/" \
-  | sed "s/inhibitxspcode\(.*\)=2/setjaparameter{cjkxspmode={\1,preonly}}/" \
-  | sed "s/inhibitxspcode\(.*\)=3/setjaparameter{cjkxspmode={\1,allow}}/" \
-  | sed "s/xspcode\(.*\)=0/setjaparameter{asciixspmode={\1,inhibit}}/" \
-  | sed "s/xspcode\(.*\)=2/setjaparameter{asciixspmode={\1,postonly}}/" \
-  | sed "s/xspcode\(.*\)=1/setjaparameter{asciixspmode={\1,preonly}}/" \
-  | sed "s/xspcode\(.*\)=3/setjaparameter{asciixspmode={\1,allow}}/"  > luatexja-kinsoku.tex
\ No newline at end of file
+  | sed "s/prebreakpenalty\(.*\)=\([0-9]*\)/ltjsetparameter{prebreakpenalty={\1,\2}}/" \
+  | sed "s/postbreakpenalty\(.*\)=\([0-9]*\)/ltjsetparameter{postbreakpenalty={\1,\2}}/" \
+  | sed "s/inhibitxspcode\(.*\)=0/ltjsetparameter{cjkxspmode={\1,inhibit}}/" \
+  | sed "s/inhibitxspcode\(.*\)=1/ltjsetparameter{cjkxspmode={\1,postonly}}/" \
+  | sed "s/inhibitxspcode\(.*\)=2/ltjsetparameter{cjkxspmode={\1,preonly}}/" \
+  | sed "s/inhibitxspcode\(.*\)=3/ltjsetparameter{cjkxspmode={\1,allow}}/" \
+  | sed "s/xspcode\(.*\)=0/ltjsetparameter{asciixspmode={\1,inhibit}}/" \
+  | sed "s/xspcode\(.*\)=2/ltjsetparameter{asciixspmode={\1,postonly}}/" \
+  | sed "s/xspcode\(.*\)=1/ltjsetparameter{asciixspmode={\1,preonly}}/" \
+  | sed "s/xspcode\(.*\)=3/ltjsetparameter{asciixspmode={\1,allow}}/"  > luatexja-kinsoku.tex
\ No newline at end of file
index 47ab680..435e0d4 100644 (file)
@@ -10,7 +10,7 @@
 \let\mc=\tenmin
 \let\gt=\tengt
 \mc
-\setjaparameter{kanjiskip=0pt plus 0.4pt minus 0.4pt, 
+\ltjsetparameter{kanjiskip=0pt plus 0.4pt minus 0.4pt, 
   xkanjiskip=.25\zw plus 1pt minus 1pt,
   autospacing, autoxspacing, jcharrange={-1}, 
   yabaselineshift=0pt, ykbaselineshift=0pt,
 
 \luatexja@tempcnta="2000%"
 \loop\ifnum\luatexja@tempcnta<"2070%"
-  \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
+  \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
   \advance\luatexja@tempcnta by1
 \repeat
 
 \luatexja@tempcnta="3000%"
 \loop\ifnum\luatexja@tempcnta<"3040%"
-  \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
+  \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
   \advance\luatexja@tempcnta by1
 \repeat
 
 \luatexja@tempcnta="FF00%"
 \loop\ifnum\luatexja@tempcnta<"FFF0%"
-  \setjaparameter{kcatcode={\luatexja@tempcnta,1}}%
+  \ltjsetparameter{kcatcode={\luatexja@tempcnta,1}}%
   \advance\luatexja@tempcnta by1
 \repeat
 \endinput
\ No newline at end of file
diff --git a/src/luatexja-xkanji.lua b/src/luatexja-xkanji.lua
new file mode 100644 (file)
index 0000000..8d224b5
--- /dev/null
@@ -0,0 +1,267 @@
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 3: insert \xkanjiskip (prefix: none)
+------------------------------------------------------------------------
+
+local node_type = node.type
+local node_new = node.new
+local node_prev = node.prev
+local node_next = node.next
+local has_attr = node.has_attribute
+local node_insert_before = node.insert_before
+local node_insert_after = node.insert_after
+local node_hpack = node.hpack
+
+local id_penalty = node.id('penalty')
+local id_glyph = node.id('glyph')
+local id_glue = node.id('glue')
+local id_glue_spec = node.id('glue_spec')
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_ins = node.id('ins')
+local id_mark = node.id('mark')
+local id_adjust = node.id('adjust')
+local id_math = node.id('math')
+local id_whatsit = node.id('whatsit')
+
+local attr_icflag = luatexbase.attributes['luatexja@icflag']
+local attr_curjfnt = luatexbase.attributes['luatexja@curjfnt']
+
+local kanji_skip
+local xkanji_skip
+local no_skip = 0
+local after_schar = 1
+local after_wchar = 2
+local insert_skip = no_skip
+
+-- (glyph_node nr) ... (node nq) <GLUE> ,,, (node np)
+local np, nq, nrc
+local no_skip = 0 
+local after_schar = 1
+local after_wchar = 2 -- nr is a Japanese glyph_node
+local insert_skip = no_skip
+
+local cstb_get_inhibit_xsp_table = ltj.int_get_inhibit_xsp_table
+
+local function is_japanese_glyph_node(p)
+   return p and (p.id==id_glyph) 
+   and (p.font==has_attr(p,attr_curjfnt))
+end
+
+-- the following 2 functions are the lowest part.
+-- cx: the Kanji code of np
+local function insert_ascii_kanji_xkskip(head,q,cx)
+   if cstb_get_inhibit_xsp_table(cx)<=1 then return end
+   local g = node_new(id_glue)
+   g.subtype = 0; g.spec = node.copy(xkanji_skip)
+   node_insert_after(head, q, g)
+end
+
+local function insert_kanji_ascii_xkskip(head,q,p)
+   local g=true
+   local c = p.char
+   while p.components and p.subtype 
+      and math.floor(p.subtype/2)%2==1 do
+      p = p.components; c = p.char
+   end
+   if cstb_get_inhibit_xsp_table(c)%2 == 1 then
+      if cstb_get_inhibit_xsp_table(nrc)%2 == 0 then g = false end
+   else g = false
+   end
+   if g then
+      g = node_new(id_glue)
+      g.subtype = 0; g.spec = node.copy(xkanji_skip)
+      node_insert_after(head, q, g)
+   end
+end
+
+
+local function set_insert_skip_after_achar(p)
+   local c = p.char
+   while p.components and p.subtype 
+      and math.floor(p.subtype/2)%2 == 1 do
+      p=node.tail(p.components); c = p.char
+   end
+  if cstb_get_inhibit_xsp_table(c)>=2 then
+     insert_skip = after_schar
+  else
+     insert_skip = no_skip
+  end
+end
+
+-- When p is a glyph_node ...
+local function insks_around_char(head)
+   if is_japanese_glyph_node(np) then
+      if insert_skip==after_wchar then
+        local g = node_new(id_glue)
+        g.subtype=0; g.spec=node.copy(kanji_skip)
+        node_insert_before(head, np, g)
+      elseif insert_skip==after_schar then
+        insert_ascii_kanji_xkskip(head, nq, np.char)
+      end
+      insert_skip=after_wchar; nrc = np.char
+   else
+      if insert_skip==after_wchar then
+        insert_kanji_ascii_xkskip(head, nq, np)
+      end
+      set_insert_skip_after_achar(np)
+   end
+   nq = np
+end
+
+-- Return first and last glyph nodes in a hbox
+local first_char = nil
+local last_char = nil
+local find_first_char = nil
+local function check_box(box_ptr)
+   local p = box_ptr; local found_visible_node = false
+   while p do
+      if p.id==id_glyph then
+        repeat 
+           if find_first_char then
+              first_char = p; find_first_char = false
+           end
+           last_char = p; found_visible_node = true; p=node_next(p)
+           if not p then return found_visible_node end
+        until p.id~=id_glyph
+      end
+      if p.id==id_hlist then
+        found_visible_node = true
+        if p.shift==0 then
+           if check_box(p.head) then found_visible_node = true end
+        else if find_first_char then 
+              find_first_char = false
+           else 
+              last_char = nil
+           end
+        end
+      elseif p.id==id_ins    or p.id==id_mark
+          or p.id==id_adjust or p.id==id_whatsit
+          or p.id==id_penalty then
+        p=p
+      else
+        found_visible_node = true
+        if find_first_char then 
+           find_first_char = false
+        else 
+           last_char = nil
+        end
+      end
+      p = node_next(p)
+   end
+   return found_visible_node
+end 
+
+-- When np is a hlist_node ...
+local function insks_around_hbox(head)
+   if np.shift==0 then
+      find_first_char = true; first_char = nil; last_char = nil
+      if check_box(np.head) then
+        -- first char
+        if is_japanese_glyph_node(first_char) then
+           nrc = first_char.char
+           if insert_skip==after_schar then 
+              insert_ascii_kanji_xkskip(head, nq, first_char.char)
+           elseif insert_skip==after_wchar then
+              local g = node_new(id_glue)
+              g.subtype = 0; g.spec = node.copy(kanji_skip)
+              node_insert_before(head, np, g)
+           end
+           insert_skip = after_wchar
+        elseif first_char then
+           if insert_skip==after_wchar then
+              insert_kanji_ascii_xkskip(head, nq, first_char)
+           end
+           set_insert_skip_after_achar(first_char)
+        end
+        -- last char
+        if is_japanese_glyph_node(last_char) then
+           if is_japanese_glyph_node(node_next(np)) then
+              local g = node_new(id_glue)
+              g.subtype = 0; g.spec = node.copy(kanji_skip)
+              node_insert_after(head, np, g)
+           end
+           insert_skip = after_wchar; nrc = last_char.char
+        elseif last_char then
+           set_insert_skip_after_achar(last_char)
+        else insert_skip = no_skip
+        end
+      else insert_skip = no_skip
+      end
+   else insert_skip = no_skip
+   end
+   nq = np
+end
+
+-- When np is a penalty ...
+local function insks_around_penalty(head)
+   nq = np
+end
+
+-- When np is a kern ...
+-- 
+local function insks_around_kern(head)
+   if np.subtype==1 then -- \kern or \/
+      local i = has_attr(np, attr_icflag)
+      if not i then -- \kern
+        insert_skip = no_skip
+      elseif i==1 then
+        nq = np
+      end
+   elseif np.subtype==2 then 
+      -- (np = kern from \accent) .. (accent char) .. (kern from \accent) .. (glyph)
+      np = node_next(node_next(np))
+   end
+end
+
+-- When np is a math_node ...
+local function insks_around_math(head)
+   local g = { char = -1 }
+   if (np.subtype==0) and (insert_skip==after_wchar) then
+      insert_kanji_ascii_xkskip(head, nq, g)
+      insert_skip = no_skip
+   else
+      nq = np; set_insert_skip_after_achar(g)
+   end
+end
+
+function ltj.int_insert_kanji_skip(head)
+   if ltj.auto_spacing then
+      kanji_skip=tex.skip['kanjiskip']
+   else
+      kanji_skip=node_new(id_glue_spec)
+      kanji_skip.width=0;  kanji_skip.stretch=0; kanji_skip.shrink=0
+   end
+   if ltj.auto_xspacing then
+      xkanji_skip=tex.skip['xkanjiskip']
+   else
+      xkanji_skip=node_new(id_glue_spec)
+      xkanji_skip.width=0;  xkanji_skip.stretch=0; xkanji_skip.shrink=0
+   end
+   np = head; nq = nil; insert_skip = no_skip
+   while np do
+      if np.id==id_glyph then
+        repeat 
+           insks_around_char(head); np=node_next(np)
+        until (not np) or np.id~=id_glyph
+      else
+        if np.id==id_hlist then
+           insks_around_hbox(head)
+        elseif np.id==id_penalty then
+           insks_around_penalty(head)
+        elseif np.id==id_kern then
+           insks_around_kern(head)
+        elseif np.id==id_math then
+           insks_around_math(head)
+        elseif np.id==id_ins    or np.id==id_mark
+             or np.id==id_adjust or np.id==id_whatsit then
+           -- do nothing
+           np = np
+        else
+           -- rule, disc, glue, margin_kern
+           insert_skip = no_skip
+        end
+        np = node_next(np)
+      end
+   end
+   return head
+end
diff --git a/test/jfm-hang.lua b/test/jfm-hang.lua
new file mode 100644 (file)
index 0000000..911319e
--- /dev/null
@@ -0,0 +1,34 @@
+
+jfm.dir = 'yoko'
+-- 'yoko'
+
+jfm.zw= 1.0; jfm.zh = 1.0
+-- amount of ``1zw'' and ``1zh'' (these units are used in pTeX)
+
+
+-- character type
+-- jfm.define_char_type(<type>, <letters>)
+jfm.define_char_type(1, {
+  0x3042
+}) 
+jfm.define_char_type(2, {
+  0x3044
+}) 
+jfm.define_char_type(3, {
+  0x3048
+}) 
+jfm.define_char_type(4, {
+  0x304A
+}) 
+jfm.define_char_type(8, {'lineend'})
+
+
+jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(1, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(2, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(3, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0)
+jfm.define_type_dim(4, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.50)
+
+jfm.define_kern(1,8, -0.5)
+jfm.define_glue(2,3,  0.25, 0.25, 0.25)
+jfm.define_glue(1,3,  0.25, 0.0, 0.25)
\ No newline at end of file
index 4b74089..9795be3 100644 (file)
Binary files a/test/test01-noembed.pdf and b/test/test01-noembed.pdf differ
index f146421..6a4b14a 100644 (file)
 
 {\noindent\bf\tengt {\tt differentjfm=small}(小さい方)}
 
-\setjaparameter{differentjfm=small}\djtest
+\ltjsetparameter{differentjfm=small}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=large}(大きい方)}
 
-\setjaparameter{differentjfm=LARGE}\djtest
+\ltjsetparameter{differentjfm=LARGE}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=average}(default,平均)}
 
-\setjaparameter{differentjfm=AVERAGE}\djtest
+\ltjsetparameter{differentjfm=AVERAGE}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=both}(両方挿入)}
 
-\setjaparameter{differentjfm=Both}\djtest
+\ltjsetparameter{differentjfm=Both}\djtest
 
 
 \end
index deb751a..d477a98 100644 (file)
Binary files a/test/test01.pdf and b/test/test01.pdf differ
index 02b5104..33b0d02 100644 (file)
 
 {\noindent\bf\tengt {\tt differentjfm=small}(小さい方)}
 
-\setjaparameter{differentjfm=small}\djtest
+\ltjsetparameter{differentjfm=small}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=large}(大きい方)}
 
-\setjaparameter{differentjfm=LARGE}\djtest
+\ltjsetparameter{differentjfm=LARGE}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=average}(default,平均)}
 
-\setjaparameter{differentjfm=AVERAGE}\djtest
+\ltjsetparameter{differentjfm=AVERAGE}\djtest
 
 {\noindent\bf\tengt {\tt differentjfm=both}(両方挿入)}
 
-\setjaparameter{differentjfm=Both}\djtest
+\ltjsetparameter{differentjfm=Both}\djtest
 
 
 \end
index 911a967..27be300 100644 (file)
Binary files a/test/test02-latex.pdf and b/test/test02-latex.pdf differ
index a59372c..8364f34 100644 (file)
Binary files a/test/test03-after.pdf and b/test/test03-after.pdf differ
index f552683..be97b7a 100644 (file)
@@ -7,64 +7,64 @@
 
 \catcode`\@=11
 \the\luatexja@ykblshift
-\setjaparameter{ykbaselineshift=\maxdimen,autoxspacing=false}
+\ltjsetparameter{ykbaselineshift=\maxdimen,autoxspacing=false}
 \the\luatexja@ykblshift\ 
-\getjaparameter{ykbaselineshift}
+\ltjgetparameter{ykbaselineshift}
 
-\getjaparameter{kanjiskip},
-\getjaparameter{xkanjiskip}
+\ltjgetparameter{kanjiskip},
+\ltjgetparameter{xkanjiskip}
 
-\getjaparameter{autospacing},
-\getjaparameter{autoxspacing}
+\ltjgetparameter{autospacing},
+\ltjgetparameter{autoxspacing}
 
-\getjaparameter{differentjfm}.
-\setjaparameter{ykbaselineshift=0pt,autoxspacing=true}
+\ltjgetparameter{differentjfm}.
+\ltjsetparameter{ykbaselineshift=0pt,autoxspacing=true}
 
 
-あいうえお{\setjaparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: local
+あいうえお{\ltjsetparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: local
 
-あいうえお{\globalsetjaparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: global
+あいうえお{\globalltjsetparameter{ykbaselineshift=2pt}かきくけこ}さしすせそ: global
 
-\getjaparameter{prebreakpenalty}{`(},
-\getjaparameter{prebreakpenalty}{`)},
-\getjaparameter{prebreakpenalty}{`あ}
+\ltjgetparameter{prebreakpenalty}{`(},
+\ltjgetparameter{prebreakpenalty}{`)},
+\ltjgetparameter{prebreakpenalty}{`あ}
 
 
-\getjaparameter{postbreakpenalty}{`(},
-\getjaparameter{postbreakpenalty}{`)},
-\getjaparameter{postbreakpenalty}{`あ}
+\ltjgetparameter{postbreakpenalty}{`(},
+\ltjgetparameter{postbreakpenalty}{`)},
+\ltjgetparameter{postbreakpenalty}{`あ}
 
 a\inhibitglue (a)\inhibitglue aあa〜a
 
 \medskip
 xspmode
 
-\getjaparameter{cjkxspmode}{`(},
-\getjaparameter{cjkxspmode}{`)},
-\getjaparameter{cjkxspmode}{`あ},
-\getjaparameter{cjkxspmode}{`〜}
+\ltjgetparameter{cjkxspmode}{`(},
+\ltjgetparameter{cjkxspmode}{`)},
+\ltjgetparameter{cjkxspmode}{`あ},
+\ltjgetparameter{cjkxspmode}{`〜}
 
-\setjaparameter{asciixspmode={`\b,inhibit}}
+\ltjsetparameter{asciixspmode={`\b,inhibit}}
 あ[あ]あaあbあ
 
-\getjaparameter{asciixspmode}{`[},
-\getjaparameter{asciixspmode}{`]},
-\getjaparameter{asciixspmode}{`a},
-\getjaparameter{asciixspmode}{`b}
+\ltjgetparameter{asciixspmode}{`[},
+\ltjgetparameter{asciixspmode}{`]},
+\ltjgetparameter{asciixspmode}{`a},
+\ltjgetparameter{asciixspmode}{`b}
 
-{\setjaparameter{kanjiskip=0pt plus 1fi minus 1fil}\getjaparameter{kanjiskip}\par}
-{x\setjaparameter{kanjiskip=0pt plus 1fill minus 1filll}\getjaparameter{kanjiskip}\par}
+{\ltjsetparameter{kanjiskip=0pt plus 1fi minus 1fil}\ltjgetparameter{kanjiskip}\par}
+{x\ltjsetparameter{kanjiskip=0pt plus 1fill minus 1filll}\ltjgetparameter{kanjiskip}\par}
 
 \medskip
 {\tengt ■合字テスト}
 
 \tenrm
-{\setjaparameter{asciixspmode={`i,preonly},ykbaselineshift=0pt}
+{\ltjsetparameter{asciixspmode={`i,preonly},ykbaselineshift=0pt}
 あiあfiあffiあ\par}
 
-{\setjaparameter{asciixspmode={`f,postonly},ykbaselineshift=0pt}
+{\ltjsetparameter{asciixspmode={`f,postonly},ykbaselineshift=0pt}
 あfあfiあffiあ\par}
 
-\setjaparameter{asciixspmode={0,inhibit}}
+\ltjsetparameter{asciixspmode={-1,inhibit}}
 あ$a$あ
 \end
index 2060e17..3ca9e23 100644 (file)
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
index 6c0ae11..feabe8d 100644 (file)
@@ -1,6 +1,7 @@
 %#!luatex
 \input luatexja-core.sty
 
+\def\head#1{\medskip\noindent{\bf\tengt ■ #1}\par}
 \jfont\rml={psft:Ryumin-Light:jfm=ujis} at 10pt
 \rml あ\inhibitglue\char"201Cあ←Ryumin-Light
 
 \jfont\rml={file:KozMinPr6N-Regular.otf:jfm=ujis} at 10pt
 \rml あ\inhibitglue\char"201Cあ←KozMinPr6N-Regular
 
-\scrollmode
-\jfont\rml={psft:GothicBBB-Medium:jfm=bad} at 10pt % must be error
+{\scrollmode
+\gjfont\rml={psft:GothicBBB-Medium:jfm=bad} at 10pt % must be error
+}
 \rml あ123 % \rml は未定義となる
+{\tt\meaning\rml}
 
 \bigskip
 \font\rml={file:ipaexg.ttf} at 10pt\rml
 ここからは,欧文文字フォントはIPA EXゴシック
 
 
-\medskip{\tengt 文字範囲の代入/取得テスト}
+\head{文字範囲の代入/取得テスト}
 
-\defcharrange{2}{`あ,"E0-"FF}
+\ltjdefcharrange{2}{`あ,"E0-"FF}
 「\char"F4」は2番の文字範囲なので,和文扱いのはず
 
-{iso8859-1 和文扱い:\setjaparameter{jcharrange={1}}%
-\getjaparameter{jcharrange}{1}%
+{iso8859-1 和文扱い:\ltjsetparameter{jcharrange={1}}%
+\ltjgetparameter{jcharrange}{1}%
 § ¶ ° £ ¥ \char"F4}
 
-{iso8859-1 欧文扱い:\setjaparameter{jcharrange={-1}}%
-\getjaparameter{jcharrange}{1}%
+{iso8859-1 欧文扱い:\ltjsetparameter{jcharrange={-1}}%
+\ltjgetparameter{jcharrange}{1}%
 § ¶ ° £ ¥ \char"F4}
 
 
-\medskip{\tengt 文字範囲の状況取得}
-\getjaparameter{jcharrange}{0}
-\getjaparameter{jcharrange}{1}
-\getjaparameter{jcharrange}{2}
+\head{文字範囲の状況取得}
+\ltjgetparameter{jcharrange}{0}
+\ltjgetparameter{jcharrange}{1}
+\ltjgetparameter{jcharrange}{2}
 
-\medskip{\tengt 文字コード→文字範囲}
-\getjaparameter{chartorange}{`い} % must be 217
-\getjaparameter{chartorange}{`§} % must be 1
-\getjaparameter{chartorange}{"F7} % must be 2
-\getjaparameter{chartorange}{-1}  % must be -1
+\head{文字コード→文字範囲}
+\ltjgetparameter{chartorange}{`い} % must be 217
+\ltjgetparameter{chartorange}{`§} % must be 1
+\ltjgetparameter{chartorange}{"F7} % must be 2
+\ltjgetparameter{chartorange}{-1}  % must be error "
 
 \medskip
-\setjaparameter{jcharrange={-217}}
+\ltjsetparameter{jcharrange={-217}}
 ほとんど欧文扱い.2番は別(「あ」)
-\setjaparameter{jcharrange={218}}
+\ltjsetparameter{jcharrange={218}}
 和文扱いにもどる
+
+\vfill\eject
+\jfont\rmlh={psft:Ryumin-Light:jfm=hang} at 10pt
+\head{‘lineend’検証}
+\jfont\sixgt={psft:GothicBBB-Medium:jfm=ujis} at 6pt
+\font\sixtt=cmtt10 at 6pt
+
+
+\def\dumplist#1{\par\noindent\leavevmode
+\hbox to 0.2\hsize{\copy#1\hss}%
+\vbox{\hsize=0.6\hsize\sixtt\baselineskip=7.2pt\sixgt\let\\=\relax
+\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par', tex.print)}\hrule}}
+
+\setbox0=\hbox{\rmlh あえあいえ}
+\dumplist0
+
+\medskip
+\ltjsetparameter{postbreakpenalty={`あ,100}}
+\ltjsetparameter{postbreakpenalty={`い,100}}
+\ltjsetparameter{postbreakpenalty={`う,100}}
+\ltjsetparameter{postbreakpenalty={`え,100}}
+\setbox0=\hbox{\rmlh あえあいえ}
+\dumplist0
+
+\head{italic correction}
+
+\setbox0=\hbox{x{\rmlh お\/}({\rmlh お\/}あ}
+\dumplist0
+
+\setbox0=\hbox{x{\it f\/}({\it g\/}あ}
+\dumplist0
+
 \end
diff --git a/test/test05-speed.pdf b/test/test05-speed.pdf
new file mode 100644 (file)
index 0000000..6017fc1
Binary files /dev/null and b/test/test05-speed.pdf differ
diff --git a/test/test05-speed.tex b/test/test05-speed.tex
new file mode 100644 (file)
index 0000000..e79d9bd
--- /dev/null
@@ -0,0 +1,18 @@
+%#! time luatex  test05-speed.tex
+\input luatexja-core.sty
+
+\newcount\cnt\newcount\cnta
+\cnt=0
+\long\def\loop#1\repeat{\def\body{#1}\iterate}
+\loop\ifnum\cnt<10 % <= this value
+  \cnta=0 \message{\the\cnt:}\par
+  {\loop\ifnum\cnta<500 あ.「い,うえお・か(き)く)(けこ\advance\cnta1\repeat}
+  \advance\cnt1
+\repeat
+
+\end
+
+%     real time:
+% 20: 14.373s
+% 10:  8.476s
+% env: C2D E7300, Mem 4GB, LuaTeX 0.66.0pre, Gentoo amd64 unstable
\ No newline at end of file