> Lua does have a "debug" module
> 
>     https://www.lua.org/manual/5.3/manual.html#6.10
> 
> (that you can enable in LuaTeX with "--luadebug"), but I've never
> found it helpful for debugging. Usually I just manually add
> "print(var)" and/or "inspect(var)" calls to the source code.

Yeah :-)

I've come up with the attached solution, which works fine for the
small example.  Not sure whether this is the correct way, though.


    Werner
\documentclass{article}

\usepackage{luacode}
\usepackage{fontspec}

\begin{luacode}
  local report = luaotfload.log.report

  local patch_functions = {}

  local function glyph_to_unicode(glyph, unicodes, fontname)
    local unicode = unicodes[glyph]
    if not unicode then
      report("both", 0, "add_to_mark",
             "error: there is no glyph '%s' in font '%s'",
             glyph, fontname)
    end
    return unicode
  end

  local function missing_base_glyph(base_glyph, fontname)
    report("both", 0, "add_to_mark",
           "error: base glyph '%s' not in 'mark' feature of font '%s'",
           base_glyph, fontname)
  end

  local function missing_mark_glyph(mark_glyph, fontname)
    report("both", 0, "add_to_mark",
           "error: mark glyph '%s' not in 'mark' feature of font '%s'",
           mark_glyph, fontname)
  end


  -- Add glyph with name ACC as a diacritic to an existing 'mark'
  -- feature of font file FONT.  The arguments BASE and MARK specify
  -- names of glyphs that represent the desired anchor class that
  -- connects base and mark glyphs, respectively, to which ACC should
  -- be added.  The coordinates X and Y give the position of the
  -- anchor for ACC.
  --
  -- FONT should be the base name of an OpenType font, i.e., a file
  -- name without a path (example: `foo.otf`).
  --
  -- BASE and MARK must exist in FONT, and there must be an entry in
  -- the 'mark' feature that pairs them.  ACC must exist in FONT, too.
  --
  -- This function can be used repeatedly.  Note, however, that a mark
  -- glyph can only be part of a single anchor class.  As a
  -- consequence, a second call to this function with the same
  -- argument ACC that results in a different anchor class overrides
  -- the result of the first call.
  function add_to_mark_feature(font, acc, base, mark, x, y)
    if not patch_functions[font] then
      patch_functions[font] = {}
    end

    local function patch_function(fontdata)
      local fd = fontdata
      local path = fd.specification.filename
      local fn = file.basename(path)

      local uni = fd.resources.unicodes
      if not uni then
        report("both", 0, "add_to_mark",
               "error: 'unicodes' subtable missing;"
               .. " cannot map glyph names to Unicode")
        return
      end

      local u_acc = glyph_to_unicode(acc, uni, fn)
      local u_base = glyph_to_unicode(base, uni, fn)
      local u_mark = glyph_to_unicode(mark, uni, fn)
      if not (u_acc and u_base and u_mark) then
        return
      end

      local i = 1
      while true do
        local seq = fd.resources.sequences[i]
        if not seq then
          break
        elseif (seq.type == "gpos_mark2base"
                and seq.features["mark"]) then
          local st = seq.steps
          if st then
            for j = 1, #st do
              local cov = st[j].coverage
              if cov then
                local cov_mark = cov[u_mark]
                if cov_mark then
                  local cov_base = cov_mark[1][u_base]
                  if cov_base then
                    local bc = st[j].baseclasses
                    for k = 1, #bc do
                      local bck = bc[k]
                      if bck[u_base] then
                        report("log", 0, "add_to_mark",
                               "found base-mark glyph combination '%s+%s'"
                               .. "in 'mark' feature of font '%s'",
                               base, mark, fn)
                        -- Report OpenType value for anchor class, not
                        -- the one used in luatex.
                        report("log", 0, "add_to_mark",
                               "adding glyph '%s' to anchor class %d",
                               acc, k - 1)
                        cov[u_acc] = {bck, {x, y}}
                        return
                      end
                    end
                  else
                    missing_base_glyph(base, fn)
                    return
                  end
                else
                  missing_mark_glyph(mark, fn)
                  return
                end
              end
            end
          end
        end
        i = i + 1
      end

      report("log", 0, "add_to_mark",
             "no 'mark' feature in font '%s'",
             fn)
      return
    end

    table.insert(patch_functions[font], patch_function)

    luatexbase.add_to_callback(
      "luaotfload.patch_font",
      function(fontdata)
        local path = fontdata.specification.filename
        local filename = file.basename(path)

        local patch_functions = patch_functions[filename]
        if not patch_functions then
          return
        end

        for _, v in pairs(patch_functions) do
          v(fontdata)
        end
      end,
      "patch-fonts"
    )
  end
\end{luacode}


\begin{luacode}
  add_to_mark_feature("EBGaramond-Regular.otf",
                      "uni0364", "e", "gravecomb", 115, 440)
\end{luacode}


\setmainfont{EB Garamond}


\begin{document}

schoͤn

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

Reply via email to