[NTG-context] modifying kerning breaks opentype ligatures (and other features)

mf massifr at fastwebnet.it
Tue Dec 11 11:34:09 CET 2018


> But i should consider all the text parts with a modified kerning and 
> disable kerning around character sequences like "ff", "ffi", "fl" and 
> so on. Luckily, the XHTML markup "knows" where the kerning is modified:
>
> <p class="wide">A paragraph with a modified kerning</p>
>
> should become
>
> <p class="wide">A paragraph with a modi<dk>fi</dk>ed kerning</p>
>
> Where <dk>...</dk> (dk=Disable Kerning) are tags to be inserted 
> automatically before feeding the XHTML into ConTeXt.
> I'm not very happy or proud about it, but it can be done.
> Do you think it can be better done inside ConTeXt?
>
I nearly managed to do it in ConTeXt, but I can't create the "<dk>" 
elements right (the "new_dk_element" function is wrong):

\startbuffer[test]
<text>
<p>Some ligatures: float, finance, affine, affluent.</p>
<p>Modified kerning:</p>
<p class="narrow">Some ligatures: float, finance, affine, affluent.</p>
<p class="wide">Some ligatures: float, finance, affine, affluent.</p>
</text>
\stopbuffer

\startluacode
local function new_dk_element( parent, text )
   return {
     tag     = "dk",
     ns      = "",
     rn      = "",
     dt      = { text },
     at      = {},
     command = "xml:dk",
     __p__   = parent
   }
--[[
   local t = xml.toxml( "<dk>" .. text .. "</dk>" )
   t.__p__ = parent
   return t
]]--
end

local append = table.insert
local function saveLigaturesFromKerning( t )
   if t and t.dt then
     local dt = t.dt
     local t_copy = {}
     for k,v in pairs( t ) do
       if k ~= "dt" then t_copy[ k ] = v end
     end
     local new_dt = {}
     local i
     local child
     local b, e
     for i = 1, #dt, 1 do
       child = dt[ i ]
       if type( child ) == "string" then
         local s = child
         repeat
           b, e = string.find( s, "f?f[il]" )
           if b then
             if b > 1 then append( new_dt, string.sub( s, 1, b - 1 ) ) end
             append( new_dt, new_dk_element( t, string.sub( s, b, e ) ) )
--            append( new_dt, "[" .. string.sub( s, b, e ) .. "]" )
             s = string.sub( s, e + 1 )
           else
             append( new_dt, s )
           end
         until not b
       else
         append( new_dt, child )
       end
     end
     t.dt = new_dt
   end
   return t
end

function xml.functions.textWithKerning( t )
   local kt = saveLigaturesFromKerning( t )
   lxml.flush( kt )
end
\stopluacode

\definecharacterkerning[narrow][factor=-.02]
\definecharacterkerning[wide][factor=.02]
\def\Narrow#1{\bgroup\setcharacterkerning[narrow]#1\egroup}
\def\Wide#1{\bgroup\setcharacterkerning[wide]#1\egroup}
\def\NoKerning#1{\bgroup\resetcharacterkerning #1\egroup}

\startxmlsetups xml:test
   \xmlsetsetup{#1}{text|p|dk}{xml:*}
   \xmlsetsetup{#1}{{p.narrow}}{xml:p:narrow}
   \xmlsetsetup{#1}{{p.wide}}{xml:p:wide}
\stopxmlsetups

\xmlregistersetup{xml:test}

\startxmlsetups xml:text
   \xmlflush{#1}
\stopxmlsetups

\startxmlsetups xml:p
   \xmlflush{#1}\par
\stopxmlsetups

\startxmlsetups xml:p:narrow
   \Narrow{\xmlfunction{#1}{textWithKerning}}\par
\stopxmlsetups

\startxmlsetups xml:p:wide
   \Wide{\xmlfunction{#1}{textWithKerning}}\par
\stopxmlsetups

\startxmlsetups xml:dk
   \NoKerning{\red\xmlflush{#1}}
\stopxmlsetups

\starttext
   \xmlprocessbuffer{xml:test}{test}{}
\stoptext



More information about the ntg-context mailing list