
TeXボックスからUTF-8文字列を抽出する方法を試していたところ、ユーザーからの投稿を見つけました。ミカール-H21ここ:UTF-8テキスト抽出グリフ データがノードリストに格納される方法を確認した後、コードを変更して、別の方法が機能するかどうかを確認しました。私の方法では、複合グリフ/ディスクの構成要素を走査して、構成文字を抽出します。彼の方法では、合字などの複合グリフを何らかの関数に渡して分解しているようです。両方のコードで印刷された出力 (例のテスト文字列) は同じです。どなたかレビューして、両方の方法が機能的に同等に正しいかどうかを提案してください (私のコードでは TeX 合字の特別な処理が必要であることは承知していますが、それは無視してください)。正しい場合、どちらがパフォーマンスの点で優れているでしょうか (unicode.utf8.char
彼のようにコードにキャッシュできますが、パフォーマンスに関するコメントではその矛盾は無視してください)。
ターミナルと出力ファイルhello.txtに書き込まれた出力テキストは次のとおりです。Příliš žluťoučký kůň úpěl ďábelské ódy difference diffierence.
完全なコードは次のとおりです。UTF-8テキスト抽出、私たちのコードが異なるのは、私が彼の次の関数 ( ) を使用せずget_unicode
、グリフ コンポーネントに適用するだけに固執している点ですunicode.utf8.char(glyphnodename.char)
(一方、彼は、get_unicode
グリフ ノードを 1 レベル深く掘り下げて分解されたグリフを取得するのではなく、この関数を適用して複雑なグリフを分解しています [私の理解する限りでは])。
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}