Una prueba de concepto

Una prueba de concepto

¿Existe algún paquete que pueda resaltar automáticamente palabras sin guiones en el PDF de salida? Es decir, palabras que no están en la lista de palabras para separación de palabras. Por ejemplo:

ingrese la descripción de la imagen aquí

Estoy usando el paquete poliglosia. ¡Muchas gracias!

Respuesta1

Una prueba de concepto

Hemos comprobado algunos paquetes comunes, comoulem(Donald Arseneau) yalma(Melchior Franz), después de eso hemos trasladado nuestra atención almostrar guiones,lua-comprobar-guionylua-visual-depuraciónpaquetes creados por Patrick Gundlach. Desafortunadamente, el OP necesita lo contrario de lo que ofrecen estos paquetes.

Comenzamos nuestro trabajo analizando y aprendiendo deeste código de TeX.SX(ver tambiénhttp://wiki.luatex.org/index.php/Show_the_hyphenation_points) de Patrick Gundlach. Siempre estamos apoyados por elmanual de referencia de LuaTeX,donde hemos notado tipos definidos de nodos (ver Capítulo 8 Nodos, primera página; página 169+ en el manual). Podemos leer sobre sus campos en las siguientes páginas.

Necesitábamos especialmente estos tipos:

  • hlist (0), listas horizontales,
  • vlist (1), listas verticales,
  • disco (7), un lugar donde una palabra podría dividirse con guiones,
  • whasit (8), tipo adecuado para la creación de un nuevo nodo,
  • pegamento (10), espacios,
  • kern (11), kernings y,
  • glifo (37), el tipo de nodo clave para este tipo de trabajo.

Nuestra tarea era revisar todos los nodos, recopilar y almacenar su ID en una tabla Lua, hacer un análisis básico a nivel de texto y luego resaltar algunos resultados básicos (en este ejemplo, usamos subrayado de cada glifo).

Estamos pasando un número mínimo de letras que debe tener esa palabra para que quede resaltada. Una sola palabra consta de letras, dígitos, signos de puntuación, etc. Creemos que debería ser suficiente para esta prueba de concepto.

El código original para mostrar guiones utiliza un algoritmo recursivo para recorrer el árbol de nodos. Necesitábamos dos pases, por lo tanto ajustamos esa función ( show_hyph) a otra ( towork). El análisis se realiza en la showmefunción. Usamos headdatos de usuario, podríamos imprimir los campos usando la getmetatablefunción. Está comentado en el código y también imprime información adicional sobre los nodos.

El análisis de texto consta de varias condiciones, principalmente de:

  • ID 0 o ID 10 seguido de ID 37 (además, la palabra no puede estar dividida con guiones), ese es el comienzo de una palabra. Es una nueva línea o un espacio seguido de un glifo.
  • ID 7 significa que puede haber un disco y esa palabra no nos interesa.
  • ID 11 (kerning) o ID 37 (glifo) es parte de una palabra, incluimos esa parte para un análisis más detallado.
  • El ID 37 seguido del ID 10 es el final de una palabra.

Almacenamos toda la información en una tabla Lua. Necesitábamos dos variables sobre la longitud de la palabra, para mostrar una palabra que usamos malsizetrue(glifos + nodos de interletraje), para la interacción con un usuario que usamos malsize(solo glifos). Al principio me resultó extraño pensar en las palabras en esos términos, pero era necesario.

Usamos head.width( spunidades) para obtener un subrayado adecuado. En el siguiente ejemplo, cada letra está subrayada por separado; se podría mejorar para dibujar una sola línea por palabra. Dejamos esta idea abierta para futuros experimentos con el código. Eso requeriría almacenar anchos en la primera ejecución de la función y usarlos en la segunda ejecución en un nivel Lua.

En el siguiente ejemplo, utilizamos un texto básico y establecemos un número mínimo de letras por palabra de 1 a 8. Adjuntamos el código y una vista previa del resultado (8 páginas). Funciona como se esperaba en este ejemplo, pero supongo que este fragmento requiere más pruebas.

Corremos lualatex mal-hyph.tex.

% lualatex mal-hyph.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{luacode} % the core package in LuaLaTeX, recommended is luatextra
\usepackage[english]{babel} % loading some hyphenation rules
\usepackage{kantlipsum} % loading some text
\usepackage{fontspec} % loading some font

\begin{luacode*}
-- This is the core function for callback...
function towork(head)

-- This inner function is recursive...
function show_hyph(head)
while head do

  -- If we want to see userdata of >head<...
  -- for i,j in pairs(getmetatable(head)) do
  --    print(i,j)
  -- end

  -- If we need to get nodes ID..., this is the way.
  --[=[  io.write(head.id.." ")
    if head.id ==10 then io.write(" ") end
    if head.id == 37 then 
       io.write(unicode.utf8.char(head.char).."; ")
       end    
    --]=] -- be silent

    if head.id == 0 or head.id == 1 then
       show_hyph(head.head) -- the core of recursion
    end -- if, head.id, 0 (hlist) or 1 (vlist)

    counter=counter+1 -- number of nodes
    malglyphs[counter]=head.id -- saving IDs for later analysis

if run then -- We can add nodes after analysis...
  if maldraw[counter]==1 then -- These letters belong to unhyphenateable words.
      local n = node.new("whatsit","pdf_literal") -- Underline them, please,
      n.mode = 0
      if head.width then dista=head.width/65535 else dista=0 end -- with proper  width,
      distb=0
      n.data = "q 1 w 0 0 1 RG "..-dista.." -2 m "..distb.." -2 l S Q" -- with some common line.
      n.next = head.next -- Add line to the node tree.
      n.prev = head
      head.next = n
      head = n
  end -- if we are done with lines.

    if head.id == 7 and run then -- a divis, this is an original example, addition of disc
      local n = node.new("whatsit","pdf_literal")
      n.mode = 0
      n.data = "q 0.9 w 1 .1 .1 RG 0 2 m 0 7 l S Q" -- an original setting was: q 0.3 w 0 2 m 0 7 l S Q
      n.next = head.next
      n.prev = head
      head.next = n
      head = n
    end -- if, head.id==7
end -- if, run

head = head.next -- go to the next node
end -- while, node three

end -- function, show_hyph


-- This function analyses ID of nodes.
function showme()
-- Initialize some variables.
malwrite=0 -- Can I store a unhyphenateable word?
maldraw={} -- Table with 1s for storing information.
malsize=0 -- A size of the last word (only letters, ID 37).
malsizetrue=0 -- A size of the last word (letters+kerning, IDs 11+37).
broken=0 -- Is a word already hyphenated?

for malcounter=1,#malglyphs do -- Let's analyse all nodes.

-- Print some letters from actual position backward.
-- print(malglyphs[malcounter-2], malglyphs[malcounter-1], malglyphs[malcounter]) 

-- Are we at the beginning of the word?
if  (malglyphs[malcounter-1]==0 or malglyphs[malcounter-1]==10) and malglyphs[malcounter]==37 and broken~=1 then malwrite=1; malsize=0; malsizetrue=0 end

-- Are we at the end of the word? Can we modify data in our Lua table?
if malglyphs[malcounter-1]==37 and (malglyphs[malcounter]==10 or malglyphs[malcounter]==12) then 
   if malwrite==1 and malsize>=malmax then -- used to be: malsize>0
   for malback=1,malsizetrue do -- set letters of unhyphenated word for underlining/highlighting, plus kerning
      maldraw[malcounter-malback]=1 -- mark them letter by letter
   end -- for, malback
   end -- if, malwrite
end -- if, malglyphs...

-- Are we in the middle of the hyphenated word?
if malglyphs[malcounter]==7 then broken=1 end -- Yes, we are!
if malglyphs[malcounter]==37 then broken=0 end -- No, at least not at the beginning of the line!

-- Is this a node with letter or kerning in some word?
if malglyphs[malcounter]==37 or malglyphs[malcounter]==11 then 
   malsizetrue=malsizetrue+1 -- letters+kernings
   if malglyphs[malcounter]==37 then malsize=malsize+1 end -- Only letters.
   else 
   malwrite=0 -- Stop analysing actual word, it has no meaning anymore.
   end -- stop searching

end -- for, malcounter

-- If we need some information from the Lua table...
--[[for allchars=1,#malglyphs do
   if maldraw then print(allchars, maldraw[allchars]) end
   end -- for, malheader
   ]]
end -- function, showme


-- This is the first run, we need data about nodes.
malglyphs={}; run=nil; counter=0
show_hyph(head)
showme()

-- This is the second run, we will highlight letters (and also kerning with an invisible pen :-) ).
malglyphs={}; run=1; counter=0
show_hyph(head)
showme()

return true -- Let's finish our work and send data back to a callback.
end -- major function, towork()
\end{luacode*}


% Some TeX commands for general use...
% A minimum of letters required in an unhyphenateable word to be highlighted.
\def\malactivateset#1{
   \luaexec{
   print("malmax "..#1)
   malmax=tonumber(#1) or 0
   }}

% This command activates a callback.
\def\malactivate{
   \directlua{luatexbase.add_to_callback("post_linebreak_filter",towork,"towork")}
   } % End of \activateme...

% This command deactivates a callback.
\def\maldeactivate{
   \directlua{luatexbase.remove_from_callback("post_linebreak_filter","towork")}
   } % End of \deactivateme...

% This text is an example for TeX.SX.
\def\maltext{\newpage
   Minimum of required letters: \the\malletters.\par
   Hello, the World!\par
   Here is some text without meaning.\par 
   \kant[1]\par
   } % End of \maltext...

% Small changes in paper mirror...
\rightskip=7cm
\parindent=0pt


\begin{document}
% A small example...
\malactivate % This command activates the algorithm...
\newcount\malletters 
\malletters=0 % Start with 0+1 letters, a common minimum.
\loop
   \advance\malletters by 1 % Try more letters.
   \malactivateset{\the\malletters} % Pass No. of letters to Lua.
   \maltext \relax % Text to be tested.
\ifnum\malletters<8 \repeat % Show us 8 pages.
\maldeactivate % This command deactivates the algorithm...
\end{document}

un ejemplo de la prueba de concepto

información relacionada