summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/typo-chr.lmt
diff options
context:
space:
mode:
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.lmt291
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,
+}
+