OSDN Git Service

Merge branch 'zh-maqiyuan' into kitagawa_test
[luatex-ja/luatexja.git] / src / ltj-math.lua
1 --
2 -- luatexja/math.lua
3 --
4 luatexbase.provides_module({
5   name = 'luatexja.math',
6   date = '2011/08/14',
7   version = '0.1',
8   description = 'Handling routines for Japanese characters in math mode',
9 })
10 module('luatexja.math', package.seeall)
11
12 luatexja.load_module('base');      local ltjb = luatexja.base
13 luatexja.load_module('charrange'); local ltjc = luatexja.charrange
14 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
15 luatexja.load_module('stack');     local ltjs = luatexja.stack
16 luatexja.load_module('setwidth');  local ltjw = luatexja.setwidth
17
18 local node_new = node.new
19 local node_next = node.next
20 local node_free = node.free
21 local has_attr = node.has_attribute
22 local set_attr = node.set_attribute
23
24 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
25 local attr_icflag = luatexbase.attributes['ltj@icflag']
26 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
27 local attr_jfam = luatexbase.attributes['jfam']
28 local attr_yablshift = luatexbase.attributes['ltj@yablshift']
29
30 local id_glyph = node.id('glyph')
31 local id_hlist = node.id('hlist')
32 local id_vlist = node.id('vlist')
33 local id_mchar = node.id('math_char')
34 local id_sub_box = node.id('sub_box')
35 local id_radical = node.id('radical')
36 local id_choice  = node.id('choice')
37 local id_accent  = node.id('accent')
38 local id_style   = node.id('style')
39 local id_frac    = node.id('fraction')
40 local id_simple  = node.id('noad')
41 local id_sub_mlist = node.id('sub_mlist')
42
43 local PROCESSED = 8
44
45 local ltjf_font_metric_table = ltjf.font_metric_table
46 local ltjf_find_char_class = ltjf.find_char_class
47
48 -- table of mathematical characters
49 is_math_letters = {}
50
51 local conv_jchar_to_hbox_A
52
53 -- sty : 0 (display or text), 1 (script), >=2 (scriptscript)
54 local function conv_jchar_to_hbox(head, sty)
55    local p = head
56    local bhead = head
57    while p do
58       if p.id == id_simple or p.id == id_accent then
59          p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
60          p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
61          p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
62       elseif p.id == id_choice then
63          p.display = conv_jchar_to_hbox(p.display, 0)
64          p.text = conv_jchar_to_hbox(p.text, 0)
65          p.script = conv_jchar_to_hbox(p.script, 1)
66          p.scriptscript = conv_jchar_to_hbox(p.scriptscript, 2)
67       elseif p.id == id_frac then
68          p.num = conv_jchar_to_hbox_A(p.num, sty + 1)
69          p.denom = conv_jchar_to_hbox_A(p.denom, sty + 1)
70       elseif p.id == id_radical then
71          p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
72          p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
73          p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
74          if p.degree then
75             p.degree = conv_jchar_to_hbox_A(p.degree, sty + 1)
76          end
77       elseif p.id == id_style then
78          if p.style == "display'" or  p.style == 'display'
79             or  p.style == "text'" or  p.style == 'text' then
80             sty = 0
81          elseif  p.style == "script'" or  p.style == 'script' then
82             sty = 1
83          else sty = 2
84          end
85        end
86        p = node.next(p)
87    end 
88    return head
89 end 
90
91 conv_jchar_to_hbox_A = 
92 function (p, sty)
93    if not p then return nil
94    elseif p.id == id_sub_mlist then
95       if p.head then
96          p.head = conv_jchar_to_hbox(p.head, sty)
97       end
98    elseif p.id == 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 mode = 'mjss'
102          if sty == 0 then mode = 'mjtext'
103          elseif sty == 1 then mode = 'mjscr'
104          end
105          local f = ltjs.get_penalty_table(mode, fam, -1, tex.getcount('ltj@@stack'))
106          if f ~= -1 then
107             local q = node_new(id_sub_box)
108             local r = node_new(id_glyph); r.next = nil
109             r.char = p.char; r.font = f; r.subtype = 256
110             set_attr(r, attr_icflag, PROCESSED)
111             set_attr(r, attr_yablshift, 0)
112             local met = ltjf_font_metric_table[f]
113             local class = ltjf_find_char_class(p.char, met)
114             set_attr(r, attr_jchar_class, class)
115             ltjw.char_data = ltjf.metrics[met.jfm].size_cache[met.size].char_type[class]
116             ltjw.head = r; ltjw.capsule_glyph(r, tex.mathdir , true, met, class);
117             q.head = ltjw.head; node_free(p); p=q;
118          end
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)