From 84b147aa9d550cbe549d68b00143201f4b68dddc Mon Sep 17 00:00:00 2001
From: Hans Hagen The code defined here may move to the big character table. The next three tables can for instance be be used to enhance
-kerning tables that lack kerning pairs for these special characters.
-Of course they may come in handy elsewhere too. Using shcodes is
-not handy here (incpmplete). The following function is used in the indexing code, where we
-need some sort of default fallback mapping. (This is obsolete!) Only characters with a code smaller than 128 make sense,
-anything larger is encoding dependent. An interesting complication
-is that a character can be in an encoding twice but is hashed
-once. Requesting lower and uppercase codes: Requesting lower and uppercase codes:
Only characters with a code smaller than 128 make sense, +anything larger is encoding dependent. An interesting complication +is that a character can be in an encoding twice but is hashed +once.
+--ldx]]-- + +local ligatures = { -- okay, nowadays we could parse the name + ['f'] = { + { 'f', 'ff' }, + { 'i', 'fi' }, + { 'l', 'fl' }, + }, + ['ff'] = { + { 'i', 'ffi' } + }, + ['fi'] = { + { 'i', 'fii' } + }, + ['fl'] = { + { 'i', 'fli' } + }, + ['s'] = { + { 't', 'st' } + }, + ['i'] = { + { 'j', 'ij' } + }, +} + +local texligatures = { + -- ['space'] = { + -- { 'L', 'Lslash' }, + -- { 'l', 'lslash' } + -- }, + -- ['question'] = { + -- { 'quoteleft', 'questiondown' } + -- }, + -- ['exclam'] = { + -- { 'quoteleft', 'exclamdown' } + -- }, + ['quoteleft'] = { + { 'quoteleft', 'quotedblleft' } + }, + ['quoteright'] = { + { 'quoteright', 'quotedblright' } + }, + ['hyphen'] = { + { 'hyphen', 'endash' } + }, + ['endash'] = { + { 'hyphen', 'emdash' } + } +} + +local addthem = function(afmdata,ligatures) local glyphs, luatex = afmdata.glyphs, afmdata.luatex local indices, unicodes, names = luatex.indices, luatex.unicodes, luatex.names - for k,v in next, characters[ligatures] do -- main characters table - local one = glyphs[names[k]] + for ligname, ligdata in next, ligatures do + local one = glyphs[names[ligname]] if one then - for _, b in next, v do - two, three = b[1], b[2] + for _, pair in next, ligdata do + local two, three = pair[1], pair[2] if two and three and names[two] and names[three] then - local ol = one[ligatures] + local ol = one.ligatures if ol then if not ol[two] then -- was one.ligatures ... bug ol[two] = three end else - one[ligatures] = { [two] = three } + one.ligatures = { [two] = three } end end end @@ -411,22 +468,168 @@ addligatures = function(afmdata,ligatures) end end +addligatures = function(afmdata) addthem(afmdata,ligatures ) end +addtexligatures = function(afmdata) addthem(afmdata,texligatures) end + --[[ldx--We keep the extra kerns in separate kerning tables so that we can use them selectively.
--ldx]]-- +-- This is rather old code (from the beginning when we had only tfm). If +-- we unify the afm data (now we have names all over the place) then +-- we can use shcodes but there will be many more looping then. But we +-- could get rid of the tables in char-cmp then. + +local left = { + AEligature = "A", aeligature = "a", + OEligature = "O", oeligature = "o", + IJligature = "I", ijligature = "i", + AE = "A", ae = "a", + OE = "O", oe = "o", + IJ = "I", ij = "i", + Ssharp = "S", ssharp = "s", +} + +local right = { + AEligature = "E", aeligature = "e", + OEligature = "E", oeligature = "e", + IJligature = "J", ijligature = "j", + AE = "E", ae = "e", + OE = "E", oe = "e", + IJ = "J", ij = "j", + Ssharp = "S", ssharp = "s", +} + +local both = { + Acircumflex = "A", acircumflex = "a", + Ccircumflex = "C", ccircumflex = "c", + Ecircumflex = "E", ecircumflex = "e", + Gcircumflex = "G", gcircumflex = "g", + Hcircumflex = "H", hcircumflex = "h", + Icircumflex = "I", icircumflex = "i", + Jcircumflex = "J", jcircumflex = "j", + Ocircumflex = "O", ocircumflex = "o", + Scircumflex = "S", scircumflex = "s", + Ucircumflex = "U", ucircumflex = "u", + Wcircumflex = "W", wcircumflex = "w", + Ycircumflex = "Y", ycircumflex = "y", + + Agrave = "A", agrave = "a", + Egrave = "E", egrave = "e", + Igrave = "I", igrave = "i", + Ograve = "O", ograve = "o", + Ugrave = "U", ugrave = "u", + Ygrave = "Y", ygrave = "y", + + Atilde = "A", atilde = "a", + Itilde = "I", itilde = "i", + Otilde = "O", otilde = "o", + Utilde = "U", utilde = "u", + Ntilde = "N", ntilde = "n", + + Adiaeresis = "A", adiaeresis = "a", Adieresis = "A", adieresis = "a", + Ediaeresis = "E", ediaeresis = "e", Edieresis = "E", edieresis = "e", + Idiaeresis = "I", idiaeresis = "i", Idieresis = "I", idieresis = "i", + Odiaeresis = "O", odiaeresis = "o", Odieresis = "O", odieresis = "o", + Udiaeresis = "U", udiaeresis = "u", Udieresis = "U", udieresis = "u", + Ydiaeresis = "Y", ydiaeresis = "y", Ydieresis = "Y", ydieresis = "y", + + Aacute = "A", aacute = "a", + Cacute = "C", cacute = "c", + Eacute = "E", eacute = "e", + Iacute = "I", iacute = "i", + Lacute = "L", lacute = "l", + Nacute = "N", nacute = "n", + Oacute = "O", oacute = "o", + Racute = "R", racute = "r", + Sacute = "S", sacute = "s", + Uacute = "U", uacute = "u", + Yacute = "Y", yacute = "y", + Zacute = "Z", zacute = "z", + + Dstroke = "D", dstroke = "d", + Hstroke = "H", hstroke = "h", + Tstroke = "T", tstroke = "t", + + Cdotaccent = "C", cdotaccent = "c", + Edotaccent = "E", edotaccent = "e", + Gdotaccent = "G", gdotaccent = "g", + Idotaccent = "I", idotaccent = "i", + Zdotaccent = "Z", zdotaccent = "z", + + Amacron = "A", amacron = "a", + Emacron = "E", emacron = "e", + Imacron = "I", imacron = "i", + Omacron = "O", omacron = "o", + Umacron = "U", umacron = "u", + + Ccedilla = "C", ccedilla = "c", + Kcedilla = "K", kcedilla = "k", + Lcedilla = "L", lcedilla = "l", + Ncedilla = "N", ncedilla = "n", + Rcedilla = "R", rcedilla = "r", + Scedilla = "S", scedilla = "s", + Tcedilla = "T", tcedilla = "t", + + Ohungarumlaut = "O", ohungarumlaut = "o", + Uhungarumlaut = "U", uhungarumlaut = "u", + + Aogonek = "A", aogonek = "a", + Eogonek = "E", eogonek = "e", + Iogonek = "I", iogonek = "i", + Uogonek = "U", uogonek = "u", + + Aring = "A", aring = "a", + Uring = "U", uring = "u", + + Abreve = "A", abreve = "a", + Ebreve = "E", ebreve = "e", + Gbreve = "G", gbreve = "g", + Ibreve = "I", ibreve = "i", + Obreve = "O", obreve = "o", + Ubreve = "U", ubreve = "u", + + Ccaron = "C", ccaron = "c", + Dcaron = "D", dcaron = "d", + Ecaron = "E", ecaron = "e", + Lcaron = "L", lcaron = "l", + Ncaron = "N", ncaron = "n", + Rcaron = "R", rcaron = "r", + Scaron = "S", scaron = "s", + Tcaron = "T", tcaron = "t", + Zcaron = "Z", zcaron = "z", + + dotlessI = "I", dotlessi = "i", + dotlessJ = "J", dotlessj = "j", + + AEligature = "AE", aeligature = "ae", AE = "AE", ae = "ae", + OEligature = "OE", oeligature = "oe", OE = "OE", oe = "oe", + IJligature = "IJ", ijligature = "ij", IJ = "IJ", ij = "ij", + + Lstroke = "L", lstroke = "l", Lslash = "L", lslash = "l", + Ostroke = "O", ostroke = "o", Oslash = "O", oslash = "o", + + Ssharp = "SS", ssharp = "ss", + + Aumlaut = "A", aumlaut = "a", + Eumlaut = "E", eumlaut = "e", + Iumlaut = "I", iumlaut = "i", + Oumlaut = "O", oumlaut = "o", + Uumlaut = "U", uumlaut = "u", + +} + addkerns = function(afmdata) -- using shcodes is not robust here local glyphs = afmdata.glyphs local names = afmdata.luatex.names - local uncomposed = characters.uncomposed local function do_it_left(what) for index, glyph in next, glyphs do local kerns = glyph.kerns if kerns then local extrakerns = glyph.extrakerns or { } - for complex, simple in next, uncomposed[what] do - if names[compex] then + for complex, simple in next, what do + if names[complex] then local ks = kerns[simple] if ks and not kerns[complex] then extrakerns[complex] = ks @@ -440,7 +643,7 @@ addkerns = function(afmdata) -- using shcodes is not robust here end end local function do_it_copy(what) - for complex, simple in next, uncomposed[what] do + for complex, simple in next, what do local c = glyphs[names[complex]] if c then -- optional local s = glyphs[names[simple]] @@ -462,11 +665,11 @@ addkerns = function(afmdata) -- using shcodes is not robust here end end -- add complex with values of simplified when present - do_it_left("left") - do_it_left("both") + do_it_left(left) + do_it_left(both) -- copy kerns from simple char to complex char unless set - do_it_copy("both") - do_it_copy("right") + do_it_copy(both) + do_it_copy(right) end --[[ldx-- diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index f08ba0e26..dc6765c79 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -479,6 +479,9 @@ function splitters.utf(str) -- we could append m and u but this is cleaner, s is local l = lower[sc] n = n + 1 l = l and utfbyte(l) or lccodes[b] + if type(l) == "table" then + l = l[1] -- there are currently no tables in lccodes but it can be some, day + end z_case[n] = l if l ~= b then m_case[n] = l - 1 diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 56441cb1e..e9fde1cd5 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index 17169acbf..f9c339dff 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -59,23 +59,15 @@ %D to use development versions of \MKIV\ for real documents. %D %D \starttyping -%D \doifolderversionelse\contextversion{2001.02.03}{yes}{no} -%D \doifolderversionelse\contextversion{3001.02.03}{yes}{no} +%D \doifolderversionelse\contextversion{1010.10.10} {OLDER} {OKAY} => OLDER +%D \doifolderversionelse\contextversion{2020.20.20} {OLDER} {OKAY} => OKAY +%D \doifolderversionelse\contextversion{2020} {OLDER} {OKAY} => OKAY %D \stoptyping %D -%D The \type {yyyy.mm.dd} syntax is rather strict. +%D The version pattern is \type {yyyy.mm.dd} (with mm and dd being optional). -% todo: lua - -\def\@@versiontonumber#1.#2.#3#4#5\relax - {\numexpr#1*\plustenthousand+#2*\plushundred+#3#4\relax} - -\def\doifolderversionelse#1#2% - {\normalexpanded{\noexpand\ifnum\noexpand\@@versiontonumber#1\relax<\noexpand\@@versiontonumber#2\relax}\relax - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} +\def\doifolderversionelse#1#2{\ctxcommand{doifolderversionelse("#1","#2")}} +\def\doifoldercontextelse #1{\ctxcommand{doifolderversionelse("#1")}} %D \macros %D {normalspace} diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua index fefe415cf..7c619b6d3 100644 --- a/tex/context/base/syst-lua.lua +++ b/tex/context/base/syst-lua.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['syst-lua'] = { local texsprint, texprint, texwrite, texiowrite_nl = tex.sprint, tex.print, tex.write, texio.write_nl local format, find = string.format, string.find -local lpegmatch = lpeg.match +local tonumber = tonumber +local S, Ct, lpegmatch, lpegsplitat = lpeg.S, lpeg.Ct, lpeg.match, lpeg.splitat local ctxcatcodes = tex.ctxcatcodes @@ -53,7 +54,7 @@ function commands.doifelsespaces(str) return commands.doifelse(find(str,"^ +$")) end -local s = lpeg.Ct(lpeg.splitat(",")) +local s = Ct(lpegsplitat(",")) local h = { } function commands.doifcommonelse(a,b) @@ -87,3 +88,20 @@ local pattern = lpeg.patterns.validdimen function commands.doifdimenstringelse(str) testcase(lpegmatch(pattern,str)) end + +local splitter = lpegsplitat(S(". ")) + +function commands.doifolderversionelse(one,two) -- no checking done + if not two then + one, two = environment.version, one + elseif one == "" then + one = environment.version + end + local y_1, m_1, d_1 = lpeg.match(splitter,one) + local y_2, m_2, d_2 = lpeg.match(splitter,two) + commands.testcase ( not ( + (tonumber(y_2) or 0) >= (tonumber(y_1) or 0) and + (tonumber(m_2) or 99) >= (tonumber(m_1) or 0) and + (tonumber(d_2) or 99) >= (tonumber(d_1) or 0) + ) ) +end diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua index aaa9de933..a8e714a9b 100644 --- a/tex/context/base/typo-cap.lua +++ b/tex/context/base/typo-cap.lua @@ -63,9 +63,12 @@ local lastfont = nil -- -- \WORD {far too \Word{many \WORD{more \word{pushed} in between} useless} words} -local function helper(start, code, codes, special, attribute, once) +local uccodes = characters.uccodes +local lccodes = characters.lccodes + +local function helper(start, codes, special, attribute, once) local char = start.char - local dc = chardata[char] + local dc = codes[char] if dc then local fnt = start.font if special then @@ -84,16 +87,16 @@ local function helper(start, code, codes, special, attribute, once) end end local ifc = fontchar[fnt] - local ucs = dc[codes] - if ucs then + if type(dc) == "table" then local ok = true - for i=1,#ucs do - ok = ok and ifc[ucs[i]] + for i=1,#dc do + ok = ok and ifc[dc[i]] end if ok then + -- tood; use generic injector local prev, original = start, start - for i=1,#ucs do - local chr = ucs[i] + for i=1,#dc do + local chr = dc[i] prev = start if i == 1 then start.char = chr @@ -115,10 +118,8 @@ local function helper(start, code, codes, special, attribute, once) end if once then lastfont = nil end return start, false - end - local uc = dc[code] - if uc and ifc[uc] then - start.char = uc + elseif ifc[dc] then + start.char = dc if once then lastfont = nil end return start, true end @@ -129,12 +130,12 @@ end actions[1] = function(start,attribute) lastfont = nil - return helper(start,'uccode','uccodes') + return helper(start,uccodes) end actions[2] = function(start,attribute) lastfont = nil - return helper(start,'lccode','lccodes') + return helper(start,lccodes) end actions[3] = function(start,attribute,attr) @@ -154,7 +155,7 @@ actions[3] = function(start,attribute,attr) end -- we could return the last in the range and save some scanning -- but why bother - return helper(start,'uccode','uccodes') + return helper(start,uccodes) else return start, false end @@ -167,18 +168,18 @@ actions[4] = function(start,attribute) prev = prev.prev end if not prev or prev.id ~= glyph_code then - return helper(start,'uccode','uccodes') + return helper(start,uccodes) else return start, false end end actions[5] = function(start,attribute) -- 3 - return helper(start,'uccode','uccodes',true,attribute,true) + return helper(start,uccodes,true,attribute,true) end actions[6] = function(start,attribute) -- 4 - return helper(start,'uccode','uccodes',true,attribute,false) + return helper(start,uccodes,true,attribute,false) end actions[8] = function(start) @@ -187,23 +188,23 @@ actions[8] = function(start) local mr = math.random -- local tfm = fontdata[start.font].characters local tfm = fontchar[start.font] - if chardata[ch].lccode then + if lccodes[ch] then while true do local d = chardata[mr(1,0xFFFF)] if d then - local uc = d.uccode - if uc and tfm[uc] then + local uc = uccodes[d] + if uc and tfm[uc] then -- this also intercepts tables start.char = uc return start, true end end end - elseif chardata[ch].uccode then + elseif uccodes[ch] then while true do local d = chardata[mr(1,0xFFFF)] if d then - local lc = d.lccode - if lc and tfm[lc] then + local lc = lccodes[d] + if lc and tfm[lc] then -- this also intercepts tables start.char = lc return start, true end diff --git a/tex/context/base/typo-cln.lua b/tex/context/base/typo-cln.lua index 09e8744ea..2327ef6be 100644 --- a/tex/context/base/typo-cln.lua +++ b/tex/context/base/typo-cln.lua @@ -32,7 +32,7 @@ local traverse_id = node.traverse_id local glyph_code = nodecodes.glyph local uccodes = characters.uccodes -local a_cleaner = attributes.private("cleaner") +local a_cleaner = attributes.private("cleaner") local resetter = { -- this will become an entry in char-def [utfbyte(".")] = true @@ -53,11 +53,15 @@ local function process(namespace,attribute,head) local a = has_attribute(n,attribute) if a == 1 then -- currently only one cleaner so no need to be fancy local upper = uccodes[char] - n.char = upper - inline = true - done = true - if trace_autocase then - report_autocase("") + if type(upper) == "table" then + -- some day, not much change that \SS ends up here + else + n.char = upper + inline = true + done = true + if trace_autocase then + report_autocase("") + end end end end diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua index 9bf3cb1f5..597950c6a 100644 --- a/tex/context/base/typo-krn.lua +++ b/tex/context/base/typo-krn.lua @@ -80,7 +80,7 @@ kerns.keeptogether = false -- just for fun (todo: control setting with key/value -- can be optimized .. the prev thing .. but hardly worth the effort -local function do_process(namespace,attribute,head,force) +local function do_process(namespace,attribute,head,force) -- todo: glue so that we can fully stretch local start, done, lastfont = head, false, nil local keepligature = kerns.keepligature local keeptogether = kerns.keeptogether @@ -130,7 +130,7 @@ if keeptogether and prev.prev.id == glyph_code and keeptogether(prev.prev,start) -- keep 'm else prev.subtype = userkern_code - prev.kern = prev.kern + quaddata[lastfont]*krn + prev.kern = prev.kern + quaddata[lastfont]*krn -- here done = true end elseif pid == glyph_code then @@ -141,12 +141,12 @@ if keeptogether and keeptogether(prev,start) then else local kerns = chardata[lastfont][prevchar].kerns local kern = kerns and kerns[lastchar] or 0 - krn = kern + quaddata[lastfont]*krn + krn = kern + quaddata[lastfont]*krn -- here insert_node_before(head,start,new_kern(krn)) done = true end else - krn = quaddata[lastfont]*krn + krn = quaddata[lastfont]*krn -- here insert_node_before(head,start,new_kern(krn)) done = true end @@ -201,9 +201,9 @@ end local prevchar, lastchar = prv.char, start.char local kerns = chardata[lastfont][prevchar].kerns local kern = kerns and kerns[lastchar] or 0 - krn = kern + quaddata[lastfont]*krn + krn = kern + quaddata[lastfont]*krn -- here else - krn = quaddata[lastfont]*krn + krn = quaddata[lastfont]*krn -- here end disc.replace = new_kern(krn) end -- cgit v1.2.3