Show error hook

From LuaTeXWiki
Revision as of 10:24, 28 February 2012 by Paul (talk | contribs) (The API is not deprecated in LuaTeX itself, it's luatexbase that deprecates it; it's better here to document LuaTeX, not luatexbase, because it's not used by everybody. See the page on callbacks.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The show_error_hook callback

This callback doesn't replace any internal code and isn't supposed to do anything meaningful. It is called when an error message occurs, precisely right after the first line of the error message (beginning with an exclamation mark) has been printed, and before the rest of the message is given.

No argument is passed to the function registered in the callback, and return values, if any, are ignored. Its best use is probably to report additional information besides the error message. For instance, the input text a_1 will produce the following error message (and another one quite similar at the end of the paragraph):

! Missing $ inserted.
<inserted text> 
                $
<to be read again> 
                   _
l.1 a_
      1
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.

This message can be annoying for two reasons: first, if one has a document made of several files, one doesn't know which file is concerned here (one can read the log file upward to spot the latest input file, but that isn't very convenient); second, the line number takes some time to arrive after the message's first line. The lines 2 to 4 aren't very informative, and it could be useful if the line number was available at once.

The following code inserts the input file's name and line number just after the first line of the message; thus the rest of the message can be ignored (as many users do, the first line, along with where the error happened, being often informative enough):

callback.register("show_error_hook",
  function ()
    texio.write_nl("[FILE: " .. status.filename .. ", LINE: " .. status.linenumber .. "]")
  end)

Some information from the status library is put to use here: status.filename returns a string with the name of the current input file, status.linenumber returns a number (automatically converted to a string here) indicating the line TeX is currently reading.

Now the error message looks like this, assuming that a_1 appeared in file called test_input.tex in the same directory as the main file:

! Missing $ inserted.
[FILE: ./test_input.tex, LINE: 1]
<inserted text> 
                $
<to be read again> 
                   _
l.1 a_
      1
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.

If one wants a full path instead of a relative path, one can use the LuaFileSystem library, shipped with LuaTeX (the use of % implies that this code isn't simply passed to \directlua; see Writing Lua in TeX):

callback.register("show_error_hook",
  function ()
    local f = status.filename
    f = string.gsub(f, "^%.", lfs.currentdir())
    texio.write_nl("[FILE: " .. f .. ", LINE: " .. status.linenumber .. "]")
  end)

This replaces ./ at the beginning of the filename (if any) with the string returned by lfs.currentdir(), whose meaning should be obvious. (See the Lua reference manual for information on string.gsib().)