diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt b/Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt new file mode 100644 index 00000000000..bb11f54a64c --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt @@ -0,0 +1,291 @@ +if not modules then modules = { } end modules ['typo-chr'] = { + version = 1.001, + comment = "companion to typo-bld.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- A historic intermediate version can be found in the mkiv variant. The code +-- can probably be improved but performance etc is not really an issue here. + +local insert, remove = table.insert, table.remove + +local context = context +local ctx_doifelse = commands.doifelse + +local nodecodes = nodes.nodecodes +local boundarycodes = nodes.boundarycodes +local subtypes = nodes.subtypes + +local glyph_code = nodecodes.glyph +local par_code = nodecodes.par +local boundary_code = nodecodes.boundary + +local wordboundary_code = boundarycodes.word + +local texgetnest = tex.getnest -- to be used +local texsetcount = tex.setcount + +local flush_node = nodes.flush_node +local flush_list = nodes.flush_list + +local settexattribute = tex.setattribute +local punctuation = characters.is_punctuation + +local variables = interfaces.variables +local v_all = variables.all +local v_reset = variables.reset + +local stack = { } + +local a_marked = attributes.numbers['marked'] +local lastmarked = 0 +local marked = { + [v_all] = 1, + [""] = 1, + [v_reset] = attributes.unsetvalue, +} + +local function pickup() + local list = texgetnest() + if list then + local tail = list.tail + if tail and tail.id == glyph_code and punctuation[tail.char] then + local prev = tail.prev + list.tail = prev + if prev then + prev.next = nil + end + list.tail = prev + tail.prev = nil + return tail + end + end +end + +local actions = { + remove = function(specification) + local n = pickup() + if n then + flush_node(n) + end + end, + push = function(specification) + local n = pickup() + if n then + insert(stack,n or false) + end + end, + pop = function(specification) + local n = remove(stack) + if n then + context(n) + end + end, +} + +local function pickuppunctuation(specification) + local action = actions[specification.action or "remove"] + if action then + action(specification) + end +end + +-- I played with nested marked content but it makes no sense and gives +-- complex code. Also, it's never needed so why bother. + +local function pickup(head,tail,str) + local attr = marked[str] + local last = tail + if last[a_marked] == attr then + local first = last + while true do + local prev = first.prev + if prev and prev[a_marked] == attr then + if prev.id == par_code then -- and start_of_par(prev) + break + else + first = prev + end + else + break + end + end + return first, last + end +end + +local function found(str) + local list = texgetnest() + if list then + local tail = list.tail + return tail and tail[a_marked] == marked[str] + end +end + +local actions = { + remove = function(specification) + local list = texgetnest() + if list then + local head = list.head + local tail = list.tail + local first, last = pickup(head,tail,specification.mark) + if first then + if first == head then + list.head = nil + list.tail = nil + else + local prev = first.prev + list.tail = prev + prev.next = nil + end + flush_list(first) + end + end + end, +} + +local function pickupmarkedcontent(specification) + local action = actions[specification.action or "remove"] + if action then + action(specification) + end +end + +local function markcontent(str) + local currentmarked = marked[str or v_all] + if not currentmarked then + lastmarked = lastmarked + 1 + currentmarked = lastmarked + marked[str] = currentmarked + end + settexattribute(a_marked,currentmarked) +end + +interfaces.implement { + name = "pickuppunctuation", + actions = pickuppunctuation, + arguments = { + { + { "action" } + } + } +} + +interfaces.implement { + name = "pickupmarkedcontent", + actions = pickupmarkedcontent, + arguments = { + { + { "action" }, + { "mark" } + } + } +} + +interfaces.implement { + name = "markcontent", + actions = markcontent, + arguments = "string", +} + +interfaces.implement { + name = "doifelsemarkedcontent", + actions = function(str) ctx_doifelse(found(str)) end, + arguments = "string", +} + +-- We just put these here. + +interfaces.implement { + name = "lastnodeidstring", + public = true, + actions = function() + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if tail then + okay = nodecodes[tail.id] + end + end + context(okay or "") + end, +} + +-- local t_lastnodeid = token.create("c_syst_last_node_id") +-- +-- interfaces.implement { +-- name = "lastnodeid", +-- public = true, +-- actions = function() +-- ... +-- tex.setcount("c_syst_last_node_id",okay) +-- context.sprint(t_lastnodeid) +-- end, +-- } + +-- not needed in lmtx ... + +interfaces.implement { + name = "lastnodeid", + actions = function() + local list = texgetnest() -- "top" + local okay = -1 + if list then + local tail = list.tail + if tail then + okay = tail.id + end + end + texsetcount("c_syst_last_node_id",okay) + end, +} + +interfaces.implement { + name = "lastnodesubtypestring", + public = true, + actions = function() + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if head then + okay = subtypes[tail.id][tail.subtype] + end + end + context(okay or "") + end, +} + +local function lastnodeequals(id,subtype) + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if tail then + local i = tail.id + okay = i == id or i == nodecodes[id] + if subtype then + local s = tail.subtype + okay = s == subtype or s == subtypes[i][subtype] + end + end + end + ctx_doifelse(okay) +end + +interfaces.implement { + name = "lastnodeequals", + arguments = "2 strings", + actions = lastnodeequals, +} + +interfaces.implement { + name = "atwordboundary", + actions = function() + lastnodeequals(boundary_code,wordboundary_code) + end, +} + |