Is it possible to accurately determine the group nesting level in lualatex properly(without creating a parser but having lualatex decide)?

As of now I can easily map the source line number to the pdf page. This allows me to associate the tex code with the pages that is generates which will eventually help with caching.

The problem is that I cannot arbitrarily partition the source code in to chunks because because some code(e.g., macros) may span multiple chunks which will break the caching mechanism.

A hackish way to do this is simply parse the source code and test for grouping tokens({ and }) and simply keep a count({ = 1 and } = -1). When the count is 0 then we are in the outermost level and that is all I need.

The problem with this method is it is not robust(have to deal with {, }, environments, since they are effectively groups, macro alignment, verb, etc).

The point is that when I split the source code in to chunks, I have to split them in ways that will allow the caching to be valid tex code. I cannot split a macro or environment(like a table in to two chunks and cache one and not cache the other because the other will not compile(e.g., it will be like \include{}... \end{array} and the \include has the \begin{array})

So knowing when things are in side a group or environment is critical. Rather than writing a full blown tex parser I'd like to somehow get the engine to inform me when it is inside some group. Basically, when it is safe to split the text file in to chunks that could, hypothetically be compiled as individual tex files.

I am only referring to stuff between \begin{document} and \end{document} and certain assumptions could be made such as no commands will be defined inside the document environment except possibly through calling other macros(but not in the source).

It would be ideal if there was a callback that was called when a group was entered, but I haven't found such a callback.

To understand this better: Each source tex file has natural splitting points in it's document environment. These natural splitting points partition the source code in to ranges/chunks of code that could be compiled by themselves. For each chunk, if every other chunk was removed from the source, the code could still compile fine. By knowing these chunks(the splitting points), they can be easily cached with little issue(in some extreme cases it may not work, but most code would work fine).

These splitting points are going to be defined by the groups in the document environment and with macro calls(normal text has a splitting point at every token) and possibly other things I am not aware of or that is rarely found in tex files.

An example

This is a test
This is more stuff...

has splitting points everywhere in the environment but across the line \textcolor{...} (although if we knew that \textcolor{<x><y>} = \textcolor{<x>}\textcolor{<y>} we could use that to create splitting points at each letter in the argument, but I don't see how that could be done easily).

So, splitting the document in to something like


results in an invalid file and so that chunk is not valid(due to it splitting the textcolor macro in half and only keeping half of it)

Anything like this in lualatex or will I have to accept an inferior hackish method?

1 Answer 1


You can examine the current group level with the parameter \currentgrouplevel.

(start) \the\currentgrouplevel\hfill\break
(open brace) {\the\currentgrouplevel\hfill\break
(open brace) {\the\currentgrouplevel\hfill\break
(closed brace) }\the\currentgrouplevel\hfill\break
(begingroup) \begingroup\the\currentgrouplevel\hfill\break
(open brace) {\the\currentgrouplevel\hfill\break
(closed brace) }\the\currentgrouplevel\hfill\break
(endgroup) \endgroup\the\currentgrouplevel\hfill\break
(closed brace) }\the\currentgrouplevel\hfill\break


enter image description here

There is also \currentgrouptype that shows what type of group is current (image from the manual of e-TeX):

enter image description here

See section 9.3.3 in the manual of LuaTeX 0.95 to see that the internal name for the parameter is tex.currentgrouplevel.

  • Ok, that might work. any to get this value directly in lua? Because I am using lua to parse code I can't really make this solution work I think. If I try something like tex.print it will be executed after the lua function returns. I'm using process_input_buffer and need the currentgrouptype(all I care about is 0 and not 0) in the lua function for that line(which, unfortunately might have multiple group expansions in it, if, say, the source code was all on one line). Feb 9, 2017 at 15:46
  • Ok, that might work. any to get this value directly in lua? tex.currentgrouplevel Feb 12, 2017 at 0:42
  • @PhilippGesang Things, exactly what I needed! Please add this to your answer egreg. Feb 12, 2017 at 13:18

You must log in to answer this question.

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