summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/lualatex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-12-03 22:49:28 +0000
committerKarl Berry <karl@freefriends.org>2018-12-03 22:49:28 +0000
commit510cc1b8395f714ec6c1b7299cf73371563b1a16 (patch)
treeef1d3f055e87db8e906501a88ca550b861ac22e2 /Master/texmf-dist/tex/lualatex
parentf855360800d3dd036378f102ca41cf5fa3e87db1 (diff)
xindex (2dec18)
git-svn-id: svn://tug.org/texlive/trunk@49312 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/lualatex')
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-DIN2.lua102
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-HAdW.lua231
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-base.lua222
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-cfg-common.lua29
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-cfg.lua89
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-dtk.lua157
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-lapp.lua325
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-lib.lua908
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex-pretty.lua254
-rw-r--r--Master/texmf-dist/tex/lualatex/xindex/xindex.sty76
10 files changed, 2393 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-DIN2.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-DIN2.lua
new file mode 100644
index 00000000000..58c33a5e2b8
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-DIN2.lua
@@ -0,0 +1,102 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-cfg.lua
+-- DESCRIPTION: configuration file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+if not modules then modules = { } end modules ['xindex-cfg'] = {
+ version = 0.05,
+ comment = "configuration to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+escape_chars = { -- by default " is the escape char
+ {'""', "\\escapedquote", "\"{}" },
+ {'"@', "\\escapedat", "@" },
+ {'"|', "\\escapedvert", "|" },
+ {'"!', "\\escapedexcl", "!" }
+}
+
+itemPageDelimiter = "," -- Hello, 14
+compressPages = true -- something like 12--15, instaead of 12,13,14,15. the |( ... |) syntax is still valid
+fCompress = true -- 3f -> page 3, 4 and 3ff -> page 3, 4, 5
+minCompress = 3 -- 14--17 or
+numericPage = true -- for non numerical pagenumbers, like "VI-17"
+sublabels = {"", "-\\,", "--\\,", "---\\,"} -- for the (sub(sub(sub-items first one is for item
+pageNoPrefixDel = "" -- a delimiter for page numbers like "VI-17"
+indexOpening = "" -- commands after \begin{theindex}
+
+
+--[[
+ Each character's position in this array-like table determines its 'priority'.
+ Several characters in the same slot have the same 'priority'.
+]]
+alphabet_lower = { -- for sorting
+ { ' ' }, -- only for internal tests
+ { 'a', 'á', 'à', 'å', 'æ', },
+ { 'ae', 'ä'},
+ { 'b' },
+ { 'c', 'ç' },
+ { 'd' },
+ { 'e', 'é', 'è', 'ë' },
+ { 'f' },
+ { 'g' },
+ { 'h' },
+ { 'i', 'í', 'ì', 'ï' },
+ { 'j' },
+ { 'k' },
+ { 'l' },
+ { 'm' },
+ { 'n', 'ñ' },
+ { 'o', 'ó', 'ò', 'ø', 'œ'},
+ { 'oe', 'ö' },
+ { 'p' },
+ { 'q' },
+ { 'r' },
+ { 's', 'š', 'ß' },
+ { 't' },
+ { 'u', 'ú', 'ù' },
+ { 'ue', 'ü' },
+ { 'v' },
+ { 'w' },
+ { 'x' },
+ { 'y', 'ý', 'ÿ' },
+ { 'z', 'ž' }
+}
+alphabet_upper = { -- for sorting
+ { ' ' },
+ { 'A', 'Á', 'À', 'Å', 'Æ'},
+ { 'AE', 'Ä'},
+ { 'B' },
+ { 'C', 'Ç' },
+ { 'D' },
+ { 'E', 'È', 'È', 'Ë' },
+ { 'F' },
+ { 'G' },
+ { 'H' },
+ { 'I', 'Í', 'Ì', 'Ï' },
+ { 'J' },
+ { 'K' },
+ { 'L' },
+ { 'M' },
+ { 'N', 'Ñ' },
+ { 'O', 'Ó', 'Ò', 'Ø','Œ' },
+ { 'OE', 'Ö' },
+ { 'P' },
+ { 'Q' },
+ { 'R' },
+ { 'S', 'Š' },
+ { 'T' },
+ { 'U', 'Ú', 'Ù' },
+ { 'UE', 'Ü' },
+ { 'V' },
+ { 'W' },
+ { 'X' },
+ { 'Y', 'Ý', 'Ÿ' },
+ { 'Z', 'Ž' }
+}
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-HAdW.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-HAdW.lua
new file mode 100644
index 00000000000..a45bd744332
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-HAdW.lua
@@ -0,0 +1,231 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-HAdW.lua
+-- DESCRIPTION: configuration file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+--
+-- configuration for index files of the Heidelberger Akademie der Wissenschaften
+
+if not modules then modules = { } end modules ['xindex-HAdW'] = {
+ version = 0.05,
+ comment = "configuration to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+--local version = "0.01"
+
+itemPageDelimiter = "," -- Hello, 14
+compressPages = true -- something like 12--15, instaead of 12,13,14,15. the |( ... |) syntax is still valid
+fCompress = true -- 3f -> page 3, 4 and 3ff -> page 3, 4, 5
+minCompress = 3 -- 14--17 or
+numericPage = false -- for non numerical pagenumbers, like "VI-17"
+sublabels = {"", "-\\,", "--\\,", "---\\,"} -- for the (sub(sub(sub-items first one is for item
+pageNoPrefixDel = "" -- a delimiter for page numbers like "VI-17"
+indexOpening = "" -- commands after \begin{theindex}
+
+
+
+--[[
+ Each character's position in this array-like table determines its 'priority'.
+ Several characters in the same slot have the same 'priority'.
+]]
+alphabet_lower = { -- for sorting
+ { ' ' }, -- only for internal tests
+ { 'a', 'á', 'à', 'ä'},
+ { 'b' },
+ { 'c' },
+ { 'd' },
+ { 'e', 'é', 'è', 'ë' },
+ { 'f' },
+ { 'g' },
+ { 'h' },
+ { 'i', 'í', 'ì', 'ï' },
+ { 'j' },
+ { 'k' },
+ { 'l' },
+ { 'm' },
+ { 'n', 'ñ' },
+ { 'o', 'ó', 'ò', 'ö' },
+ { 'p' },
+ { 'q' },
+ { 'r' },
+ { 's' },
+ { 't' },
+ { 'u', 'ú', 'ù', 'ü' },
+ { 'v' },
+ { 'w' },
+ { 'x' },
+ { 'y' },
+ { 'z' }
+}
+alphabet_upper = { -- for sorting
+ { ' ' },
+ { 'A', 'Á', 'À', 'Ä'},
+ { 'B' },
+ { 'C' },
+ { 'D' },
+ { 'E', 'È', 'È', 'ë' },
+ { 'F' },
+ { 'G' },
+ { 'H' },
+ { 'I', 'Í', 'Ì', 'ï' },
+ { 'J' },
+ { 'K' },
+ { 'L' },
+ { 'M' },
+ { 'N', 'Ñ' },
+ { 'O', 'Ó', 'Ò', 'Ö' },
+ { 'P' },
+ { 'Q' },
+ { 'R' },
+ { 'S' },
+ { 'T' },
+ { 'U', 'Ú', 'Ù', 'Ü' },
+ { 'V' },
+ { 'W' },
+ { 'X' },
+ { 'Y' },
+ { 'Z' }
+}
+
+
+--\indexentry{Ackers, Carolus}{VII/1-715}
+--\indexentry{Bremen!Adalbert I. von, Erzbischof}{VII/2/1-948}
+--\indexentry{Bremen!Adalbert I. von, Erzbischof}{VII/1-50}
+
+function specialCompressPageList(pages)
+ if (#pages <= 1) or (pages[1]["number"] == "") then
+ pages[1]["number"] = pages[1]["number"]:gsub('-',' ')
+ return pages
+ end -- only one pageno
+--[[
+modify pagelist
+sortPages = {{ origin = { number=VII/1-715, special="" },
+ sort = 07/1-00715 },
+ {...}
+ }
+]]
+ local sortPages = {}
+ local roman
+ local volume
+ local page
+ local i
+ for i=1,#pages do
+ roman = string.gsub(pages[i]["number"],'%U*','') -- only uppercase to catch VII123f (folium pages)
+ roman = string.format("%03d",tonumber(romanToNumber(roman)))
+ volume = string.gsub(pages[i]["number"],'%a*','')
+ if volume then volume = volume:gsub('-%d*','') end
+ page = string.gsub(pages[i]["number"],'.*-','')
+ page = string.format("%5s",page)
+--print(roman..volume.." "..page)
+ sortPages[#sortPages+1] = {
+ origin = pages[i],
+ sort = roman..volume.." "..page } -- no minus between Roman/Volume and first page
+ end
+-- sort the page list
+ table.sort(sortPages, function(a,b) return a["sort"] < b["sort"] end )
+ local Pages = {}
+ for i=1,#sortPages do -- use the sorted origin table
+ Pages[#Pages+1] = sortPages[i]["origin"]
+ end
+-- writeLog(1,print(getRawPagesP(Pages)),2)
+-- test if two or more pages in the list
+ if #Pages == 2 then -- only two pages
+ local page1 = string.gsub(Pages[1]["number"],'%A*','') -- get prefix1
+ local page2 = string.gsub(Pages[2]["number"],'%A*','') -- ger prefix2
+ if page1 == page2 then -- same prefix
+ page1 = string.gsub(Pages[1]["number"],'.*-','') -- get page1
+ page2 = string.gsub(Pages[2]["number"],'.*-','') -- get page2
+ if (page2-page1) == 1 then -- pagediff = 1
+ Pages[1]["number"] = Pages[1]["number"].."f"
+ Pages[2] = nil -- remove second page
+ return Pages
+ else -- page difference > 1
+ pages[1]["number"] = pages[1]["number"]:gsub('-',' ')
+ Pages[2]["number"] = string.gsub(Pages[2]["number"],'.*-','') -- use only number -> same prefix
+ return Pages -- Pages[1] is the same
+ end
+ else
+ pages[1]["number"] = pages[1]["number"]:gsub('-',' ')
+ pages[2]["number"] = pages[2]["number"]:gsub('-',' ')
+ return Pages -- different prefix -> simple return of the two pages
+ end
+ else -- more than two pages
+ local prefixList = {}
+ local lastPrefix = ""
+ local currentPrefix
+ for i=1,#Pages do -- create the list of different prefixes, eg {VI, VI/2/1, VI/2/2}
+ currentPrefix, j = string.gsub(Pages[i]["number"],'-.*','')
+ if currentPrefix ~= lastPrefix then
+ prefixList[#prefixList+1] = currentPrefix
+ lastPrefix = currentPrefix
+ end
+ end
+ pages = {}
+ for j = 1,#prefixList do
+ lastPrefix = prefixList[j]
+ i = 1
+ local subPageList = {}
+ while (i <= #Pages) do
+ currentPrefix, _ = string.gsub(Pages[i]["number"],'-.*','')
+ if (lastPrefix == currentPrefix) then
+ subPageList[#subPageList+1] = { number = string.gsub(Pages[i]["number"],'.*-',''), special = Pages[i]["special"] }
+ end
+ i = i +1
+ end
+ sortPages = compressPageList(subPageList)
+ -- no minus between Roman/Volume and first page
+ pages[#pages+1] = { number = lastPrefix.." "..sortPages[1]["number"], special = sortPages[1]["special"] }
+ for i=2,#sortPages do
+ pages[#pages+1] = sortPages[i]
+ end
+ end
+ return pages
+ end
+end
+
+function replaceRoman(r)
+ local i = romanToNumber(r)
+ if i then return "//"..string.format("%03d",i).."//"
+ else return r
+ end
+end
+
+function SORTprehook(data) -- replace roman with algebraic, eg Karl IX -> Karl // 9//
+-- writeLog(1,require 'xindex-pretty'.dump(data),0) -- only for internal dump
+ local entry
+ local elements = {}
+ for i=1,#data do
+ entry = data[i]["Entry"]
+ elements = entry:split()
+ local number = romanToNumber(elements[#elements])
+ if number then
+ local strNr = string.format("%03d",tostring(number))
+ elements[#elements] = "//"..strNr.."//"
+ entry = ""
+ for j=1,#elements do entry=entry.." "..elements[j] end
+ else
+ entry:gsub("!(.-)%p",replaceRoman)
+ end
+ data[i]["Entry"] = entry
+ end
+ return data
+end
+
+function SORTposthook(data) -- the other way round as prehook
+ local entry
+ local elements = {}
+ for i=1,#data do
+ entry = data[i]["Entry"]
+ if entry:find("//") then
+ data[i]["Entry"] = entry:gsub("//(.-)//",numberToRoman)
+ end
+ end
+ return data
+end
+
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-base.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-base.lua
new file mode 100644
index 00000000000..e8ba4a4b827
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-base.lua
@@ -0,0 +1,222 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-base.lua
+-- DESCRIPTION: base file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+local info = { version = 0.05}
+
+-- check config
+if pageNoPrefixDel ~= "" then
+-- numericPage = false
+ pageNoPrefixPattern = "^.*"..pageNoPrefixDel
+end
+
+writeLog(2,"Read Data from file "..inFile.." ... \n",0)
+local lines = read_lines_from(inFile)
+writeLog(2,#lines.." lines of data read\n",0)
+
+if vlevel > 1 then
+ writeLog(1,"--------------- Input data -----------------\n",2)
+ for _,l in pairs(lines) do writeLog(1,l.."\n",2) end
+ writeLog(1,"--------------- end Input data -----------------\n",2)
+end
+
+local Index = {} -- Entry = "Seitenzahl(en)"
+local pages = {}
+local noEntryfound
+local noPagefound
+
+hyperpage, lines = checkHyperpage(lines) -- hyperref used?
+if hyperpage then writeLog(1,"We have hyperpages ... \n",1) end
+
+--for _,l in pairs(lines) do print (l) end
+
+writeLog(1,"Change escape chars with macros ... \n",0)
+for k,v in pairs(lines) do
+ if not commandEntry(v) then
+ for i, str0 in ipairs(escape_chars) do
+ v = v:gsub(str0[1],str0[2])
+ end
+ if k < #lines then
+ if commandEntry(lines[k+1]) then -- is the next line not a \indexentry ?
+ Index = getEntryAndPage(v,lines[k+1],Index)-- read two lines
+ else
+ Index = getEntryAndPage(v,"",Index)-- current line
+ end
+ else
+ Index = getEntryAndPage(v,"",Index)-- current line
+ end
+ end
+end
+
+writeLog(1,"... done\n",0)
+writeLog(1,"------------------ Start list after getEntryAndPage() ------------------------\n,",2)
+printList(Index,2)
+writeLog(1,"\n------------------ end list after getEntryAndPage() ------------------------\n",2)
+writeLog(2,"Sorting entries: for LARGE idx files it can take some minutes ... \n",0)
+
+if SORTprehook then Index = SORTprehook(Index) end
+k = 0
+table.sort(Index,UTFCompare)
+if SORTposthook then Index = SORTposthook(Index) end
+
+writeLog(1,"------------------ Start list after table.sort(Index,UTFCompare)------------\n",2)
+printList(Index,2)
+writeLog(1,require 'xindex-pretty'.dump(Index),3) -- only for internal dump
+writeLog(1,"\n------------------ end list after table.sort(Index,UTFCompare)------------\n",2)
+
+writeLog(1,"\n",0)
+writeLog(2,"\ncheck for |(...|) \n",0)
+writeLog(1,"------------------ Start list before checkParenthesis(Index)------------\n",2)
+writeLog(1,require 'xindex-pretty'.dump(Index),3) -- only for internal dump
+--for i=1,#Index do print(Index[i]["Entry"],Index[i]["pages"][1]["number"],Index[i]["pages"][1]["special"]) end
+
+Index = checkParenthesis(Index)
+
+writeLog(1,"\n",0)
+
+--for i=1,#Index do print(Index[i]["Entry"],Index[i]["pages"][1]["number"],Index[i]["pages"][1]["special"]) end
+writeLog(1,require 'xindex-pretty'.dump(Index),3) -- only for internal dump
+printList(Index,2)
+writeLog(1,"------------------ End list after checkParenthesis(Index) ------------\n",2)
+writeLog(2,"done\n",0)
+
+
+
+writeLog(2,"Replace @-operator ...\n",0)
+writeLog(1,"------------------ Start list before compressEntryList(Index)------------\n",1)
+writeLog(1,require 'xindex-pretty'.dump(Index),3) -- only for internal dump
+
+local NewIndex = {}
+NewIndex = compressEntryList(Index) -- replaces also foo@bar -> bar
+
+-- for i=1,#NewIndex do print(NewIndex[i]["Entry"],NewIndex[i]["pages"][1]["number"],NewIndex[i]["pages"][1]["special"]) end
+writeLog(1,require 'xindex-pretty'.dump(NewIndex),3) -- only for internal dump
+printList(NewIndex,2)
+writeLog(1,"------------------ End list after compressEntryList(Index)------------\n",1)
+writeLog(2,"done\n",0)
+
+-- output the .ind-list
+--[[
+for i, str0 in ipairs(escape_chars) do
+ outFile:write("\\def"..str0[2].."{"..str0[3].."}\n")
+end
+]] -- no more needed, we redo the setting
+
+
+outFile:write("\n")
+outFile:write("\\begin{theindex}\n")
+
+if indexOpening ~= "" then -- commands after \begin{theindex}
+ outFile:write(indexOpening)
+end
+
+local entry
+local firstCLine = true
+local firstNLine = true
+local firstSLine = true
+local firstChar
+local symbols = true
+local numbers = false
+local letters = false
+local charType
+local currentChar
+local currentCharType = 0 -- assume Symbol; 1 number; 2 letter
+local oldChar = ""
+local excl = 0 -- number of ! symbols in one entry
+local lastItems = {"","",""}
+
+writeLog(2,"Start writing .ind file ... \n",0)
+
+-- first the special cases for symbols and numbers:
+
+writeLog(1,"---------- Start list to write the ind file --------------\n",1)
+writeLog(1,require 'xindex-pretty'.dump(NewIndex),3) -- only for internal dump
+for k=1,#NewIndex do
+-- require 'xindex-pretty'.dump(NewIndex[k]) -- only for internal dump
+ if NewIndex[k]["Entry"] then
+ local v = NewIndex[k]
+ writeLog(1," NewIndex[k]: "..v["Entry"].."\n",2)
+ writeLog(1,require 'xindex-pretty'.dump(v),3) -- only for internal dump
+ entry = v["Entry"]
+ writeLog(1,"\nBase start: "..entry.."\n",2)
+-- local c = utf.sub(v["sortChar"],1,1)
+-- if utf8.codepoint(c) < 12288 then -- Japanese starts at hex 3000
+-- firstChar = v["sortChar"]
+-- else
+ firstChar = utf.sub(v["sortChar"],1,1) -- catch a translatet Ö->OE
+-- end
+ currentChar = firstChar
+ charType = getCharType(firstChar)
+ if charType == 0 then
+ numbers = false
+ symbols = true
+ end
+ if charType == 1 then
+ numbers = true
+ symbols = false
+ end
+ if charType > 1 then
+ numbers = false
+ symbols = false
+ letters = true
+ end
+ if symbols then
+ writeLog(1,"We have symbols to print ...\n",3)
+ if firstSLine then
+ firstSLine = false
+ if not no_headings then
+ outFile:write("\\textbf{"..index_header[1].."}\n\\nopagebreak[4]\n")
+ end
+ end
+ if specialItemOutput then
+ lastItems = specialItemOutput(lastItems, v, hyperpage)
+ else
+ lastItems = itemOutput(lastItems, v, hyperpage)
+ end
+ else
+ writeLog(1,"We have no symbols to print ...\n",3)
+ end
+ if numbers then
+ writeLog(1,"We have numbers to print ...\n",3)
+ if firstNLine then
+ firstNLine = false
+ outFile:write("\n\\indexspace\n")
+ if not no_headings then
+ outFile:write("\\textbf{"..index_header[2].."}\n\\nopagebreak[4]\n")
+ end
+ end
+ if specialItemOutput then
+ lastItems = specialItemOutput(lastItems, v, hyperpage)
+ else
+ lastItems = itemOutput(lastItems, v, hyperpage)
+ end
+ else
+ writeLog(1,"We have no numbers to print ...\n",3)
+ end
+ if letters then
+ writeLog(1,"We have letters to print ...\n",3)
+ if (currentChar ~= oldChar) and (charType == 2) then
+ outFile:write("\n\\indexspace\n")
+ if not no_headings then
+ outFile:write("\\textbf{"..currentChar.."}\n\\nopagebreak[4]\n")
+ end
+ oldChar = currentChar
+ end
+ if specialItemOutput then
+ lastItems = specialItemOutput(lastItems, v, hyperpage)
+ else
+ lastItems = itemOutput(lastItems, v, hyperpage)
+ end
+ end
+ if v["Macro"] then outFile:write(v["Macro"].."\n") end
+ end
+end
+outFile:write("\\end{theindex}\n")
+outFile:close()
+
+writeLog(2,"\ndone! closing program\n",0)
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg-common.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg-common.lua
new file mode 100644
index 00000000000..8237dd5022e
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg-common.lua
@@ -0,0 +1,29 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-cfg-common.lua
+-- DESCRIPTION: configuration file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+if not modules then modules = { } end modules ['xindex-cfg-common'] = {
+ version = 0.05,
+ comment = "configuration to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+indexheader = {
+ de = {"Symbole", "Zahlen"},
+ en = {"Symbols", "Numbers"},
+ fr = {"Symboles","Chiffre"},
+ jp = {"シンボル","番号"},
+}
+
+folium = {
+ de = {"f", "ff"},
+ en = {"f", "ff"},
+ fr = {"\\,sq","\\,sqq"},
+}
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg.lua
new file mode 100644
index 00000000000..f4d726bd039
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-cfg.lua
@@ -0,0 +1,89 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-cfg.lua
+-- DESCRIPTION: configuration file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+if not modules then modules = { } end modules ['xindex-cfg'] = {
+ version = 0.05,
+ comment = "main configuration to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+itemPageDelimiter = "," -- Hello, 14
+compressPages = true -- something like 12--15, instaead of 12,13,14,15. the |( ... |) syntax is still valid
+fCompress = true -- 3f -> page 3, 4 and 3ff -> page 3, 4, 5
+minCompress = 3 -- 14--17 or
+numericPage = true -- for non numerical pagenumbers, like "VI-17"
+sublabels = {"", "-\\,", "--\\,", "---\\,"} -- for the (sub(sub(sub-items first one is for item
+pageNoPrefixDel = "" -- a delimiter for page numbers like "VI-17" -- not used !!!
+indexOpening = "" -- commands after \begin{theindex}
+
+
+--[[
+ Each character's position in this array-like table determines its 'priority'.
+ Several characters in the same slot have the same 'priority'.
+]]
+alphabet_lower = { -- for sorting
+ { ' ' }, -- only for internal tests
+ { 'a', 'á', 'à', 'ä', 'å', 'æ', },
+ { 'b' },
+ { 'c', 'ç' },
+ { 'd' },
+ { 'e', 'é', 'è', 'ë' },
+ { 'f' },
+ { 'g' },
+ { 'h' },
+ { 'i', 'í', 'ì', 'ï' },
+ { 'j' },
+ { 'k' },
+ { 'l' },
+ { 'm' },
+ { 'n', 'ñ' },
+ { 'o', 'ó', 'ò', 'ö', 'ø', 'œ'},
+ { 'p' },
+ { 'q' },
+ { 'r' },
+ { 's', 'š', 'ß' },
+ { 't' },
+ { 'u', 'ú', 'ù', 'ü' },
+ { 'v' },
+ { 'w' },
+ { 'x' },
+ { 'y', 'ý', 'ÿ' },
+ { 'z', 'ž' }
+}
+alphabet_upper = { -- for sorting
+ { ' ' },
+ { 'A', 'Á', 'À', 'Ä', 'Å', 'Æ'},
+ { 'B' },
+ { 'C', 'Ç' },
+ { 'D' },
+ { 'E', 'È', 'È', 'Ë' },
+ { 'F' },
+ { 'G' },
+ { 'H' },
+ { 'I', 'Í', 'Ì', 'Ï' },
+ { 'J' },
+ { 'K' },
+ { 'L' },
+ { 'M' },
+ { 'N', 'Ñ' },
+ { 'O', 'Ó', 'Ò', 'Ö', 'Ø','Œ' },
+ { 'P' },
+ { 'Q' },
+ { 'R' },
+ { 'S', 'Š' },
+ { 'T' },
+ { 'U', 'Ú', 'Ù', 'Ü' },
+ { 'V' },
+ { 'W' },
+ { 'X' },
+ { 'Y', 'Ý', 'Ÿ' },
+ { 'Z', 'Ž' }
+}
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-dtk.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-dtk.lua
new file mode 100644
index 00000000000..0104f37cece
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-dtk.lua
@@ -0,0 +1,157 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-cfg.lua
+-- DESCRIPTION: configuration file for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+if not modules then modules = { } end modules ['xindex-cfg'] = {
+ version = 0.05,
+ comment = "DTK configuration to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+itemPageDelimiter = "" -- Hello, 14
+compressPages = true -- something like 12--15, instaead of 12,13,14,15. the |( ... |) syntax is still valid
+fCompress = true -- 3f -> page 3, 4 and 3ff -> page 3, 4, 5
+minCompress = 3 -- 14--17 or
+numericPage = true -- for non numerical pagenumbers, like "VI-17"
+sublabels = {"","","",""} -- for the sub(sub(sub-items
+pageNoPrefixDel = "" -- a delimiter for page numbers like "VI-17" -- not used !!!
+indexOpening = "" --[[\providecommand*\lettergroupDefault[1]{}
+\providecommand*\lettergroup[1]{%
+ \par\textbf{#1}\par
+ \nopagebreak
+ }
+]]
+
+
+--[[
+ Each character's position in this array-like table determines its 'priority'.
+ Several characters in the same slot have the same 'priority'.
+]]
+alphabet_lower = { -- for sorting
+ { ' ' }, -- only for internal tests
+ { 'a', 'á', 'à', 'ä'},
+ { 'b' },
+ { 'c' },
+ { 'd' },
+ { 'e', 'é', 'è', 'ë' },
+ { 'f' },
+ { 'g' },
+ { 'h' },
+ { 'i', 'í', 'ì', 'ï' },
+ { 'j' },
+ { 'k' },
+ { 'l' },
+ { 'm' },
+ { 'n', 'ñ' },
+ { 'o', 'ó', 'ò', 'ö' },
+ { 'p' },
+ { 'q' },
+ { 'r' },
+ { 's' },
+ { 't' },
+ { 'u', 'ú', 'ù', 'ü' },
+ { 'v' },
+ { 'w' },
+ { 'x' },
+ { 'y' },
+ { 'z' }
+}
+alphabet_upper = { -- for sorting
+ { ' ' },
+ { 'A', 'Á', 'À', 'Ä'},
+ { 'B' },
+ { 'C' },
+ { 'D' },
+ { 'E', 'È', 'È', 'ë' },
+ { 'F' },
+ { 'G' },
+ { 'H' },
+ { 'I', 'Í', 'Ì', 'ï' },
+ { 'J' },
+ { 'K' },
+ { 'L' },
+ { 'M' },
+ { 'N', 'Ñ' },
+ { 'O', 'Ó', 'Ò', 'Ö' },
+ { 'P' },
+ { 'Q' },
+ { 'R' },
+ { 'S' },
+ { 'T' },
+ { 'U', 'Ú', 'Ù', 'Ü' },
+ { 'V' },
+ { 'W' },
+ { 'X' },
+ { 'Y' },
+ { 'Z' }
+}
+
+
+function specialGetPageList(v,hyperpage)
+ local Pages = {}
+ if v["pages"] then
+ table.sort(v["pages"],pageCompare)-- nur nötig, da User manuell eine Zeile einfügen kann
+ if specialCompressPageList then
+ Pages = specialCompressPageList(v["pages"])
+ else
+ Pages = compressPageList(v["pages"])
+ end
+ local pageNo
+ if hyperpage then
+ if string.find(v["pages"][1]["special"],"hyperindexformat") then
+ pageNo = v["pages"][1]["special"].."{"..checkFF(Pages[1]["number"].."}")
+ else
+ pageNo = "\\hyperpage{"..checkFF(Pages[1]["number"]).."}"
+ end
+ for i=2,#Pages do
+ if string.find(v["pages"][i]["special"],"hyperindexformat") then
+ pageNo = pageNo..", "..v["pages"][i]["special"].."{"..checkFF(Pages[i]["number"].."}")
+ else
+ pageNo = pageNo..", \\hyperpage{"..checkFF(Pages[i]["number"]).."}"
+ end
+-- Pages[i] = nil
+ end
+ else
+ if args_v then print("getPageList: "..tostring(Pages[1]["special"])..tostring(Pages[1]["number"])) end
+ if (Pages[1]["special"] == nil) or (Pages[1]["number"] == nil) then return "" end
+ if #Pages == 1 then
+ return "\\relax "..Pages[1]["number"].."\\@nil"
+ else
+ pageNo = "\\relax "..Pages[1]["number"]
+ for i=2,#Pages do
+ if Pages[i]["number"] then
+ pageNo = pageNo..", "..Pages[i]["number"]
+ Pages[i] = {}
+ end
+ end
+ pageNo = pageNo.."\\@nil" -- add \@nil
+ end
+ return pageNo
+ end
+ else
+ return ""
+ end
+end
+
+function specialItemOutput(last, v, hyperpage)
+ local lastItems = last
+ local currentItems = {}
+ local Entry = v["Entry"]
+ local name = getItem(Entry,0)
+ local adress = getItem(Entry,1)
+ outFile:write(" \\item "..name..itemPageDelimiter.."\n")
+ str = " \\subitem "..itemPageDelimiter.." "..adress..getPageList(v,hyperpage).."\n"
+ for i, str0 in ipairs(escape_chars) do -- undo the escape char setting
+ str = str:gsub(str0[2],str0[3])
+ end
+ outFile:write(str)
+ return last
+end
+
+
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-lapp.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-lapp.lua
new file mode 100644
index 00000000000..d0e01e634e6
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-lapp.lua
@@ -0,0 +1,325 @@
+-- lapp.lua
+-- Simple command-line parsing using human-readable specification
+-----------------------------
+--~ -- args.lua
+--~ local args = require ('lapp') [[
+--~ Testing parameter handling
+--~ -p Plain flag (defaults to false)
+--~ -q,--quiet Plain flag with GNU-style optional long name
+--~ -o (string) Required string option
+--~ -n (number) Required number option
+--~ -s (default 1.0) Option that takes a number, but will default
+--~ <start> (number) Required number argument
+--~ <input> (default stdin) A parameter which is an input file
+--~ <output> (default stdout) One that is an output file
+--~ ]]
+--~ for k,v in pairs(args) do
+--~ print(k,v)
+--~ end
+-------------------------------
+--~ > args -pq -o help -n 2 2.3
+--~ input file (781C1B78)
+--~ p true
+--~ s 1
+--~ output file (781C1B98)
+--~ quiet true
+--~ start 2.3
+--~ o help
+--~ n 2
+--------------------------------
+if not modules then modules = { } end modules ['xindex-lapp'] = {
+ version = 0.05,
+ comment = "read parameter for xindex.lua",
+ author = "Steve Donovan",
+ copyright = "Steve Donovan",
+ license = "MIT"
+}
+
+
+lapp = {}
+
+local append = table.insert
+local usage
+local open_files = {}
+local parms = {}
+local aliases = {}
+local parmlist = {}
+
+local filetypes = {
+ stdin = {io.stdin,'file-in'}, stdout = {io.stdout,'file-out'},
+ stderr = {io.stderr,'file-out'}
+}
+
+local function quit(msg,no_usage)
+ if msg then
+ io.stderr:write(msg..'\n\n')
+ end
+ if not no_usage then
+ io.stderr:write(usage)
+ end
+ os.exit(1);
+end
+
+local function error(msg,no_usage)
+ quit(arg[0]:gsub('.+[\\/]','')..':'..msg,no_usage)
+end
+
+local function ltrim(line)
+ return line:gsub('^%s*','')
+end
+
+local function rtrim(line)
+ return line:gsub('%s*$','')
+end
+
+local function trim(s)
+ return ltrim(rtrim(s))
+end
+
+local function open (file,opt)
+ local val,err = io.open(file,opt)
+ if not val then error(err,true) end
+ append(open_files,val)
+ return val
+end
+
+local function xassert(condn,msg)
+ if not condn then
+ error(msg)
+ end
+end
+
+local function range_check(x,min,max,parm)
+ xassert(min <= x and max >= x,parm..' out of range')
+end
+
+local function xtonumber(s)
+ local val = tonumber(s)
+ if not val then error("unable to convert to number: "..s) end
+ return val
+end
+
+local function is_filetype(type)
+ return type == 'file-in' or type == 'file-out'
+end
+
+local types = {}
+
+local function convert_parameter(ps,val)
+ if ps.converter then
+ val = ps.converter(val)
+ end
+ if ps.type == 'number' then
+ val = xtonumber(val)
+ elseif is_filetype(ps.type) then
+ val = open(val,(ps.type == 'file-in' and 'r') or 'w' )
+ elseif ps.type == 'boolean' then
+ val = true
+ end
+ if ps.constraint then
+ ps.constraint(val)
+ end
+ return val
+end
+
+function lapp.add_type (name,converter,constraint)
+ types[name] = {converter=converter,constraint=constraint}
+end
+
+local function force_short(short)
+ xassert(#short==1,short..": short parameters should be one character")
+end
+
+function process_options_string(str)
+ local res = {}
+ local varargs
+
+ local function check_varargs(s)
+ local res,cnt = s:gsub('%.%.%.$','')
+ varargs = cnt > 0
+ return res
+ end
+
+ local function set_result(ps,parm,val)
+ if not ps.varargs then
+ res[parm] = val
+ else
+ if not res[parm] then
+ res[parm] = { val }
+ else
+ append(res[parm],val)
+ end
+ end
+ end
+
+ usage = str
+
+ for line in str:gmatch('([^\n]*)\n') do
+ local optspec,optparm,i1,i2,defval,vtype,constraint
+ line = ltrim(line)
+ -- flags: either -<short> or -<short>,<long>
+ i1,i2,optspec = line:find('^%-(%S+)')
+ if i1 then
+ optspec = check_varargs(optspec)
+ local short,long = optspec:match('([^,]+),(.+)')
+ if short then
+ optparm = long:sub(3)
+ aliases[short] = optparm
+ force_short(short)
+ else
+ optparm = optspec
+ force_short(optparm)
+ end
+ else -- is it <parameter_name>?
+ i1,i2,optparm = line:find('(%b<>)')
+ if i1 then
+ -- so <input file...> becomes input_file ...
+ optparm = check_varargs(optparm:sub(2,-2)):gsub('%A','_')
+ append(parmlist,optparm)
+ end
+ end
+ if i1 then -- this is not a pure doc line
+ local last_i2 = i2
+ local sval
+ line = ltrim(line:sub(i2+1))
+ -- do we have (default <val>) or (<type>)?
+ i1,i2,typespec = line:find('^%s*(%b())')
+ if i1 then
+ typespec = trim(typespec:sub(2,-2)) -- trim the parens and any space
+ sval = typespec:match('default%s+(.+)')
+ if sval then
+ local val = tonumber(sval)
+ if val then -- we have a number!
+ defval = val
+ vtype = 'number'
+ elseif filetypes[sval] then
+ local ft = filetypes[sval]
+ defval = ft[1]
+ vtype = ft[2]
+ else
+ defval = sval
+ vtype = 'string'
+ end
+ else
+ local min,max = typespec:match '([^%.]+)%.%.(.+)'
+ if min then -- it's (min..max)
+ vtype = 'number'
+ min = xtonumber(min)
+ max = xtonumber(max)
+ constraint = function(x)
+ range_check(x,min,max,optparm)
+ end
+ else -- () just contains type of required parameter
+ vtype = typespec
+ end
+ end
+ else -- must be a plain flag, no extra parameter required
+ defval = false
+ vtype = 'boolean'
+ end
+ local ps = {
+ type = vtype,
+ defval = defval,
+ required = defval == nil,
+ comment = line:sub((i2 or last_i2)+1) or optparm,
+ constraint = constraint,
+ varargs = varargs
+ }
+ if types[vtype] then
+ local converter = types[vtype].converter
+ if type(converter) == 'string' then
+ ps.type = converter
+ else
+ ps.converter = converter
+ end
+ ps.constraint = types[vtype].constraint
+ end
+ parms[optparm] = ps
+ end
+ end
+ -- cool, we have our parms, let's parse the command line args
+ local iparm = 1
+ local iextra = 1
+ local i = 1
+ local parm,ps,val
+ while i <= #arg do
+ -- look for a flag, -<short flags> or --<long flag>
+ local i1,i2,dash,parmstr = arg[i]:find('^(%-+)(%a.*)')
+ if i1 then -- we have a flag
+ if #dash == 2 then -- long option
+ parm = parmstr
+ else -- short option
+ if #parmstr == 1 then
+ parm = parmstr
+ else -- multiple flags after a '-',?
+ parm = parmstr:sub(1,1)
+ if parmstr:find('^%a%d+') then
+ -- a short option followed by a digit? (exception for AW ;))
+ -- push ahead into the arg array
+ table.insert(arg,i+1,parmstr:sub(2))
+ else
+ -- push multiple flags into the arg array!
+ for k = 2,#parmstr do
+ table.insert(arg,i+k-1,'-'..parmstr:sub(k,k))
+ end
+ end
+ end
+ end
+ if parm == 'h' or parm == 'help' then
+ quit()
+ end
+ if aliases[parm] then parm = aliases[parm] end
+ ps = parms[parm]
+ if not ps then error("unrecognized parameter: "..parm) end
+ if ps.type ~= 'boolean' then -- we need a value! This should follow
+ val = arg[i+1]
+ i = i + 1
+ xassert(val,parm.." was expecting a value")
+ end
+ else -- a parameter
+ parm = parmlist[iparm]
+ if not parm then
+ -- extra unnamed parameters are indexed starting at 1
+ parm = iextra
+ iextra = iextra + 1
+ ps = { type = 'string' }
+ else
+ ps = parms[parm]
+ end
+ if not ps.varargs then
+ iparm = iparm + 1
+ end
+ val = arg[i]
+ end
+ ps.used = true
+ val = convert_parameter(ps,val)
+ set_result(ps,parm,val)
+ if is_filetype(ps.type) then
+ set_result(ps,parm..'_name',arg[i])
+ end
+ if lapp.callback then
+ lapp.callback(parm,arg[i],res)
+ end
+ i = i + 1
+ end
+ -- check unused parms, set defaults and check if any required parameters were missed
+ for parm,ps in pairs(parms) do
+ if not ps.used then
+ if ps.required then error("missing required parameter: "..parm) end
+ set_result(ps,parm,ps.defval)
+ end
+ end
+ return res
+end
+
+setmetatable(lapp, {
+ __call = function(tbl,str) return process_options_string(str) end,
+ __index = {
+ open = open,
+ quit = quit,
+ error = error,
+ assert = xassert,
+ }
+})
+
+return lapp
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-lib.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-lib.lua
new file mode 100644
index 00000000000..f570771776d
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-lib.lua
@@ -0,0 +1,908 @@
+-----------------------------------------------------------------------
+-- FILE: xindex-lib.lua
+-- DESCRIPTION: library for xindex.lua
+-- REQUIREMENTS:
+-- AUTHOR: Herbert Voß
+-- LICENSE: LPPL1.3
+-----------------------------------------------------------------------
+
+if not modules then modules = { } end modules ['xindex-lib'] = {
+ version = 0.05,
+ comment = "main library to xindex.lua",
+ author = "Herbert Voss",
+ copyright = "Herbert Voss",
+ license = "LPPL 1.3"
+}
+
+local escapechar1 = "\""
+local escapechar2 = "\"\""
+local Letters = "ÄÖÜäöüabcdefghijklmnopqrstuvwxyzßABCDEFGHIJKLMNOPQRSTUVWXYZ"
+local Digits = "0123456789"
+
+-- Looks up the character `character´ in the alphabet and returns its 'normalization' for sorting
+local function get_normalized_char( CharList, character )
+ for i, alphabet_entry in ipairs(CharList) do
+ for _, alphabet_char in ipairs(alphabet_entry) do
+ if character == alphabet_char then
+ return alphabet_entry[1]
+ end
+ end
+ end
+ return character
+end
+
+function Lower(strOrig) -- return UTF string.lower
+ local str = ""
+ for i=1, utf.len(strOrig) do
+ local c = utf.sub(strOrig,i,i)
+ if c == "Ä" then str = str.."ä"
+ elseif c == "Ö" then str = str.."ö"
+ elseif c == "Ü" then str = str.."ü"
+ else str = str..utf.lower(c)
+ end
+ end
+ return str
+end
+
+function NormalizedLower(strOrig) -- return normalized UTF string.lower (ä -> a)
+ local str = ""
+ for i=1, utf.len(strOrig) do
+ local c = get_normalized_char(alphabet_lower,utf.sub(strOrig,i,i))
+ str = str..string.lower(c)
+ end
+ return str
+end
+
+function NormalizedUpper(strOrig) -- return normalized UTF string.upper (ä -> A)
+ local str = ""
+ for i=1, utf.len(strOrig) do
+ local c = get_normalized_char(alphabet_lower,utf.sub(strOrig,i,i))
+ str = str..string.upper(c)
+ end
+ strOrig = str
+ str = ""
+ for i=1, utf.len(strOrig) do
+ local c = get_normalized_char(alphabet_upper,utf.sub(strOrig,i,i))
+ str = str..string.upper(c)
+ end
+ return str
+end
+
+function checkVert(str) -- get the | part
+ local vert = string.find(str,"|",1,true)
+ if (vert) then
+ vertStr = string.sub(str,vert+1)
+ str = string.sub(str,1,vert-1)
+ return (vertStr)
+ else
+ return ("")
+ end
+end
+
+function checkEntry(str) -- get the index entry name
+ local at=string.find(str,"@")
+ local excl=string.find(str,"!")
+ if (excl and at) then
+ if (at < excl) then
+ return string.sub(str,1,at-1)
+ else
+ return string.sub(str,1,excl-1)
+ end
+ elseif (excl) then
+ return string.sub(str,1,excl-1)
+ elseif (at) then
+ return string.sub(str,1,at-1)
+ else
+ return (str)
+ end
+end
+
+function replaceAt(str) -- return "bar" from "foo@bar"
+-- return str:gsub('[^!|@%s]+@', '')
+ return str:gsub('[^!|@]+@', '')
+end
+
+function dofile(filename)
+ local file = kpse.find_file(filename)
+ local f = assert(loadfile(file))
+ return f()
+end
+
+-- see if the file exists
+function file_exists(file)
+local f = io.open(file, "rb")
+if f then f:close() end
+return f ~= nil
+end
+
+-- get all lines from a file, returns an empty
+-- list/table if the file does not exist
+function read_lines_from(infile)
+ if not file_exists(infile) then return {} end
+ local lines = {}
+ local str
+ local c
+ for line in io.lines(infile) do
+ if line ~= "" then
+ if string.find(line,'\\indexentry',1,true) then
+ str = line:gsub('^\\%a+%s*{','{') -- remove "\\indexentry "
+ writeLog(1,"read_lines: str="..str.." ("..utf.sub(str,2,2)..")\n",2)
+ if getCharType(utf.sub(str,2,2)) == 0 then -- we have a symbol
+ lines[#lines + 1] = str:gsub('^{*','{ ') -- add a space before the symbol
+ else
+ lines[#lines + 1] = str
+ end
+ else
+ lines[#lines + 1] = "\\MACRO<<< "..line -- allow macros between entries
+ end
+ end
+ end
+ return lines
+end
+
+function array_concat(...)
+ local t = {}
+ for n = 1,select("#",...) do
+ local arg = select(n,...)
+ if type(arg)=="table" then
+ for _,v in ipairs(arg) do
+ t[#t+1] = v
+ end
+ else
+ t[#t+1] = arg
+ end
+ end
+ return t
+end
+
+function findSequences(a) -- look for 1,2,3,4, ...
+ local b = {}
+ local firstPage = a[1] -- first page in the sequence
+ for i=2,#a do -- next page until end of page list
+ if a[i]-a[i-1] > 1 then -- not next page
+ lastPage = a[i-1] -- new start for a sequence search
+ if lastPage - firstPage >= minCompress then -- sequence found
+ b[#b+1]= tostring(firstPage).."--"..tostring(lastPage)
+ else
+ b[#b+1]= firstPage
+ if (firstPage ~= lastPage) then b[#b+1]= lastPage end
+ end
+ firstPage=a[i]
+ end
+ end
+ if a[#a] - firstPage > 2 then -- test file end
+ b[#b+1]= tostring(firstPage).."--"..tostring(a[#a])
+ else
+ b[#b+1]= firstPage
+ if (firstPage ~= a[#a]) then b[#b+1]= a[#a] end
+ end
+ return (b)
+end
+
+
+function deleteOpenClose(v) -- remove |( and/or |)
+ res, _ = string.gsub(v:gsub('\\[()]%s*$', ''), '\\[()]%s*', ' \\')
+ return res
+end
+
+-- "\) " -> ""
+-- "\)foo" -> \foo
+
+function checkParenthesis(Entries) -- search for |( ... |) entries
+ local paraOpen
+ local paraClose
+ local firstPage = 0
+ local lastPage
+ local newEntries = {}
+ for k,v in pairs(Entries) do
+ if (k % 50) == 0 then writeLog(1,".",1) end
+ if v["Entry"] then
+ v["Entry"] = replaceAt(v["Entry"]) -- foo@bar!baz@foobar -> bar!foobar
+ CurrentEntry = v["Entry"]
+ paraOpen = v["pages"][1]["special"]:find("\\(",1,true)
+ paraClose = v["pages"][1]["special"]:find("\\)",1,true)
+ if paraOpen then
+ firstPage = v["pages"][1]["number"]
+ elseif paraClose then
+ lastPage = v["pages"][1]["number"]
+ newEntries[#newEntries+1] = { Entry = v["Entry"],
+ pages = {{ number = firstPage.."--"..lastPage,
+ special = deleteOpenClose(v["pages"][1]["special"])}},
+ sortChar= v["sortChar"],
+ Macro = v["Macro"]
+ }
+ firstPage = 0
+ elseif ((firstPage == 0) and not paraClose) then
+ newEntries[#newEntries+1] = v -- same Entry with greater page or new entry
+ end
+ end
+ end
+ return newEntries
+end
+
+function replaceVerticalChar(v)
+-- res, _ = string.gsub(v:gsub('|[()]$', ''), '|[()]?', ' \\')
+-- return res
+ if not v:match('|') then
+ return v,""
+ else
+ return v:gsub('|.*',''), v:match('|.*'):gsub('|','\\'):gsub("%s+", "") -- part before, part after | without spaces
+ end
+end
+
+function getEntryAndPage(w, nextW, EntryList)
+-- \indexentry{Aachen, Johann von}{VII/1-215}
+-- \indexentry {Document@\idxtextClasses !IEEEtran@{\sfffffamily IEEEtran}}{185}
+-- if indexEntry(w) then
+ local macro = nil
+ if string.find(nextW,"\\MACRO<<< ") then
+ macro = string.gsub(nextW,'\\MACRO<<<','')
+ end
+ local entry, pageNo = w:match('{(.*)}%s*{(.*)}')
+-- if numericPage then
+-- if tonumber(pageNo) then -- check for roman numbering
+-- pageNo = tonumber(pageNo)
+-- end
+-- end
+ local IndexString, Special = replaceVerticalChar(entry)
+ EntryList[#EntryList+1] = {
+ Entry = IndexString, -- the index item foo@bar
+ pages = {{
+ number = pageNo,
+ special = Special }}, -- the page number(s) and the part after |
+ sortChar= NormalizedUpper(utf.sub(IndexString,1,1)), -- :byte(), -- Initial for later output
+ Macro = macro
+ }
+ if args_v then
+ if Special == "" then Special = "-" end
+ writeLog(1,"getEntryAndPage: "..tostring(IndexString,pageNo,Special,utf.sub(IndexString,1,1),macro).."\n",2)
+ end
+ return EntryList
+end
+
+function compressEntryList(EntryList)
+-- require 'xindex-pretty'.dump(EntryList) -- only for internal dump
+ local newList = {}
+ newList[1] = EntryList[1] -- at least one entry
+ local nPages = 1
+ for k=2,#EntryList do
+ if EntryList[k] then -- exists?
+ local vEntry = EntryList[k]["Entry"]
+ local last = EntryList[k-1] -- complete data
+ if (getSortString(last["Entry"]) == getSortString(vEntry)) then -- Entry exists -> add page
+-- require 'xindex-pretty'.dump(EntryList) -- only for internal dump
+-- require 'xindex-pretty'.dump(newList) -- only for internal dump
+ if (newList[#newList]["pages"][nPages]["number"] ~= EntryList[k]["pages"][1]["number"]) -- different pages or special?
+ or (newList[#newList]["pages"][nPages]["special"] ~= EntryList[k]["pages"][1]["special"]) then
+ newList[#newList]["pages"][nPages+1] = EntryList[k]["pages"][1]
+ nPages = nPages + 1
+-- require 'xindex-pretty'.dump(newList) -- only for internal dump
+ else
+ -- gleiche Entries, gleiche Seiten, gleiche specials -> nichts tun
+ end
+ else -- not the same entry
+-- require 'xindex-pretty'.dump(newList) -- only for internal dump
+ newList[#newList]["pages"] = deletePageDups(newList[#newList]["pages"])
+ newList[#newList+1] = EntryList[k]
+ nPages = 1
+ end
+ end
+ end
+ -- last data line
+ newList[#newList]["pages"] = deletePageDups(newList[#newList]["pages"])
+-- require 'xindex-pretty'.dump(newList) -- only for internal dump
+ return newList
+end
+
+--[[ example entry
+EntryList[2] = {
+ Entry = "Johann", -- the index item foo@bar
+ pages = { -- the page number(s) and the part after |
+ { number = 111,
+ special = '\\emph' },
+ { number = 11,
+ special = "\\textit"}
+ },
+ sortChar= "", -- Initial for later output
+ Macro = ""
+}
+]]
+
+
+function deletePageDups(pages)
+ if #pages == 1 then return pages end
+ local newPages = {pages[1]}
+ local notfound
+ for i=2,#pages do
+ notfound = true
+ for j=1,#newPages do
+ if (pages[i]["number"] == newPages[j]["number"]) and (pages[i]["special"] == newPages[j]["special"]) then
+ notfound = false
+ break
+ end
+ end
+ if notfound then
+ newPages[#newPages+1] = pages[i]
+ end
+ end
+ return newPages
+end
+
+
+function compressPageList(pages) -- called with (v["pages"])
+ writeLog(1,"compressPageList: we have "..#pages.." pages for this entry",2)
+-- require 'xindex-pretty'.dump(pages) -- only for internal dump
+ pages = deletePageDups(pages) -- delete duplicate page numners with same special
+ local str
+ if #pages == 1 then -- only one pageno
+ return pages
+ end -- only one pageno
+ if #pages == 2 then -- only two pages
+ if tonumber(pages[1]["number"]) and tonumber(pages[2]["number"]) then
+ if ((tonumber(pages[2]["number"]) - tonumber(pages[1]["number"])) == 1) and
+ (pages[1]["special"] == pages[2]["special"]) then
+ pages[1]["number"] = pages[1]["number"].."f"
+ pages[2] = nil
+-- elseif (pages[1]["number"] == pages[2]["number"]) and
+-- (pages[1]["special"] == pages[2]["special"]) then
+-- pages[2] = nil
+ end
+ end
+ return pages
+ end
+ -- we have at least three pages
+ pages[#pages+1] = {number = 9999999, special = ""} -- dummy to sort the last real page number correct
+ local startIndex
+ local newPages = {} -- { pages[1], pages[2], ... }
+ local series = {} -- { pages[1], pages[2], ... }
+ if tonumber(pages[1]["number"]) then -- if a number we start with seconf page
+ newPages = {}
+ series = {pages[1]}
+ startIndex = 2
+ else -- if not a number we start with third page
+ newPages = {pages[1]}
+ series = {pages[2]}
+ startIndex = 3
+ end
+if args_v then print ("compressPageList: more than two pages for the entry") end
+ for i=startIndex,#pages do
+ if tonumber(pages[i-1]["number"]) and tonumber(pages[i]["number"]) then -- de we have something like 17--31 in the current list
+ if ((tonumber(pages[i]["number"])-tonumber(pages[i-1]["number"])) == 1) and
+ (pages[i]["special"] == pages[i-1]["special"]) then -- something like 12, 13 with identical |\special
+ series[#series+1] = pages[i]-- page difference is 1, add page to series
+ elseif (#series == 1) then -- no -f page -> only one page -> output
+ newPages[#newPages+1] = series[1]
+ series = {pages[i]}
+ elseif (#series > minCompress) then -- we found series od f pages like 11, 12, 13, 14
+ -- the sequenz gets the special from the first page
+ newPages[#newPages+1] = { number = series[1]["number"].."--"..series[#series]["number"], special = series[1]["special"]} -- first..last
+ series = {pages[i]}
+ else -- series < minCompress
+ if fCompress then
+ if #series == 2 then -- two pages -> 3f
+ writeLog(1,"compressPageList: Two consecutive pages for this entry",2)
+ if series[1]["special"] == series[2]["special"] then
+ newPages[#newPages+1] = { number = series[1]["number"]..page_folium[1], special = series[1]["special"] }
+ else
+ newPages[#newPages+1] = series[1] -- different |\special -> no compress to -f
+ newPages[#newPages+1] = series[2]
+ end
+ else -- must be #series=3
+ if (series[1]["special"] == series[2]["special"]) and (series[2]["special"] == series[3]["special"]) then
+ newPages[#newPages+1] = { number = series[1]["number"]..page_folium[2], special = series[1]["special"] } -- three pages
+ elseif (series[1]["special"] == series[2]["special"]) then
+ newPages[#newPages+1] = { number = series[1]["number"]..page_folium[1], special = series[1]["special"] } -- three pages
+ newPages[#newPages+1] = series[3]
+ elseif (series[2]["special"] == series[3]["special"]) then
+ newPages[#newPages+1] = series[1]
+ newPages[#newPages+1] = { number = series[2]["number"]..page_folium[1], special = series[2]["special"] } -- three pages
+ else -- all different specials
+ newPages[#newPages+1] = series[1]
+ newPages[#newPages+1] = series[2]
+ newPages[#newPages+1] = series[3]
+ end
+ end
+ else
+ for i=1,#series do
+ newPages[#newPages+1] = series[i]
+ end
+ end
+ series = {pages[i]}
+ end
+ else -- current or forgoing page is not a number, we simply add it
+ if tonumber(pages[i]["number"]) then -- p[i-1] is non numeric p[i] is ok and not last no
+ series = {pages[i]}
+ else -- current page is non numeric
+ if (#series > minCompress) then -- we found a page series
+ newPages[#newPages+1] = { number = series[1]["number"].."--"..series[#series]["number"], -- first..last
+ special =series[1]["special"] }
+ series = {pages[i]}
+ else -- series < minCompress
+ for i=1,#series do
+ newPages[#newPages+1] = series[i]
+ end
+ series = {pages[i]}
+ end
+ end
+ end
+ end
+-- require 'xindex-pretty'.dump(newPages)
+ return newPages
+end
+
+
+-- 2 letter
+-- 1 digit
+-- 0 symbol
+
+UTFdatafile = kpse.find_file("unicode-category.lua")
+local category_data = dofile(UTFdatafile)
+local floor = math.floor
+
+local function binary_range_search(code_point, ranges)
+ local low, mid, high
+ low, high = 1, #ranges
+ while low <= high do
+ mid = floor((low + high) / 2)
+ local range = ranges[mid]
+ if code_point < range[1] then
+ high = mid - 1
+ elseif code_point <= range[2] then
+ return range, mid
+ else
+ low = mid + 1
+ end
+ end
+ return nil, mid
+end
+
+function get_category(code_point)
+ if category_data.singles[code_point] then
+ return category_data.singles[code_point]
+ else
+ local range = binary_range_search(code_point, category_data.ranges)
+ return range and range[3] or "Cn"
+ end
+end
+
+function getCharType(c)
+-- print ("getCharType c="..c..": codepoint="..utf8.codepoint(c))
+ local category = get_category(utf8.codepoint(c))
+-- print ("getCharType: "..category)
+ if category == "Nd" then return 1
+ elseif category:sub(1, 1) == "L" then return 2
+ else return 0
+ end
+end
+
+--print(get_category(utf8.codepoint('ö')))
+--print(category_to_number(get_category(utf8.codepoint('ö'))))
+
+function getCharTypeOld(c) -- in case of Lua < 5.3 (has no utf support)
+ if utf.find(Letters,c,1,true) then return 2
+ elseif utf.find(Digits,c,1,true) then return 1
+ else return 0
+ end
+end
+
+-- string.gsub('{Entry}{page}', '{[^{}]*}$', '') -> {Entry}
+-- str = "\indexentry {foo}{bar}"
+-- first, second = str:match('{([^}]*)}%s*{([^}]*)}') -> foo, bar
+
+function UTFCompare(a,b)
+-- a, b are something like \indexentry{foo}{bar}
+ writeLog(1,"UTFCompare: "..a["Entry"]..", "..a["pages"][1]["number"].." - "..b["Entry"]..", "..b["pages"][1]["number"],2)
+ k = k + 1
+ if (k % 50) == 0 then writeLog(1,".",1) end
+ local A,B,Apage,Bpage
+ if numericPage then
+ if tonumber(a["pages"][1]["number"]) then
+ Apage = string.format("%09d",a["pages"][1]["number"])
+ else
+ Apage = string.format("%09d",romanToNumber(a["pages"][1]["number"]))
+ end
+ if tonumber(b["pages"][1]["number"]) then
+ Bpage = string.format("%09d",b["pages"][1]["number"])
+ else
+ Bpage = string.format("%09d",romanToNumber(b["pages"][1]["number"]))
+ end
+ else
+ Apage = string.format("%09s",a["pages"][1]["number"])
+ Bpage = string.format("%09s",b["pages"][1]["number"])
+ end
+ A = NormalizedUpper(getSortString(a["Entry"].." "..Apage..a["pages"][1]["special"]):gsub('!',' '))
+ B = NormalizedUpper(getSortString(b["Entry"].." "..Bpage..b["pages"][1]["special"]):gsub('!',' '))
+-- print(A,B)
+--[[
+ if A == B then -- same entry, use also page number
+ Apage = string.format("%09s",a["pages"][1]["number"])
+ Bpage = string.format("%09s",b["pages"][1]["number"])
+ A = string.format("%-90s",A)..Apage
+ B = string.format("%-90s",B)..Bpage
+ end
+ if numericPage then
+ if tonumber(a["pages"][1]["number"]) then
+ Apage = string.format("%09d",a["pages"][1]["number"])
+ else
+ Apage = string.format("%09d",romanToNumber(a["pages"][1]["number"]))
+ end
+ if tonumber(b["pages"][1]["number"]) then
+ Bpage = string.format("%09d",b["pages"][1]["number"])
+ else
+ Bpage = string.format("%09d",romanToNumber(b["pages"][1]["number"]))
+ end
+ else
+ Apage = string.format("%09s",a["pages"][1]["number"])
+ Bpage = string.format("%09s",b["pages"][1]["number"])
+ end
+ A = string.format("%-90s",A)..Apage
+ B = string.format("%-90s",B)..Bpage
+]]
+ return A < B
+end
+
+function pageCompare(a,b) -- a = {{number=...,special=..},{...,...}}
+-- a["number"], b["number"] are something like "3" or "VI-17" or "9--31"
+ writeLog(1,"pageCompare: "..a["number"].." "..b["number"].."\n",2)
+ if (a["number"] == nil) or (b["number"] == nil) then return true end -- should be no nil here
+ local a0 = a["number"] -- can be numeric or alphanumeric
+ local b0 = b["number"]
+-- if pageNoPrefixDel ~= "" then ---- not active
+-- A = (a0:gsub(pageNoPrefixPattern,''))
+-- B = (b0:gsub(pageNoPrefixPattern,''))
+-- a0 = tonumber(A) or romanToNumber(A)
+-- b0 = tonumber(B) or romanToNumber(B)
+-- else
+ if numericPage then
+ if (type(a0) == "number") and (type(b0) == "number") then return a0 < b0 end
+ if romanToNumber(a0) and (type(b0) == "number") then return true end -- ii < 2
+ if (type(a0) == "number") and romanToNumber(b0) then return false end -- ii > 2
+ if romanToNumber(a0) and romanToNumber(b0) then return a0 < b0 end -- ii < iii
+ -- now we have some special page numbers
+ A = tostring(a0)
+ B = tostring(b0)
+ A1 = A:find("--",1,true) or A:find("f",1,true) -- sequence or folio pages
+ B1 = B:find("--",1,true) or B:find("f",1,true)
+ if A1 then a0 = tonumber(A:sub(1,A1-1)) end
+ if B1 then b0 = tonumber(B:sub(1,B1-1)) end
+ return tonumber(a0) < tonumber(b0) -- numeric
+ else
+ return a0 < b0 -- alphanumeric (strings)
+ end
+end
+
+function checkFF(p)
+ if not p then return p end
+ local P = tostring(p)
+ if P:find("ff") then
+ return P:gsub('%a+','').."\\nohyperpage{"..page_folium[2].."}"
+ elseif P:find("f") then
+ return P:gsub('%a+','').."\\nohyperpage{"..page_folium[1].."}"
+ else
+ return P
+ end
+end
+
+function getRawPages(v)
+ writeLog(1,"getRawPages, Entry: "..v["Entry"]..", page: "..tostring(v["pages"][1]["number"]),2)
+ if v then
+ local str = tostring(v["pages"][1]["number"]).."("..tostring(v["pages"][1]["special"])..")"
+ for i=2,#v["pages"] do
+ if v["pages"] then
+ str = str..", "..tostring(v["pages"][i]["number"]).."("..tostring(v["pages"][i]["special"])..")"
+ end
+ end
+ return str
+ else
+ return "v->nil"
+ end
+end
+
+function getRawPagesP(p) -- does the same but uses table pages
+ if p then
+ local str = tostring(p[1]["number"]).."("..tostring(p[1]["special"])..")"
+ for i=2,#p do
+ if p then
+ str = str..", "..tostring(p[i]["number"]).."("..tostring(p[i]["special"])..")"
+ end
+ end
+ return str
+ else
+ return "pages->nil"
+ end
+end
+
+
+function getPageList(v,hyperpage)
+ if specialGetPageList then
+ local pageNo = specialGetPageList(v,hyperpage)
+ return pageNo
+ end
+ local Pages = {}
+ if v["pages"] then
+ table.sort(v["pages"],pageCompare)-- nur nötig, da User manuell eine Zeile einfügen kann
+ if specialCompressPageList then
+ Pages = specialCompressPageList(v["pages"])
+ else
+ Pages = compressPageList(v["pages"])
+ end
+-- require 'xindex-pretty'.dump(Pages) -- only for internal dump
+ local pageNo
+--[[
+\indexentry{Auto|hyperindexformat{\textbf}}{1}
+-> \item Auto, \hyperindexformat{\textbf}{1}
+
+ add for example \hyperpage{5\nohyperpage{f}} , same for ff
+
+ \item foo, \hyperpage{1\nohyperpage{f}},
+ \hyperpage{4\nohyperpage{ff}}, \hyperpage{8}
+
+]]
+ if hyperpage then
+ if string.find(v["pages"][1]["special"],"hyperindexformat") then
+ pageNo = v["pages"][1]["special"].."{"..checkFF(Pages[1]["number"].."}")
+ else
+ pageNo = "\\hyperpage{"..checkFF(Pages[1]["number"]).."}"
+ end
+ for i=2,#Pages do
+ if string.find(v["pages"][i]["special"],"hyperindexformat") then
+ pageNo = pageNo..", "..v["pages"][i]["special"].."{"..checkFF(Pages[i]["number"].."}")
+ else
+ pageNo = pageNo..", \\hyperpage{"..checkFF(Pages[i]["number"]).."}"
+ end
+-- Pages[i] = nil
+ end
+ else
+ writeLog(1,"getPageList: "..tostring(Pages[1]["special"]).."{"..tostring(Pages[1]["number"]).."}\n",2)
+ if (Pages[1]["special"] == nil) or (Pages[1]["number"] == nil) then return "" end
+ pageNo = Pages[1]["special"].."{"..Pages[1]["number"].."}"
+ for i=2,#Pages do
+ if Pages[i]["number"] then
+ pageNo = pageNo..", "..Pages[i]["special"].."{"..Pages[i]["number"].."}"
+ Pages[i] = {}
+ end
+ end
+ end
+ return pageNo
+ else
+ return ""
+ end
+end
+
+
+function getPathFileExt(str)
+ local filepath = str:match("(.*[/\\])")
+ local filename = str:match("^.+/(.+)$")
+ local fileext = str:match("^.+(%..+)$")
+ return filepath,filename,fileext
+end
+
+function printList(Index,level)
+ for k,v in pairs(Index) do
+ if v["Entry"] then
+ local sortChar = v["sortChar"]
+ if v["Entry"] and v["Macro"] then
+ writeLog(1,"Entry: "..v["Entry"].."; Pages: "..getRawPages(v).."Special: "..v["pages"][1]["special"].."; Type: "..sortChar.."; Macro: "..v["Macro"].."\n",level)
+ else
+ writeLog(1,"Entry: "..v["Entry"].."; Pages: "..getRawPages(v).."Special: "..v["pages"][1]["special"].."; Type: "..sortChar.."; Macro: nil".."\n",level)
+ end
+ end
+ end
+end
+
+function getItem(str,n)
+ if n >= 0 then
+ local item = (str:gsub("!.*", "%0!")
+ :gsub("[^!]*!", "", n)
+ :match("^([^!]*)!") )
+ writeLog(1,"getItem ("..str..", "..n..") = "..item.."\n",2)
+ return item
+ end
+end
+
+local romanMap = {
+ I = 1,
+ V = 5,
+ X = 10,
+ L = 50,
+ C = 100,
+ D = 500,
+ M = 1000,
+}
+
+local numbers = { 1, 5, 10, 50, 100, 500, 1000 }
+local romanchars = { "I", "V", "X", "L", "C", "D", "M" }
+local RomanNumerals = { }
+
+function numberToRoman(s)
+ --s = tostring(s)
+ s = tonumber(s)
+ if not s or s ~= s then error"Unable to convert to number" end
+ if s == math.huge then error"Unable to convert infinity" end
+ s = math.floor(s)
+ if s <= 0 then return s end
+ local ret = ""
+ for i = #numbers, 1, -1 do
+ local num = numbers[i]
+ while s - num >= 0 and s > 0 do
+ ret = ret .. romanchars[i]
+ s = s - num
+ end
+ for j = 1, i - 1 do
+ local n2 = numbers[j]
+ if s - (num - n2) >= 0 and s < num and s > 0 and num - n2 ~= n2 then
+ ret = ret .. romanchars[j] .. romanchars[i]
+ s = s - (num - n2)
+ break
+ end
+ end
+ end
+ return ret
+end
+
+function romanToNumber(s)
+-- if args_v then print("romanToNumber: "..tostring(s)) end
+-- if not s then return end
+ s = s:upper()
+ local ret = 0
+ local i = 1
+ while i <= s:len() do
+ local c = s:sub(i, i)
+ if c ~= " " then -- allow spaces
+ local m = romanMap[c]
+ if not m then return nil end --error("Unknown Roman Numeral '" .. c .. "'")
+ local next = s:sub(i + 1, i + 1)
+ local nextm = romanMap[next]
+ if next and nextm then
+ if nextm > m then
+ ret = ret + (nextm - m)
+ i = i + 1
+ else
+ ret = ret + m
+ end
+ else
+ ret = ret + m
+ end
+ end
+ i = i + 1
+ end
+ return ret
+end
+
+function commandEntry(line)
+ return string.find(line,"\\MACRO<<<",1,true)
+end
+
+function checkHyperpage(lines)
+ local hyperpage = false
+ for i=1,#lines do
+ if string.find(lines[i],'hyperpage}') then
+ hyperpage = true
+ break
+ end
+ end
+ if hyperpage then
+ for i=1,#lines do
+ lines[i] = string.gsub(lines[i],'|?hyperpage}{','}{')
+ end
+ return true, lines
+ else
+ return false, lines
+ end
+ return
+end
+
+function itemOutput(last, v, hyperpage)
+ local lastItems = last
+ local currentItems = {}
+ local Entry = v["Entry"]
+-- require 'xindex-pretty'.dump(v) -- only for internal dump
+ local str
+ local excl = select(2,string.gsub(Entry,"!","!")) -- Number of !
+ writeLog(1,"itemOutput(): We have entry "..Entry.."\n",2)
+ writeLog(1,"itemOutput(): The entry has "..excl.." Exclamation characters\n",2)
+ if excl == 0 then
+ str = " \\item "..Entry..itemPageDelimiter.." "..getPageList(v,hyperpage).."\n"
+ for i, str0 in ipairs(escape_chars) do -- undo the escape char setting
+ str = str:gsub(str0[2],str0[3])
+ end
+ outFile:write(str)
+-- lastItems[1] = Entry
+ else
+ for i = 1,excl+1 do
+ currentItems[i] = getItem(Entry,i-1) -- 0 ! 1 ! 2 ! ...
+ local item = "item"
+ if (currentItems[i] ~= lastItems[i]) then
+ writeLog(1,"itemOutput: currentItems[i]: "..tostring(currentItems[i]).."~= lastItems[i]: "..tostring(lastItems[i]).."\n",2)
+ local space = " "
+ for j = 2,i do
+ item = "sub"..item -- get the sub...subitem
+ space = space.." "
+ end
+ if not sublabels[i] then sublabels[i] = "---" end -- only three levels are predefined
+ writeLog(1,"itemOutput: currentItems[i]: "..currentItems[i].."; item: "..item.."\n",2)
+ if (i == 1) and (item == "item") then
+ str = space.."\\"..item.." "..sublabels[i]..currentItems[i].."\n"
+ else
+ str = space.."\\"..item.." "..sublabels[i]..currentItems[i]..itemPageDelimiter.." "..getPageList(v,hyperpage).."\n"
+ end
+ for i, str0 in ipairs(escape_chars) do -- undo the escape char setting
+ str = string.gsub(str,str0[2],str0[3])
+ end
+ outFile:write(str)
+ lastItems[i] = currentItems[i]
+ else
+ writeLog(1,"itemOutput: currentItems[i]: "..currentItems[i].."= lastItems[i]: "..lastItems[i].."\n",2)
+ end
+ end
+ end
+ return lastItems
+end
+
+-- \item Bugenhagen, {VII/1-16}, {166}, {17}, {215}, {222f}, {226}, {237f}, {248}, {258f}, {263}, {269}, {316f}, {321}, {361}, {365f}, {368}, {385}, {431}, {57}, {65}, {68}, {71}, {714}, {728}, {73f}, {748}, {75}, {79}, {81}, {85}, {90f}, {VII/2/1-1013}, {1015}, {1049}, {1085}, {1088}, {1097--1100}, {1110}, {1114}, {1120}, {1126}, {1148}, {1175}, {1234}, {1236ff}, {761}, {782}, {785}, {799}, {803--811}, {813f}, {818}, {822f}, {829}, {832--835}, {839f}, {848f}, {851}, {857--862}, {864f}, {867--871}, {873}, {875}, {877}, {880}, {882}, {884}, {961}, {973}, {IX-277}
+-- \subitem -\,Johannes, {VII/1-16}, {166}, {17}, {215}, {222f}, {226}, {237f}, {248}, {258f}, {263}, {269}, {316f}, {321}, {361}, {365f}, {368}, {385}, {431}, {57}, {65}, {68}, {71}, {714}, {728}, {73f}, {748}, {75}, {79}, {81}, {85}, {90f}, {VII/2/1-1013}, {1015}, {1049}, {1085}, {1088}, {1097--1100}, {1110}, {1114}, {1120}, {1126}, {1148}, {1175}, {1234}, {1236ff}, {761}, {782}, {785}, {799}, {803--811}, {813f}, {818}, {822f}, {829}, {832--835}, {839f}, {848f}, {851}, {857--862}, {864f}, {867--871}, {873}, {875}, {877}, {880}, {882}, {884}, {961}, {973}, {IX-277}
+
+local match = function(expr)
+ local C, Ct, S = lpeg.C, lpeg.Ct, lpeg.S
+ local sep = S("@!|")
+ local str = C((1 - sep)^0)
+ local prefix = function(prefix)
+ return function(match)
+ return prefix .. match
+ end
+ end
+ local idx = str * ( "@" * str / prefix("@")
+ + "!" * str / prefix("!")
+ + "|" * str / prefix("|"))^0
+ return Ct(idx):match(expr)
+end
+
+function getSortString(Entry)
+ local t = match(Entry)
+-- require 'xindex-pretty'.dump(t) -- only for internal dump
+ local data = t[1]
+ local c = utf.sub(data,1,1)
+ if getCharType(c) == 0 then
+ data = " "..data
+ end
+ for i = 2,#t do
+ if not (t[i]:sub(1,1) == "@") then -- and not (t[i]:sub(1,1) == "|") then
+ data = data..t[i]
+ end
+ end
+ return data
+end
+
+function writeLog(i, str, level) -- mode i 0->console; 1->logfile: 2->both
+ if not_quiet then
+ if level <= vlevel then
+ if (i ~= 1) or (i < 0) then io.write(tostring(str)) end
+ if i > 0 then logFile:write(tostring(str)) end
+ end
+ else
+ if level < 0 then
+ io.write(tostring(str))
+ elseif level == 0 then
+ logFile:write(tostring(str))
+ end
+ end
+end
+
+function string:split()
+ local sep, fields = " ", {}
+ local pattern = string.format("([^%s]+)", sep)
+ self:gsub(pattern, function(c) fields[#fields+1] = c end)
+ return fields
+end
+
+
+
+--\indexentry{hello@foo!world@foo!bar|bar}{60}
+
+
+--[[
+\indexentry {Schrift!Höhe}{64}
+\indexentry {Schrift!Breite}{64}
+\indexentry {Schrift!Tiefe}{64}
+
+]] \ No newline at end of file
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex-pretty.lua b/Master/texmf-dist/tex/lualatex/xindex/xindex-pretty.lua
new file mode 100644
index 00000000000..290c30d1c96
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex-pretty.lua
@@ -0,0 +1,254 @@
+--- Pretty-printing Lua tables.
+-- based on Steve Donovans Penlight package
+-- Also provides a sandboxed Lua table reader and
+-- a function to present large numbers in human-friendly format.
+--
+
+if not modules then modules = { } end modules ['xindex-pretty'] = {
+ version = 0.05,
+ comment = "dump a Lua table for debugging",
+ author = "Steve Donovan",
+ copyright = "Steve Donovan",
+ license = "MIT"
+}
+
+local append = table.insert
+local concat = table.concat
+local mfloor, mhuge = math.floor, math.huge
+local mtype = math.type
+
+local original_tostring = tostring
+
+--- Utility function that finds any patterns that match a long string's an open or close.
+-- Note that having this function use the least number of equal signs that is possible is a harder algorithm to come up with.
+-- Right now, it simply returns the greatest number of them found.
+-- @param s The string
+-- @return 'nil' if not found. If found, the maximum number of equal signs found within all matches.
+local function has_lquote(s)
+ local lstring_pat = '([%[%]])(=*)%1'
+ local equals, new_equals, _
+ local finish = 1
+ repeat
+ _, finish, _, new_equals = s:find(lstring_pat, finish)
+ if new_equals then
+ equals = max(equals or 0, #new_equals)
+ end
+ until not new_equals
+
+ return equals
+end
+
+--- Quote the given string and preserve any control or escape characters, such that reloading the string in Lua returns the same result.
+-- @param s The string to be quoted.
+-- @return The quoted string.
+
+function quote_string(s)
+-- assert_string(1,s)
+ -- Find out if there are any embedded long-quote sequences that may cause issues.
+ -- This is important when strings are embedded within strings, like when serializing.
+ -- Append a closing bracket to catch unfinished long-quote sequences at the end of the string.
+ local equal_signs = has_lquote(s .. "]")
+
+ -- Note that strings containing "\r" can't be quoted using long brackets
+ -- as Lua lexer converts all newlines to "\n" within long strings.
+ if (s:find("\n") or equal_signs) and not s:find("\r") then
+ -- If there is an embedded sequence that matches a long quote, then
+ -- find the one with the maximum number of = signs and add one to that number.
+ equal_signs = ("="):rep((equal_signs or -1) + 1)
+ -- Long strings strip out leading newline. We want to retain that, when quoting.
+ if s:find("^\n") then s = "\n" .. s end
+ local lbracket, rbracket =
+ "[" .. equal_signs .. "[",
+ "]" .. equal_signs .. "]"
+ s = lbracket .. s .. rbracket
+ else
+ -- Escape funny stuff. Lua 5.1 does not handle "\r" correctly.
+ s = ("%q"):format(s):gsub("\r", "\\r")
+ end
+ return s
+end
+
+-- Patch tostring to format numbers with better precision
+-- and to produce cross-platform results for
+-- infinite values and NaN.
+local function tostring(value)
+ if type(value) ~= "number" then
+ return original_tostring(value)
+ elseif value ~= value then
+ return "NaN"
+ elseif value == mhuge then
+ return "Inf"
+ elseif value == -mhuge then
+ return "-Inf"
+ elseif (_VERSION ~= "Lua 5.3" or mtype(value) == "integer") and mfloor(value) == value then
+ return ("%d"):format(value)
+ else
+ local res = ("%.14g"):format(value)
+ if _VERSION == "Lua 5.3" and mtype(value) == "float" and not res:find("%.") then
+ -- Number is internally a float but looks like an integer.
+ -- Insert ".0" after first run of digits.
+ res = res:gsub("%d+", "%0.0", 1)
+ end
+ return res
+ end
+end
+
+local pretty = {}
+
+local function quote_if_necessary (v)
+ if not v then return ''
+ else
+ --AAS
+ if v:find ' ' then v = quote_string(v) end
+ end
+ return v
+end
+
+local keywords
+
+local function is_identifier (s)
+ return type(s) == 'string' and s:find('^[%a_][%w_]*$') and not keywords[s]
+end
+
+local function quote (s)
+ if type(s) == 'table' then
+ return pretty.write(s,'')
+ else
+ --AAS
+ return quote_string(s)-- ('%q'):format(tostring(s))
+ end
+end
+
+local function index (numkey,key)
+ --AAS
+ if not numkey then
+ key = quote(key)
+ key = key:find("^%[") and (" " .. key .. " ") or key
+ end
+ return '['..key..']'
+end
+
+--- Create a string representation of a Lua table.
+-- This function never fails, but may complain by returning an
+-- extra value. Normally puts out one item per line, using
+-- the provided indent; set the second parameter to an empty string
+-- if you want output on one line.
+-- @tab tbl Table to serialize to a string.
+-- @string[opt] space The indent to use.
+-- Defaults to two spaces; pass an empty string for no indentation.
+-- @bool[opt] not_clever Pass `true` for plain output, e.g `{['key']=1}`.
+-- Defaults to `false`.
+-- @return a string
+-- @return an optional error message
+
+function pretty.dump (tbl,space,not_clever)
+ if type(tbl) ~= 'table' then
+ local res = tostring(tbl)
+ if type(tbl) == 'string' then return quote(tbl) end
+ return res, 'not a table'
+ end
+ if not keywords then
+ keywords = {
+ ["and"] = true, ["break"] = true, ["do"] = true,
+ ["else"] = true, ["elseif"] = true, ["end"] = true,
+ ["false"] = true, ["for"] = true, ["function"] = true,
+ ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true,
+ ["not"] = true, ["or"] = true, ["repeat"] = true,
+ ["return"] = true, ["then"] = true, ["true"] = true,
+ ["until"] = true, ["while"] = true
+ }
+ end
+ local set = ' = '
+ if space == '' then set = '=' end
+ space = space or ' '
+ local lines = {}
+ local line = ''
+ local tables = {}
+
+
+ local function put(s)
+ if #s > 0 then
+ line = line..s
+ end
+ end
+
+ local function putln (s)
+ if #line > 0 then
+ line = line..s
+ append(lines,line)
+ line = ''
+ else
+ append(lines,s)
+ end
+ end
+
+ local function eat_last_comma ()
+ local n = #lines
+ local lastch = lines[n]:sub(-1,-1)
+ if lastch == ',' then
+ lines[n] = lines[n]:sub(1,-2)
+ end
+ end
+
+ local writeit
+ writeit = function (t,oldindent,indent)
+ local tp = type(t)
+ if tp ~= 'string' and tp ~= 'table' then
+ putln(quote_if_necessary(tostring(t))..',')
+ elseif tp == 'string' then
+ -- if t:find('\n') then
+ -- putln('[[\n'..t..']],')
+ -- else
+ -- putln(quote(t)..',')
+ -- end
+ --AAS
+ putln(quote_string(t) ..",")
+ elseif tp == 'table' then
+ if tables[t] then
+ putln('<cycle>,')
+ return
+ end
+ tables[t] = true
+ local newindent = indent..space
+ putln('{')
+ local used = {}
+ if not not_clever then
+ for i,val in ipairs(t) do
+ put(indent)
+ writeit(val,indent,newindent)
+ used[i] = true
+ end
+ end
+ for key,val in pairs(t) do
+ local tkey = type(key)
+ local numkey = tkey == 'number'
+ if not_clever then
+ key = tostring(key)
+ put(indent..index(numkey,key)..set)
+ writeit(val,indent,newindent)
+ else
+ if not numkey or not used[key] then -- non-array indices
+ if tkey ~= 'string' then
+ key = tostring(key)
+ end
+ if numkey or not is_identifier(key) then
+ key = index(numkey,key)
+ end
+ put(indent..key..set)
+ writeit(val,indent,newindent)
+ end
+ end
+ end
+ tables[t] = nil
+ eat_last_comma()
+ putln(oldindent..'},')
+ else
+ putln(tostring(t)..',')
+ end
+ end
+ writeit(tbl,'',space)
+ eat_last_comma()
+ return concat(lines,#space > 0 and '\n' or '')
+end
+
+return pretty
diff --git a/Master/texmf-dist/tex/lualatex/xindex/xindex.sty b/Master/texmf-dist/tex/lualatex/xindex/xindex.sty
new file mode 100644
index 00000000000..58afc99c20d
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/xindex/xindex.sty
@@ -0,0 +1,76 @@
+%% This is file `xindex.sty',
+%%
+%% Copyright (C) 2018
+%% Herbert Voss
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%
+% $Id: xindex.sty 836 2018-11-11 20:22:56Z herbert $
+%
+% -------------------------------------
+\ProvidesPackage{xindex}[2018/11/11 v. 0.02 write into an idx file (hv)]
+%
+\RequirePackage{xkeyval}
+
+\newif\if@@imakeidx \@@imakeidxfalse
+
+\DeclareOptionX{imakeidx}{\@@imakeidxtrue}
+\DeclareOptionX*{\PassOptionsToPackage\CurrentOption{imakeidx}}
+\ProcessOptionsX\relax
+
+\@ifpackageloaded{imakeidx}{}{% imakeidx already loaded?? if not then define ...
+ \newif\ifimki@startedidx
+ \newif\ifimki@splitindex
+}
+
+\if@@imakeidx
+ \typeout{xindex: Using package imakeidx}%
+ \RequirePackage{imakeidx}
+ \def\imki@progdefault{xindex}
+ \def\imki@program{xindex}
+%
+ \def\imki@@startidxsplit#1{%
+ \if@filesw
+ \def\index{\@bsphack
+ \@ifnextchar [{\@index}{\@index[\imki@jobname]}}
+ \expandafter\newwrite\csname #1@idxfile\endcsname
+ \immediate\openout \csname #1@idxfile\endcsname #1.idx\relax
+ \def\writeidx##1{\write\expandafter\csname #1@idxfile\endcsname{\noexpand##1}}%
+ \typeout{Writing index file #1.idx}%
+ \fi
+ }
+ \global\imki@startedidxfalse
+ \def\imki@@startidxunique#1{%
+ \if@filesw
+ \ifimki@startedidx\else
+ \newwrite\@indexfile
+ \immediate\openout\@indexfile\imki@jobname.idx%
+ \def\writeidx##1{\write\@indexfile{\noexpand##1}}%
+ \global\imki@startedidxtrue
+ \fi
+ \def\index{\@bsphack
+ \@ifnextchar [{\@index}{\@index[\imki@jobname]}}
+ \expandafter\let\csname #1@idxfile\endcsname\@empty
+ \typeout{Started index file #1}%
+ \fi
+ }
+%
+ \ifimki@splitindex
+ \let\imki@startidx\imki@@startidxunique
+ \else
+ \let\imki@startidx\imki@@startidxsplit
+ \fi
+\else
+ \typeout{xindex: Using package makeidx}%
+ \RequirePackage{makeidx}
+ \def\writeidx#1{\write\@indexfile{\noexpand#1}}
+\fi
+
+\endinput
+