summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-not.lua
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2010-07-04 15:32:09 +0300
committerMarius <mariausol@gmail.com>2010-07-04 15:32:09 +0300
commit85b7bc695629926641c7cb752fd478adfdf374f3 (patch)
tree80293f5aaa7b95a500a78392c39688d8ee7a32fc /tex/context/base/strc-not.lua
downloadcontext-85b7bc695629926641c7cb752fd478adfdf374f3.tar.gz
stable 2010-05-24 13:10
Diffstat (limited to 'tex/context/base/strc-not.lua')
-rw-r--r--tex/context/base/strc-not.lua338
1 files changed, 338 insertions, 0 deletions
diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua
new file mode 100644
index 000000000..be883af57
--- /dev/null
+++ b/tex/context/base/strc-not.lua
@@ -0,0 +1,338 @@
+if not modules then modules = { } end modules ['strc-not'] = {
+ version = 1.001,
+ comment = "companion to strc-not.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+local next = next
+local texsprint, texwrite, texcount = tex.sprint, tex.write, tex.count
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local trace_notes = false trackers.register("structure.notes", function(v) trace_notes = v end)
+
+structure = structure or { }
+structure.helpers = structure.helpers or { }
+structure.lists = structure.lists or { }
+structure.sections = structure.sections or { }
+structure.counters = structure.counters or { }
+structure.notes = structure.notes or { }
+
+structure.notes.states = structure.notes.states or { }
+structure.lists.enhancers = structure.lists.enhancers or { }
+
+storage.register("structure/notes/states", structure.notes.states, "structure.notes.states")
+
+local helpers = structure.helpers
+local lists = structure.lists
+local sections = structure.sections
+local counters = structure.counters
+local notes = structure.notes
+
+local notestates = structure.notes.states
+local notedata = { }
+
+-- state: store, insert, postpone
+
+function notes.store(tag,n)
+ local nd = notedata[tag]
+ if not nd then
+ nd = { }
+ notedata[tag] = nd
+ end
+ local nnd = #nd+1
+ nd[nnd] = n
+ local state = notestates[tag]
+ if state.kind ~= "insert" then
+ if trace_notes then
+ logs.report("notes","storing %s with state %s as %s",tag,state.kind,nnd)
+ end
+ state.start = state.start or nnd
+ end
+ texwrite(#nd)
+end
+
+local function get(tag,n)
+ local nd = notedata[tag]
+ if nd then
+ n = n or #nd
+ nd = nd[n]
+ if nd then
+ if trace_notes then
+ logs.report("notes","getting %s of %s",n,tag)
+ end
+ return structure.lists.collected[nd]
+ end
+ end
+end
+
+local function getn(tag)
+ local nd = notedata[tag]
+ return (nd and #nd) or 0
+end
+
+nodes.get = get
+nodes.getn = getn
+
+-- we could make a special enhancer
+
+function notes.listindex(tag,n)
+ return notedata[tag][n]
+end
+
+function notes.define(tag,kind,number)
+ local state = notes.setstate(tag,kind)
+ state.number = number
+end
+
+function notes.save(tag,newkind)
+ local state = notestates[tag]
+ if state and not state.saved then
+ if trace_notes then
+ logs.report("notes","saving state of %s: %s -> %s",tag,state.kind,newkind or state.kind)
+ end
+ state.saved = notedata[tag]
+ state.savedkind = state.kind
+ state.kind = newkind or state.kind
+ notedata[tag] = { }
+ end
+end
+
+function notes.restore(tag,forcedstate)
+ local state = notestates[tag]
+ if state and state.saved then
+ if trace_notes then
+ logs.report("notes","restoring state of %s: %s -> %s",tag,state.kind,state.savedkind)
+ end
+ state.saved = nil
+ state.kind = forcedstate or state.savedkind
+ notedata[tag] = state.saved
+ end
+end
+
+function notes.setstate(tag,newkind)
+ local state = notestates[tag]
+ if trace_notes then
+ logs.report("notes","setting state of %s from %s to %s",tag,(state and state.kind) or "unset",newkind)
+ end
+ if not state then
+ state = {
+ kind = newkind
+ }
+ notestates[tag] = state
+ elseif newkind == "insert" then
+ if not state.start then
+ state.kind = newkind
+ end
+ else
+ state.kind = newkind
+ end
+ -- state.start can already be set and will be set when an entry is added or flushed
+ return state
+end
+
+function notes.getstate(tag)
+ local state = notestates[tag]
+ texsprint(ctxcatcodes,(state and state.kind ) or "unknown")
+end
+
+function notes.doifcontent(tag)
+ local ok = notestates[tag]
+ if ok then
+ if ok.kind == "insert" then
+ ok = tex.box[ok.number]
+ if ok then
+ ok = tbs.list
+ ok = lst and lst.next
+ end
+ else
+ ok = ok.start
+ end
+ end
+ commands.doif(ok)
+end
+
+local function internal(tag,n)
+ local nd = get(tag,n)
+ if nd then
+ local r = nd.references
+ if r then
+ local i = r.internal
+--~ return i and lists.internals[i]
+ return i and jobreferences.internals[i]
+ end
+ end
+ return nil
+end
+
+local function ordered(kind,name,n)
+ local o = lists.ordered[kind]
+ o = o and o[name]
+ return o and o[n]
+end
+
+notes.internal = internal
+notes.ordered = ordered
+
+function notes.doifonsamepageasprevious(tag)
+ local same = false
+ local n = getn(tag,n)
+ local current, previous = get(tag,n), get(tag,n-1)
+ if current and previous then
+ local cr, pr = current.references, previous.references
+ same = cr and pr and cr.realpage == pr.realpage
+ end
+ commands.doifelse(same)
+end
+
+function notes.checkpagechange(tag) -- called before increment !
+ local nd = notedata[tag] -- can be unset at first entry
+ if nd then
+ local current = ordered("note",tag,#nd)
+ local nextone = ordered("note",tag,#nd+1)
+ if nextone then
+ -- we can use data from the previous pass
+ if nextone.pagenumber.number > current.pagenumber.number then
+ counters.reset(tag)
+ end
+ elseif current then
+ -- we need to locate the next one, best guess
+ if texcount.realpageno > current.pagenumber.number then
+ counters.reset(tag)
+ end
+ end
+ end
+end
+
+function notes.deltapage(tag,n)
+ -- 0:unknown 1:textbefore, 2:textafter, 3:samepage
+ local what = 0
+ local li = internal(tag,n)
+ if li then
+ local metadata, pagenumber = li.metadata, li.pagenumber
+ if metadata and pagenumber then
+ local symbolpage = metadata.symbolpage or 0
+ local notepage = pagenumber.number or 0
+ if notepage > 0 and symbolpage > 0 then
+ if notepage < symbolpage then
+ what = 1
+ elseif notepage > symbolpage then
+ what = 2
+ else
+ what = 3
+ end
+ end
+ else
+ -- might be a note that is not flushed due to to deep
+ -- nesting in a vbox
+ what = 3
+ end
+ end
+ texwrite(what)
+end
+
+function notes.postpone()
+ if trace_notes then
+ logs.report("notes","postponing all insert notes")
+ end
+ for tag, state in next, notestates do
+ if state.kind ~= "store" then
+ notes.setstate(tag,"postpone")
+ end
+ end
+end
+
+function notes.setsymbolpage(tag,n)
+ local nd = get(tag,n)
+ if nd then
+ nd.metadata.symbolpage = texcount.realpageno
+ end
+end
+
+function notes.getsymbolpage(tag,n)
+ local nd = get(tag,n)
+ nd = nd and nd.metadata.symbolpage
+ texwrite(nd or 0)
+end
+
+function notes.getnumberpage(tag,n)
+ local li = internal(tag,n)
+ li = li and li.pagenumber
+ li = li and li.numbers
+ li = li and li[1]
+ texwrite(li or 0)
+end
+
+function notes.flush(tag,whatkind) -- store and postpone
+ local state = notestates[tag]
+ local kind = state.kind
+ if kind == whatkind then
+ local nd = notedata[tag]
+ local ns = state.start -- first index
+ if kind == "postpone" then
+ if nd and ns then
+ if trace_notes then
+ logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd)
+ end
+ for i=ns,#nd do
+ texsprint(ctxcatcodes,format("\\handlenoteinsert{%s}{%s}",tag,i))
+ end
+ end
+ state.start = nil
+ state.kind = "insert"
+ elseif kind == "store" then
+ if nd and ns then
+ if trace_notes then
+ logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd)
+ end
+ for i=ns,#nd do
+ texsprint(ctxcatcodes,format("\\handlenoteitself{%s}{%s}",tag,i))
+ end
+ end
+ state.start = nil
+ elseif kind == "reset" then
+ if nd and ns then
+ if trace_notes then
+ logs.report("notes","flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd)
+ end
+ end
+ state.start = nil
+ elseif trace_notes then
+ logs.report("notes","not flushing state %s of %s",whatkind,tag)
+ end
+ elseif trace_notes then
+ logs.report("notes","not flushing state %s of %s",whatkind,tag)
+ end
+end
+
+function notes.flushpostponed()
+ if trace_notes then
+ logs.report("notes","flushing all postponed notes")
+ end
+ for tag, _ in next, notestates do
+ notes.flush(tag,"postpone")
+ end
+end
+
+function notes.resetpostponed()
+ if trace_notes then
+ logs.report("notes","resetting all postponed notes")
+ end
+ for tag, state in next, notestates do
+ if state.kind == "postpone" then
+ state.start = nil
+ state.kind = "insert"
+ end
+ end
+end
+
+function notes.title(tag,n)
+ structure.lists.savedtitle(tag,notedata[tag][n])
+end
+
+function notes.number(tag,n,spec)
+ structure.lists.savedprefixednumber(tag,notedata[tag][n])
+end