summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/optex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/base/optex.lua')
-rw-r--r--macros/luatex/optex/base/optex.lua356
1 files changed, 0 insertions, 356 deletions
diff --git a/macros/luatex/optex/base/optex.lua b/macros/luatex/optex/base/optex.lua
deleted file mode 100644
index 2d83f38ed6..0000000000
--- a/macros/luatex/optex/base/optex.lua
+++ /dev/null
@@ -1,356 +0,0 @@
--- This is part of the OpTeX project, see http://petr.olsak.net/optex
-
--- The basic lua functions and declarations used in \OpTeX/ are here
-
--- GENERAL
-
--- Error function used by following functions for critical errors.
-local function err(message)
- error("\nerror: "..message.."\n")
-end
---
--- For a `\chardef`'d, `\countdef`'d, etc., csname return corresponding register
--- number. The responsibility of providing a `\XXdef`'d name is on the caller.
-function registernumber(name)
- return token.create(name).index
-end
---
--- ALLOCATORS
-alloc = alloc or {}
---
--- An attribute allocator in Lua that cooperates with normal \OpTeX/ allocator.
-local attributes = {}
-function alloc.new_attribute(name)
- local cnt = tex.count["_attributealloc"] + 1
- if cnt > 65534 then
- tex.error("No room for a new attribute")
- else
- tex.setcount("global", "_attributealloc", cnt)
- texio.write_nl("log", '"'..name..'"=\\attribute'..tostring(cnt))
- attributes[name] = cnt
- return cnt
- end
-end
---
--- `provides_module` is needed by older version of luaotfload
-provides_module = function() end
---
--- CALLBACKS
-callback = callback or {}
---
--- Save `callback.register` function for internal use.
-local callback_register = callback.register
-function callback.register(name, fn)
- err("direct registering of callbacks is forbidden, use 'callback.add_to_callback'")
-end
---
--- Table with lists of functions for different callbacks.
-local callback_functions = {}
--- Table that maps callback name to a list of descriptions of its added
--- functions. The order corresponds with `callback_functions`.
-local callback_description = {}
---
--- Table used to differentiate user callbacks from standard callbacks. Contains
--- user callbacks as keys.
-local user_callbacks = {}
--- Table containing default functions for callbacks, which are called if either
--- a user created callback is defined, but doesn't have added functions or for
--- standard callbacks that are \"extended" (see `mlist_to_hlist` and its pre/post
--- filters below).
-local default_functions = {}
---
--- Table that maps standard (and later user) callback names to their types.
-local callback_types = {
- -- file discovery
- find_read_file = "exclusive",
- find_write_file = "exclusive",
- find_font_file = "data",
- find_output_file = "data",
- find_format_file = "data",
- find_vf_file = "data",
- find_map_file = "data",
- find_enc_file = "data",
- find_pk_file = "data",
- find_data_file = "data",
- find_opentype_file = "data",
- find_truetype_file = "data",
- find_type1_file = "data",
- find_image_file = "data",
-
- open_read_file = "exclusive",
- read_font_file = "exclusive",
- read_vf_file = "exclusive",
- read_map_file = "exclusive",
- read_enc_file = "exclusive",
- read_pk_file = "exclusive",
- read_data_file = "exclusive",
- read_truetype_file = "exclusive",
- read_type1_file = "exclusive",
- read_opentype_file = "exclusive",
-
- -- data processing
- process_input_buffer = "data",
- process_output_buffer = "data",
- process_jobname = "data",
- input_level_string = "data",
-
- -- node list processing
- contribute_filter = "simple",
- buildpage_filter = "simple",
- build_page_insert = "exclusive",
- pre_linebreak_filter = "list",
- linebreak_filter = "exclusive",
- append_to_vlist_filter = "exclusive",
- post_linebreak_filter = "reverselist",
- hpack_filter = "list",
- vpack_filter = "list",
- hpack_quality = "list",
- vpack_quality = "list",
- process_rule = "exclusive",
- pre_output_filter = "list",
- hyphenate = "simple",
- ligaturing = "simple",
- kerning = "simple",
- insert_local_par = "simple",
- mlist_to_hlist = "exclusive",
-
- -- information reporting
- pre_dump = "simple",
- start_run = "simple",
- stop_run = "simple",
- start_page_number = "simple",
- stop_page_number = "simple",
- show_error_hook = "simple",
- show_error_message = "simple",
- show_lua_error_hook = "simple",
- start_file = "simple",
- stop_file = "simple",
- call_edit = "simple",
- finish_synctex = "simple",
- wrapup_run = "simple",
-
- -- pdf related
- finish_pdffile = "data",
- finish_pdfpage = "data",
- page_order_index = "data",
- process_pdf_image_content = "data",
-
- -- font related
- define_font = "exclusive",
- glyph_not_found = "exclusive",
- glyph_info = "exclusive",
-
- -- undocumented
- glyph_stream_provider = "exclusive",
- provide_charproc_data = "exclusive",
-}
---
--- Return a list containing descriptions of added callback functions for
--- specific callback.
-function callback.callback_descriptions(name)
- return callback_description[name] or {}
-end
-
-local valid_callback_types = {
- exclusive = true,
- simple = true,
- data = true,
- list = true,
- reverselist = true,
-}
---
--- Create a user callback that can only be called manually using
--- `call_callback`. A default function is only needed by "exclusive" callbacks.
-function callback.create_callback(name, cbtype, default)
- if callback_types[name] then
- err("cannot create callback '"..name.."' - it already exists")
- elseif not valid_callback_types[cbtype] then
- err("cannot create callback '"..name.. "' with invalid callback type '"..cbtype.."'")
- elseif ctype == "exclusive" and not default then
- err("unable to create exclusive callback '"..name.."', default function is required")
- end
-
- callback_types[name] = cbtype
- default_functions[name] = default or nil
- user_callbacks[name] = true
-end
---
--- Add a function to the list of functions executed when callback is called.
--- For standard luatex callback a proxy function that calls our machinery is
--- registered as the real callback function. This doesn't happen for user
--- callbacks, that are called manually by user using `call_callback` or for
--- standard callbacks that have default functions -- like `mlist_to_hlist` (see
--- below).
-function callback.add_to_callback(name, fn, description)
- if user_callbacks[name] or callback_functions[name] or default_functions[name] then
- -- either:
- -- a) user callback - no need to register anything
- -- b) standard callback that has already been registered
- -- c) standard callback with default function registered separately
- -- (mlist_to_hlist)
- elseif callback_types[name] then
- -- This is a standard luatex callback with first function being added,
- -- register a proxy function as a real callback. Assert, so we know
- -- when things break, like when callbacks get redefined by future
- -- luatex.
- assert(callback_register(name, function(...)
- return callback.call_callback(name, ...)
- end))
- else
- err("cannot add to callback '"..name.."' - no such callback exists")
- end
-
- -- add function to callback list for this callback
- callback_functions[name] = callback_functions[name] or {}
- table.insert(callback_functions[name], fn)
-
- -- add description to description list
- callback_description[name] = callback_description[name] or {}
- table.insert(callback_description[name], description)
-end
---
--- Remove a function from the list of functions executed when callback is
--- called. If last function in the list is removed delete the list entirely.
-function callback.remove_from_callback(name, description)
- local descriptions = callback_description[name]
- local index
- for i, desc in ipairs(descriptions) do
- if desc == description then
- index = i
- break
- end
- end
-
- table.remove(descriptions, index)
- local fn = table.remove(callback_functions[name], index)
-
- if #descriptions == 0 then
- -- Delete the list entirely to allow easy checking of "truthiness".
- callback_functions[name] = nil
-
- if not user_callbacks[name] and not default_functions[name] then
- -- this is a standard callback with no added functions and no
- -- default function (i.e. not mlist_to_hlist), restore standard
- -- behaviour by unregistering.
- callback_register(name, nil)
- end
- end
-
- return fn, description
-end
---
--- helper iterator generator for iterating over reverselist callback functions
-local function reverse_ipairs(t)
- local i, n = #t + 1, 1
- return function()
- i = i - 1
- if i >= n then
- return i, t[i]
- end
- end
-end
---
--- Call all functions added to callback. This function handles standard
--- callbacks as well as user created callbacks. It can happen that this
--- function is called when no functions were added to callback -- like for user
--- created callbacks or `mlist_to_hlist` (see below), these are handled either
--- by a default function (like for `mlist_to_hlist` and those user created
--- callbacks that set a default function) or by doing nothing for empty
--- function list.
-function callback.call_callback(name, ...)
- local cbtype = callback_types[name]
- -- either take added functions or the default function if there is one
- local functions = callback_functions[name] or {default_functions[name]}
-
- if cbtype == nil then
- err("cannot call callback '"..name.."' - no such callback exists")
- elseif cbtype == "exclusive" then
- -- only one function, atleast default function is guaranteed by
- -- create_callback
- return functions[1](...)
- elseif cbtype == "simple" then
- -- call all functions one after another, no passing of data
- for _, fn in ipairs(functions) do
- fn(...)
- end
- return
- elseif cbtype == "data" then
- -- pass data (first argument) from one function to other, while keeping
- -- other arguments
- local data = (...)
- for _, fn in ipairs(functions) do
- data = fn(data, select(2, ...))
- end
- return data
- end
-
- -- list and reverselist are like data, but "true" keeps data (head node)
- -- unchanged and "false" ends the chain immediately
- local iter
- if cbtype == "list" then
- iter = ipairs
- elseif cbtype == "reverselist" then
- iter = reverse_ipairs
- end
-
- local head = (...)
- local new_head
- local changed = false
- for _, fn in iter(functions) do
- new_head = fn(head, select(2, ...))
- if new_head == false then
- return false
- elseif new_head ~= true then
- head = new_head
- changed = true
- end
- end
- return not changed or head
-end
---
--- Create \"virtual" callbacks `pre/post_mlist_to_hlist_filter` by setting
--- `mlist_to_hlist` callback. The default behaviour of `mlist_to_hlist` is kept by
--- using a default function, but it can still be overriden by using
--- `add_to_callback`.
-default_functions["mlist_to_hlist"] = node.mlist_to_hlist
-callback.create_callback("pre_mlist_to_hlist_filter", "list")
-callback.create_callback("post_mlist_to_hlist_filter", "reverselist")
-callback_register("mlist_to_hlist", function(head, ...)
- -- pre_mlist_to_hlist_filter
- local new_head = callback.call_callback("pre_mlist_to_hlist_filter", head, ...)
- if new_head == false then
- node.flush_list(head)
- return nil
- elseif new_head ~= true then
- head = new_head
- end
-
- -- mlist_to_hlist means either added functions or standard luatex behavior
- -- of node.mlist_to_hlist (handled by default function)
- head = callback.call_callback("mlist_to_hlist", head, ...)
-
- -- post_mlist_to_hlist_filter
- new_head = callback.call_callback("post_mlist_to_hlist_filter", head, ...)
- if new_head == false then
- node.flush_list(head)
- return nil
- elseif new_head ~= true then
- head = new_head
- end
- return head
-end)
---
--- Compatibility with \LaTeX/ through luatexbase namespace. Needed for
--- luaotfload.
-luatexbase = {
- registernumber = registernumber,
- attributes = attributes,
- provides_module = provides_module,
- new_attribute = alloc.new_attribute,
- callback_descriptions = callback.callback_descriptions,
- create_callback = callback.create_callback,
- add_to_callback = callback.add_to_callback,
- remove_from_callback = callback.remove_from_callback,
- call_callback = callback.call_callback,
- callbacktypes = {}
-}