summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua443
1 files changed, 443 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua
new file mode 100644
index 00000000000..3d23d5f602f
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-base.lua
@@ -0,0 +1,443 @@
+--
+-- luatexja/base.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.base',
+ date = '2011/04/01',
+ version = '0.1',
+ description = '',
+})
+module('luatexja.base', package.seeall)
+local err, warn, info, log = luatexbase.errwarinf(_NAME)
+
+local ltb = luatexbase
+local tostring = tostring
+local node, table, tex, token = node, table, tex, token
+
+local cat_lp = luatexbase.catcodetables['latex-package']
+
+--------------------
+
+public_name = 'luatexja'
+public_version = 'alpha'
+
+-------------------- Fully-expandable error messaging
+do
+--! LaTeX 形式のエラーメッセージ(\PackageError 等)を
+--! Lua 関数の呼び出しで行う.
+
+ local LF = "\n"
+ local err_break = ""
+ local err_main = ""
+ local err_help = ""
+
+ local function message_cont(str, c)
+ return str:gsub(err_break, LF .. c)
+ end
+ local function into_lines(str)
+ return str:gsub(err_break, LF):explode(LF)
+ end
+
+ function _error_set_break(str)
+ err_break = str
+ end
+
+ function _error_set_message(msgcont, main, help)
+ err_main = message_cont(main, msgcont)
+ err_help = into_lines(help)
+ end
+
+ function _error_show(escchar)
+ local escapechar = tex.escapechar
+ local newlinechar = tex.newlinechar
+ local errorcontextlines = tex.errorcontextlines
+ if not escchar then tex.escapechar = -1 end
+ tex.newlinechar = 10
+ tex.errorcontextlines = -1
+ tex.error(err_main, err_help)
+ tex.escapechar = escapechar
+ tex.newlinechar = newlinechar
+ tex.errorcontextlines = errorcontextlines
+ end
+
+ local message_a = "Type H <return> for immediate help"
+
+ function generic_error(msgcont, main, ref, help)
+ local mainref = main..".\n\n"..ref.."\n"..message_a
+ _error_set_message(msgcont, mainref, help)
+ _error_show(true)
+ end
+
+ function _generic_warn_info(msgcont, main, warn, line)
+ local mainc = message_cont(main, msgcont)
+ local br = warn and "\n" or ""
+ local out = warn and "term and log" or "log"
+ local on_line = line and (" on input line "..tex.inputlineno) or ""
+ local newlinechar = tex.newlinechar
+ tex.newlinechar = -1
+ texio.write_nl(out, br..main..on_line.."."..br)
+ tex.newlinechar = newlinechar
+ end
+
+ function generic_warning(msgcont, main)
+ _generic_warn_info(msgcont, main, true, true)
+ end
+ function generic_warning_no_line(msgcont, main)
+ _generic_warn_info(msgcont, main, true, false)
+ end
+ function generic_info(msgcont, main)
+ _generic_warn_info(msgcont, main, false, true)
+ end
+ function generic_info_no_line(msgcont, main)
+ _generic_warn_info(msgcont, main, false, false)
+ end
+
+ function package_error(pkgname, main, help)
+ generic_error("("..pkgname.." ",
+ "Package "..pkgname.." Error: "..main,
+ "See the "..pkgname.." package documentation for explanation.",
+ help)
+ end
+ function package_warning(pkgname, main)
+ generic_warning("("..pkgname.." ",
+ "Package "..pkgname.." Warning: "..main)
+ end
+ function package_warning_no_line(pkgname, main)
+ generic_warning_no_line("("..pkgname.." ",
+ "Package "..pkgname.." Warning: "..main)
+ end
+ function package_info(pkgname, main)
+ generic_info("("..pkgname.." ",
+ "Package "..pkgname.." Info: "..main)
+ end
+ function package_info_no_line(pkgname, main)
+ generic_info_no_line("("..pkgname.." ",
+ "Package "..pkgname.." Info: "..main)
+ end
+
+ function ltj_error(main, help)
+ package_error(public_name, main, help)
+ end
+ function ltj_warning_no_line(main)
+ package_warning_no_line(public_name, main, help)
+ end
+
+end
+-------------------- TeX stream I/O
+do
+
+--! ixbase.print() と同じ
+ --- Extension to tex.print(). Each argument string may contain
+ -- newline characters, in which case the string is output (to
+ -- TeX input stream) as multiple lines.
+ -- @param ... (string) string to output
+ function mprint(...)
+ local arg = {...}
+ local lines = {}
+ if type(arg[1]) == "number" then
+ table.insert(lines, arg[1])
+ table.remove(arg, 1)
+ end
+ for _, cnk in ipairs(arg) do
+ local ls = cnk:explode("\n")
+ if ls[#ls] == "" then
+ table.remove(ls, #ls)
+ end
+ for _, l in ipairs(ls) do
+ table.insert(lines, l)
+ end
+ end
+ return tex.print(unpack(lines))
+ end
+
+end
+-------------------- Handling of TeX values
+do
+
+ local glue_spec_id = node.id("glue_spec")
+
+ local function copy_skip(s1, s2)
+ if not s1 then
+ s1 = node.new(glue_spec_id)
+ end
+ s1.width = s2.width or 0
+ s1.stretch = s2.stretch or 0
+ s1.stretch_order = s2.stretch_order or 0
+ s1.shrink = s2.shrink or 0
+ s1.shrink_order = s2.shrink_order or 0
+ return s1
+ end
+
+--! ixbase.to_dimen() と同じ
+ function to_dimen(val)
+ if val == nil then
+ return 0
+ elseif type(val) == "number" then
+ return val
+ else
+ return tex.sp(tostring(val))
+ end
+ end
+
+ local function parse_dimen(val)
+ val = tostring(val):lower()
+ local r, fil = val:match("([-.%d]+)fi(l*)")
+ if r then
+ val, fil = r.."pt", fil:len() + 1
+ else
+ fil = 0
+ end
+ return tex.sp(val), fil
+ end
+
+--! ixbase.to_skip() と同じ
+ function to_skip(val)
+ if type(val) == "userdata" then
+ return val
+ end
+ local res = node.new(glue_spec_id)
+ if val == nil then
+ res.width = 0
+ elseif type(val) == "number" then
+ res.width = val
+ elseif type(val) == "table" then
+ copy_skip(res, val)
+ else
+ local t = tostring(val):lower():explode()
+ local w, p, m = t[1], t[3], t[5]
+ if t[2] == "minus" then
+ p, m = nil, t[3]
+ end
+ res.width = tex.sp(t[1])
+ if t[3] then
+ res.stretch, res.stretch_order = parse_dimen(t[3])
+ end
+ if t[5] then
+ res.shrink, res.shrink_order = parse_dimen(t[5])
+ end
+ end
+ return res
+ end
+
+ function dump_skip(s)
+ print(("%s+%s<%s>-%s<%s>"):format(
+ s.width or 0, s.stretch or 0, s.stretch_order or 0,
+ s.shrink or 0, s.shrink_order or 0))
+ end
+
+end
+-------------------- Virtual table for LaTeX counters
+do
+
+--! ixbase.counter と同じ
+ counter = {}
+ local mt_counter = {}
+ setmetatable(counter, mt_counter)
+
+ function mt_counter.__index(tbl, key)
+ return tex.count['c@'..key]
+ end
+ function mt_counter.__newindex(tbl, key, val)
+ tex.count['c@'..key] = val
+ end
+
+--! ixbase.length は tex.skip と全く同じなので不要.
+
+end
+-------------------- Number handling in TeX source
+do
+
+ local tok_escape = token.create("ltj@@q@escape")
+ local tok_num = token.create("ltj@@q@escapenum")
+ local c_id_assign_int = token.command_id("assign_int")
+ local c_id_char_given = token.command_id("char_given")
+
+ local function error_scan()
+ _M.package_error("luatexja",
+ "Missing number of a permitted form, treated as zero",
+ "A number should have been here; I inserted '0'.")
+ end
+
+ local function get_expd_next()
+ local next = token.get_next()
+ while token.is_expandable(next) do
+ token.expand(next)
+ next = token.get_next()
+ end
+ return next
+ end
+
+ local function grab_decimal(next, res)
+ table.insert(res, next)
+ while true do
+ next = get_expd_next()
+ if not (next[1] == 12 and 0x30 <= next[2] and next[2] <= 0x39) then
+ break
+ end
+ table.insert(res, next)
+ end
+ if next[1] == 10 then next = nil end
+ return true, next
+ end
+
+ local function grab_hexa(next, res)
+ local ok = false
+ table.insert(res, next)
+ while true do
+ next = get_expd_next()
+ if not ((next[1] == 12 and (0x30 <= next[2] and next[2] <= 0x39)) or
+ ((next[1] == 12 or next[1] == 11) and
+ (0x41 <= next[2] and next[2] <= 0x46))) then
+ break
+ end
+ ok = true
+ table.insert(res, next)
+ end
+ if next[1] == 10 then next = nil end
+ return ok, next
+ end
+
+ local function grab_octal(next, res)
+ local ok = false
+ table.insert(res, next)
+ while true do
+ next = get_expd_next()
+ if not (next[1] == 12 and (0x30 <= next[2] and next[2] <= 0x37)) then
+ break
+ end
+ ok = true
+ table.insert(res, next)
+ end
+ if next[1] == 10 then next = nil end
+ return ok, next
+ end
+
+ local function grab_charnum(next, res)
+ table.insert(res, next)
+ next = token.get_next()
+ table.insert(res, next)
+ next = get_expd_next()
+ if next[1] == 10 then next = nil end
+ return true, next
+ end
+
+ local function scan_with(delay, scanner)
+ local function proc()
+ if delay ~= 0 then
+ if delay > 0 then delay = delay - 1 end
+ return token.get_next()
+ else
+ local cont, back = scanner()
+ if not cont then
+ ltb.remove_from_callback("token_filter", "ltj@grab@num")
+ end
+ return back
+ end
+ end
+ ltb.add_to_callback("token_filter", proc, "ltj@grab@num", 1)
+ end
+
+ function scan_brace()
+ scan_with(1, function()
+ local next = token.get_next()
+ if next[1] == 1 then
+ return false, { tok_escape, next }
+ elseif next[1] == 10 then
+ return true, { next }
+ else
+ return false, { next }
+ end
+ end)
+ end
+
+ function scan_number()
+ scan_with(1, function()
+ local next = get_expd_next()
+ local res, ok = { tok_num }, false
+ while true do
+ if next[1] == 12 and (next[2] == 0x2B or next[2] == 0x2D) then
+ table.insert(res, next)
+ elseif next[1] ~= 10 then
+ break
+ end
+ next = get_expd_next()
+ end
+ if next[1] == 12 and 0x30 <= next[2] and next[2] <= 0x39 then
+ ok, next = grab_decimal(next, res)
+ elseif next[1] == 12 and next[2] == 0x22 then
+ ok, next = grab_hexa(next, res)
+ elseif next[1] == 12 and next[2] == 0x27 then
+ ok, next = grab_octal(next, res)
+ elseif next[1] == 12 and next[2] == 0x60 then
+ ok, next = grab_charnum(next, res)
+ elseif next[1] == c_id_assign_int or next[1] == c_id_char_given then
+ table.insert(res, next)
+ ok, next = true, nil
+ end
+ if ok then
+ table.insert(res, tok_num)
+ else
+ error_scan()
+ res = { tok_escape }
+ end
+ if next then table.insert(res, next) end
+ return false, res
+ end)
+ end
+
+end
+-------------------- TeX register allocation
+do
+ local cmod_base_count = token.create('ltj@@count@zero')[2]
+ local cmod_base_attr = token.create('ltj@@attr@zero')[2]
+ local cmod_base_dimen = token.create('ltj@@dimen@zero')[2]
+ local cmod_base_skip = token.create('ltj@@skip@zero')[2]
+
+ function const_number(name)
+ if name:sub(1, 1) == '\\' then name = name:sub(2) end
+ return token.create(name)[2]
+ end
+
+ function count_number(name)
+ if name:sub(1, 1) == '\\' then name = name:sub(2) end
+ return token.create(name)[2] - cmod_base_count
+ end
+
+ function attribute_number(name)
+ if name:sub(1, 1) == '\\' then name = name:sub(2) end
+ return token.create(name)[2] - cmod_base_attr
+ end
+
+ function dimen_number(name)
+ if name:sub(1, 1) == '\\' then name = name:sub(2) end
+ return token.create(name)[2] - cmod_base_dimen
+ end
+
+ function skip_number(name)
+ if name:sub(1, 1) == '\\' then name = name:sub(2) end
+ return token.create(name)[2] - cmod_base_skip
+ end
+
+end
+-------------------- mock of debug logger
+
+if not _M.debug or _M.debug == _G.debug then
+ local function no_op() end
+ debug = no_op
+ package_debug = no_op
+ show_term = no_op
+ show_log = no_op
+ function debug_logger()
+ return no_op
+ end
+end
+
+-------------------- getting next token
+cstemp = nil
+function get_cs(s)
+ cstemp = token.csname_name(token.get_next())
+ tex.sprint(cat_lp,'\\' .. s)
+end
+
+-------------------- all done
+-- EOF