From a41fe00a674c46d923de837778e9ee44565dc341 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 31 Mar 2021 18:16:45 +0200 Subject: 2021-03-31 18:03:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/l-lpeg.lua | 2 +- tex/context/base/mkiv/mult-low.lua | 2 +- tex/context/base/mkiv/status-files.pdf | Bin 25395 -> 25407 bytes tex/context/base/mkiv/status-lua.pdf | Bin 257329 -> 257519 bytes tex/context/base/mkxl/cont-new.mkxl | 2 +- tex/context/base/mkxl/context.mkxl | 2 +- tex/context/base/mkxl/font-ots.lmt | 94 +-- tex/context/base/mkxl/lang-hup.lmt | 5 +- tex/context/base/mkxl/lang-ini.lmt | 630 +++++++++++++++++---- tex/context/base/mkxl/lang-ini.mkxl | 31 +- tex/context/base/mkxl/lpdf-ini.lmt | 48 +- tex/context/base/mkxl/mlib-pps.lmt | 5 +- tex/context/base/mkxl/mlib-svg.lmt | 233 +++++--- tex/context/base/mkxl/strc-flt.mklx | 71 +-- tex/context/base/mkxl/typo-brk.lmt | 1 + tex/context/modules/mkiv/s-languages-goodies.lmt | 32 ++ tex/context/modules/mkiv/s-languages-goodies.mkxl | 40 ++ tex/context/patterns/lmtx/lang-de.llg | 589 +++++++++++++++++++ tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 23 files changed, 1491 insertions(+), 306 deletions(-) create mode 100644 tex/context/modules/mkiv/s-languages-goodies.lmt create mode 100644 tex/context/modules/mkiv/s-languages-goodies.mkxl create mode 100644 tex/context/patterns/lmtx/lang-de.llg (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 8fd36b843..8abe3c057 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2021.03.27 19:03} +\newcontextversion{2021.03.31 18:00} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 4f3ab902a..aa9e7e08f 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2021.03.27 19:03} +\edef\contextversion{2021.03.31 18:00} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index cd9476787..241e31a2e 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.03.27 19:03} +\newcontextversion{2021.03.31 18:00} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 5e957e8bf..f878dd195 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2021.03.27 19:03} +\edef\contextversion{2021.03.31 18:00} %D Kind of special: diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua index b0868ba48..50306e4ab 100644 --- a/tex/context/base/mkiv/l-lpeg.lua +++ b/tex/context/base/mkiv/l-lpeg.lua @@ -507,7 +507,7 @@ end -- todo: cache when string -function lpeg.replacer(one,two,makefunction,isutf) -- in principle we should sort the keys +function lpeg.replacer(one,two,makefunction,isutf) -- in principle we should sort the keys but we have a better one anyway local pattern local u = isutf and utf8char or 1 if type(one) == "table" then diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index 8360ec81f..ee924b469 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -163,7 +163,7 @@ return { "compoundhyphenationmodecode", "strictstarthyphenationmodecode", "strictendhyphenationmodecode", "automaticpenaltyhyphenationmodecode", "explicitpenaltyhyphenationmodecode", "permitgluehyphenationmodecode", "permitallhyphenationmodecode", "permitmathreplacehyphenationmodecode", - "forcecheckhyphenationmodecode", "lazyligatureshyphenationmodecode", + "forcecheckhyphenationmodecode", "lazyligatureshyphenationmodecode", "forcehandlerhyphenationmodecode", -- "normalizelinecode", "parindentskipcode", "swaphangindentcode", "swapparsshapecode", "breakafterdircode", "removemarginkernscode", "clipwidthcode", "flattendiscretionariescode", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 3f6d1a605..3b842839c 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 880d4b9c3..a47f44479 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index c09bfb8dc..ba8893ea6 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.03.27 19:03} +\newcontextversion{2021.03.31 18:00} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 3bb67e070..1ace620b2 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.03.27 19:03} +\immutable\edef\contextversion{2021.03.31 18:00} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt index d9ff6635c..d5d04e978 100644 --- a/tex/context/base/mkxl/font-ots.lmt +++ b/tex/context/base/mkxl/font-ots.lmt @@ -507,10 +507,12 @@ end -- we can have more granularity here but for now we only do a simple check -local no_left_ligature_code = 1 -local no_right_ligature_code = 2 -local no_left_kern_code = 4 -local no_right_kern_code = 8 +local glyphoptioncodes = tex.glyphoptioncodes + +local no_left_ligature_code = glyphoptioncodes.noleftligature +local no_right_ligature_code = glyphoptioncodes.norightligature +local no_left_kern_code = glyphoptioncodes.noleftkern +local no_right_kern_code = glyphoptioncodes.norightkern local has_glyph_option = nuts.has_glyph_option @@ -544,9 +546,9 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou setchar(start,char) return head, start end --- if inhibited(start,stop) then --- return head, start --- end + if inhibited(start,stop) then + return head, start + end local prev = getprev(start) local next = getnext(stop) local comp = start @@ -780,9 +782,9 @@ end -- Blocking is nasty: (ff\zwj l) vs (ff\zwj l) vs (ffl) vs (f\zwj fl} function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) -if start and has_glyph_option(start,no_right_ligature_code) then - return head, start, false, false -end + if start and has_glyph_option(start,no_right_ligature_code) then + return head, start, false, nil + end local current = getnext(start) if not current then return head, start, false, nil @@ -791,11 +793,8 @@ end local startchar = getchar(start) if skiphash and skiphash[startchar] then while current do -if current and has_glyph_option(current,no_left_ligature_code) then - break -end local nxt, char = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) - if char then + if char and not has_glyph_option(current,no_left_ligature_code) then local lg = ligature[char] if lg then stop = current @@ -827,13 +826,12 @@ end local discfound = false local hasmarks = marks[startchar] while current do -if current and has_glyph_option(current,no_left_ligature_code) then - break -end local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) if char then if skiphash and skiphash[char] then current = nxt + elseif has_glyph_option(current,no_left_ligature_code) then + break else local lg = ligature[char] if lg then @@ -864,25 +862,27 @@ end -- Challenge for Kai (latinmodern): \hyphenation{fii-f-f-iif} fiiffiif -- if discfound then + -- todo: check for no right ligature -- don't assume marks in a disc and we don't run over a disc (for now) local pre, post, replace = getdisc(discfound) local match if replace then local nxt, char = isnextchar(replace,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) - if char and ligature[char] then + if char and ligature[char] and not has_glyph_option(replace,no_left_ligature_code) then match = true end end if not match and pre then local nxt, char = isnextchar(pre,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) - if char and ligature[char] then + if char and ligature[char] and not has_glyph_option(pre,no_left_ligature_code) then match = true end end -- is this test ok: if not match and not pre or not replace then - local nxt, char = isnextchar(getnext(discfound),currentfont,currentdynamic,currentscale,currentxscale,currentyscale) - if char and ligature[char] then + local ndf = getnext(discfound) + local nxt, char = isnextchar(ndf,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) + if char and ligature[char] and not has_glyph_option(ndf,no_left_ligature_code) then match = true end end @@ -1486,9 +1486,9 @@ assume rather stupid ligatures (no complex disc nodes).

-- compare to handlers.gsub_ligature which is more complex ... why function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -if start and has_glyph_option(start,no_right_ligature_code) then - return head, start, false, 0, false -end + if start and has_glyph_option(start,no_right_ligature_code) then + return head, start, false, 0, false + end local mapping = currentlookup.mapping if mapping == nil then mapping = getmapping(dataset,sequence,currentlookup) @@ -1507,57 +1507,18 @@ end local last = stop local nofreplacements = 1 while current do + local nxt, schar, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) + if schar then if current and has_glyph_option(current,no_left_ligature_code) then break end - -- todo: ischar ... can there really be disc nodes here? --- local id = getid(current) --- if id == disc_code then --- if not discfound then --- discfound = current --- end --- if current == stop then --- break -- okay? or before the disc --- else --- current = getnext(current) --- end --- else --- local schar = getchar(current) --- if skiphash and skiphash[schar] then -- marks --- -- if current == stop then -- maybe add this --- -- break --- -- else --- current = getnext(current) --- -- end --- else --- local lg = ligatures[schar] --- if lg then --- ligatures = lg --- last = current --- nofreplacements = nofreplacements + 1 --- if marks[char] then --- hasmarks = true --- end --- if current == stop then --- break --- else --- current = getnext(current) --- end --- else --- break --- end --- end --- end - -- - local nxt, schar, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale) - if schar then if skiphash and skiphash[schar] then -- marks -- if current == stop then -- maybe add this -- break -- else current = nxt -- end - else + else local lg = ligatures[schar] if lg then ligatures = lg @@ -1587,7 +1548,6 @@ end else break end - -- end local ligature = ligatures.ligature if ligature then diff --git a/tex/context/base/mkxl/lang-hup.lmt b/tex/context/base/mkxl/lang-hup.lmt index c42f0ffd8..6658f0aab 100644 --- a/tex/context/base/mkxl/lang-hup.lmt +++ b/tex/context/base/mkxl/lang-hup.lmt @@ -212,12 +212,15 @@ function nodes.handlers.visualizehyphenation(head) if ligature_mode then for n in nextglyph, list do local d = getdiscpart(n) + local s = getsubtype(n) if d > 0 and d < 4 then - if getsubtype(n) == ligature_code then + if s == ligature_code then setcolor(n,color_l[d]) else setcolor(n,color_n[d]) end + elseif s == ligature_code then + setcolor(n,"darkgray") end end else diff --git a/tex/context/base/mkxl/lang-ini.lmt b/tex/context/base/mkxl/lang-ini.lmt index 2e2d5e57d..7364eb7c7 100644 --- a/tex/context/base/mkxl/lang-ini.lmt +++ b/tex/context/base/mkxl/lang-ini.lmt @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['lang-ini'] = { -- needs a cleanup (share locals) -- discard language when redefined +-- 002D : hyphen-minus (ascii) -- 002D : hyphen-minus (ascii) -- 2010 : hyphen -- 2011 : nonbreakable hyphen @@ -19,9 +20,10 @@ if not modules then modules = { } end modules ['lang-ini'] = { -- todo: no foo:bar but foo(bar,...) local type, tonumber, next = type, tonumber, next -local utfbyte = utf.byte +local utfbyte, utflength = utf.byte, utf.length local format, gsub, gmatch, find = string.format, string.gsub, string.gmatch, string.find local concat, sortedkeys, sortedpairs, keys, insert = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert +local setmetatableindex = table.setmetatableindex local utfvalues, strip, utfcharacters = string.utfvalues, string.strip, utf.characters local context = context @@ -29,11 +31,13 @@ local commands = commands local implement = interfaces.implement local settings_to_array = utilities.parsers.settings_to_array -local settings_to_set = utilities.parsers.settings_to_set +local settings_to_set = utilities.parsers.settings_to_set local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end) +local trace_goodies = false trackers.register("languages.goodies", function(v) trace_goodies = v end) local report_initialization = logs.reporter("languages","initialization") +local report_goodies = logs.reporter("languages","goodies") local prehyphenchar = language.prehyphenchar -- global per language local posthyphenchar = language.posthyphenchar -- global per language @@ -94,6 +98,9 @@ local function tolang(what) -- returns lang object if not what then what = currentlanguage() end + if type(what) == "userdata" then + return what + end local tag = numbers[what] local data = tag and registered[tag] or registered[what] if data then @@ -114,7 +121,7 @@ function languages.getdata(tag) -- or number end end --- languages.tolang = tolang +languages.tolang = tolang -- patterns=en -- patterns=en,de @@ -188,10 +195,21 @@ local function sethjcodes(instance,loaded,what,factor) local s = tex.savinghyphcodes tex.savinghyphcodes = 0 if type(c) == "table" then - for l in next, c do - setcode(utfbyte(l)) + if #c > 0 then + -- list: { U, U, U, "chr", "chr", ... } + for i=1,#c do + local v = c[i] + setcode(type(v) == "string" and utfbyte(v) or v) + end + else + -- hash: { ["chr"] = true, ... } + for k, v in next, c do + if v then + setcode(utfbyte(k)) + end + end end - else + elseif type(c) == "string" then for l in utfvalues(c) do setcode(l) end @@ -200,9 +218,35 @@ local function sethjcodes(instance,loaded,what,factor) end end +local function addhjcodestoinstance(instance,characters) + if type(characters) == "table" then + local nofcharacters = #characters + if nofcharacters > 0 then + -- list: { U, U, U, "chr", "chr", ... } + for i=1,nofcharacters do + local v = characters[i] + local h = type(v) == "string" and utfbyte(v) or v + sethjcode(instance,h,h) + end + else + -- hash: { ["chr"] = true, ... } + for k, v in next, characters do + if v then + local h = type(k) == "string" and utfbyte(k) or k + sethjcode(instance,h,h) + end + end + end + elseif type(characters) == "string" then + for h in utfvalues(characters) do + sethjcode(instance,h,h) + end + end +end + -- 2'2 conflicts with 4' ... and luatex barks on it -local P, R, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns +local P, S, R, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.S, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns local utfsplit = utf.split @@ -450,65 +494,6 @@ function languages.unload(tag) end end -if environment.initex then - - function languages.getnumber() - return 0 - end - -else - - function languages.getnumber(tag,default,patterns,factor) - local l = registered[tag] - if l then - if l.dirty then - l.factor = factor == v_yes and true or false - if trace_patterns then - report_initialization("checking patterns for %a with default %a",tag,default) - end - -- patterns is already resolved to parent patterns if applicable - if patterns and patterns ~= "" then - if l.patterns ~= patterns then - l.patterns = patterns - if trace_patterns then - report_initialization("loading patterns for %a using specification %a",tag,patterns) - end - loaddefinitions(tag,l) - else - -- unchanged - end - elseif l.patterns == "" then - l.patterns = tag - if trace_patterns then - report_initialization("loading patterns for %a using tag",tag) - end - local ok = loaddefinitions(tag,l) - if not ok and tag ~= default then - l.patterns = default - if trace_patterns then - report_initialization("loading patterns for %a using default",tag) - end - loaddefinitions(tag,l) - end - end - l.loaded = true - l.dirty = false - end - return l.number - else - return 0 - end - end - - numbers[0] = "null" - - registered.null = { - number = 0, - instance = new_language(0), - } - -end - -- not that usefull, global values function languages.prehyphenchar (what) return prehyphenchar (tolang(what)) end @@ -528,9 +513,18 @@ local invalid = { "{", "}", "(", ")", "-", " " } local function collecthjcodes(data,str) local found = data.extras and data.extras.characters or { } - for s in utfcharacters(str) do - if not found[s] then - found[s] = true + if type(str) == "string" then + for s in utfcharacters(str) do + if not found[s] then + found[s] = true + end + end + elseif type(str) == "table" then + for i=1,#str do + local s = str[i] + if not found[s] then + found[s] = true + end end end for i=1,#invalid do -- less checks this way @@ -573,6 +567,10 @@ end languages.setwordhandler = setwordhandler +function languages.setoptions(tag,str) + languages.addgoodiesdata(tag,{ { words = str } }) +end + function languages.hyphenate(tag,str) -- todo: does this still work? local data, instance = resolve(tag) @@ -593,24 +591,122 @@ end do - local nuts = nodes.nuts - local nextglyph = nuts.traversers.glyph - local setoptions = nuts.setoptions - local glyphoptioncodes = tex.glyphoptioncodes + local nuts = nodes.nuts + local nextglyph = nuts.traversers.glyph + local setoptions = nuts.setoptions + local glyphoptioncodes = tex.glyphoptioncodes + + local lower = characters.lower + local replacer = utf.replacer + local utfchartabletopattern = lpeg.utfchartabletopattern + + local report = logs.reporter("languages","goodies") + +local getnext = nuts.getnext +local getprev = nuts.getprev +local setchar = nuts.setchar +local setnext = nuts.setnext +local setlink = nuts.setlink +local setdisc = nuts.setdisc +local getprop = nuts.getprop +local setprop = nuts.setprop +local setattrlist = nuts.setattrlist + +local new_disc = nuts.pool.disc +local new_glyph = nuts.pool.glyph +local copy_node = nuts.copy +local flush_list = nuts.flush_list + + -- can be shared + + local goodiesdata = setmetatableindex(function(t,k) + local v = { + properties = { }, + replacements = { }, + characters = { }, + } + t[k] = v + return v + end) + + -- can be a helper + + local function setcompound(current,id) + local prev = getprev(current) + local language = tolang(id) + local prechar = prehyphenchar(language) + local postchar = posthyphenchar(language) + local pre = prechar and copy_node(current) + local post = postchar and copy_node(current) + local disc = new_disc() + if pre then + setchar(pre,prechar) + end + if post then + setchar(post,postchar) + end + setattrlist(disc,current) + setoptions(disc,0x3) -- todo foo_code + setdisc(disc,pre,post) + setlink(prev,disc,current) + end - local cache = table.setmetatableindex(function(t,k) + local function replaceword(first,last,old,new,oldlen) + local oldlen = utflength(old) + local newlen = utflength(new) + if newlen == 0 then + -- forget about it + elseif newlen <= oldlen then + for s in utfvalues(new) do + setchar(first,s) + first = getnext(first) + end + if newlen < oldlen then + -- first is one ahead + local after = getnext(last) + local before = getprev(first) + setnext(last) + setlink(before,after) + flush_list(first) + end + else + local i = 0 + local l = getnext(last) + for s in utfvalues(new) do + i = i + 1 + if i > oldlen then + local g = copy_node(first) + setlink(first,g,l) + setchar(g,s) + first = g + elseif i == oldlen then + setchar(first,s) + else + setchar(first,s) + first = getnext(first) + end + end + end + end + + local cache = setmetatableindex(function(t,k) local v = 0 - for s in gmatch(k,"%w+") do - local o = glyphoptioncodes[s] - if o then - v = v | o + if k == "compound" then + v = setcompound + else + v = 0 + for s in gmatch(k,"%w+") do + local o = glyphoptioncodes[s] + if o then + v = v | o + end end end t[k] = v return v end) - local function checkglyphoptions(options) + local function checkglyphproperties(options) for word, list in next, options do if type(list) == "string" then options[word] = options[list] @@ -624,32 +720,364 @@ do end end - function languages.setoptionhandler(tag,options) - if type(options) == "table" then - checkglyphoptions(options) -- checks in place! - setwordhandler(tag, - function(n,word,length,first,last) - local o = options[word] - if o then - local index = 0 - for g, c in nextglyph, first do - index = index + 1 - local t = o[index] - if t then - setoptions(g,t) +-- statistics.starttiming(languages) +-- statistics.stoptiming(languages) + + languages.setgoodieshandler = function(specification) -- will become a table specifier + if type(specification) == "table" then + local tag = specification.tag + local goodies = specification.goodies or tag + local result = specification.result or false + local data = goodiesdata[goodies] + local properties = data.properties + local replacements = data.replacements + local characters = data.characters + local replacer = nil + local d, instance = resolve(tag) + local done = false + -- check if something at all + if type(characters) == "table" and characters and next(characters) then + addhjcodestoinstance(instance,characters) + if trace_goodies then + report_goodies("registering %a characters for %a",goodies,tag) + end + done = true + end + if type(properties) == "table" and next(properties) then + checkglyphproperties(properties) -- checks in place! + if trace_goodies then + report_goodies("registering %a properties for %a",goodies,tag) + end + done = true + end + if type(replacements) == "table" and next(replacements) then + replacer = Cs((utfchartabletopattern(replacements) / replacements + 1)^0) + if trace_goodies then + report_goodies("registering %a replacer for %a",goodies,tag) + end + done = true + end + if done then + setwordhandler(tag, + function(n,original,remapped,length,first,last) + local restart = nil + local o = properties[remapped] + if o then + if trace_goodies then + report("properties: %s %s",original,remapped) + end + local index = 0 + for g, c in nextglyph, first do + index = index + 1 + local oi = o[index] + if oi == setcompound then + setcompound(g,n) + restart = getprev(first) + elseif oi then + setoptions(g,oi) + end + if g == last then + break + end end - if g == last then - break + elseif replacer then + -- todo: check lengths so that we can avoid a check + if getprop(first,"replaced") then + -- maybe some deadcycles + else + local r = lpegmatch(replacer,original) + if original == r then + if trace_goodies then + report_goodies("kept: %s => %s",original,remapped) + end + else + if trace_goodies then + report_goodies("replaced: %s => %s => %s",original,remapped,r) + end + setprop(first,"replaced",true) + replaceword(first,last,original,r,length) + restart = getprev(first) + end + end + else + if trace_goodies then + report_goodies("ignored: %s => %s",original,remapped) end end - end - return false - end) + return result, restart + end) + elseif trace_goodies then + report_goodies("nothing useable in %a for %a",goodies,tag) + end else setwordhandler(tag) end end + -- local function xreplacer(t,n) + -- local i = 0 + -- local h = table.tohash(n) + -- if #h == 0 then + -- local p = Cs((utfchartabletopattern(t) / t + utf8char)^0) + -- return function(s) + -- return lpegmatch(p,s) + -- end + -- else + -- local f = function(k) i = i + 1 if h[i] then return t[k] else return k end end + -- local p = Cs((utfchartabletopattern(t) / f + utf8char)^0) + -- return function(s) + -- i = 0 + -- return lpegmatch(p,s) + -- end + -- end + -- end + + local function blockligature(v,n) + if n > 0 then + local vv = v[n-1] + if vv then + v[n-1] = vv .. " norightligature" + else + v[n-1] = "norightligature" + end + end + v[n] = "noleftligature" + end + + local function analyzed(m,t,k) + local v = { } + local n = 1 + if m == true then + for c in gmatch(k,".") do + if c == "|" then + blockligature(v,n) + elseif c == "=" then + v[n] = setcompound + else + n = n + 1 + end + end + elseif type(m) == "number" then + local i = 0 + for c in gmatch(k,".") do + if c == "|" then + i = i + 1 + if i == m then + blockligature(v,n) + break + end + elseif c == "=" then + i = i + 1 + if i == m then + v[n] = setcompound + break + end + else + n = n + 1 + end + end + elseif type(m) == "table" then + local i = 0 + m = table.tohash(m) + for c in gmatch(k,".") do + if c == "|" then + i = i + 1 + if m[i] then + blockligature(v,n) + end + elseif c == "=" then + i = i + 1 + if m[i] then + v[n] = setcompound + end + else + n = n + 1 + end + end + else + -- error + end + t[k] = v + return v + end + + local cache = setmetatableindex(function(t,m) + local v = setmetatableindex(function(t,k) + return analyzed(m,t,k) + end) + t[m] = v + return v + end) + + local replace1 = Cs ( ( S("|=")/"" + lpeg.patterns.utf8character )^0 ) + local replace2 = Cs ( ( S("|=") + lpeg.patterns.utf8character/".")^0 ) + + local function stripped(str) + str = gsub(str,"[%-%%]+[^\n]+\n","") + str = gsub(str,"%s+"," ") + return str + end + + function languages.strippedgoodiewords(str) + return lpegmatch(replace1,stripped(str)) + end + + local function addgoodies(tag,list,filename) + local np = 0 + local nd = 0 + local nw = 0 + local nl = #list + -- + local data = goodiesdata[tag] + local properties = data.properties + local replacements = data.replacements + local characters = data.characters + if filename then + if not data.goodies then + data.goodies = { } + end + table.insert(data.goodies,filename) + end + -- + for i=1,nl do + local l = list[i] + if type(l) == "table" then + local w = l.words + local p = l.patterns + local c = l.characters + if c then + for v in utfvalues(c) do + characters[v] = true + end + end + if w then + w = lower(stripped(w)) + if p then + local pattern = Cs((utfchartabletopattern(p) / p + 1)^0) + w = lpegmatch(pattern,w) + np = np + 1 + else + nd = nd + 1 + end + local cach = cache[l.matches or true] + for s in gmatch(w,"%S+") do + properties[lpegmatch(replace1,s)] = cach[lpegmatch(replace2,s)] + nw = nw + 1 + end + elseif p then + for k, v in next, p do + -- todo: warning overload + replacements[k] = v + end + end + end + end + return { np = np, nd = nd, nw = nw, nl = nl } + end + + function languages.goodiefiles(tag) + local d = goodiesdata[tag] + return d and d.goodies + end + + function languages.addgoodiesfile(tag,filename) + local fullname = resolvers.findfile(file.addsuffix(filename,"llg")) or "" + if fullname == "" then + report_goodies("file %a is not found",filename) + else + local list = table.load(fullname) + if not list then + report_goodies("file %a is invalid",fullname) + else + list = list.options + if not list then + report_goodies("file %a has no options",fullname) + else + local ok = addgoodies(tag,list,filename) + report_goodies("tag %a, file %a loaded, %i lists, %i via patterns, %i direct, %i words", + tag,fullname,ok.nl,ok.np,ok.nd,ok.nw) + end + end + end + end + + function languages.addgoodiesdata(tag,list) + local ok = addgoodies(tag,list) + report_goodies("tag %a, data loaded, %i lists, %i via patterns, %i direct, %i words", + tag,ok.nl,ok.np,ok.nd,ok.nw) + end + +end + +if environment.initex then + + function languages.getnumber() + return 0 + end + +else + + function languages.getnumber(tag,default,patterns,goodies,factor) + local l = registered[tag] + if l then + if l.dirty then + l.factor = factor == v_yes and true or false + if trace_patterns then + report_initialization("checking patterns for %a with default %a",tag,default) + end + -- patterns is already resolved to parent patterns if applicable + if patterns and patterns ~= "" then + if l.patterns ~= patterns then + l.patterns = patterns + if trace_patterns then + report_initialization("loading patterns for %a using specification %a",tag,patterns) + end + loaddefinitions(tag,l) + else + -- unchanged + end + elseif l.patterns == "" then + l.patterns = tag + if trace_patterns then + report_initialization("loading patterns for %a using tag",tag) + end + local ok = loaddefinitions(tag,l) + if not ok and tag ~= default then + l.patterns = default + if trace_patterns then + report_initialization("loading patterns for %a using default",tag) + end + loaddefinitions(tag,l) + end + end + if goodies and goodies ~= "" then + goodies = settings_to_array(goodies) + for i=1,#goodies do + local goodie = goodies[i] + -- we can cache this but it doesn't pay off to do so + languages.addgoodiesfile(tag,goodie) + end + languages.setgoodieshandler { + tag = tag, + goodies = tag, + } + end + l.loaded = true + l.dirty = false + end + return l.number + else + return 0 + end + end + + numbers[0] = "null" + + registered.null = { + number = 0, + instance = new_language(0), + } + end -- hyphenation.define ("zerolanguage") @@ -695,7 +1123,7 @@ end) implement { name = "languagenumber", actions = { languages.getnumber, context }, - arguments = "4 strings" + arguments = "5 strings" } implement { @@ -727,6 +1155,12 @@ implement { arguments = "2 strings" } +implement { + name = "setlanguageoptions", + actions = languages.setoptions, + arguments = "2 strings" +} + implement { name = "currentprehyphenchar", actions = function() diff --git a/tex/context/base/mkxl/lang-ini.mkxl b/tex/context/base/mkxl/lang-ini.mkxl index 5df975c66..6af61077b 100644 --- a/tex/context/base/mkxl/lang-ini.mkxl +++ b/tex/context/base/mkxl/lang-ini.mkxl @@ -268,6 +268,7 @@ \setuplanguage [\s!default] [\s!patterns=, + \s!goodies=, \s!lefthyphenmin=2, \s!righthyphenmin=2, \s!lefthyphenchar=-1, @@ -369,6 +370,7 @@ {\currentlanguage}% {\defaultlanguage\currentlanguage}% {\languageparameter\s!patterns}% + {\languageparameter\s!goodies}% {\languageparameter\c!factor}% \relax \normallanguage\csname\??languagenumbers\currentlanguage\endcsname} @@ -431,10 +433,14 @@ + \permitgluehyphenationmodecode % turn glue into kern in \discretionary + \permitallhyphenationmodecode % okay, let's be even more tolerant + \permitmathreplacehyphenationmodecode % and again we're more permissive + + \forcehandlerhyphenationmodecode % kick in the handler (could be an option) \relax -\permanent\protected\def\dohyphens{\hyphenationmode\completehyphenationmodecode} -\permanent\protected\def\nohyphens{\hyphenationmode\zerocount} +% maybe a (un)setter for handlers + +\permanent\protected\def\dohyphens {\hyphenationmode\completehyphenationmodecode} +%permanent\protected\def\nohyphens {\hyphenationmode\zerocount} +\permanent\protected\def\nohyphens {\hyphenationmode\forcehandlerhyphenationmodecode} \permanent\protected\def\usehyphensparameter#1% {\edef\p_hyphens{#1\c!hyphens}% @@ -784,4 +790,25 @@ \permanent\protected\def\norightkerning {\bitwiseflip\glyphoptions\norightkerncode} \permanent\protected\def\norightligaturing{\bitwiseflip\glyphoptions\norightligaturecode} +%D Also \LMTX: + +% \startlanguageoptions[de] +% Zapf|innovation +% \stoplanguageoptions + +\permanent\let\stoplanguageoptions\relax + +\permanent\protected\def\startlanguageoptions + {\begingroup + \catcode`|\othercatcode + \lang_startlanguageoptions} + +\tolerant\def\lang_startlanguageoptions[#1]#:#2\stoplanguageoptions + {\edef\askedlanguage{\reallanguagetag{#1}}% + \ifempty\askedlanguage + \let\askedlanguage\currentlanguage + \fi + \clf_setlanguageoptions{\askedlanguage}{#2}% + \endgroup} + \protect \endinput diff --git a/tex/context/base/mkxl/lpdf-ini.lmt b/tex/context/base/mkxl/lpdf-ini.lmt index ee9248bf7..bfa180b7e 100644 --- a/tex/context/base/mkxl/lpdf-ini.lmt +++ b/tex/context/base/mkxl/lpdf-ini.lmt @@ -7,7 +7,53 @@ if not modules then modules = { } end modules ['lpdf-ini'] = { license = "see context related readme files" } --- beware of "too many locals" here +-- This file is the starting point for PDF related features. Although quite a bit +-- evolved over time, most of what we do in MkIV and LMTX already was available in +-- MkII (with e.g. pdfTeX) anyway, but it was implemented in TeX. We're talking of +-- arbitrary annotations, media like audio and video, widgets (aka forms) with +-- chains and appearances, comments, attachments, javascript based manipulation of +-- layers, graphic trickery like shading, color spaces, transparancy, flash stuff, +-- executing commands, accessing the interface, etc. In that respect there isn't +-- much really new here, after all MkII was there before the turn of the century, +-- but it's just more fun to maintain it in Lua than in low level TeX. Also, because +-- we no longer deal with other engines, there is no need to go low level TeX, which +-- makes for better code. +-- +-- However, over the decades PDF evolved and it shows. For instance audio and video +-- support changed and became worse. Some things were dropped (smil, flash, movies, +-- audio). Using appearances for widgets became a pain because it sort of assumes +-- that you construct these forms in acrobat which then leads to bugs becoming +-- features which means that certain things simply don't work (initializations, +-- chained widgets, funny dingabt defaults, etc), probably because they never were +-- tested when viewers evolved. +-- +-- Attachment are also a fragile bit. And comments that at some point became +-- dependent on rendering annotations ... it all deserves no beauty price because +-- reliable simplicity was replaced by unreliable complexity. Something that might +-- work today often didn't in the past and might fail in the future, if only because +-- it more relates to the viewer user interface, maybe changing security demands or +-- whatever. We cannot predict this. A side effect is that we keep adapting and even +-- worse, have to remove features that originally were expected to stay (media +-- stuff). To some extend it's a waste of time to get it all supported, also because +-- the open source viewers lag behind. It makes no sense to keep tons of code +-- arround that will never be used (again). +-- +-- Also, I don't think that these PDF features were added with something else than +-- Acrobat in mind: a flexible system like TeX that actually could inject these low +-- level features right from the moment that they showed up (and before they were +-- fully tested) is not mainstream enough to be taken into account. One cannot blame +-- a commercial product for its own priorities. The evolution of the web might also +-- have interfered with the agendas. +-- +-- As a consequence, the code that we use is spread over files and it might change +-- over time as we try to adapt. But it's easy for the mentioned features to fix one +-- aspect and break another. Eventually we might see more of these fancy features to +-- be removed because they make no sense on the long run, than such features being +-- added. In retrospect maybe many such features were just experiments: anchored in +-- time for throw away documents (like presentations), never meant to be used on the +-- long term. In that respect PDF is a disappointment. + +-- Comment: beware of "too many locals" problem here. local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setmetatable, getmetatable, type, next, tostring, tonumber, rawset local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string.byte, string.format, string.gsub, table.concat, string.match, string.sub, string.gmatch diff --git a/tex/context/base/mkxl/mlib-pps.lmt b/tex/context/base/mkxl/mlib-pps.lmt index 20593f5f2..01e0dbfcf 100644 --- a/tex/context/base/mkxl/mlib-pps.lmt +++ b/tex/context/base/mkxl/mlib-pps.lmt @@ -1238,7 +1238,10 @@ local function sh_process(object,prescript,before,after) end end end - +-- local transformation = prescript.sh_transformation +-- if transformation then +-- print("todo: " .. transformation) +-- end local steps = tonumber(prescript.sh_step) or 1 local sh_color_a = prescript.sh_color_a_1 or prescript.sh_color_a or "1" local sh_color_b = prescript.sh_color_b_1 or prescript.sh_color_b or "1" -- sh_color_b_ diff --git a/tex/context/base/mkxl/mlib-svg.lmt b/tex/context/base/mkxl/mlib-svg.lmt index 885d2cd77..e76580862 100644 --- a/tex/context/base/mkxl/mlib-svg.lmt +++ b/tex/context/base/mkxl/mlib-svg.lmt @@ -81,6 +81,14 @@ if not modules then modules = { } end modules ['mlib-svg'] = { -- One can run into pretty crazy images, like lines that are fills being clipped -- to some width. That's the danger of hiding yourself behind an interface I guess. +-- +-- One would expect official examples to sort of follow the structure guideline, +-- like putting gradient definitions in a "defs" element but forget about it ... +-- structure seems not to be important (one can even wonder why "defs" is there at +-- all). In the end all these systems (tex macro packages included) end up as a +-- mess simply because conceptually wrong input gets accepted as normal. A side +-- effect is that one starts to get a disliking. Anyway, at sime point I can just +-- simplify some code because ugliness is part of the game. local rawget, rawset, type, tonumber, tostring, next, setmetatable = rawget, rawset, type, tonumber, tostring, next, setmetatable @@ -359,6 +367,7 @@ do local c_number_u = C(p_number) * (p_percent + p_unit)^-1 p_number_n = c_number_n / convert + p_number_u = c_number_u / convert p_number_x = c_number_u / convert_x p_number_vx = c_number_u / convert_vx p_number_y = c_number_u / convert_y @@ -382,7 +391,8 @@ do asnumber_vx_t = function(s) return s and lpegmatch(p_number_vx_t,s) or zerotable end asnumber_vy_t = function(s) return s and lpegmatch(p_number_vy_t,s) or zerotable end - local p_numbersep = p_number_n + p_separator +-- local p_numbersep = p_number_n + p_separator + local p_numbersep = p_number_u + p_separator p_numbers = p_optseparator * P("(") * p_numbersep^0 * p_optseparator * P(")") p_fournumbers = p_numbersep^4 p_path = Ct ( ( @@ -1243,9 +1253,11 @@ local handletransform, handleviewbox do end local function translate(x,y) + if x == 0 then x = false end + if y == 0 then y = false end if y then noftransforms = noftransforms + 1 - transforms[noftransforms] = f_shifted(x,-y) + transforms[noftransforms] = f_shifted(x or 0,-y) elseif x then noftransforms = noftransforms + 1 transforms[noftransforms] = f_shifted(x,0) @@ -1253,23 +1265,24 @@ local handletransform, handleviewbox do end local function scale(x,y) + if x == 1 then x = false end + if y == 1 then y = false end if y then noftransforms = noftransforms + 1 - transforms[noftransforms] = f_xyscaled(x,y) + transforms[noftransforms] = f_xyscaled(x or 1,y) elseif x then noftransforms = noftransforms + 1 transforms[noftransforms] = f_scaled(x) end end - local function skewx(x) + local function skew(x,y) + -- if x = 0 then x = false end + -- if y = 0 then y = false end if x then noftransforms = noftransforms + 1 transforms[noftransforms] = f_slanted_x(sind(-x)) end - end - - local function skewy(y) if y then noftransforms = noftransforms + 1 transforms[noftransforms] = f_slanted_y(sind(-y)) @@ -1303,12 +1316,17 @@ local handletransform, handleviewbox do local p_transform = ( lpegpatterns.whitespace^0 * ( - P("translate") * (p_numbers / translate) -- maybe xy - + P("scale") * (p_numbers / scale) - + P("rotate") * (p_numbers / rotate) - + P("matrix") * (p_numbers / matrix) - + P("skewX") * (p_numbers / skewx) - + P("skewY") * (p_numbers / skewy) + P("translate") * (p_numbers / translate) -- maybe xy + + P("scale") * (p_numbers / scale) + + P("rotate") * (p_numbers / rotate) + + P("matrix") * (p_numbers / matrix) + + P("skew") * (p_numbers / skew) + + P("translateX") * (p_numbers / translate) + + P("translateY") * (Cc(false) * p_numbers / translate) + + P("scaleX") * (p_numbers / translate) + + P("scaleY") * (Cc(false) * p_numbers / translate) + + P("skewX") * (p_numbers / skew) + + P("skewY") * (Cc(false) * p_numbers / skew) ) )^1 @@ -1754,15 +1772,6 @@ do local f_opacity = formatters[' withopacity %N'] local f_pen = formatters[' withpen pencircle scaled %N'] - local f_shade_step = formatters['withshadestep ( withshadefraction %N withshadecolors (%s,%s) )'] - local f_shade_step_opacity = formatters['withshadestep ( withshadefraction %N withshadecolors (%s,%s) withshadeopacity %N )'] - local f_shade_radius = formatters['withshaderadius (%N,%N) '] - local f_shade_center_one = formatters['withshadecenterone (%N,%N)'] - local f_shade_center_two = formatters['withshadecentertwo (%N,%N)'] - local f_shade_center_one_f = formatters['withshadecenteronefraction (%N,%N)'] - local f_shade_center_two_f = formatters['withshadecentertwofraction (%N,%N)'] - local f_shade_center_f = formatters['withshadecenterfraction (%N,%N)'] - local f_shade_radius_f = formatters['withshaderadiusfraction %N'] -- todo: gradient unfinished -- todo: opacity but first we need groups in mp @@ -1857,83 +1866,121 @@ do end end - local function gradient(id) - local spec = definitions[id] -- no locate ! - if spec then - local kind = spec.tg - local shade = nil - local n = 1 - local a = spec.at - if kind == "linearGradient" then - shade = { s_shade_linear } - -- - local x1 = rawget(a,"x1") - local y1 = rawget(a,"y1") - local x2 = rawget(a,"x2") - local y2 = rawget(a,"y2") - if x1 and y1 then - n = n + 1 ; shade[n] = f_shade_center_one_f(asnumber_p(x1),1-asnumber_p(y1)) - end - if x2 and y2 then - n = n + 1 ; shade[n] = f_shade_center_two_f(asnumber_p(x2),1-asnumber_p(y2)) - end - -- - elseif kind == "radialGradient" then - shade = { s_shade_circular } + local gradient do + + local f_shade_step = formatters['withshadestep ( withshadefraction %N withshadecolors (%s,%s) )'] + local f_shade_step_opacity = formatters['withshadestep ( withshadefraction %N withshadecolors (%s,%s) withshadeopacity %N )'] + local f_shade_center = formatters['withshadecenter (%N,%N)'] + local f_shade_center_f = formatters['withshadecenterfraction (%N,%N)'] + local f_shade_radius = formatters['withshaderadius (%N,%N) '] + local f_shade_radius_f = formatters['withshaderadiusfraction %N'] + local f_shade_center_one = formatters['withshadecenterone (%N,%N)'] + local f_shade_center_two = formatters['withshadecentertwo (%N,%N)'] + local f_shade_center_one_f = formatters['withshadecenteronefraction (%N,%N)'] + local f_shade_center_two_f = formatters['withshadecentertwofraction (%N,%N)'] + + gradient = function(id) + local spec = definitions[id] -- no locate ! + if spec then + local kind = spec.tg + local shade = nil + local n = 1 + local a = spec.at + -- bah + local gu = rawget(a, "gradientUnits") -- userSpaceOnUse + local gt = rawget(a, "gradientTransform") + local sm = rawget(a, "spreadMethod") -- - local cx = rawget(a,"cx") -- x center - local cy = rawget(a,"cy") -- y center - local r = rawget(a,"r" ) -- radius - local fx = rawget(a,"fx") -- focal points - local fy = rawget(a,"fy") -- focal points + local userspace = gu == "userSpaceOnUse" -- - if cx and cy then - n = n + 1 ; shade[n] = f_shade_center_f(asnumber_p(cx),1-asnumber_p(cy)) - end - if fx and fy then - n = n + 1 ; shade[n] = f_shade_center_one_f(asnumber_p(fx),1-asnumber_p(fy)) - end - if r then - n = n + 1 ; shade[n] = f_shade_radius_f(asnumber_p(r)) - end - if fx and fy then - -- todo + if kind == "linearGradient" then + shade = { s_shade_linear } + -- + local x1 = rawget(a,"x1") + local y1 = rawget(a,"y1") + local x2 = rawget(a,"x2") + local y2 = rawget(a,"y2") + if x1 and y1 then + n = n + 1 ; shade[n] = f_shade_center_one_f(asnumber_p(x1),1-asnumber_p(y1)) + end + if x2 and y2 then + n = n + 1 ; shade[n] = f_shade_center_two_f(asnumber_p(x2),1-asnumber_p(y2)) + end + -- + elseif kind == "radialGradient" then + shade = { s_shade_circular } + -- + local cx = rawget(a,"cx") -- x center + local cy = rawget(a,"cy") -- y center + local r = rawget(a,"r" ) -- radius + local fx = rawget(a,"fx") -- focal points + local fy = rawget(a,"fy") -- focal points + -- + if userspace then + if cx and cy then + n = n + 1 ; shade[n] = f_shade_center(asnumber_p(cx),asnumber_p(cy)) + end + if fx and fy then + n = n + 1 ; shade[n] = f_shade_center_one(asnumber_p(fx),-asnumber_p(fy)) + end + if r then + n = n + 1 ; shade[n] = f_shade_radius(asnumber_p(r)) + end + if fx and fy then + -- todo + end + else + if cx and cy then + n = n + 1 ; shade[n] = f_shade_center_f(asnumber_p(cx),1-asnumber_p(cy)) + end + if fx and fy then + n = n + 1 ; shade[n] = f_shade_center_one_f(asnumber_p(fx),1-asnumber_p(fy)) + end + if r then + n = n + 1 ; shade[n] = f_shade_radius_f(asnumber_p(r)) + end + if fx and fy then + -- todo + end + end + else + return end - else - return - end - -- local gu = a.gradientUnits - -- local gt = a.gradientTransform - -- local sm = a.spreadMethod - local colora, colorb - -- startcolor ? - for c in xmlcollected(spec,"/stop") do - local a = c.at - local offset = rawget(a,"offset") - local colorb = rawget(a,"stop-color") - -- local opacity = rawget(a,"stop-opacity") -- not in pdf for steps - if not colora then + local colora, colorb + -- startcolor ? + for c in xmlcollected(spec,"/stop") do + local a = c.at + local offset = rawget(a,"offset") + local colorb = rawget(a,"stop-color") + -- local opacity = rawget(a,"stop-opacity") -- not in pdf for steps + if not colora then + colora = colorb + end + -- what if no percentage +-- local fraction = offset and asnumber_r(offset) -- asnumber_p ? +local fraction = offset and asnumber_p(offset) + if not fraction then + -- for now + fraction = xmlcount(spec,"/stop")/100 -- asnumber_p ? + end + if colora and colorb and colora ~= "" and colorb ~= "" then + n = n + 1 + -- if opacity then + -- shade[n] = f_shade_step_opacity(fraction,thecolor(colora),thecolor(colorb),asnumber(o)) + -- else + if userspace then + shade[n] = f_shade_step(fraction,thecolor(colora),thecolor(colorb)) + else + shade[n] = f_shade_step(fraction,thecolor(colora),thecolor(colorb)) + end + -- end + end colora = colorb end - -- what if no percentage - local fraction = offset and asnumber_r(offset) -- asnumber_p ? - if not fraction then - -- offset = tonumber(offset) - -- for now - fraction = xmlcount(spec,"/stop")/100 -- asnumber_p ? - end - if colora and colorb and colora ~= "" and colorb ~= "" then - n = n + 1 - -- if opacity then - -- shade[n] = f_shade_step_opacity(fraction,thecolor(colora),thecolor(colorb),asnumber(o)) - -- else - shade[n] = f_shade_step(fraction,thecolor(colora),thecolor(colorb)) - -- end - end - colora = colorb + return concat(shade,"\n ") end - return concat(shade,"\n ") end + end local function drawproperties(stroke,at,opacity) @@ -2065,7 +2112,7 @@ do end end end - for c in xmlcollected(c,"symbol") do + for c in xmlcollected(c,"(symbol|radialGradient|linearGradient") do local id = rawget(c.at,"id") if id then definitions["#" .. id ] = c diff --git a/tex/context/base/mkxl/strc-flt.mklx b/tex/context/base/mkxl/strc-flt.mklx index 8f96701f5..81ce4401e 100644 --- a/tex/context/base/mkxl/strc-flt.mklx +++ b/tex/context/base/mkxl/strc-flt.mklx @@ -1,5 +1,4 @@ %D \module -%D \module %D [ file=strc-flt, %D version=2008.10.20, %D title=\CONTEXT\ Structure Macros, @@ -263,17 +262,17 @@ \strc_floats_define_commands{#1}{#2}} \def\strc_floats_define_commands#1#2% - {\frozen\instance\setuevalue{\e!place\e!listof#2}{\strc_lists_place[#1]}% call will change - \frozen\instance\setuevalue{\e!complete\e!listof#2}{\strc_lists_complete[#1][#2]}% call will change - \frozen\instance\setuevalue{\e!place#1}{\placefloat[#1]}% - \frozen\instance\setuevalue{\e!start\e!place#1}{\startplacefloat[#1]}% - \frozen\instance\setuevalue{\e!stop\e!place#1}{\stopplacefloat}% - \frozen\instance\setuevalue{\e!start#1\e!text}{\strc_floats_start_text[#1]}% - \frozen\instance\setuevalue{\e!stop#1\e!text}{\strc_floats_stop_text}% + {\frozen\protected\instance\edefcsname\e!place \e!listof#2\endcsname{\strc_lists_place[#1]}% call will change + \frozen\protected\instance\edefcsname\e!complete\e!listof#2\endcsname{\strc_lists_complete[#1][#2]}% call will change + \frozen\protected\instance\edefcsname\e!place #1\endcsname{\placefloat[#1]}% + \frozen\protected\instance\edefcsname\e!start \e!place#1\endcsname{\startplacefloat[#1]}% + \frozen\protected\instance\edefcsname\e!stop \e!place#1\endcsname{\stopplacefloat}% + \frozen\protected\instance\edefcsname\e!start #1\e!text\endcsname{\strc_floats_start_text[#1]}% + \frozen\protected\instance\edefcsname\e!stop #1\e!text\endcsname{\strc_floats_stop_text}% % these will become obsolete: - \frozen\instance\setuevalue{\e!reserve#1}{\strc_floats_reserve[#1]}% - \frozen\instance\setuevalue{\e!start\e!reserve#1\e!text}{\strc_floats_start_reserve_text[#1]}% - \frozen\instance\setuevalue{\e!stop\e!reserve#1\e!text}{\strc_floats_stop_reserve_text}} + \frozen\instance\protected\edefcsname\e!reserve #1\endcsname{\strc_floats_reserve[#1]}% + \frozen\instance\protected\edefcsname\e!start\e!reserve#1\e!text\endcsname{\strc_floats_start_reserve_text[#1]}% + \frozen\instance\protected\edefcsname\e!stop \e!reserve#1\e!text\endcsname{\strc_floats_stop_reserve_text}} %D Fallback float body: @@ -1235,18 +1234,18 @@ \installcorenamespace{floatmovement} -\setvalue{\??floatmovement \v!line}{\strc_floats_move_down_line+} -\setvalue{\??floatmovement+\v!line}{\strc_floats_move_down_line+} -\setvalue{\??floatmovement-\v!line}{\strc_floats_move_down_line-} -\setvalue{\??floatmovement \v!hang}{\strc_floats_move_down_hang\plusone} -\setvalue{\??floatmovement+\v!hang}{\strc_floats_move_down_hang\plusone} -\setvalue{\??floatmovement-\v!hang}{\strc_floats_move_down_hang\minusone} +\defcsname\??floatmovement \v!line\endcsname{\strc_floats_move_down_line+} +\defcsname\??floatmovement+\v!line\endcsname{\strc_floats_move_down_line+} +\defcsname\??floatmovement-\v!line\endcsname{\strc_floats_move_down_line-} +\defcsname\??floatmovement \v!hang\endcsname{\strc_floats_move_down_hang\plusone} +\defcsname\??floatmovement+\v!hang\endcsname{\strc_floats_move_down_hang\plusone} +\defcsname\??floatmovement-\v!hang\endcsname{\strc_floats_move_down_hang\minusone} -\setvalue{\??floatmovement-2*\v!line}{\strc_floats_move_down_line{-2}} -\setvalue{\??floatmovement+2*\v!line}{\strc_floats_move_down_line{2}} -\setvalue{\??floatmovement 2*\v!line}{\strc_floats_move_down_line{2}} +\defcsname\??floatmovement-2*\v!line\endcsname{\strc_floats_move_down_line{-2}} +\defcsname\??floatmovement+2*\v!line\endcsname{\strc_floats_move_down_line{2}} +\defcsname\??floatmovement 2*\v!line\endcsname{\strc_floats_move_down_line{2}} -\permanent\protected\def\installfloatmovement#1#2{\setvalue{\??floatmovement#1}{#2}} +\permanent\protected\def\installfloatmovement#1#2{\defcsname\??floatmovement#1\endcsname{#2}} \def\strc_floats_move_down#setting% {\begincsname\??floatmovement#setting\endcsname} @@ -1287,19 +1286,19 @@ \installcorenamespace{extrafloataction} -\setvalue{\??extrafloataction \v!inner}#1{\strc_floats_set_extra_action\v!left \v!right} -\setvalue{\??extrafloataction \v!outer}#1{\strc_floats_set_extra_action\v!right \v!left} -\setvalue{\??extrafloataction\v!innermargin}#1{\strc_floats_set_extra_action\v!leftmargin \v!rightmargin} -\setvalue{\??extrafloataction\v!outermargin}#1{\strc_floats_set_extra_action\v!rightmargin\v!leftmargin} -\setvalue{\??extrafloataction \v!inneredge}#1{\strc_floats_set_extra_action\v!leftedge \v!rightedge} -\setvalue{\??extrafloataction \v!outeredge}#1{\strc_floats_set_extra_action\v!rightedge \v!leftedge} -\setvalue{\??extrafloataction \v!backspace}#1{\strc_floats_set_extra_action\v!backspace \v!cutspace} -\setvalue{\??extrafloataction \v!cutspace}#1{\strc_floats_set_extra_action\v!cutspace \v!backspace} -%setvalue{\??extrafloataction \v!margin}#1{\strc_floats_set_extra_action\v!cutspace \v!backspace} -\setvalue{\??extrafloataction \v!left}#1{\strc_floats_set_extra_action\v!left \v!left} -\setvalue{\??extrafloataction \v!right}#1{\strc_floats_set_extra_action\v!right \v!right} -\setvalue{\??extrafloataction \v!line}#1{} % only -n*line is handled (see ***) -\setvalue{\??extrafloataction \s!unknown}#1{\movedownsidefloat[#1]} +\defcsname\??extrafloataction \v!inner\endcsname#1{\strc_floats_set_extra_action\v!left \v!right} +\defcsname\??extrafloataction \v!outer\endcsname#1{\strc_floats_set_extra_action\v!right \v!left} +\defcsname\??extrafloataction\v!innermargin\endcsname#1{\strc_floats_set_extra_action\v!leftmargin \v!rightmargin} +\defcsname\??extrafloataction\v!outermargin\endcsname#1{\strc_floats_set_extra_action\v!rightmargin\v!leftmargin} +\defcsname\??extrafloataction \v!inneredge\endcsname#1{\strc_floats_set_extra_action\v!leftedge \v!rightedge} +\defcsname\??extrafloataction \v!outeredge\endcsname#1{\strc_floats_set_extra_action\v!rightedge \v!leftedge} +\defcsname\??extrafloataction \v!backspace\endcsname#1{\strc_floats_set_extra_action\v!backspace \v!cutspace} +\defcsname\??extrafloataction \v!cutspace\endcsname#1{\strc_floats_set_extra_action\v!cutspace \v!backspace} +%defcsname\??extrafloataction \v!margin\endcsname#1{\strc_floats_set_extra_action\v!cutspace \v!backspace} +\defcsname\??extrafloataction \v!left\endcsname#1{\strc_floats_set_extra_action\v!left \v!left} +\defcsname\??extrafloataction \v!right\endcsname#1{\strc_floats_set_extra_action\v!right \v!right} +\defcsname\??extrafloataction \v!line\endcsname#1{} % only -n*line is handled (see ***) +\defcsname\??extrafloataction \s!unknown\endcsname#1{\movedownsidefloat[#1]} \def\strc_floats_check_extra_actions % less tracingthis way .... {\doifnotinset\v!text\floatlocation % fuzzy, text overloads left, since then it's a directive @@ -1617,6 +1616,10 @@ \strc_floats_prepare_no_caption \strc_floats_set_caption_dimensions\voidbox %\page_backgrounds_add_local_to_box\floatbox % was \doglobal but not needed +\ifx\forcedfloatmethod\v!local + % we need \ifinfloatcombination + \strc_floats_build_box +\fi \else % todo: installable maken, variant/method=auto vs macro \strc_floats_prepare_page_caption diff --git a/tex/context/base/mkxl/typo-brk.lmt b/tex/context/base/mkxl/typo-brk.lmt index 8d2fcd147..bebd4a149 100644 --- a/tex/context/base/mkxl/typo-brk.lmt +++ b/tex/context/base/mkxl/typo-brk.lmt @@ -143,6 +143,7 @@ methods[6] = function(head,start,stop,settings,kern) if kern then insert_break(head,start,stop,10000,0,kern) else + -- replace this local l = new_wordboundary() local d = new_disc() local r = new_wordboundary() diff --git a/tex/context/modules/mkiv/s-languages-goodies.lmt b/tex/context/modules/mkiv/s-languages-goodies.lmt new file mode 100644 index 000000000..cb17680d1 --- /dev/null +++ b/tex/context/modules/mkiv/s-languages-goodies.lmt @@ -0,0 +1,32 @@ +if not modules then modules = { } end modules ['s-languages-goodies'] = { + version = 1.001, + comment = "companion to s-languages-goodies.mkxl", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.goodies = moduledata.languages.goodies or { } + +function moduledata.languages.goodies.show(specification) + specification = interfaces.checkedspecification(specification) + local filename = specification.file + if filename and filename ~= "" then + local list = table.load(resolvers.findfile(filename)) + if list then + list = list.options + if list then + for i=1,#list do + local l = list[i] + local w = l.words + if w then + context.startsubject { title = table.concat(table.sortedkeys(l.patterns)," ") } + context(languages.strippedgoodiewords(w)) + context.stopsubject() + end + end + end + end + end +end diff --git a/tex/context/modules/mkiv/s-languages-goodies.mkxl b/tex/context/modules/mkiv/s-languages-goodies.mkxl new file mode 100644 index 000000000..b98df2c26 --- /dev/null +++ b/tex/context/modules/mkiv/s-languages-goodies.mkxl @@ -0,0 +1,40 @@ +%D \module +%D [ file=s-languages-goodies, +%D version=2021.25.03, +%D title=\CONTEXT\ Style File, +%D subtitle=Language Goodies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[languages-goodies] + +\registerctxluafile{s-languages-goodies}{autosuffix} + +\installmodulecommandluasingle \showlanguagegoodies {moduledata.languages.goodies.show} + +\stopmodule + +\continueifinputfile{s-languages-goodies.mkxl} + +\usemodule[art-01] + +% \setupbodyfont[libertine] + +\setuplanguage[de][goodies={lang-de.llg}] + +\mainlanguage[de] + +\setupalign[stretch,verytolerant,flushleft,nothyphenated] \dontcomplain + +% \startlanguageoptions[de] +% Zapf|innovation +% \stoplanguageoptions + +\starttext + \showlanguagegoodies[file={lang-de.llg}] +\stoptext diff --git a/tex/context/patterns/lmtx/lang-de.llg b/tex/context/patterns/lmtx/lang-de.llg new file mode 100644 index 000000000..9e64eb3b1 --- /dev/null +++ b/tex/context/patterns/lmtx/lang-de.llg @@ -0,0 +1,589 @@ +-- In ConTeXt we have several mechanisms to deal with compound words, ligatures etc. We have language +-- features, font features, in-stream replacers etc. At some point Denis Maier played with all of this +-- and in the process we decided to look at yet another variant. For that we also needed lists of words +-- and he came with one at: +-- +-- https://github.com/micoloretan/selnolig/blob/master/selnolig-german-wordlist.tex +-- +-- I'm not sure where that list originates (to be sorted out) and didn't look into how it is used (as +-- we already followed different routes when we started with MKIV). We will also extend the list and let +-- users add stuff. The main reason is to deal with compound words (for which we have multiple +-- mechanisms) in a more automates way, using modern LMTX features. So this is not for MKIV (at least +-- not now). This mechanism can and will also deal with some other language issues. + +-- Comment : this is a starting point, not de definitve list of words +-- Todo : break down this list in more meaningfull categories (like 'matches') +-- Todo : maybe make options into a tabel with named option sets (only if needed) + +return { + name = "german", + version = "1.00", + comment = "Goodies that complement german.", + author = "Denis Maier & Hans Hagen", + copyright = "ConTeXt development team & whoever made this list", + options = { + -- For Denis: + { + patterns = { + ff = "f|f", + fl = "f|l", + fi = "f|i", + ffi = "f|f|i", + ffl = "f|f|l", + fff = "f|f|f", + }, + matches = { 1 }, + words = [[ + Auflaufform Auflaufformen + Ablauffolge Ablauffolgen + ablauffähig ablauffähige ablauffähigem ablauffähigen ablauffähiger ablauffähiges Ablauffähigkeit Ablauffähigkeiten + Ablaufleitung Ablaufleitungen + Ablaufliste Ablauflisten + Abruffunktion Abruffunktionen + Anruffalle Anruffallen + Anruffunktion Anruffunktionen + Anzweiflung Anzweiflungen + auffahrbar auffahrbare auffahrbarem auffahrbaren auffahrbarer auffahrbares auffahre auffahren auffahrend auffahrende auffahrendem auffahrenden auffahrender auffahrendes auffahrt Auffahrten Auffahrtsweg Auffahrunfall Auffahrunfalls Auffahrunfälle Auffahrunfällen + auffalle auffallen auffallend auffallende auffallendem auffallenden auffallender auffallendere auffallenderem auffallenderen auffallenderer auffallenderes auffallenderweise auffallendes auffallendst auffallendste auffallendstem auffallendsten auffallendster auffallendstes auffallt + auffaltbar Auffaltungen + auffand auffanden auffandest auffandet auffandst + auffangbar auffangbare auffangbarem auffangbaren auffangbarer auffangbares auffange auffangen auffangend auffangende auffangendem auffangenden auffangender auffangendes + Auffangbecken Auffangbeckens Auffanglager Auffanglagern Auffanglagers Auffangregister Auffangregistern Auffangregisters Auffangt Auffangvorrichtung Auffangvorrichtungen Auffangwanne Auffangwannen Auffangweiche Auffangweichen + auffassbar auffassbare auffassbarem auffassbaren auffassbarer auffassbares auffasse auffassen auffassend auffassende auffassendem auffassenden auffassender auffassendes auffassens auffassest auffasst auffasste auffassten auffasstest auffasstet + Auffassbarkeit Auffassbarkeiten Auffassung Auffassungen Auffassungsgabe Auffassungsgaben Auffassungsvermögen Auffassungsvermögens + auffasst auffasste auffassten auffasstest auffasstet + auffaßt auffaßte auffaßten auffaßtest auffaßtet + auffiel auffiele auffielen auffielst auffielt + auffindbar auffindbare auffindbarem auffindbaren auffindbarer auffindbares Auffindbarkeit Auffindbarkeiten auffinde auffinden auffindend auffindende auffindendem auffindenden auffindender auffindendes auffindens auffindest auffindet Auffindung Auffindungen + auffing auffinge auffingen auffingst auffingt + auffische auffischen auffischend auffischende auffischendem auffischenden auffischender auffischendes auffischest auffischst auffischt auffischte auffischten auffischtest auffischtet + aufflackern Aufflackerns + aufflamme aufflammen aufflammend aufflammende aufflammendem aufflammenden aufflammender aufflammendes aufflammst aufflammt aufflammte aufflammten aufflammtest aufflammtet + auffliege auffliegen auffliegend auffliegende auffliegendem auffliegenden auffliegender auffliegendes auffliegst auffliegt + auffloge aufflogen aufflogest auffloget + aufflöge aufflögen aufflögest aufflöget + auffordere auffordern auffordernd auffordernde aufforderndem auffordernden auffordernder aufforderndes aufforderns aufforderst auffordert aufforderte aufforderten auffordertest auffordertet Aufforderung Aufforderungen auffordre + aufforstbar aufforstbare aufforstbarem aufforstbaren aufforstbarer aufforstbares aufforste aufforsten aufforstend aufforstende aufforstendem aufforstenden aufforstender aufforstendes aufforstens aufforstest aufforstet aufforstete aufforsteten aufforstetest aufforstetet Aufforstung Aufforstungen + auffrass auffrassen auffrassest auffrasst + auffraß auffraßen auffraßest auffraßt + auffresse auffressen auffressend auffressende auffressendem auffressenden auffressender auffressendes + auffresst + auffreßt + auffrischbar auffrischbare auffrischbarem auffrischbaren auffrischbarer auffrischbares auffrische auffrischen auffrischend auffrischende auffrischendem auffrischenden auffrischender auffrischendes auffrischens auffrischest auffrischst auffrischt auffrischte auffrischten auffrischtest auffrischtet Auffrischung Auffrischungen + auffrisiere auffrisieren auffrisierend auffrisierende auffrisierendem auffrisierenden auffrisierender auffrisierendes auffrisierst auffrisiert auffrisierte auffrisiertem auffrisierten auffrisierter auffrisiertes auffrisiertest auffrisiertet + auffrisst + auffrißt + auffräse auffräsen auffräsest auffräset + auffrässe auffrässen auffrässest auffrässet + auffräße auffräßen auffräßest auffräßet + auffuhr auffuhren auffuhrst auffuhrt + auffächerbar auffächerbare auffächerbarem auffächerbaren auffächerbarer auffächerbares auffächere auffächern auffächernd auffächernde auffächerndem auffächernden auffächernder auffächerndes auffächerns auffächerst auffächert auffächerte auffächerten auffächertest auffächertet Auffächerung Auffächerungen auffächre + auffährst auffährt hinauffährt + arbeitskampffähig hoffähig Kampffähigkeit kampffähig lauffähig prüffähige straffähig tariffähig Tariffähigkeit Umlauffähigkeit wettkampffähiges + auffällig auffällige auffälligem auffälligen auffälliger auffälligere auffälligerem auffälligeren auffälligerer auffälligeres auffälliges auffälligkeit auffälligkeiten auffälligst auffälligste auffälligstem auffälligsten auffälligster auffälligstes auffällst auffällt + auffängst auffängt + aufführbar aufführbare aufführbarem aufführbaren aufführbarer aufführbares aufführe aufführen aufführend aufführende aufführendem aufführenden aufführender aufführendes aufführens aufführst aufführt aufführte aufführten aufführtest aufführtet Aufführung Aufführungen Aufführungsstatistik Aufführungsstil Aufführungsstile Aufführungsstilen Aufführungsstils + auffüllbar auffüllbare auffüllbarem auffüllbaren auffüllbarer auffüllbares auffülle auffüllen auffüllend auffüllende auffüllendem auffüllenden auffüllender auffüllendes auffüllens auffüllst auffüllt auffüllte auffüllten auffülltest auffülltet Auffüllung Auffüllungen + aufisst + auflache auflachen auflachend auflachende auflachendem auflachenden auflachender auflachendes + auflachst + auflacht auflachte auflachten auflachtest auflachtet + aufladbar aufladbare aufladbarem aufladbaren aufladbarer aufladbares + auflade aufladen aufladend aufladende aufladendem aufladenden aufladender aufladendes aufladens Auflader Aufladerin Aufladerinnen Aufladern Aufladers Aufladet Aufladevorgang Aufladevorgangs + Aufladung Aufladungen + Auflage Auflagefläche Auflageflächen Auflagen Auflagenerhöhung Auflagenerhöhungen Auflagenstark Auflagenstarke Auflagenstarkem Auflagenstarken Auflagenstarker Auflagenstarkes Auflagenstärke Auflagenzahl Auflagenzahlen Auflagenziffer Auflagenziffern + auflandig auflandige auflandigem auflandigen auflandiger auflandiges + auflasse auflassen auflassend auflassende auflassendem auflassenden auflassender auflassendes auflassens auflasst Auflassung Auflassungen + auflauere auflauern auflauernd auflauernde auflauerndem auflauernden auflauernder auflauerndes auflauerst auflauert auflauerte auflauerten auflauertest auflauertet + Auflauf auflaufe auflaufen auflaufend auflaufende auflaufendem auflaufenden auflaufender auflaufendes Auflaufs auflauft + auflaure + auflaßt + auflebe aufleben auflebend auflebende auflebendem auflebenden auflebender auflebendes + auflebst + auflebt auflebte auflebten auflebtest auflebtet + auflege auflegen auflegend auflegende auflegendem auflegenden auflegender auflegendes + auflegst + auflegt auflegte auflegten auflegtest auflegtet + auflehne auflehnen auflehnend auflehnende auflehnendem auflehnenden auflehnender auflehnendes auflehnens auflehnst auflehnt auflehnte auflehnten auflehntest auflehntet Auflehnung Auflehnungen + auflese auflesen auflesend auflesende auflesendem auflesenden auflesender auflesendes + auflest + aufleuchte aufleuchten aufleuchtend aufleuchtende aufleuchtendem aufleuchtenden aufleuchtender aufleuchtendes aufleuchtest aufleuchtet aufleuchtete aufleuchteten aufleuchtetest aufleuchtetet + aufliege aufliegen aufliegend aufliegende aufliegendem aufliegenden aufliegender aufliegendes Aufliegeschema aufliegst aufliegt + aufliesse aufliessen aufliessest aufliesset + aufließe aufließen aufließest aufließet + auflistbar auflistbare auflistbarem auflistbaren auflistbarer auflistbares + aufliste auflisten auflistend auflistende auflistendem auflistenden auflistender auflistendes auflistens auflistest auflistet auflistete auflisteten auflistetest auflistetet Auflistung Auflistungen + auflockere auflockern auflockernd auflockernde auflockerndem auflockernden auflockernder auflockerndes auflockerns auflockerst auflockert auflockerte auflockerten auflockertest auflockertet Auflockerung Auflockerungen Auflockerungstendenz Auflockerungstendenzen auflockre + auflodere auflodern auflodernd auflodernde aufloderndem auflodernden auflodernder aufloderndes aufloderns aufloderst auflodert aufloderte aufloderten auflodertest auflodertet auflodre + auflädst auflädt + Aufläufe Aufläufen aufläuft + auflösbar auflösbare auflösbarem auflösbaren auflösbarer auflösbares auflöse auflösen auflösend auflösende auflösendem auflösenden auflösender auflösendes auflösens auflösest auflöst auflöste auflösten auflöstest auflöstet Auflösung Auflösungen Auflösungsbeschluss Auflösungsbeschlusses Auflösungsbeschluß Auflösungsbeschlüsse Auflösungsbeschlüssen Auflösungserscheinung Auflösungserscheinungen Auflösungsprozess Auflösungsprozesse Auflösungsprozessen Auflösungsprozeß + auflüde auflüden auflüdest auflüdet + Autobahnauffahrt + Bauauflage Bauauflagen + Baustoffindustrie Baustoffindustrien + Baustoffingenieur Baustoffingenieure + begreiflich begreifliche begreiflichem begreiflichen begreiflicher begreiflichere begreiflicherem begreiflicheren begreiflicherer begreiflicheres begreiflicherweise begreifliches begreiflichst begreiflichste begreiflichstem begreiflichsten begreiflichster begreiflichstes + begrifflich begriffliche begrifflichem begrifflichen begrifflicher begriffliches + behilflich behilfliche behilflichem behilflichen behilflicher behilfliches + beruflich berufliche beruflichem beruflichen beruflicher berufliches + Bettauflage Bettauflagen + bezweifle bezweiflete bezweifleten + Bezweiflung + Bildschirmauflösung Bildschirmauflösungen + Biohofladen + bischöflich bischöfliche bischöflichem bischöflichen bischöflicher bischöfliches + Bischoffinger + Brieffach + Briefform + Brieffächer + Briefintrige + Brieflaufzeiten + brieflich briefliche brieflichem brieflichen brieflicher briefliches + Büffler Büfflerin Büfflerinnen + Chefflugleiter + Cheffunktion + Chefideologe + Dampfleistung + Dampflokomotiven + darauffolge darauffolgen darauffolgend darauffolgende darauffolgendem darauffolgenden darauffolgender darauffolgendes darauffolgst darauffolgt darauffolgte darauffolgten darauffolgtest darauffolgtet + Darstellungsauffassung Darstellungsauffassungen + Dauertropfflasche + Dorffeuerwehr + Dorfladen + drauflege drauflegen drauflegend drauflegende drauflegendem drauflegenden drauflegender drauflegendes drauflegst drauflegt drauflegte drauflegten drauflegtest drauflegtet + drauflos drauflosgegangen drauflosgegangene drauflosgegangenem drauflosgegangenen drauflosgegangener drauflosgegangenes drauflosgehe drauflosgehen drauflosgehend drauflosgehende drauflosgehendem drauflosgehenden drauflosgehender drauflosgehendes drauflosgehst drauflosgeht drauflosging drauflosginge drauflosgingen drauflosgingst drauflosgingt + dörflich dörfliche dörflichem dörflichen dörflicher dörfliches + Düsenkampfflugzeug + Eingabeaufforderung + Einwurffächer + Einzelhandelskaufleute Einzelhandelskaufleuten + elffach elffache elffachem elffachen elffacher elffaches + elffingrig elffingrige + Erstaufführung + Erstauflage + Erstauflagen + erzbischöflich erzbischöfliche erzbischöflichem erzbischöflichen erzbischöflicher erzbischöfliches + Freiberufler Freiberuflerin Freiberuflerinnen Freiberuflern Freiberuflers + freiberuflich freiberufliche freiberuflichem freiberuflichen freiberuflicher freiberufliches + Freilichtaufführung Freilichtaufführungen + fünffach fünffache fünffachem fünffachen fünffacher fünffaches + fünffingerig fünffingerige fünffingerigem fünffingerigen fünffingeriger fünffingeriges + Fünflinge Fünflingen + Gastspielaufführung + Gebirgsauffaltung + glimpflich glimpfliche glimpflichem glimpflichen glimpflicher glimpfliches + Grafikauflösung Grafikauflösungen Grafikkartenauflösung Grafikkartenauflösungen + grifffest grifffeste grifffestem grifffesten grifffester grifffestes + Großkaufleute Großkaufleuten % Buddenbrooks + Grundauffassung Grundauffassungen + Gugelhupfform + handgreiflich handgreifliche handgreiflichem handgreiflichen handgreiflicher handgreifliches Handgreiflichkeit Handgreiflichkeiten + hauptberuflich hauptberufliche hauptberuflichem hauptberuflichen hauptberuflicher hauptberufliches + hilflos hilflose hilflosem hilflosen hilfloser hilflosere hilfloserem hilfloseren hilfloserer hilfloseres hilfloses hilflosest hilfloseste hilflosestem hilflosesten hilflosester hilflosestes + hinauffahre hinauffahren hinauffahrend hinauffahrende hinauffahrendem hinauffahrenden hinauffahrender hinauffahrendes hinauffahrt + hinauffuhr hinauffuhren hinauffuhrst hinauffuhrt + hinaufführe hinaufführen hinaufführend hinaufführende hinaufführendem hinaufführenden hinaufführender hinaufführendes hinaufführst hinaufführt hinaufführte hinaufführten hinaufführtest hinaufführtet + hochauflösend hochauflösende hochauflösendem hochauflösenden hochauflösender hochauflösendes + hoffähig + Hofladen + Hoflandwirtschaft + Hofleben + Hufform + Häuflein Häufleins + höflich höfliche höflichem höflichen höflicher höflichere höflicherem höflicheren höflicherer höflicheres höfliches höflichkeit höflichkeiten höflichkeitsbesuche höflichkeitsbesuches höflichkeitsformeln höflichst höflichste höflichstem höflichsten höflichster höflichstes + Impffolgen + Impfforschung + Impfflüssigkeit + inbegriffleitend + Kampfflieger Kampffliegers + Kampfflugzeug Kampfflugzeuge Kampfflugzeuges + Kampffront + kampffähig kampffähige kampffähigem kampffähigen kampffähiger kampffähiges Kampffähigkeit + Kampfführung + Kampflaune + Kampflied Kampflieder Kampfliedern + kampflos kampflose kampflosem kampflosen kampfloser kampfloses + kampflustig kampflustige kampflustigem kampflustigen kampflustiger kampflustigere kampflustigerem kampflustigeren kampflustigerer kampflustigeres kampflustiges kampflustigst kampflustigste kampflustigstem kampflustigsten kampflustigster kampflustigstes + Kauffahrer Kauffahrerin Kauffahrerinnen Kauffahrern Kauffahrers + Kauffahrt + Kauffrau Kauffrauen + Kaufindex Kaufindizes + Kaufinteresse Kaufinteressenten + Kaufladen Kaufladens + Kauflaune + Kaufleidenschaft + Kaufleitung + Kaufleute Kaufleuten + Kauflust kauflustig kauflustige kauflustiger kauflustigste kauflustigsten + Kaufläden + Kettensträfling Kettensträflinge Kettensträflingen Kettensträflings + Kleiderstoffindustrie + knifflig knifflige kniffligem kniffligen kniffliger kniffligere kniffligerem kniffligeren kniffligerer kniffligeres kniffliges kniffligst kniffligste kniffligstem kniffligsten kniffligster kniffligstes + Knopfloch + Knopflöcher + Knoepffler + Kontoauflösung + Kopfform Menschenkopfform + kopflastig kopflastige kopflastigem kopflastigen kopflastiger kopflastiges + Kopfleiste + kopflos kopflose kopflosem kopflosen kopfloser kopflosere kopfloserem kopfloseren kopfloserer kopfloseres kopfloses kopflosest kopfloseste kopflosestem kopflosesten kopflosester kopflosestes + Kreislauffunktion + Kreislaufleiden + Kunststoffindustrie + käuflich käufliche käuflichem käuflichen käuflicher käufliches Käuflichkeit + Köpflein + Lagerauffüllung + Lagerauflösung + Lauffeuer Lauffeuern Lauffeuers + Lauffolgen + lauffähig lauffähige lauffähigem lauffähigen lauffähiger lauffähiges Lauffähigkeit + Laufindex Laufindexe Laufindexen Laufindexes Laufindices + Laufleine Laufleinen + Lauflernhilfen + Lebensauffassung Lebensauffassungen + Liebhaberaufführung + Löffler + markgräflich markgräfliche markgräflichem markgräflichen markgräflicher markgräfliches + Mindestreserveauflagen + Monitorauflösung Monitorauflösungen + nebenberuflich nebenberufliche nebenberuflichem nebenberuflichen nebenberuflicher nebenberufliches + Neuauflage Neuauflagen + Oberstufler + offline + Opernaufführung Opernaufführungen + Parlamentsauflösung + Politikauffassung Politikauffassungen + Produktionsauflagen + Prüffach + Prüffeld + Prüffächer + Prüfingenieur + Prüfling Prüflinge Prüflingen Prüflings + Prüfliste Prüflisten + rauflustig rauflustige rauflustigem rauflustigen rauflustiger rauflustiges + Reichstagsauflösung + reiflich reifliche reiflichem reiflichen reiflicher reiflichere reiflicherem reiflicheren reiflicherer reiflicheres reifliches reiflichst reiflichste reiflichstem reiflichsten reiflichster reiflichstes + Restauflage Restauflagen + Rinderkopffleisch + Rohstoffindex Rohstoffindexe Rohstoffindices Rohstoffindustrie + Rohstoffingenieur Rohstoffingenieure + Schaffell Schaffelle Schaffellen Schaffells + Schafleder Schafledern Schafleders + Scherflein Scherfleins + schieflache schieflachen schieflachend schieflachende schieflachendem schieflachenden schieflachender schieflachendes schieflachst schieflacht schieflachte schieflachten schieflachtest schieflachtet + schieflag Schieflage Schieflagen schieflagst schieflagt + Schieflaufen + schiefliege schiefliegen schiefliegend schiefliegende schiefliegendem schiefliegenden schiefliegender schiefliegendes schiefliegst schiefliegt + schiefläuft + Schilffeld Schilffelder % Th. Mann's "Tod in Venedig" + Schilfinsel Schilfinseln + schimpflich schimpfliche schimpflichem schimpflichen schimpflicher schimpfliches + Schlafforscher Schlafforschung + Schlaffrisur + Schlaflied Schlaflieder Schlafliedern Schlafliedes Schlaflieds + schlaflos schlaflose schlaflosem schlaflosen schlafloser schlafloses Schlaflosigkeit Schlaflosigkeiten + Schlupfloch Schlupfloches Schlupflochs + Schlupflöcher Schlupflöchern + Schnüffler Schnüfflerin Schnüfflerinnen Schnüfflern Schnüfflers + schweflig schweflige schwefligem schwefligen schwefliger schwefliges + Schöpflöffel Schöpflöffeln Schöpflöffels + selbstauffaltend + Selbstauflösung + Serienbrieffunktion + Sprengstofffallen + steckbrieflich + Steuerschnüffler Steuerschnüfflern Steuerschnüfflers + Straffall Straffalls + straffrisch + Straffälle straffällig straffällige straffälligem straffälligen straffälliger straffälliges + Strafforderung + straffähig + Straflager Straflagern Straflagers + straflos straflose straflosem straflosen strafloser strafloses + Streiflicht Streiflichter Streiflichtern Streiflichts + sträflich sträfliche sträflichem sträflichen sträflicher sträfliches + Sträfling Sträflinge Sträflingen Sträflings + Sturzkampfflugzeug Sturzkampfflugzeuge Sturzkampfflugzeugen Sturzkampfflugzeugs + Sumpffieber + Sumpffliege Sumpffliegen + Sumpfland Sumpflandes Sumpflands + Sumpflicht Sumpflichter + Sumpfländer Sumpfländern + Surfladen + tariflich tarifliche tariflichem tariflichen tariflicher tarifliches + Tariffalle Tariffallen + Tarifforderung + Tariffront + Tariflohn Tariflohns + Tariflöhne Tariflöhnen + teuflisch teuflische teuflischem teuflischen teuflischer teuflischere teuflischerem teuflischeren teuflischerer teuflischeres teuflisches teuflischst teuflischste teuflischstem teuflischsten teuflischster teuflischstes + Theateraufführung Theateraufführungen + tieffliege tieffliegen tieffliegend tieffliegende tieffliegendem tieffliegenden tieffliegender tieffliegendes Tiefflieger Tieffliegern Tieffliegers tieffliegst tieffliegt + tiefflog tiefflogen tiefflogst tiefflogt + Tiefflug Tieffluges Tiefflugs + Tiefflüge Tiefflügen + tiefladbar tiefladbare tiefladbarem tiefladbaren tiefladbarer tiefladbares tieflade tiefladen Tieflader Tiefladeprogramm + Tieflage Tieflagen + Tiefland Tieflandes Tieflands + tiefliege tiefliegen tiefliegend tiefliegende tiefliegendem tiefliegenden tiefliegender tiefliegendes tiefliegst tiefliegt + Tiefländer Tiefländern + Tieflöffel Tieflöffelbagger Tieflöffelbaggern tieflöffeln Tieflöffels + Torffeuer + Totenkopfflagge + trefflich treffliche trefflichem trefflichen trefflicher trefflichere trefflicherem trefflicheren trefflicherer trefflicheres treffliches trefflichkeit trefflichst trefflichste trefflichstem trefflichsten trefflichster trefflichstes + Täufling Täuflinge Täuflingen Täuflings + Tüpflischeißer Tüpflischiesser + unauffindbar unauffindbare unauffindbarem unauffindbaren unauffindbarer unauffindbares Unauffindbarkeit Unauffindbarkeiten + unauffällig unauffällige unauffälligem unauffälligen unauffälliger unauffälligere unauffälligerem unauffälligeren unauffälligerer unauffälligeres unauffälliges unauffälligkeit unauffälligkeiten unauffälligst unauffälligste unauffälligstem unauffälligsten unauffälligster unauffälligstes + unauflösbar unauflösbare unauflösbarem unauflösbaren unauflösbarer unauflösbares + unauflöslich unauflösliche unauflöslichem unauflöslichen unauflöslicher unauflösliches + unbegreiflich unbegreifliche unbegreiflichem unbegreiflichen unbegreiflicher unbegreiflichere unbegreiflicherem unbegreiflicheren unbegreiflicherer unbegreiflicheres unbegreifliches unbegreiflichkeit unbegreiflichst unbegreiflichste unbegreiflichstem unbegreiflichsten unbegreiflichster unbegreiflichstes + unerschöpflich unerschöpfliche unerschöpflichem unerschöpflichen unerschöpflicher unerschöpflichere unerschöpflicherem unerschöpflicheren unerschöpflicherer unerschöpflicheres unerschöpfliches unerschöpflichst unerschöpflichste unerschöpflichstem unerschöpflichsten unerschöpflichster unerschöpflichstes + unglimpflich unglimpfliche unglimpflichem unglimpflichen unglimpflicher unglimpfliches + unhöflich unhöfliche unhöflichem unhöflichen unhöflicher unhöflichere unhöflicherem unhöflicheren unhöflicherer unhöflicheres unhöfliches unhöflichkeit unhöflichkeiten unhöflichst unhöflichste unhöflichstem unhöflichsten unhöflichster unhöflichstes + unverkäuflich unverkäufliche unverkäuflichem unverkäuflichen unverkäuflicher unverkäufliches Unverkäuflichkeit + unwiderruflich unwiderrufliche unwiderruflichem unwiderruflichen unwiderruflicher unwiderrufliches + unübertrefflich + uraufführe uraufführen uraufführend uraufführende uraufführendem uraufführenden uraufführender uraufführendes uraufführst uraufführt uraufführte uraufführten uraufführtest uraufführtet Uraufführung Uraufführungen + übertariflich übertarifliche übertariflichem übertariflichen übertariflicher übertarifliches + verelffache verelffachen verelffachend verelffachende verelffachendem verelffachenden verelffachender verelffachendes verelffachst verelffacht verelffachte verelffachtem verelffachten verelffachter verelffachtes verelffachtest verelffachtet + verfünffache verfünffachen verfünffachend verfünffachende verfünffachendem verfünffachenden verfünffachender verfünffachendes verfünffachst verfünffacht verfünffachte verfünffachtem verfünffachten verfünffachter verfünffachtes verfünffachtest verfünffachtet + verkäuflich verkäufliche verkäuflichem verkäuflichen verkäuflicher verkäufliches Verkäuflichkeit + verwerflich verwerfliche verwerflichem verwerflichen verwerflicher verwerflichere verwerflicherem verwerflicheren verwerflicherer verwerflicheres verwerfliches verwerflichst verwerflichste verwerflichstem verwerflichsten verwerflichster verwerflichstes + Verzweiflung Verzweiflungsschritt Verzweiflungstat + verzwölffache verzwölffachen verzwölffachend verzwölffachende verzwölffachendem verzwölffachenden verzwölffachender verzwölffachendes verzwölffachst verzwölffacht verzwölffachte verzwölffachtem verzwölffachten verzwölffachter verzwölffachtes verzwölffachtest verzwölffachtet + Voraufführung Voraufführungen + vorberuflich vorberufliche vorberuflichem vorberuflichen vorberuflicher vorberufliches + Vorlaufindikator Vorlaufindikatoren + vortrefflich vortreffliche vortrefflichem vortrefflichen vortrefflicher vortreffliches + Wahlkampffieber Wahlkampfflyer Wahlkampfflamme Wahlkampffloskeln + Waldorflehrer Waldorflehrerin Waldorflehrerinnen Waldorflehrern Waldorflehrers + Wegwerfformat + Wettkampffieber Wettkampffläche Wettkampfflair + widerruflich widerrufliche widerruflichem widerruflichen widerruflicher widerrufliches + wiederaufführung wiederaufführungen + wiederaufladbar wiederaufladbare wiederaufladbarem wiederaufladbaren wiederaufladbarer wiederaufladbares + wiederauflade wiederaufladen wiederaufladend wiederaufladende wiederaufladendem wiederaufladenden wiederaufladender wiederaufladendes wiederaufladet Wiederaufladung + wiederauflebe wiederaufleben wiederauflebend wiederauflebende wiederauflebendem wiederauflebenden wiederauflebender wiederauflebendes wiederauflebst wiederauflebt wiederauflebte wiederauflebten wiederauflebtest wiederauflebtet + Wirtschaftsauffassung + würflig würflige würfligem würfligen würfliger würfliges + Wölflein + Wölfling + Wurflaune + Zahlungsaufforderung Zahlungsaufforderungen + Zeitauflösung + Zöpflein + Zupfinstrument Zupfinstrumente Zupfinstrumenten Zupfinstrumentes Zupfinstruments + zweifle + Zweifler Zweiflerin Zweiflerinnen Zweiflern Zweiflers + Zweitauflage Zweitauflagen + zwölffach zwölffache zwölffachem zwölffachen zwölffacher zwölffaches + Zwölffingerdarm Zwölffingerdarmes Zwölffingerdarms + ]] + }, + { + patterns = { + ft = "f|t", + fft = "fft", + }, + words = [[ + Auftakt + auftanken auftasten auftat + auftauen auftaute + auftauchen auftauchte + aufteilen Aufteilung Aufteilungen + auftischen auftischte auftoupieren + auftraben + Auftrag auftragen, Auftraggeber + auftrat + auftreiben + auftreten + Auftritt + Aufträge + auftun auftürmen + Sauftrottel + kauftüchtig + Lauftherapie + Golftheorie Kampftheorien Auflauftheorien Kreislauftheorie + Tauftag Fünftagewoche + Treibstofftank + fünftausend Fünftausender + fünftürig Senftüte + Hoftür + elftausend zwölftausend Golftasche + Ruftaste Vorlauftaste + Ruftaxi + Wettkampftag Kampftaktik + wahlkampftauglich Schnupftabak + -- kämpfte schimpfte schrumpfte + -- klopfte schöpften + Schimpftiraden Mehrkampftitel Stapftiefe + Dampftopf Sumpftour + Kampftruppe Wettkampftrubel + Kopftreffer Zopfträger + Kopftuch Schnupftuch + Kampftätigkeit Kampftänzer + Herzklopftöne Wahlkampftöne + Kopftücher Kopftüchlein Schnupftücher + Stofftasche Stofftapete Sauerstofftank + -- schaffte hoffte klaffte verpuffte + Stofftheorie + Stofftier Stofftiger Stofftischtuch + Auspufftopf Kunststofftonne + Stofftradition Stofftrennung + Kunststofftube Stoffturnschuhe + Stofftäschchen + Auspufftöpfe Kunststofftöpfe + Kunststofftüten + Schlaftablette Schlafteddy Schlaftee Schlaftemperatur + Schlaftherapeut Schlaftherapie Schlaftier Schlaftod + Schlaftrank schlaftrunken + Straftarif Strafteam Straftechnisch Straftendenz + Straftermin Straftheologisch Straftilgung + Straftor Straftribunal + -- bestraft vorbestraft + Brieftasche Brieftaube + Cheftheoretiker Cheftestpilot Cheftrainer + Dorftrottel Dorftratsch Dorftradition Dorftölpel + Wurftraining Surftrip Freiwurftreffer + Wurftuch Dorftümpel + Lauftrainer + Eingreiftruppe Nadelstreifträger + Pfeifton Zwölftonmusik Rufton + Wurftalent Auswurftaste Surftalent + -- Hälfte + Schifftyp Stofftyp waldorftypisch Dorftyrann Hoftyrann + Stieftochter Tiefton + Stieftöchter tieftönend + fünfte fünfter elfte elfter zwölfte zwölfter + -- fünft zu elft zu zwölft + zwölftönend + Zwölftonmusik Elftonner Golftour + Senftopf Senftöpfchen + Freiwurftor Surftour Dorftourismus + ]] + }, + { + patterns = { + fb = "f|b", + ffb = "f|f|b", + }, + words = [[ + abrufbar + Anrufbeantworter + aufbahren aufbauen aufbegehren aufbereiten aufbessern aufbewahren aufbefördern aufbieten aufblasen aufblicken Aufblick aufblitzen aufblähen aufblühen aufbrauchen aufbrausen aufbrechen aufbringen Aufbruch aufbäumen aufbürden + Aufbauspieler + Briefbombe Briefbogen + Chefberater + Dampfbad Dorfbewohner Dorfbevölkerung + greifbar angreifbar unangreifbar griffbereit Golfball + Griffbrett + Briefbeschwerer Hofbräuhaus + Kopfbewegung Kopfball Kopfbedeckung Kaufbeleg kampfbetont + Laufbahn Laufband Laufbereitschaft Laufbursche + Raufbold Rohstoffboom Regenüberlaufbecken + Schadstoffbelastung Schlafbedürfnis Scharfblick + schiffbar Schiffbau Schiffbruch + steifbeinig Stoffbahnen + Sauerstoffbedarf Stiefbruder + Strafbestimmungen strafbar Strafbefehl + Surfbretter + Tarifbezirk Tarifbindung + Tiefbau tiefbelustigt tiefblau + Umlaufbahn überprüfbar + (un)widerrufbar + Wasserstoffbombe + Wiederaufbau + ]], + }, + { + patterns = { + fh = "f|h", + ffh = "f|f|h", + }, + words = [[ + aufhaben aufhacken aufhalsen aufhalten aufhatte aufheben aufheitern aufheizen aufhelfen aufhellen aufhetzen aufheulen aufholen aufhorchen aufhängen aufhören aufhübschen + Chefhändler + daraufhin draufhat draufhauen + Dorfhaus + Eislaufhalle + fünfhundert + Hofherr + Kampfhandlung Kampfhubschrauber Kampfhunde Kampfhähne + Kopfhaar Kopfhaltung Kopfhaube Kopfhaut Kopfhörer + Kaufhalle Kaufhaus Kaufherr Kaufhold + krampfhaft + Schafhaltung Schafherde Schafhirte + Schilfhütte + Steifheit Schlaffheit + Strafhaft + Strumpfhose Stumpfheit + Topfhaarschnitt + unaufhaltsam unaufhörlich + Wahlkampfhelfer + Impfstoffhersteller + Luftschiffhafen + Pfaffhausen Schaffhausen + Riffhai + Stoffhändler + Werkstoffhof + ]], + }, + { + patterns = { + fj = "f|j", + ffj = "f|f|j", + }, + words = [[ + aufjagen aufjaulen aufjauchzen aufjohlt + Dorfjunge Dorfjustiz Dorfjugend Dorfjäger Dorfjubiläum + Fünfjahresplan Fünfjahresfeier Knefjahr Tarifjahr Strafjahr + fünfjährig elfjährig zwölfjährig + Kopfjäger Kopfjucken Kopfjagd + Strafjustiz Strafjurist Chefjurist + Laufjunge Laufjahr Laufjacke + Wahlkampfjahr Wettkampfjahr Kampfjet + Stoffjacke + Kampfjagd Kampfjodeln + Hofjäger + Golfjahr Golfjunge Golfjunioren Golfjuniorinnen + -- Sognefjord Dovrefjell Prokofjew + ]], + }, + { + patterns = { + fk = "f|k", + ffk = "f|f|k", + }, + words = [[ + aufkam aufkaufen aufkeimen aufkehren aufklaffen aufkläffen aufklappen aufklatschen aufklauben aufkleben aufklären aufklingen aufklopfen aufknacken aufknöpfen aufknüpfen aufkochen aufkommen aufkreischen aufkrempeln aufkreuzen aufkriegen aufkurbeln aufkündigen + Napfkuchen Stopfkugel Briefkasten Briefkästen Kopfkissen + Kehlkopfknoten Kaufkraft + Pfeifkonzert Trumpfkarte + Tarifkonflikt Tarifkommission + Stoffkissen Stoffkatze Treibstoffkosten Kliffkante Auspuffklang + ]], + }, + -- For Wolfgang + { + characters = "ẞ", + patterns = { + ["ẞ"] = "SS", + }, + }, + -- For Hans (an example of a compound word): + -- { + -- patterns = { + -- ffl = "ff=l", + -- }, + -- words = [[ + -- whatever=whatever + -- wafflaw + -- wawafflawaw + -- wawaffluwuw + -- wawufflawuw + -- ]], + -- }, + } +} diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index c981601b9..14c50d6b7 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2021-03-27 19:03 +-- merge date : 2021-03-31 18:00 do -- begin closure to overcome local limits and interference -- cgit v1.2.3