LuaTeX: la extracción de caracteres UTF-8 es de una forma más precisa y/o preferible que otra

LuaTeX: la extracción de caracteres UTF-8 es de una forma más precisa y/o preferible que otra

Mientras experimentaba formas de extraer cadenas de caracteres UTF-8 de cuadros TeX, encontré una publicación del usuariomicahl-h21aquí:Extracción de texto UTF-8. Después de observar la forma en que se almacenan los datos de glifos en la lista de nodos, modifiqué el código para ver si funciona otro enfoque. En mi enfoque, recorro los componentes de glifos/discos complejos compuestos para extraer los caracteres constituyentes. En su enfoque, parece estar pasando glifos complejos como ligaduras a alguna función para descomponerlo. El resultado impreso por nuestros dos códigos (para la cadena de prueba en el ejemplo) tiene el mismo aspecto. ¿Alguien puede revisar y sugerir si ambos enfoques son igualmente funcionalmente correctos (sé que mi código requiere un manejo especial de las ligaduras TeX, ignórelo). Y en caso afirmativo, cuál sería mejor para el rendimiento (puedo almacenar unicode.utf8.charen caché mi código como él, ignore esa discrepancia en cualquier comentario sobre el rendimiento).

Aquí está el texto de salida escrito en la terminal y en un archivo de salida hello.txt: Příliš žluťoučký kůň úpěl ďábelské ódy difference diffierence.Su código completo está enExtracción de texto UTF-8, el lugar donde nuestros códigos difieren es que no uso la siguiente función ( get_unicode), y simplemente me quedo con la unicode.utf8.char(glyphnodename.char)aplicada a los componentes del glifo (mientras que él aplica esta función get_unicodepara descomponer glifos complejos en lugar de profundizar un nivel más en el nodo del glifo para obtener los glifos descompuestos [según tengo entendido]).

local function get_unicode(xchar,font_id)
    local current = {}
    local uchar = identifiers[font_id].characters[xchar].tounicode
    for i= 1, string.len(uchar), 4 do
      local cchar = string.sub(uchar, i, i + 3)
      print(xchar,uchar,cchar, font_id, i)
      table.insert(current,char(tonumber(cchar,16)))
    end
    return current
  end
\documentclass{article}
\usepackage[lmargin=0.5in,tmargin=0.5in,rmargin=0.5in,bmargin=0.5in]{geometry}
\usepackage{fontspec}
\usepackage{microtype}
\usepackage[english]{babel}
\usepackage{blindtext}

\begin{document}

\setbox0=\hbox{Příliš žluťoučký \textit{kůň} úpěl \hbox{ďábelské} ódy difference diffierence.}

\directlua{
  local glyph_id = node.id("glyph")
  local disc_id = node.id("disc")
  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 function nodeText(n)
    local t =  {}
    for x in node.traverse(n) do
      % glyph node
      if x.id == glyph_id then
        if bit32.band(x.subtype,2) \csstring~=0 and unicode.utf8.char(x.char) \csstring~="“" and unicode.utf8.char(x.char) \csstring~="”" then %
          for g in node.traverse_id(glyph_id,x.components) do
            if bit32.band(g.subtype, 2) \csstring~=0 then
              for gc in node.traverse_id(glyph_id,g.components) do
                table.insert(t,unicode.utf8.char(gc.char))
              end
            else
              table.insert(t,unicode.utf8.char(g.char))
            end
          end
        else
          table.insert(t,unicode.utf8.char(x.char))
        end
      % disc node
      elseif x.id == disc_id then
        for g in node.traverse_id(glyph_id,x.replace) do
          if bit32.band(g.subtype, 2) \csstring~=0 then
            for gc in node.traverse_id(glyph_id,g.components) do
              table.insert(t,unicode.utf8.char(gc.char))
            end
          else
            table.insert(t,unicode.utf8.char(g.char))
          end
        end
        % 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}

información relacionada