diff options
Diffstat (limited to 'macros/luatex/generic/lua-uni-algos/lua-uni-case.lua')
-rw-r--r-- | macros/luatex/generic/lua-uni-algos/lua-uni-case.lua | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/macros/luatex/generic/lua-uni-algos/lua-uni-case.lua b/macros/luatex/generic/lua-uni-algos/lua-uni-case.lua new file mode 100644 index 0000000000..9014258696 --- /dev/null +++ b/macros/luatex/generic/lua-uni-algos/lua-uni-case.lua @@ -0,0 +1,67 @@ +-- lua-uni-graphemes.lua +-- Copyright 2020 Marcel Krüger +-- +-- This work may be distributed and/or modified under the +-- conditions of the LaTeX Project Public License, either version 1.3 +-- of this license or (at your option) any later version. +-- The latest version of this license is in +-- http://www.latex-project.org/lppl.txt +-- and version 1.3 or later is part of all distributions of LaTeX +-- version 2005/12/01 or later. +-- +-- This work has the LPPL maintenance status `maintained'. +-- +-- The Current Maintainer of this work is Marcel Krüger + +local unpack = table.unpack +local move = table.move +local codes = utf8.codes +local utf8char = utf8.char + +local empty = {} +local result = {} + +local casefold, casefold_lookup do + local p = require'lua-uni-parse' + local l = lpeg or require'lpeg' + + local data = p.parse_file('CaseFolding', l.Cf( + l.Ct(l.Cg(l.Ct'', 'C') * l.Cg(l.Ct'', 'F') * l.Cg(l.Ct'', 'S') * l.Cg(l.Ct'', 'T')) + * (l.Cg(p.fields(p.codepoint, l.C(1), l.Ct(p.codepoint * (' ' * p.codepoint)^0), true)) + p.eol)^0 + * -1 + , function(t, base, class, mapping) + t[class][base] = mapping + return t + end)) + local C, F, S, T = data.C, data.F, data.S, data.T + data = nil + + function casefold_lookup(c, full, special) + return (special and T[c]) or C[c] or (full and F or S)[c] + end + function casefold(s, full, special) + local first = special and T or empty + local second = C + local third = full and F or S + local result = result + for i = #result, 1, -1 do result[i] = nil end + local i = 1 + for _, c in codes(s) do + local datum = first[c] or second[c] or third[c] + if datum then + local l = #datum + move(datum, 1, l, i, result) + i = i + l + else + result[i] = c + i = i + 1 + end + end + return utf8char(unpack(result)) + end +end + +return { + casefold = casefold, + casefold_lookup = casefold_lookup, +} |