-- @titre Espaces typographiques -- @title Typographic spaces -- @categorie espacer -- @resume Ajoute les espaces qui manquent et règle leur chasse dans chaque master : espace fine insécable (U+202F, celle du français devant ; : ! ?), fine (U+2009), ultrafine (U+200A), espace de chiffre (U+2007, chasse du zéro), espace de ponctuation (U+2008, chasse du point), et l'insécable alignée sur l'espace. -- @summary Adds the missing spaces and sets their widths in every master: narrow no-break space (U+202F, used in French before ; : ! ?), thin (U+2009), hair (U+200A), figure space (U+2007, width of zero), punctuation space (U+2008, width of the period), and the no-break space matched to the space. -- Fontista · bibliothèque de scripts · https://fontista.thinkspark.dev/scripts.html local THIN = 1 / 5 -- thin and narrow no-break spaces, share of the em local HAIR = 1 / 10 -- hair space, share of the em local en = lang == "en" -- glyph already carrying a code point, whatever its name local by_code = {} for _, g in ipairs(font.glyphs) do local info = glyph(g) if info and info.unicode then by_code[info.unicode] = g end end local function width_of(code, m) local g = by_code[code] local l = g and layer(g, m) or nil return l and l.width or nil end local spaces = { { 0x202F, "uni202F", function(m) return THIN * font.upm end }, { 0x2009, "uni2009", function(m) return THIN * font.upm end }, { 0x200A, "uni200A", function(m) return HAIR * font.upm end }, { 0x2007, "uni2007", function(m) return width_of(0x30, m) end }, { 0x2008, "uni2008", function(m) return width_of(0x2E, m) end }, { 0x00A0, "uni00A0", function(m) return width_of(0x20, m) end }, } local added = {} for _, s in ipairs(spaces) do local code, name, w = s[1], s[2], s[3] local g = by_code[code] if not g then if add_glyph(name, code) then g = name added[#added + 1] = name by_code[code] = name end end if g then for _, m in ipairs(font.masters) do local v = w(m.id) if v then set_width(g, m.id, math.floor(v + 0.5)) end end end end print(#added == 0 and (en and "All spaces were there; widths set." or "Toutes les espaces existaient ; chasses réglées.") or string.format(en and "Added: %s; widths set in every master." or "Ajoutées : %s ; chasses réglées dans chaque master.", table.concat(added, ", ")))