summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-bkm.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/strc-bkm.lua')
-rw-r--r--tex/context/base/strc-bkm.lua124
1 files changed, 39 insertions, 85 deletions
diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua
index 1104157bd..8f8a3ca24 100644
--- a/tex/context/base/strc-bkm.lua
+++ b/tex/context/base/strc-bkm.lua
@@ -6,75 +6,22 @@ if not modules then modules = { } end modules ['strc-bkm'] = {
license = "see context related readme files"
}
--- todo: move some code to backend
+-- 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
-
--- todo: backend code
-
-local function pdfhexified(str)
- local t = { }
- t[#t+1] = "feff"
- for b in utfvalues(str) do
- if b < 0x10000 then
- t[#t+1] = format("%04x",b)
- else
- t[#t+1] = format("%04x%04x",b/1024+0xD800,b%1024+0xDC00)
- end
- end
- return concat(t)
-end
-
--- todo: lpeg cleaner
-
-local function pdfbookmark(level,n,text,page,open)
- text = gsub(text,"\\([A-Z]+)","%1") -- \LOGO
- text = gsub(text,"\\ "," ") -- \
- text = gsub(text,"\\([A-Za-z]+) *{(.-)}","%1") -- \bla{...}
- text = gsub(text," +"," ") -- spaces
- text = pdfhexified(text) -- somehow must happen here
- texsprint(ctxcatcodes,format("\\doinsertbookmark{%s}{%s}{%s}{%s}{%s}",level,n,text,page,open))
-end
-
--- end of todo
-
+local lists = structure.lists
local levelmap = structure.sections.levelmap
structure.bookmarks = structure.bookmarks or { }
local bookmarks = structure.bookmarks
-local function nofchildren(list,current,currentlevel)
- local i = current + 1
- local li = list[i]
- if li then
- local nextlevel = levelmap[li.metadata.name]
- if nextlevel and nextlevel > currentlevel then
- local n = 1
- i = i + 1
- li = list[i]
- while li do
- local somelevel = levelmap[li.metadata.name]
- if somelevel then
- if somelevel == nextlevel then
- n = n + 1
- elseif somelevel < nextlevel then
- break
- end
- end
- i = i + 1
- li = list[i]
- end
- return n
- end
- end
- return 0
-end
+bookmarks.method = "internal" -- or "page"
local names, opened = "", ""
@@ -83,34 +30,6 @@ function bookmarks.register(n,o)
if opened == "" then opened = o else opened = opened .. "," .. o end
end
-function bookmarks.place()
- if name ~= "" then
- local list = lists.filter(names,"all",nil,lists.collected)
- if #list > 0 then
- local allopen = (opened == interfaces.variables.all) and 1
- opened = aux.settings_to_set(opened)
- for i=1,#list do
- local li = list[i]
- local metadata = li.metadata
- if not metadata.nolist and levelmap[metadata.name] then
- local name, titledata = metadata.name, li.titledata
- if titledata then
- local level = levelmap[name]
- local children = nofchildren(list,i,level)
- local title = titledata.bookmark or titledata.title or "?"
- local realpage = li.references and li.references.realpage
- if realpage then
- local open = allopen or (opened[name] and 1)
- pdfbookmark(level,children,title,realpage,allopen or open or 0)
- end
- end
- end
- end
- bookmarks.place = function() end
- end
- end
-end
-
function bookmarks.overload(name,text)
local l, ls = lists.tobesaved, nil
if #l == 0 then
@@ -131,3 +50,38 @@ function bookmarks.overload(name,text)
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
+
+function bookmarks.place()
+ if names ~= "" then
+ local list = lists.filter(names,"all",nil,lists.collected)
+ 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 and levelmap[name] then
+ local titledata = li.titledata
+ if titledata then
+ levels[#levels+1] = {
+ levelmap[name],
+ stripped(titledata.bookmark or titledata.title or "?"),
+ 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