7

I know that TeX can't write the content of hbox in an auxiliary file (Re-parse the content of a box register).

That mean that

\newwrite\foo
\immediate\openout\foo=\jobname.txt
\setbox0=\hbox{bar}
\immediate\write\foo{\box0}

can't write However, can LuaTeX do it? I have found

\directlua{
 n = tex.getbox(0)
}

But I don't understand what n is representing and if I could use it to write the box content in a file.

  • If you indent your code by four spaces or click the {} button with more than one line selected, the code will display correctly. – Manuel Feb 15 '15 at 21:06
  • sorry, too accustomed to the github syntaxis. – Maïeul Feb 15 '15 at 21:09
  • 2
    What are you hoping to get out here? If you show the content of a box using classical TeX you'll see that it's a series of typesetting instructions not anything necessarily related to 'text'. I wonder what the aim is here. – Joseph Wright Feb 15 '15 at 21:17
  • eledmac number line. To do it, it split vboxs to little vbox (one by \baselineskip) and then add the line number. I would like to output one specific line to auxiliary file. – Maïeul Feb 15 '15 at 21:24
  • A likely better approach is to catch the macros/text before they are consumed in a box. – Heiko Oberdiek Mar 29 '18 at 17:03
8

Variablen in your example is a node list. Various types of nodes exists, such as glyphs for characters, glue for spacing, or hlist which is the type you get for your \hbox. hlist contains child nodes, which are accessible in n.head attribute. You can then loop this child list for glyphs and glues.

Each node type is distinguishable by value of n.id attribute. Particular node types and possible attributes are described in chapter "8 Nodes". In this particular example, we need to process just glyph and glue nodes, but you should keep in mind that node lists are recursive and various nodes can contain child lists, like hlist, vlist, etc. You can support them with recursive call of nodeText on current node head attribute.

Regarding glyph nodes, char attribute contains unicode value only in the case if you use opentype or truetype fonts, if you use old 8-bit fonts, it contains just 8-bit value which actual encoding depends on used font encoding and it isn't easy to convert it to unicode.

\documentclass{article}
\usepackage{fontspec}
\begin{document}
\setbox0=\hbox{Příliš žluťoučký \textit{kůň} úpěl \hbox{ďábelské} ódy}
\directlua{
    local fontstyles = require "l4fontstyles"
  local char = unicode.utf8.char
  local glyph_id = node.id("glyph")
  local glue_id  = node.id("glue")
  local hlist_id = node.id("hlist")
  local vlist_id = node.id("vlist")
  local minglue = tex.sp("0.2em")
  local usedcharacters = {}
  local identifiers = fonts.hashes.identifiers
  local function get_unicode(xchar,font_id)
     return char(tonumber(identifiers[font_id].characters[xchar].tounicode,16))
  end
  local function nodeText(n)
    local t =  {}
    for x in node.traverse(n) do
      % glyph node
      if x.id == glyph_id then
        % local currentchar = fonts.hashes.identifiers[x.font].characters[x.char].tounicode
        table.insert(t,get_unicode(x.char,x.font))
                local y = fontstyles.get_fontinfo(x.font)
                print(x.char,y.name,y.weight,y.style) 
      % glue node
      elseif x.id == glue_id and  node.getglue(x) > minglue then

        table.insert(t," ")
            elseif x.id == hlist_id or x.id == vlist_id then
                table.insert(t,nodeText(x.head))
      end
    end
    return table.concat(t)
  end
  local n = tex.getbox(0)
  print(nodeText(n.head))
  local f = io.open("hello.txt","w")
  f:write(nodeText(n.head))
  f:close()
}

\box0
\end{document}

nodeText function returns text contained in the node list. It is used to print \hbox contents to the terminal and to write to file hello.txt in this example.

For basic info about font style, you can try to use l4fontstyles module, like this:

local fontstyles = require "l4fontstyles"
...
if x.id == glyph_id then                                                        
        table.insert(t,char(x.char))
        local y = fontstyles.get_fontinfo(x.font)
        print(y.name,y.weight,y.style)
  • thank a lot for the answer and explanation ! it's what I need ! – Maïeul Feb 15 '15 at 22:14
  • just another question. In LuaTeX handbook, I don't find anything about the possible value of note.id. I unerstand 37 = non blank charater, 10 = blank charater, but what else is possible? is it possible to get some information about formating, like weight or emphase? – Maïeul Feb 16 '15 at 9:37
  • @Maïeul see updated answer – michal.h21 Feb 16 '15 at 10:22
  • Thanks. I didn't understand that the id. value was the number in parenthesis in the begining of chapter 8. – Maïeul Feb 16 '15 at 10:45
  • it seems some problem with combineed unicode charecter. In input ךְ ( U+05DA U+05B0) becomes in output (but not .pdf󰀇) ``, (U+DB80 U+DC07). Does there any library to solve this problem? – Maïeul Feb 17 '15 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.