summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-bkm.lua
blob: 5868ce42389ee0038c20b3f49f053fa917fb32eb (plain)
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
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

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

-- 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
--~ texio.write_nl(nodes.toutf(tex.box[999].list))