diff options
| author | Elie Roux <elie.roux@telecom-bretagne.eu> | 2013-05-03 01:24:36 -0700 | 
|---|---|---|
| committer | Elie Roux <elie.roux@telecom-bretagne.eu> | 2013-05-03 01:24:36 -0700 | 
| commit | 225c63363a259867bad8848e9e9880e43cbf4ad5 (patch) | |
| tree | b70a6b21034ce00c7b741329f4b5b50a29ef9e26 | |
| parent | cabc4adc0619e85a1fd020c2c820bec050f8da30 (diff) | |
| parent | eb4fdd2afe34627abece6f75187a2cd691bcf6db (diff) | |
| download | luaotfload-225c63363a259867bad8848e9e9880e43cbf4ad5.tar.gz | |
Merge pull request #30 from phi-gamma/master
implement feature request #24
| -rw-r--r-- | luaotfload-auxiliary.lua | 406 | ||||
| -rw-r--r-- | luaotfload.dtx | 10 | ||||
| -rwxr-xr-x | mkglyphlist | 6 | ||||
| -rw-r--r-- | tests/font_patch.tex | 6 | ||||
| -rw-r--r-- | tests/pln-aux-1.tex | 49 | ||||
| -rw-r--r-- | tests/pln-aux-2.tex | 102 | ||||
| -rw-r--r-- | tests/pln-aux-3.tex | 39 | ||||
| -rw-r--r-- | tests/pln-aux-4.tex | 41 | 
8 files changed, 656 insertions, 3 deletions
diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua new file mode 100644 index 0000000..2cf1e00 --- /dev/null +++ b/luaotfload-auxiliary.lua @@ -0,0 +1,406 @@ +#!/usr/bin/env texlua +----------------------------------------------------------------------- +--         FILE:  luaotfload-auxiliary.lua +--  DESCRIPTION:  part of luaotfload +-- REQUIREMENTS:  luaotfload 2.2 +--       AUTHOR:  Khaled Hosny, Élie Roux, Philipp Gesang +--      VERSION:  1.0 +--      CREATED:  2013-05-01 14:40:50+0200 +----------------------------------------------------------------------- +-- + +--- this file addresses issue #24 +--- https://github.com/lualatex/luaotfload/issues/24# + +luaotfload                  = luaotfload or {} +luaotfload.aux              = luaotfload.aux or { } + +config                      = config or { } +config.luaotfload           = config.luaotfload or { } + +local aux           = luaotfload.aux +local log           = luaotfload.log +local identifiers   = fonts.hashes.identifiers + +local fontid        = font.id +local texsprint     = tex.sprint + +local utf8          = unicode.utf8 +local stringlower   = string.lower +local stringformat  = string.format +local stringgsub    = string.gsub +local stringbyte    = string.byte + +----------------------------------------------------------------------- +---                          font patches +----------------------------------------------------------------------- + +--[[doc-- +This sets two dimensions apparently relied upon by the unicode-math +package. +--doc]]-- + +local set_sscale_dimens = function (fontdata) +  local mathconstants = fontdata.MathConstants +  local parameters    = fontdata.parameters +  if mathconstants then +    parameters[10] = mathconstants.ScriptPercentScaleDown or 70 +    parameters[11] = mathconstants.ScriptScriptPercentScaleDown or 50 +  end +  return fontdata +end + +luatexbase.add_to_callback( +  "luaotfload.patch_font", +  set_sscale_dimens, +  "luaotfload.aux.set_sscale_dimens") + +--- fontobj -> int +local lookup_units = function (fontdata) +  local metadata = fontdata.shared and fontdata.shared.rawdata.metadata +  if metadata and metadata.units_per_em then +    return metadata.units_per_em +  elseif fontdata.parameters and fontdata.parameters.units then +    return fontdata.parameters.units +  elseif fontdata.units then --- v1.x +    return fontdata.units +  end +  return 1000 +end + +--[[doc-- +This callback corrects some values of the Cambria font. +--doc]]-- +local patch_cambria_domh = function (fontdata) +  local mathconstants = fontdata.MathConstants +  if mathconstants and fontdata.psname == "CambriaMath" then +    --- my test Cambria has 2048 +    local units_per_em = fontdata.units_per_em or lookup_units(fontdata) +    local sz           = fontdata.parameters.size or fontdata.size +    local mh           = 2800 / units_per_em * sz +    if mathconstants.DisplayOperatorMinHeight < mh then +      mathconstants.DisplayOperatorMinHeight = mh +    end +  end +end + +luatexbase.add_to_callback( +  "luaotfload.patch_font", +  patch_cambria_domh, +  "luaotfload.aux.patch_cambria_domh") + +--[[doc-- + +Comment from fontspec: + + “Here we patch fonts tfm table to emulate \XeTeX's \cs{fontdimen8}, +  which stores the caps-height of the font. (Cf.\ \cs{fontdimen5} which +  stores the x-height.) + +  Falls back to measuring the glyph if the font doesn't contain the +  necessary information. +  This needs to be extended for fonts that don't contain an `X'.” + +--doc]]-- + +local set_capheight = function (fontdata) +    local shared     = fontdata.shared +    local parameters = fontdata.parameters +    local capheight +    if shared then +      local units_per_em   = parameters.units +      local size           = parameters.size +      local os2_capheight  = shared.rawdata.metadata.pfminfo.os2_capheight + +      if os2_capheight > 0 then +        capheight = os2_capheight / units_per_em * size +      else +        local X8 = stringbyte"X" +        if fontdata.characters[X8] then +          capheight = fontdata.characters[X8].height +        else +          capheight = parameters.ascender / units_per_em * size +        end +      end +    else +      local X8 = stringbyte"X" +      if fontdata.characters[X8] then +        capheight = fontdata.characters[X8].height +      end +    end +    if capheight then +      --- is this legit? afaics there’s nothing else on the +      --- array part of that table +      fontdata.parameters[8] = capheight +    end +end + +luatexbase.add_to_callback( +  "luaotfload.patch_font", +  set_capheight, +  "luaotfload.aux.set_capheight") + +----------------------------------------------------------------------- +---                             glyphs +----------------------------------------------------------------------- + +--- int -> int -> bool +local font_has_glyph = function (font_id, codepoint) +  local fontdata = fonts.hashes.identifiers[font_id] +  if fontdata then +    if fontdata.characters[codepoint] ~= nil then return true end +  end +  return false +end + +aux.font_has_glyph = font_has_glyph + +--- int -> bool +local current_font_has_glyph = function (codepoint) +  return font_has_glyph (font.current(), codepoint) +end + +aux.current_font_has_glyph = current_font_has_glyph + +local do_if_glyph_else = function (chr, positive, negative) +  local codepoint = tonumber(chr) +  if not codepoint then codepoint = utf8.byte(chr) end +  if current_font_has_glyph(codepoint) then +    tex.sprint(positive) +  else +    tex.sprint(negative) +  end +end + +aux.do_if_glyph_else = do_if_glyph_else + +--[[doc-- + +  This one is approximately “name_to_slot” from the microtype package; +  note that it is all about Adobe Glyph names and glyph slots in the +  font. The names and values may diverge from actual Unicode. + +  http://www.adobe.com/devnet/opentype/archives/glyph.html + +--doc]]-- + +--- string -> (int | false) +local slot_of_name = function (glyphname) +  local fontdata = identifiers[font.current()] +  if fontdata then +    local unicode = fontdata.resources.unicodes[glyphname] +    if unicode and type(unicode) == "number" then +      return unicode +    else +      return unicode[1] --- for multiple components +    end +  end +  return false +end + +aux.slot_of_name = slot_of_name + +--[[doc-- + +  Inverse of above; not authoritative as to my knowledge the official +  inverse of the AGL is the AGLFN. Maybe this whole issue should be +  dealt with in a separate package that loads char-def.lua and thereby +  solves the problem for the next couple decades. + +  http://partners.adobe.com/public/developer/en/opentype/aglfn13.txt + +--doc]]-- + +local indices + +--- int -> (string | false) +local name_of_slot = function (codepoint) +  if not indices then --- this will load the glyph list +    local unicodes = fonts.encodings.agl.unicodes +    indices = table.swapped(unicodes) +  end +  local glyphname = indices[codepoint] +  if glyphname then +    return glyphname +  end +  return false +end + +aux.name_of_slot      = name_of_slot + +----------------------------------------------------------------------- +---                 features / scripts / languages +----------------------------------------------------------------------- +--- lots of arrowcode ahead + +--[[doc-- +This function, modeled after “check_script()” from fontspec, returns +true if in the given font, the script “asked_script” is accounted for in at +least one feature. +--doc]]-- + +--- int -> string -> bool +local provides_script = function (font_id, asked_script) +  asked_script = stringlower(asked_script) +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local fontname = fontdata.metadata.fontname +      local features = fontdata.resources.features +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        for feature, data in next, featuredata do +          if data[asked_script] then +            log(stringformat( +              "font no %d (%s) defines feature %s for script %s", +              font_id, fontname, feature, asked_script)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) defines no feature for script %s", +        font_id, fontname, asked_script)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_script = provides_script + +--[[doc-- +This function, modeled after “check_language()” from fontspec, returns +true if in the given font, the language with tage “asked_language” is +accounted for in the script with tag “asked_script” in at least one +feature. +--doc]]-- + +--- int -> string -> string -> bool +local provides_language = function (font_id, asked_script, asked_language) +  asked_script     = stringlower(asked_script) +  asked_language   = stringlower(asked_language) +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local fontname = fontdata.metadata.fontname +      local features = fontdata.resources.features +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        for feature, data in next, featuredata do +          local scriptdata = data[asked_script] +          if scriptdata and scriptdata[asked_language] then +            log(stringformat("font no %d (%s) defines feature %s " +                          .. "for script %s with language %s", +                             font_id, fontname, feature, +                             asked_script, asked_language)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) defines no feature for script %s with language %s", +        font_id, fontname, asked_script, asked_language)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_language = provides_language + +--[[doc-- +We strip the syntax elements from feature definitions (shouldn’t +actually be there in the first place, but who cares ...) +--doc]]-- + +local lpeg        = require"lpeg" +local C, P, S     = lpeg.C, lpeg.P, lpeg.S +local lpegmatch   = lpeg.match + +local sign            = S"+-" +local rhs             = P"=" * P(1)^0 * P(-1) +local strip_garbage   = sign^-1 * C((1 - rhs)^1) + +--s   = "+foo"        --> foo +--ss  = "-bar"        --> bar +--sss = "baz"         --> baz +--t   = "foo=bar"     --> foo +--tt  = "+bar=baz"    --> bar +--ttt = "-baz=true"   --> baz +-- +--print(lpeg.match(strip_garbage, s)) +--print(lpeg.match(strip_garbage, ss)) +--print(lpeg.match(strip_garbage, sss)) +--print(lpeg.match(strip_garbage, t)) +--print(lpeg.match(strip_garbage, tt)) +--print(lpeg.match(strip_garbage, ttt)) + +--[[doc-- +This function, modeled after “check_feature()” from fontspec, returns +true if in the given font, the language with tag “asked_language” is +accounted for in the script with tag “asked_script” in feature +“asked_feature”. +--doc]]-- + +--- int -> string -> string -> string -> bool +local provides_feature = function (font_id,        asked_script, +                                   asked_language, asked_feature) +  asked_script    = stringlower(asked_script) +  asked_language  = stringlower(asked_language) +  asked_feature   = lpegmatch(strip_garbage, asked_feature) + +  if font_id and font_id > 0 then +    local fontdata = identifiers[font_id].shared.rawdata +    if fontdata then +      local features = fontdata.resources.features +      local fontname = fontdata.metadata.fontname +      for method, featuredata in next, features do +        --- where method: "gpos" | "gsub" +        local feature = featuredata[asked_feature] +        if feature then +          local scriptdata = feature[asked_script] +          if scriptdata and scriptdata[asked_language] then +            log(stringformat("font no %d (%s) defines feature %s " +                          .. "for script %s with language %s", +                             font_id, fontname, asked_feature, +                             asked_script, asked_language)) +            return true +          end +        end +      end +      log(stringformat( +        "font no %d (%s) does not define feature %s for script %s with language %s", +        font_id, fontname, asked_feature, asked_script, asked_language)) +    end +  end +  log(stringformat("no font with id %d", font_id)) +  return false +end + +aux.provides_feature = provides_feature + +----------------------------------------------------------------------- +---                         font dimensions +----------------------------------------------------------------------- + +--- string -> string -> int +local get_math_dimension = function (csname, dimenname) +  local fontdata  = identifiers[fontid(csname)] +  local mathdata  = fontdata.mathparameters +  if mathdata then return mathdata[dimenname] or 0 end +  return 0 +end + +aux.get_math_dimension = get_math_dimension + +--- string -> string -> unit +local sprint_math_dimension = function (csname, dimenname) +  local dim = get_math_dimension(csname, dimenname) +  texsprint(luatexbase.catcodetables["latex-package"], dim) +  texsprint(luatexbase.catcodetables["latex-package"], "sp") +end + +aux.sprint_math_dimension = sprint_math_dimension + +-- vim:tw=71:sw=2:ts=2:expandtab diff --git a/luaotfload.dtx b/luaotfload.dtx index dd43990..fd71485 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -1226,6 +1226,11 @@ luaotfload.font_definer = "patch" --- | “generic” | “old”  local error, warning, info, log =      luatexbase.provides_module(luaotfload.module) +luaotfload.error        = error +luaotfload.warning      = warning +luaotfload.info         = info +luaotfload.log          = log +  %    \end{macrocode}  %    We set the minimum version requirement for \LUATEX to v0.76,  %    because the font loader requires recent features like direct @@ -1542,7 +1547,6 @@ loadmodule"colors.lua"     --- “font-clr”  % genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.  % Another benefit is that we can now easily plug in or replace new lookup  % behaviors if necessary. -%  % The name resolver remains untouched, but it calls  % \luafunction{fonts.names.resolve()} internally anyways (see  % \fileent{luaotfload-database.lua}). @@ -1683,10 +1687,12 @@ elseif font_definer == "patch"  then                    1)  end -loadmodule"features.lua" --- contains what was “font-ltx” and “font-otc” +loadmodule"features.lua"    --- contains what was “font-ltx” and “font-otc” +loadmodule"auxiliary.lua"   --- additionaly high-level functionality (new)  -- vim:tw=71:sw=4:ts=4:expandtab +  %    \end{macrocode}  %  % \iffalse diff --git a/mkglyphlist b/mkglyphlist index 9ee1528..d73a608 100755 --- a/mkglyphlist +++ b/mkglyphlist @@ -8,6 +8,12 @@  --      VERSION:  1.0  --      CREATED:  04/23/2013 12:42:17 PM CEST  ----------------------------------------------------------------------- +-- interesting thread on the Context list: +-- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html +----------------------------------------------------------------------- + + +-----------------------------------------------------------------------  --                              config  -----------------------------------------------------------------------  local glyphfile     = "./glyphlist.txt" diff --git a/tests/font_patch.tex b/tests/font_patch.tex index d41ff48..d3bba07 100644 --- a/tests/font_patch.tex +++ b/tests/font_patch.tex @@ -8,7 +8,11 @@        mc.DisplayOperatorMinHeight = 2800 / em * sz      end    end -  luatexbase.add_to_callback("luaotfload.patch_font", patch, "cambria.domh") +  %% part of luaotfload-auxiliary +  %luatexbase.add_to_callback( +    %"luaotfload.patch_font", +    %patch, +    %"luaotfload.aux.patch_cambria_domh")  }  \font\4={name:Cambria Math:mode=base;script=math} at 10pt diff --git a/tests/pln-aux-1.tex b/tests/pln-aux-1.tex new file mode 100644 index 0000000..a504850 --- /dev/null +++ b/tests/pln-aux-1.tex @@ -0,0 +1,49 @@ +\input luaotfload.sty + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% usage for glyph tests +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\baselineskip=17.28pt + +\font\iwonaregular=name:iwona at 14.4pt +\font\lmromanten=file:lmroman10-regular.otf at 14.4pt +\font\cmuregular=file:cmunrm.otf at 14.4pt + +%% wrap tests in macros (could move to style file) +\def\doifglyphelse#1#2#3{% +  \directlua{ +    luaotfload.aux.do_if_glyph_else([[#1]], [[#2]], [[#3]]) +  }% +} + +\def\doifglyph#1#2{\doifglyphelse{#1}{#2}{}} + +%% no otf font loaded yet, so both fail: +first: +\doifglyphelse{a}{true}{false} +\doifglyph    {a}{yep} + +%% load lm and try repeat: +\lmromanten +second: +\doifglyphelse{a}{true}{false} +\doifglyph    {a}{yep} + +%% let’s test some more free fonts +\def\checkglyphset{% +  \doifglyphelse  ö{ö}{nope} +  \doifglyphelse  п{п}{nope} +  \doifglyphelse  α{α}{nope} +  \doifglyphelse  Æ{Æ}{nope} +  \doifglyphelse  ą{ą}{nope} +  \doifglyphelse  ř{ř}{nope} +  \doifglyphelse  ˝{˝}{nope} +  \doifglyphelse  ѩ{ѩ}{nope} +  \endgraf +} + +\iwonaregular \checkglyphset +\lmromanten   \checkglyphset +\cmuregular   \checkglyphset + +\bye diff --git a/tests/pln-aux-2.tex b/tests/pln-aux-2.tex new file mode 100644 index 0000000..62192a5 --- /dev/null +++ b/tests/pln-aux-2.tex @@ -0,0 +1,102 @@ +\input luaotfload.sty +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% script, features, and language +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\font\minionregular=file:MinionPro_Regular.otf  at 9pt +\font\biolinum=file:LinBiolinum_R.otf  at 9pt +\font\cmuregular=file:cmunrm.otf  at 9pt + +%% (1) luaotfload.aux.provides_script(font_id, script) +%%      #1 defined font; #2 OT script tag +\def\providesscript[#1][#2]{% +  \bgroup#1% +  let’s see whether \detokenize{#1} has script #2: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_script(font.current(), [[#2]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\providesscript [\minionregular][latn]%% Latin +\providesscript      [\biolinum][latn] +\providesscript    [\cmuregular][latn] +\providesscript [\minionregular][cyrl]%% Cyrillic +\providesscript      [\biolinum][cyrl] +\providesscript    [\cmuregular][cyrl] +\providesscript [\minionregular][tibt]%% Tibetan +\providesscript      [\biolinum][tibt] +\providesscript    [\cmuregular][tibt] + +\hrule % -------------------------------------------------------------- + +%% (2) luaotfload.aux.provides_language(font_id, script, language) +%%      #1 defined font; #2 OT script tag; #3 OT language tag +\def\provideslanguage[#1][#2][#3]{% +  \bgroup#1% +  let’s see whether \detokenize{#1} supports language #3 for script #2: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_language(font.current(), [[#2]], [[#3]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\provideslanguage [\minionregular][latn][nld]%% Latin/Dutch +\provideslanguage      [\biolinum][latn][nld] +\provideslanguage    [\cmuregular][latn][nld] +\provideslanguage [\minionregular][latn][deu]%% Latin/German +\provideslanguage      [\biolinum][latn][deu] +\provideslanguage    [\cmuregular][latn][deu] +\provideslanguage [\minionregular][cyrl][rus]%% Cyrillic/Russian +\provideslanguage      [\biolinum][cyrl][rus] +\provideslanguage    [\cmuregular][cyrl][rus] +\provideslanguage [\minionregular][cyrl][klm]%% Cyrillic/Kalmyk +\provideslanguage      [\biolinum][cyrl][klm] +\provideslanguage    [\cmuregular][cyrl][klm] +\provideslanguage [\minionregular][cyrl][srb]%% Cyrillic/Serbian +\provideslanguage      [\biolinum][cyrl][srb] +\provideslanguage    [\cmuregular][cyrl][srb] +\provideslanguage [\minionregular][tibt][tib]%% Tibetan +\provideslanguage      [\biolinum][tibt][tib] +\provideslanguage    [\cmuregular][tibt][tib] + +\hrule % -------------------------------------------------------------- + +%% (3) luaotfload.aux.provides_feature( +%%                      font_id, script, language, feature) +%%      #1 defined font;    #2 OT script tag; +%%      #3 OT language tag; #4 OT feature +\def\providesfeature[#1][#2][#3][#4]{%this is getting ridiculous +  \bgroup#1% +  let’s see whether \detokenize{#1} supports feature #4 for the +  combination of script #2 with language #3: +  \directlua{ +    local aux = luaotfload.aux +    local succ = aux.provides_feature( +      font.current(), [[#2]], [[#3]], [[#4]]) +    if succ then tex.sprint"true" else tex.sprint"false" end +  }% +  \egroup +  \endgraf% +} + +\providesfeature [\minionregular][latn][nld][liga]%% Latin/Dutch +\providesfeature      [\biolinum][latn][nld][liga] +\providesfeature    [\cmuregular][latn][nld][liga] +\providesfeature [\minionregular][latn][deu][liga]%% Latin/German +\providesfeature      [\biolinum][latn][deu][liga] +\providesfeature    [\cmuregular][latn][deu][liga] +\providesfeature [\minionregular][cyrl][srb][liga]%% Cyrillic/Serbian +\providesfeature      [\biolinum][cyrl][srb][liga] +\providesfeature    [\cmuregular][cyrl][srb][liga] +\providesfeature [\minionregular][tibt][tib][liga]%% Tibetan +\providesfeature      [\biolinum][tibt][tib][liga] +\providesfeature    [\cmuregular][tibt][tib][liga] + +\bye diff --git a/tests/pln-aux-3.tex b/tests/pln-aux-3.tex new file mode 100644 index 0000000..12a80cf --- /dev/null +++ b/tests/pln-aux-3.tex @@ -0,0 +1,39 @@ +\input luaotfload.sty + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% math dimension getter +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\font\xitsmath=file:xits-math.otf +\font\cambriamath=file:cambria.ttc(1) + +\font\main=file:Iwona-Regular.otf at 12pt\main + +\directlua{ +  local aux = luaotfload.aux +  local test_a = function (fontname, dimension) +    tex.sprint( +      "(", fontname, " (", dimension, " ", +      aux.get_math_dimension(fontname, dimension), +      [[))\endgraf ]]) +  end +     +  local test_b = function (fontname, dimension) +    aux.sprint_math_dimension(fontname, dimension) +    tex.print[[\endgraf ]] +  end + +  test_a("xitsmath",     "AxisHeight") +  test_a("xitsmath",     "RadicalVerticalGap") +  test_a("cambriamath",  "StackTopShiftUp") +  test_a("cambriamath",  "FractionNumeratorGapMin") + +  test_b("xitsmath",     "AxisHeight") +  test_b("xitsmath",     "RadicalVerticalGap") +  test_b("cambriamath",  "StackTopShiftUp") +  test_b("cambriamath",  "FractionNumeratorGapMin") +} + +foo bar baz + +\bye diff --git a/tests/pln-aux-4.tex b/tests/pln-aux-4.tex new file mode 100644 index 0000000..80ffc0b --- /dev/null +++ b/tests/pln-aux-4.tex @@ -0,0 +1,41 @@ +\input luaotfload.sty + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% unicode character mappings +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\font\ptserifregular = file:PTF55F.ttf \ptserifregular + +%% here we map the function luaotfload.aux.name_of_slot +%% on a short text, printing a list of letters, their +%% code points and names (as specified in the Adobe +%% Glyph List). + +\directlua{ +  local aux = luaotfload.aux +  local cbk = function (str) +    if string.match(str, "^EOF") then +      luatexbase.remove_from_callback("process_input_buffer", "weird") +      return [[the end!]] +    end +    local res = { } +    for chr in string.utfcharacters(str) do +      local val = unicode.utf8.byte(chr) +      local line = chr .. " <> " .. tostring(val) +      line = line .. " <> " .. (aux.name_of_slot(val) or "") +      res[\string#res+1] = line +    end +    return table.concat(res, [[\endgraf]]) +  end + +  luatexbase.add_to_callback("process_input_buffer", cbk, "weird") +} + +Я узнал что у меня +Есть огромная семья +И тропинка и лесок +В поле каждый колосок + +EOF + +\bye  | 
