OSDN Git Service

updated manuals.
[luatex-ja/luatexja.git] / src / ltj-math.lua
1 --
2 -- luatexja/ltj-math.lua
3 --
4
5 luatexja.load_module('base');      local ltjb = luatexja.base
6 luatexja.load_module('charrange'); local ltjc = luatexja.charrange
7 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
8 luatexja.load_module('stack');     local ltjs = luatexja.stack
9 luatexja.load_module('setwidth');  local ltjw = luatexja.setwidth
10
11 local node_new = node.new
12 local node_next = node.next
13 local node_free = node.free
14 local has_attr = node.has_attribute
15 local set_attr = node.set_attribute
16 local tex_getcount = tex.getcount
17
18 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
19 local attr_icflag = luatexbase.attributes['ltj@icflag']
20 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
21 local attr_jfam = luatexbase.attributes['jfam']
22 local attr_yablshift = luatexbase.attributes['ltj@yablshift']
23
24 local id_glyph = node.id('glyph')
25 local id_hlist = node.id('hlist')
26 local id_vlist = node.id('vlist')
27 local id_mchar = node.id('math_char')
28 local id_sub_box = node.id('sub_box')
29 local id_radical = node.id('radical')
30 local id_choice  = node.id('choice')
31 local id_accent  = node.id('accent')
32 local id_style   = node.id('style')
33 local id_frac    = node.id('fraction')
34 local id_simple  = node.id('noad')
35 local id_sub_mlist = node.id('sub_mlist')
36
37 local PROCESSED  = luatexja.icflag_table.PROCESSED
38
39 local ltjf_font_metric_table = ltjf.font_metric_table
40 local ltjf_find_char_class = ltjf.find_char_class
41
42 -- table of mathematical characters
43 local is_math_letters = {}
44
45 local conv_jchar_to_hbox_A
46
47 -- sty : 0 (display or text), 1 (script), >=2 (scriptscript)
48 local function conv_jchar_to_hbox(head, sty)
49    local p = head
50    local bhead = head
51    while p do
52       if p.id == id_simple or p.id == id_accent then
53          p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
54          p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
55          p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
56       elseif p.id == id_choice then
57          p.display = conv_jchar_to_hbox(p.display, 0)
58          p.text = conv_jchar_to_hbox(p.text, 0)
59          p.script = conv_jchar_to_hbox(p.script, 1)
60          p.scriptscript = conv_jchar_to_hbox(p.scriptscript, 2)
61       elseif p.id == id_frac then
62          p.num = conv_jchar_to_hbox_A(p.num, sty + 1)
63          p.denom = conv_jchar_to_hbox_A(p.denom, sty + 1)
64       elseif p.id == id_radical then
65          p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
66          p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
67          p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
68          if p.degree then
69             p.degree = conv_jchar_to_hbox_A(p.degree, sty + 1)
70          end
71       elseif p.id == id_style then
72          if p.style == "display'" or  p.style == 'display'
73             or  p.style == "text'" or  p.style == 'text' then
74             sty = 0
75          elseif  p.style == "script'" or  p.style == 'script' then
76             sty = 1
77          else sty = 2
78          end
79        end
80        p = node.next(p)
81    end 
82    return head
83 end 
84
85 local MJT  = luatexja.stack_table_index.MJT
86 local MJS  = luatexja.stack_table_index.MJS
87 local MJSS = luatexja.stack_table_index.MJSS
88
89 conv_jchar_to_hbox_A = 
90 function (p, sty)
91    if not p then return nil
92    else
93       local pid = p.id
94       if pid == id_sub_mlist then
95          if p.head then
96             p.head = conv_jchar_to_hbox(p.head, sty)
97          end
98       elseif pid == id_mchar then
99          local fam = has_attr(p, attr_jfam) or -1
100          if (not is_math_letters[p.char]) and ltjc.is_ucs_in_japanese_char(p) and fam>=0 then
101             local f = ltjs.get_penalty_table(MJT + 0x100 * sty + fam, -1, tex_getcount('ltj@@stack'))
102             if f ~= -1 then
103                local q = node_new(id_sub_box)
104                local r = node_new(id_glyph); r.next = nil
105                r.char = p.char; r.font = f; r.subtype = 256
106                local k = has_attr(r,attr_ykblshift) or 0 
107                set_attr(r, attr_ykblshift, 0)
108                -- ltj-setwidth 内で実際の位置補正はおこなうので,補正量を退避
109                ltjw.head = r; 
110                local met = ltjf_font_metric_table[f]
111                ltjw.capsule_glyph(r, tex.mathdir , true, met, ltjf_find_char_class(p.char, met));
112                q.head = ltjw.head; node_free(p); p=q;
113                set_attr(q.head, attr_yablshift, k)
114             end
115          end
116       elseif pid == id_sub_box and p.head then
117          -- \hbox で直に与えられた内容は上下位置を補正する必要はない
118          set_attr(p.head, attr_icflag, PROCESSED)
119       end
120    end
121    return p
122 end
123
124 luatexbase.add_to_callback('mlist_to_hlist', 
125    function (n, display_type, penalties)
126       local head = conv_jchar_to_hbox(n, 0);
127       head = node.mlist_to_hlist(head, display_type, penalties)
128       return head
129    end,'ltj.mlist_to_hlist', 1)
130
131 luatexja.math = { is_math_letters = is_math_letters }