diff options
Diffstat (limited to 'tex/context/base/strc-bkm.lua')
-rw-r--r-- | tex/context/base/strc-bkm.lua | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua new file mode 100644 index 000000000..f34d83ec5 --- /dev/null +++ b/tex/context/base/strc-bkm.lua @@ -0,0 +1,131 @@ +if not modules then modules = { } end modules ['strc-bkm'] = { + version = 0.200, + comment = "companion to strc-bkm.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- Future version will support adding arbitrary bookmarks with +-- associated complex actions (rather trivial to implement). + +local format, concat, gsub = string.format, table.concat, string.gsub +local texsprint, utfvalues = tex.sprint, string.utfvalues + +local ctxcatcodes = tex.ctxcatcodes + +local lists = structure.lists +local levelmap = structure.sections.levelmap + +structure.bookmarks = structure.bookmarks or { } + +local bookmarks = structure.bookmarks + +bookmarks.method = "internal" -- or "page" + +local names, opened = "", "" + +function bookmarks.register(n,o) + if names == "" then names = n else names = names .. "," .. n end + if opened == "" then opened = o else opened = opened .. "," .. o end +end + +function bookmarks.overload(name,text) + local l, ls = lists.tobesaved, nil + if #l == 0 then + -- no entries + elseif name == "" then + ls = l[#l] + else + for i=#l,0,-1 do + local li = l[i] + local metadata = li.metadata + if metadata and not metadata.nolist and metadata.name == name then + ls = li + break + end + end + end + if ls then + ls.titledata.bookmark = text + end +end + +local function stripped(str) -- kind of generic + str = gsub(str,"\\([A-Z]+)","%1") -- \LOGO + str = gsub(str,"\\ "," ") -- \ + str = gsub(str,"\\([A-Za-z]+) *{(.-)}","%1") -- \bla{...} + str = gsub(str," +"," ") -- spaces + return str +end + +-- todo: collect specs and collect later i.e. multiple places + +function bookmarks.place() + if names ~= "" then + local list = lists.filter(names,"all",nil,lists.collected) + local lastlevel = 1 + if #list > 0 then + local opened, levels = aux.settings_to_set(opened), { } + for i=1,#list do + local li = list[i] + local metadata = li.metadata + local name = metadata.name + if not metadata.nolist then -- and levelmap[name] then + local titledata = li.titledata + if titledata then + local structural = levelmap[name] + lastlevel = structural or lastlevel + local title = titledata.bookmark + if not title or title == "" then + if not structural then + -- placeholder, todo: bookmarklabel + title = name .. ": " .. (titledata.title or "?") + else + title = titledata.title or "?" + end + end + levels[#levels+1] = { + lastlevel, + stripped(title), + li.references, -- has internal and realpage + allopen or opened[name] + } + end + end + end + backends.codeinjections.addbookmarks(levels,bookmarks.method) + end + function bookmarks.place() end -- prevent second run + end +end + +lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) + +-- bkm +--~ function nodes.toutf(list) +--~ local t= { } +--~ for n in node.traverse(list) do +--~ local id = n.id +--~ if id == node.id("glyph") then +--~ local c = n.char +--~ local f = fonts.ids[n.font] +--~ if f then +--~ local u = f.characters[c].tounicode +--~ if u then +--~ for s in string.gmatch(u,"..") do +--~ t[#t+1] = utf.char(tonumber(s,16)) +--~ end +--~ else +--~ t[#t+1] = utf.char(c) +--~ end +--~ else +--~ t[#t+1] = utf.char(c) +--~ end +--~ elseif id == node.id("glue") then +--~ t[#t+1] = " " +--~ end +--~ end +--~ return table.concat(t,"") +--~ end +--~ print(nodes.toutf(tex.box[999].list)) |