LuaTeX: извлечение символов UTF-8, один из способов точнее и/или предпочтительнее другого

LuaTeX: извлечение символов UTF-8, один из способов точнее и/или предпочтительнее другого

Экспериментируя со способами извлечения строк символов UTF-8 из TeX-боксов, я нашел сообщение от пользователямихал-h21здесь:Извлечение текста UTF-8. Посмотрев на то, как данные глифов хранятся в nodelist, я изменил код, чтобы посмотреть, работает ли другой подход. В моем подходе я обхожу компоненты составных сложных глифов/дисков, чтобы извлечь составляющие символы. В его подходе он, похоже, передает сложные глифы, такие как лигатуры, в некоторую функцию для их разложения. Вывод, напечатанный обоими нашими кодами (для тестовой строки в примере), выглядит одинаково. Может ли кто-нибудь просмотреть и предположить, являются ли оба подхода одинаково функционально правильными (я знаю, что мой код требует специальной обработки лигатур 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для разложения сложных глифов вместо того, чтобы копать на уровень глубже в узле глифа, чтобы получить разложенные глифы [насколько я понимаю]).

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}

Связанный контент