Skip to content

Commit

Permalink
feat(packages): Allow indexes to be used anywhere in a document
Browse files Browse the repository at this point in the history
As for table of contents, use an intermediary file, so the index(es)
may be used (at the cost of a SILE re-run) anywhere, and not only
on its own page at the end of a document.
  • Loading branch information
Omikhleia authored and Didier Willis committed Jan 7, 2025
1 parent facf84c commit fed91fe
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions packages/indexer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,38 @@ local function _simplifyArabicInRange (p1, p2, format)
return p2
end

function package.buildIndex ()
local _indexer_used = false

function package.writeIndex (_) -- not a package method, called as a hook from the class
local idxdata = pl.pretty.write(SILE.scratch.index)
local idxfile, err = io.open(pl.path.splitext(SILE.input.filenames[1]) .. ".idx", "w")
if not idxfile then
return SU.error(err)
end
idxfile:write("return " .. idxdata)
idxfile:close()
if _indexer_used and not pl.tablex.deepcompare(SILE.scratch.index, SILE.scratch._index) then
SU.msg("Notice: the index has changed, please rerun SILE to update it.")
end
end

function package.readIndex (_) -- not a package method, called as a hook from the class
if SILE.scratch._index and #SILE.scratch._index > 0 then
-- already loaded
return SILE.scratch._index
end
local idxfile_name = (pl.path.splitext(SILE.input.filenames[1]) .. ".idx")
local idxfile, _ = io.open(idxfile_name)
if not idxfile then
return false -- No index yet
end
local doc = idxfile:read("*all")
local idx = assert(load(doc), idxfile_name, "r")()
SILE.scratch._index = idx
return SILE.scratch._index
end

function package.buildIndex () -- not a package method, called as a hook from the class
local nodes = SILE.scratch.info.thispage.index
local pageno = pl.tablex.copy(SILE.scratch.counters.folio)
if not nodes then
Expand Down Expand Up @@ -113,6 +144,7 @@ function package:_init (options)
self:loadPackage("infonode")
self:loadPackage("leaders")
self.class:registerHook("endpage", self.buildIndex)
self.class:registerHook("finish", self.writeIndex)
if not SILE.scratch.index then
SILE.scratch.index = {}
end
Expand Down Expand Up @@ -189,10 +221,21 @@ function package:registerCommands ()
end, "Add an entry to the index")

self:registerCommand("printindex", function (options, _)
_indexer_used = true
local idx = self:readIndex()
if idx == false then
SU.warn("The index is not available yet, rerun SILE to generate it")
return
end
if not options.index then
options.index = "main"
end
local index = SILE.scratch.index[options.index]
local index = idx[options.index]
if not index then
-- Either the index is not up-to-date (and we should rerun SILE), or it does not exist at all.
SU.warn("Index '" .. options.index .. "' does not exist, rerun SILE or check the index name")
return
end
local sortedIndex = {}
for n in pairs(index) do
table.insert(sortedIndex, n)
Expand Down

0 comments on commit fed91fe

Please sign in to comment.