if not modules then modules = { } end modules ['strc-pag'] = { version = 1.001, comment = "companion to strc-pag.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local texcount, format = tex.count, string.format local ctxcatcodes = tex.ctxcatcodes local texsprint, texwrite = tex.sprint, tex.write local trace_pages = false trackers.register("structure.pages", function(v) trace_pages = v end) structure.pages = structure.pages or { } local helpers = structure.helpers or { } local sections = structure.sections or { } local pages = structure.pages or { } local processors = structure.processors or { } local sets = structure.sets or { } local variables = interfaces.variables -- storage jobpages = jobpages or { } jobpages.collected = jobpages.collected or { } jobpages.tobesaved = jobpages.tobesaved or { } local collected, tobesaved = jobpages.collected, jobpages.tobesaved local function initializer() collected, tobesaved = jobpages.collected, jobpages.tobesaved end job.register('jobpages.collected', jobpages.tobesaved, initializer) local specification = { } -- to be checked function pages.save(prefixdata,numberdata) local realpage, userpage = texcount.realpageno, texcount.userpageno if realpage > 0 then if trace_pages then logs.report("pages","saving page %s.%s",realpage,userpage) end local data = { number = userpage, block = sections.currentblock(), prefixdata = prefixdata and helpers.simplify(prefixdata), numberdata = numberdata and helpers.simplify(numberdata), } tobesaved[realpage] = data if not collected[realpage] then collected[realpage] = data end elseif trace_pages then logs.report("pages","not saving page %s.%s",realpage,userpage) end end function structure.counters.specials.userpage() local r = texcount.realpageno if r > 0 then local t = tobesaved[r] if t then t.number = texcount.userpageno if trace_pages then logs.report("pages","forcing pagenumber of realpage %s to %s",r,t.number) end end end end --~ function pages.pagenumber(localspec) --~ local deltaspec --~ if localspec then --~ for k,v in next, localspec do --~ if v ~= "" and v ~= specification[k] then --~ if not deltaspec then deltaspec = { } end --~ deltaspec[k] = v --~ end --~ end --~ end --~ if deltaspec then --~ return { realpage = texcount.realpageno, specification = deltaspec } --~ else --~ return { realpage = texcount.realpageno } --~ end --~ end local function convertnumber(str,n) return format("\\convertnumber{%s}{%s}",str or "numbers",n) end function pages.number(realdata,pagespec) local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock() local numberspec = realdata.numberdata local conversionset = (pagespec and pagespec.conversionset ~= "" and pagespec.conversionset) or (numberspec and numberspec.conversionset ~= "" and numberspec.conversionset) or "" local conversion = (pagespec and pagespec.conversion ~= "" and pagespec.conversion ) or (numberspec and numberspec.conversion ~= "" and numberspec.conversion ) or "" local starter = (pagespec and pagespec.starter ~= "" and pagespec.starter ) or (numberspec and numberspec.starter ~= "" and numberspec.starter ) or "" local stopper = (pagespec and pagespec.stopper ~= "" and pagespec.stopper ) or (numberspec and numberspec.stopper ~= "" and numberspec.stopper ) or "" if starter ~= "" then processors.sprint(ctxcatcodes,starter) end if conversion ~= "" then texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,userpage)) else if conversionset == "" then conversionset = "default" end local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers") processors.sprint(ctxcatcodes,theconversion,convertnumber,userpage) end if stopper ~= "" then processors.sprint(ctxcatcodes,stopper) end end -- (pagespec.prefix == yes|unset) and (pages.prefix == yes) => prefix function pages.analyse(entry,pagespecification) -- safeguard if not entry then return false, false, "no entry" end local references = entry.references if not references then return false, false, "no references" end local realpage = references.realpage if not realpage then return false, false, "no realpage" end local pagedata = collected[realpage] if not pagedata then return false, false, "no pagedata" end local section = references.section if not section then return pagedata, false, "no section" end local no = variables.no -- local preferences if pagespecification and pagespecification.prefix == no then return pagedata, false, "current spec blocks prefix" end -- stored preferences --~ if entry.prefix == no then --~ return pagedata, false, "entry blocks prefix" --~ end -- stored page state pagespecification = pagedata.prefixdata if pagespecification and pagespecification.prefix == no then return pagedata, false, "pagedata blocks prefix" end -- final verdict return pagedata, jobsections.collected[references.section], "okay" end function helpers.page(data,pagespec) if data then local pagedata = pages.analyse(data,pagespec) if pagedata then pages.number(pagedata,pagespec) end end end function helpers.prefixpage(data,prefixspec,pagespec) if data then local pagedata, prefixdata, e = pages.analyse(data,pagespec) if pagedata then if prefixdata then sections.typesetnumber(prefixdata,"prefix",prefixspec or false,prefixdata or false,pagedata.prefixdata or false) end pages.number(pagedata,pagespec) end end end function helpers.prefixlastpage(data,prefixspec,pagespec) if data then local r = data.references local ls, lr = r.section, r.realpage r.section, r.realpage = r.lastsection or r.section, r.lastrealpage or r.realpage helpers.prefixpage(data,prefixspec,pagespec) r.section, r.realpage = ls, lr end end -- function helpers.analyse(entry,specification) -- safeguard if not entry then return false, false, "no entry" end local yes, no = variables.yes, variables.no -- section data local references = entry.references if not references then return entry, false, "no references" end local section = references.section if not section then return entry, false, "no section" end sectiondata = jobsections.collected[references.section] if not sectiondata then return entry, false, "no section data" end -- local preferences if specification and specification.prefix == no then return entry, false, "current spec blocks prefix" end -- stored preferences (not used) local prefixdata = entry.prefixdata if prefixdata and prefixdata.prefix == no then return entry, false, "entry blocks prefix" end -- final verdict return entry, sectiondata, "okay" end function helpers.prefix(data,prefixspec) if data then local _, prefixdata, status = helpers.analyse(data,prefixspec) if prefixdata then sections.typesetnumber(prefixdata,"prefix",prefixspec or false,data.prefixdata or false,prefixdata or false) end end end function pages.is_odd(n) n = n or texcount.realpageno if texcount.pagenoshift % 2 == 0 then return n % 2 == 0 else return n % 2 ~= 0 end end