4 luatexbase.provides_module({
5 name = 'luatexja.math',
8 description = 'Handling routines for Japanese characters in math mode',
10 module('luatexja.math', package.seeall)
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
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 local tex_getcount = tex.getcount
25 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
26 local attr_icflag = luatexbase.attributes['ltj@icflag']
27 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
28 local attr_jfam = luatexbase.attributes['jfam']
29 local attr_yablshift = luatexbase.attributes['ltj@yablshift']
31 local id_glyph = node.id('glyph')
32 local id_hlist = node.id('hlist')
33 local id_vlist = node.id('vlist')
34 local id_mchar = node.id('math_char')
35 local id_sub_box = node.id('sub_box')
36 local id_radical = node.id('radical')
37 local id_choice = node.id('choice')
38 local id_accent = node.id('accent')
39 local id_style = node.id('style')
40 local id_frac = node.id('fraction')
41 local id_simple = node.id('noad')
42 local id_sub_mlist = node.id('sub_mlist')
46 local ltjf_font_metric_table = ltjf.font_metric_table
47 local ltjf_find_char_class = ltjf.find_char_class
49 -- table of mathematical characters
52 local conv_jchar_to_hbox_A
54 -- sty : 0 (display or text), 1 (script), >=2 (scriptscript)
55 local function conv_jchar_to_hbox(head, sty)
59 if p.id == id_simple or p.id == id_accent then
60 p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
61 p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
62 p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
63 elseif p.id == id_choice then
64 p.display = conv_jchar_to_hbox(p.display, 0)
65 p.text = conv_jchar_to_hbox(p.text, 0)
66 p.script = conv_jchar_to_hbox(p.script, 1)
67 p.scriptscript = conv_jchar_to_hbox(p.scriptscript, 2)
68 elseif p.id == id_frac then
69 p.num = conv_jchar_to_hbox_A(p.num, sty + 1)
70 p.denom = conv_jchar_to_hbox_A(p.denom, sty + 1)
71 elseif p.id == id_radical then
72 p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
73 p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
74 p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
76 p.degree = conv_jchar_to_hbox_A(p.degree, sty + 1)
78 elseif p.id == id_style then
79 if p.style == "display'" or p.style == 'display'
80 or p.style == "text'" or p.style == 'text' then
82 elseif p.style == "script'" or p.style == 'script' then
92 conv_jchar_to_hbox_A =
94 if not p then return nil
95 elseif p.id == id_sub_mlist then
97 p.head = conv_jchar_to_hbox(p.head, sty)
99 elseif p.id == id_mchar then
100 local fam = has_attr(p, attr_jfam) or -1
101 if (not is_math_letters[p.char]) and ltjc.is_ucs_in_japanese_char(p) and fam>=0 then
103 if sty == 0 then mode = 'mjtext'
104 elseif sty == 1 then mode = 'mjscr'
106 local f = ltjs.get_penalty_table(mode, fam, -1, tex_getcount('ltj@@stack'))
108 local q = node_new(id_sub_box)
109 local r = node_new(id_glyph); r.next = nil
110 r.char = p.char; r.font = f; r.subtype = 256
111 set_attr(r, attr_ykblshift, 0)
112 set_attr(r, attr_icflag, PROCESSED)
113 local met = ltjf_font_metric_table[f]
114 ltjw.head = r; ltjw.capsule_glyph(r, tex.mathdir , true, met, ltjf_find_char_class(p.char, met));
115 q.head = ltjw.head; node_free(p); p=q;
122 luatexbase.add_to_callback('mlist_to_hlist',
123 function (n, display_type, penalties)
124 local head = conv_jchar_to_hbox(n, 0);
125 head = node.mlist_to_hlist(head, display_type, penalties)
127 end,'ltj.mlist_to_hlist', 1)