
Beim Experimentieren mit Möglichkeiten, UTF-8-Zeichenfolgen aus TeX-Boxen zu extrahieren, fand ich einen Beitrag des Benutzersmicahl-h21Hier:UTF-8-Textextraktion. Nachdem ich mir angesehen hatte, wie Glyphendaten in der Knotenliste gespeichert werden, habe ich den Code geändert, um zu sehen, ob ein anderer Ansatz funktioniert. Bei meinem Ansatz durchlaufe ich die Komponenten zusammengesetzter komplexer Glyphen/Discs, um die einzelnen Zeichen zu extrahieren. Bei seinem Ansatz scheint er komplexe Glyphen wie Ligaturen an eine Funktion zu übergeben, um sie zu zerlegen. Die von beiden unserer Codes gedruckte Ausgabe (für die Testzeichenfolge im Beispiel) sieht gleich aus. Kann das bitte jemand überprüfen und vorschlagen, ob beide Ansätze gleichermaßen funktional korrekt sind (ich bin mir bewusst, dass mein Code eine spezielle Behandlung von TeX-Ligaturen erfordert, bitte ignorieren Sie das). Und wenn ja, welcher wäre besser für die Leistung (ich kann unicode.utf8.char
wie er in meinem Code zwischenspeichern, bitte ignorieren Sie diese Diskrepanz in allen Kommentaren zur Leistung).
Hier ist der Ausgabetext, der in das Terminal und in die Ausgabedatei hello.txt geschrieben wurde: Příliš žluťoučký kůň úpěl ďábelské ódy difference diffierence.
Sein vollständiger Code befindet sich unterUTF-8-Textextraktion, der Unterschied zwischen unseren Codes besteht darin, dass ich seine folgende Funktion () nicht verwende get_unicode
und mich einfach unicode.utf8.char(glyphnodename.char)
auf die Glyphenkomponenten anwende (wohingegen er diese Funktion anwendet, get_unicode
um komplexe Glyphen zu zerlegen, anstatt eine Ebene tiefer im Glyphenknoten zu graben, um die zerlegten Glyphen zu erhalten [soweit ich weiß]).
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}