I am trying to create a Lua script that lets me replace all instances of -> inside my equations with \rightarrow. I found this answer that suggests a hack involving a process_input_buffer callback:

-- replacearrow.lua
callback.register('process_input_buffer', function(line)
    return line:gsub('%-%>', '\\rightarrow')
% mydocument.tex
\directlua{ dofile('replacearrow.lua')}
Hello $A -> B$ World

The problem I'm getting now is that replacing text from the input buffer wholesale like this breaks a bunch of packages. I managed to restrain the damage a bit by only replacing text between dollar signs:

-- replacearrow.lua
callback.register('process_input_buffer', function(line)
    return line:gsub('%$(.-)%$', function(mathstr)
        mathstr = mathstr:gsubgsub('%-%>', '\\rightarrow')
        return '$'..mathstr..'$'

Is there a way to make this also work for math-environments defined without dollar signs, such as \[ and \begin{math}?

Maybe the more precise way to do this would be to use some callback other than process_input_buffer but I don't know if there exists a callback that does what I want.

BTW, I am aware of the semantic package, which is what got hooked to using -> in the first place. The problem is that now that I converted to luatex that package is conflicting with the unicode-math, and some "Extended mathchar errors used as mathchar" show up. At this point, I decided that doing some preprocessing with Lua might end up being cleaner than the macro magic that the semantic package is doing.

  • why not use → rather than -> as input? Jul 5, 2015 at 15:17
  • I am using a shitty text editor and its hard to type unicode symbols. There are also some symbols like "[[" for blackboard-bold-brackets that need to be converted to latex macros due to a lack of font support.
    – hugomg
    Jul 5, 2015 at 15:19
  • Would a test case include e.g. not making such substitutions in verbatim or listings environments? You should probably be looking at the mlist_to_hlist callback. Jul 6, 2015 at 12:54

1 Answer 1


In the end I decided that typing unicode characters directly as David Carlisle suggested was the way to go for my problem. It avoids hacking the Latex parser and the formulas in my text file are much more readable.

The biggest hurdle was figuring out how to input unicode characters on linux without having to change the text editor I was using. In the end, I settled on editing my .XCompose file. It is the file used to describe how sequence of keys get converted to characters (for example, things like ' + e = é. Right now my .XCompose has a bunch of rules that I set up, which look like this:

<Multi_key> <a> <a> : "α" U03B1 # Lower alpha
<Multi_key> <b> <b> : "β" U03B2 # Lower beta
<Multi_key> <g> <g> : "γ" U03B3 # Lower gamma
<Multi_key> <d> <d> : "δ" U03B4 # Lower delta
<Multi_key> <e> <e> : "ε" U03B5 # Lower epsilon
# and much more... took a long time to type everything.
# and also lots of copy pasting from KCharSelect...

It didn't work flawlessly out of the gate though:

  • <Multi_key> is the "compose key" and its not mapped to anything by default. I had to go in my keyboard settings to assign something to it. I chose AltGr.

  • By default, GTK apps ignore the settings i .XCompose. I had to change the "IM_MODULE" by exporting an environment variable on my .profile

    export GTK_IM_MODULE="uim"

    I had to install uim to get everything to work. I also tried xim, scim and ibus but none of them seemed to work. YMMV. BTW, I recommend testing things on a xterm in order to find out if the problem is in the XCompose or on some other configuration.

  • You cannot have a sequence combo that is a prefix of another sequence combo. I chose my sequence combinations carefully to avoid conflicts. One common trick was to add a <space> to the end of a sequence because none of my combinations have a <space> in the middle.

  • The "no prefixes allowed" conflicts include predefined combinations from your systems. Most XCompose tutorials recommend adding a include "%L" directive to import the compose settings from your locale but I did NOT do that because it would break some of my combinations. For some reason this wasn't a problem though and I can still type "é" if I want. My guess is that uim is doing some magic here.

  • The keysyms for the different keys can be found on /usr/include/X11/keysymdef.h. One thing to be careful about is that "dead keys" like ~ have their own keysyms. If your keyboard is configured to use dead keys (like mine) then your XCompose rules need to use <dead_tilde> instead of <ascii_tilde>.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .