
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.char
en 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_unicode
para 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}