1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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))
|