diff options
author | Karl Berry <karl@freefriends.org> | 2020-07-08 21:18:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-07-08 21:18:08 +0000 |
commit | 637224a93d20e487f3ba4cdc5040a68c86fb6617 (patch) | |
tree | 73e4ed9dd1fcd4a3762e2367457f3a69cd70ecaf /Master/texmf-dist/tex/lualatex | |
parent | c226379cc4863e82904bd636c705d73c20670015 (diff) |
ekdosis (8jul20)
git-svn-id: svn://tug.org/texlive/trunk@55786 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/lualatex')
-rw-r--r-- | Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.lua | 1694 | ||||
-rw-r--r-- | Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.sty | 959 |
2 files changed, 2653 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.lua b/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.lua new file mode 100644 index 00000000000..cab5b029694 --- /dev/null +++ b/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.lua @@ -0,0 +1,1694 @@ +--[[ +This file is part of the `ekdosis' package + +ekdosis -- Typesetting TEI xml compliant critical editions +Copyright (C) 2020 Robert Alessi + +Please send error reports and suggestions for improvements to Robert +Alessi <alessi@robertalessi.net> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +<http://www.gnu.org/licenses/>. +--]] + +-- `' +-- This table will hold the functions: +ekdosis = {} + +-- lpeg equivalent for string.gsub() +local function gsub(s, patt, repl) + patt = lpeg.P(patt) + patt = lpeg.Cs((patt / repl + 1)^0) + return lpeg.match(patt, s) +end + +-- some basic patterns: +local letters = lpeg.R("az", "AZ") +local ascii = lpeg.R("az", "AZ", "@@") +local dblbkslash = lpeg.Cs("\\") +local bsqbrackets = lpeg.Cs{ "[" * ((1 - lpeg.S"[]") + lpeg.V(1))^0 * "]" } +local bcbraces = lpeg.Cs{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" } +local spce = lpeg.Cs(" ") +local spcenc = lpeg.P(" ") +local cmdstar = lpeg.Cs(spce * lpeg.P("*")) +local bsqbracketsii = lpeg.Cs(bsqbrackets^-2) +local bcbracesii = lpeg.Cs(bcbraces^-2) +local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1) +local rawcmd = lpeg.Cs(dblbkslash * ascii^1) +local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) +local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) +local app = lpeg.Cs("app") +local lemrdg = lpeg.Cs(lpeg.Cs("lem") + lpeg.Cs("rdg")) +local note = lpeg.Cs("note") +local lnbrk = lpeg.Cs("\\\\") +local poemline = lpeg.Cs(lnbrk * bsqbrackets^-1) +local endpoem = lpeg.Cs(lnbrk * lpeg.S("*!") * bsqbrackets^-1) +local sections = lpeg.Cs(lpeg.P("book") + lpeg.P("part") + lpeg.P("chapter") + + lpeg.P("section") + lpeg.P("subsection") + + lpeg.P("subsubsection")) +local par = lpeg.P(lpeg.P("\\par") * spce^1) +local parb = lpeg.P(lpeg.Cs("\\p@rb") * spce^1) +local para = lpeg.P(lpeg.Cs("\\p@ra") * spce^1) + +-- Bind to local variables +local next = next + +-- General +xmlids = {} + +local function xmlidfound(element) + for i = 1,#xmlids do + if xmlids[i].xmlid == element then + return true + end + end + return false +end + +-- Witnesses +listWit = {} +idsRend = {} +shorthands = {} + +local function isfound(table, value) + for i = 1,#table do + if table[i] == value then + return true + end + end + return false +end + +local function isintable(table, value) + for i = 1,#table do + if table[i].a == value then + return true + end + end + return false +end + +local function get_a_index(id, table) + local idfound = nil + for i = 1,#table + do + if table[i].a == id then + idfound = i + break + end + end + return idfound +end + +local function getindex(id, table) + local idfound = nil + for i = 1,#table + do + if table[i].xmlid == id then + idfound = i + break + end + end + return idfound +end + +function ekdosis.newwitness(id, + siglum, + description, + Settlement, + Institution, + Repository, + Collection, + Idno, + MsName, + OrigDate) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(listWit, {xmlid = id, + abbr = siglum, + detailsDesc = description, + msIdentifier = { + settlement = Settlement, + institution = Institution, + repository = Repository, + collection = Collection, + idno = Idno, + msName = MsName} + }) + local indexwit = getindex(id, listWit) + if OrigDate ~= "" then + listWit[indexwit].history = {} + listWit[indexwit].history.origin = {origDate = OrigDate} + end + end + return true +end + +function ekdosis.newhand(id, witid, siglum, description) + if xmlidfound(id) or not xmlidfound(witid) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + local indexwit = getindex(witid, listWit) + -- listWit[indexwit].handDesc = {xmlid = id, abbr = siglum, handNote = description} + if listWit[indexwit].handDesc == nil + then + listWit[indexwit].handDesc = {} + else + end + table.insert(listWit[indexwit].handDesc, + {xmlid = id, abbr = siglum, detailsDesc = description}) + end + return true +end + +function ekdosis.newshorthand(id, rend, xmlids) + if isintable(shorthands, id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a shorthand. " + .. + "Please pick another shorthand.}}") + else + table.insert(shorthands, { a = id, b = rend, c = xmlids }) + table.sort(shorthands, function(a ,b) return(#a.a > #b.a) end) + table.insert(idsRend, {xmlid = id, abbr = rend}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + +local xmlbibresource = nil + +function ekdosis.setxmlbibresource(str) + xmlbibresource = str..".xml" + return true +end + +function ekdosis.newscholar(id, siglum) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + +function ekdosis.getsiglum(str, opt) + str = str.."," + str = string.gsub(str, "%s-(%,)", "%1") + ctrl = str + if opt == "tei" then + for i = 1,#shorthands do + str = string.gsub(str, shorthands[i].a, shorthands[i].c) + end + for i = 1,#idsRend do + str = string.gsub(str, "(%f[%w])"..idsRend[i].xmlid.."(%,)", + "%1#"..idsRend[i].xmlid.."%2") + ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") + end + str = string.gsub(str, "%,(%s-)([%#])", " %2") + str = string.gsub(str, "%,$", "") + else + for i = 1,#idsRend do + str = string.gsub(str, idsRend[i].xmlid.."%,", idsRend[i].abbr) + ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") + end + end + -- if string.find(ctrl, "[A-Za-z0-9]") + if string.find(ctrl, "%S") + then + return "<??>" + else + return str + end +end + +-- begin totei functions + +local cmdtotags = { + {a="textsuperscript", b="hi", c=" rend=\"sup\""}, + {a="textsubscript", b="hi", c=" rend=\"sub\""}, + {a="LRfootnote", b="note", c=" place=\"bottom\""}, + {a="RLfootnote", b="note", c=" place=\"bottom\""}, + {a="enquote *", b="quote", c=""}, + {a="footnote", b="note", c=" place=\"bottom\""}, + {a="enquote", b="quote", c=""}, + {a="txtrans", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, + {a="textbf", b="hi", c=" rend=\"bold\""}, + {a="textit", b="hi", c=" rend=\"italic\""}, + {a="textsc", b="hi", c=" rend=\"smallcaps\""}, + {a="textsf", b="hi", c=" rend=\"sf\""}, + {a="arbup", b="hi", c=" rend=\"sup\""}, + {a="txarb", b="s", c=" xml:lang=\"arb\""}, + {a="arb", b="foreign", + c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} +} + +local texpatttotags = { + {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 <ref target=\"#%3\">%2</ref>"}, + {a="\\icite%s?%[(.-)%]{(.-)}", b="<ref target=\"#%2\">%1</ref>"}, + {a="\\icite%s?{(.-)}", b="<ptr target=\"#%1\"/>"}, + {a="\\linelabel%s?{(.-)}", b="<anchor xml:id=\"%1\"/>"}, + {a="\\label%s?{(.-)}", b="<anchor xml:id=\"%1\"/>"}, + {a="\\v?pageref%s?{(.-)}", b="<ptr target=\"#%1\"/>"}, + {a="\\v?ref%s?{(.-)}", b="<ptr target=\"#%1\"/>"} +} + +local envtotags = { + {a="flushright", b="p", c=" rend=\"align(right)\""}, + {a="flushleft", b="p", c=" rend=\"align(left)\""}, + {a="quotation", b="quote", c=""}, + {a="ekdverse", b="lg", c=""}, + {a="txarabtr", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, + {a="txarab", b="p", c=" xml:lang=\"arb\""}, + {a="center", b="p", c=" rend=\"align(center)\""}, + {a="verse", b="lg", c=""}, + {a="arab", b="p", + c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} +} + +local close_p = { + "p", + "lg" +} + +local forbid_xmlid = true + +function ekdosis.newcmdtotag(cmd, tag, attr) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + if isintable(cmdtotags, cmd) + then + local index = get_a_index(cmd, cmdtotags) + table.remove(cmdtotags, index) + table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) + table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) + else + table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) + table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) + end + return true +end + +function ekdosis.newpatttotag(pat, repl) + pat = string.gsub(pat, "([%[%]])", "%%%1") + pat = string.gsub(pat, "%#[1-9]", "(.-)") + repl = string.gsub(repl, "%#([1-9])", "%%%1") + table.insert(texpatttotags, { a = pat, b = repl }) + table.sort(texpatttotags, function(a ,b) return(#a.a > #b.a) end) + return true +end + +function ekdosis.newenvtotag(env, tag, attr, closep) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + if isintable(envtotags, env) + then + local index = get_a_index(env, envtotags) + table.remove(envtotags, index) + table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) + table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) + else + table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) + table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) + end + return true +end + +-- Get values of attributes +local function get_attr_value(str, attr) + str = str.."," + local attrval = string.match(str, "%f[%w]"..attr.."%s?%=%s?%b{}") + or string.match(str, "%f[%w]"..attr.."%s?%=%s?.-%,") + or "" + attrval = string.gsub(attrval, attr.."%s?%=%s?(%b{})", function(bbraces) + bbraces = string.sub(bbraces, 2, -2) + return string.format("%s", bbraces) + end) + attrval = string.gsub(attrval, attr.."%s?%=%s?(.-)%s?%,", "%1") + return attrval +end + +local function xml_entities(str) + str = string.gsub(str, "%<", "<") + str = string.gsub(str, "%>", ">") + return str +end + +local function note_totei(str) + str = gsub(str, + dblbkslash * + note * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + teitype = get_attr_value(opt, "type") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + right = get_attr_value(opt, "labelb") + left = get_attr_value(opt, "labele") + if left ~= "" + then + return string.format( + "<%s%s target=\"#range(right(%s),left(%s))\">%s</%s><anchor xml:id=\"%s\"/>", + cmd, teitype, right, left, arg, cmd, right) + elseif left == "" + then + return string.format( + "<%s%s target=\"#right(%s)\">%s</%s><anchor xml:id=\"%s\"/>", + cmd, teitype, right, arg, cmd, right) + end + end) + return str +end + +local function app_totei(str) + str = gsub(str, + dblbkslash * + app * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + opt = get_attr_value(opt, "type") + if opt ~= "" then opt = " type=\""..opt.."\"" else end + return app_totei(string.format("<%s%s>%s</%s>", + cmd, opt, arg, cmd)) + end) + return str +end + +local function lem_rdg_totei(str) + str = gsub(str, + spcenc^-1 * + dblbkslash * + lemrdg * + spcenc^-1 * + bsqbrackets * + bcbraces * + spcenc^-1, + function(bkslash, cmd, opt, arg) + opt = string.sub(opt, 2, -2) + arg = string.sub(arg, 2, -2) + -- opt = get_attr_value(opt, "wit") + -- + teiwit = get_attr_value(opt, "wit") + if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end + teitype = get_attr_value(opt, "type") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + -- + if opt == "" + then + return lem_rdg_totei(string.format("<%s>%s</%s>", + cmd, arg, cmd)) + else + -- opt = ekdosis.getsiglum(opt, "tei") + return lem_rdg_totei(string.format("<%s%s%s>%s</%s>", + cmd, teiwit, teitype, arg, cmd)) + end + end) + str = gsub(str, spcenc^-0 * dblbkslash * lemrdg * spcenc^-1 * bcbraces * spcenc^-1, + function(bkslash, cmd, arg) + arg = string.sub(arg, 2, -2) + return lem_rdg_totei(string.format("<%s>%s</%s>", cmd, arg, cmd)) + end) + return str +end + +local function relocate_notes(str) + str = string.gsub(str, "(%<lem.-%>.-)(%<note.->.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2") + return str +end + +local function linestotei(str) +-- str = "\n<l>"..str + str = string.gsub(str, "^%s?(.-)%s?$", "\n<l>%1</l>\n") +-- str = gsub(str, endpoem, "</l>\n") + str = gsub(str, poemline * spcenc^-1 * lpeg.P(">"), "\n<lb/>") + str = gsub(str, poemline * spcenc^-1, "</l>\n<l>") +-- str = str.."</l>\n" + return str +end + +-- better use lpeg: look into this later +local function versetotei(str) + str = string.gsub(str, "(\\begin%s?%{ekdverse%})(%b[])(.-)(\\end%s?%{ekdverse%})", function(benv, opt, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s%s", benv, opt, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{ekdverse%})(.-)(\\end%s?%{ekdverse%})", function(benv, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s", benv, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{verse%})(%b[])(.-)(\\end%s?%{verse%})", function(benv, opt, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s%s", benv, opt, arg, eenv) + end) + str = string.gsub(str, "(\\begin%s?%{verse%})(.-)(\\end%s?%{verse%})", function(benv, arg, eenv) + arg = linestotei(arg) + return string.format("%s%s%s", benv, arg, eenv) + end) + return str +end + +local function envtotei(str) + for i = 1,#envtotags + do + if envtotags[i].b ~= "" + then + if isfound(close_p, envtotags[i].b) or envtotags[i].d == "yes" + then + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "\\p@rb <"..envtotags[i].b..envtotags[i].c..">") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "</"..envtotags[i].b..">\\p@ra ") + else + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "<"..envtotags[i].b..envtotags[i].c..">") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "</"..envtotags[i].b..">") + end + else + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}") + * bsqbracketsii * bcbracesii * spcenc^-1, + "") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), + "") + end + end + str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii + * bcbracesii * spcenc^-1, + "<%1>") + str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") + * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii + * bcbracesii, + "</%1>") + return str +end + +local function texpatttotei(str) + for i = 1,#texpatttotags do + str = string.gsub(str, texpatttotags[i].a, texpatttotags[i].b) + end + return str +end + +local function cmdtotei(str) + for i = 1,#cmdtotags + do + str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * bsqbrackets * -bcbraces, "\\%1%2{}") + str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * -(bsqbrackets + bcbraces), "\\%1[]{}") + str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b{})", "%1[]%2") + str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b[])(%b{})", + function(cmd, arg, body) + body = string.sub(body, 2, -2) + arg = string.sub(arg, 2, -2) + arg = string.gsub(arg, "(%b{})", function(braces) + braces = string.sub(braces, 2, -2) + return string.format("\"%s\"", braces) + end) + body = cmdtotei(body) + -- return string.format("<"..cmdtotags[i].b..cmdtotags[i].c.." %s>%s</"..cmdtotags[i].b..">", arg, body) + if cmdtotags[i].b ~= "" + then + return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s</" .. + cmdtotags[i].b..">", body) + else + return "" + end + end) + end + -- temporarily: + str = string.gsub(str, "\\(getsiglum)%s?(%b{})", + function(cmd, body) + body = string.sub(body, 2, -2) + teisiglum = ekdosis.getsiglum(body, "tei") + printsiglum = ekdosis.getsiglum(body) + -- body = cmdtotei(body) + return string.format("<ref target=\"%s\">%s</ref>", + teisiglum, printsiglum) + end) + str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})", + function(cmd, opt, body) + body = string.sub(body, 2, -2) + body = cmdtotei(body) + return string.format("<%s>%s</%s>", cmd, body, cmd) + end) + str = string.gsub(str, "\\(%a+)%s?%*?(%b{})", + function(cmd, body) + body = string.sub(body, 2, -2) + body = cmdtotei(body) + return string.format("<%s>%s</%s>", cmd, body, cmd) + end) + str = string.gsub(str, "(%s)(%>)", "%2") + return str +end + +local function partotei(str) + str = gsub(str, lpeg.P(lpeg.P("\\par") * spcenc^1)^1, "\\par ") + str = gsub(str, ((para + parb) * par^-1)^2, "\\p@r ") + str = string.gsub(str, "\\p@ra%s+", "<p>") + str = string.gsub(str, "\\p@rb%s+", "</p>") + str = string.gsub(str, "\\p@r%s+", "") + str = string.gsub(str, "%s?\\par%s?", "<p>", 1) + str = string.gsub(str, "(%<p%>)(%s-)(%<%/?div%d?)", "%3") + str = string.gsub(str, "%s?\\par%s?", "</p><p>") + str = string.gsub(str, "<p>%s?</p>", "") + str = string.gsub(str, "(%<p%>)%s?(%</div%>)$", "%2") + str = string.gsub(str, "(%<p%>)%s?$", "") + str = string.gsub(str, "(<p>)%s?(<div.->)", "%2%1") + return str +end + +local function self_close_tags(str) + str = gsub(str, lpeg.P("<" * -lpeg.S("/")) + * lpeg.Cs(letters^1) + * lpeg.Cs((1 - lpeg.S"<>")^0) + * lpeg.P(">") + * lpeg.P("</") + * lpeg.Cs(letters^1) + * lpeg.P(">"), function(ftag, arg, ltag) + if ftag == ltag + then + return string.format("<%s%s/>", ftag, arg) + else + end + end) + return str +end + +local divdepth = { + book = 1, + part = 2, + chapter = 3, + section = 4, + subsection = 5, + subsubsection = 6 +} + +function ekdosis.mkdivdepths(...) + divdepth = {} + local num = 1 + for _, y in ipairs{...} + do + if y == "book" or "part" or "chapter" + or "section" or "subsection" or "subsubsection" + then + divdepth[y] = num + num = num + 1 + else + end + end + return true +end + +-- LaTeX side: format the divisions +local fmtdiv = {} + +function ekdosis.fmtdiv(n, fmtb, fmte) + if isintable(fmtdiv, n) + then + local index = get_a_index(n, fmtdiv) + table.remove(fmtdiv, index) + else + end + table.insert(fmtdiv, { a = n, formatb = fmtb, formate = fmte} ) + return true +end + +function ekdosis.getfmtdiv(n, pos) + local index = get_a_index(n, fmtdiv) + if index ~= nil + then + if pos == "b" + then + return fmtdiv[index].formatb + elseif pos == "e" + then + return fmtdiv[index].formate + end + else + return "" + end +end + +local ekddivs = true + +function ekdosis.setekddivsfalse() + ekddivs = false +end + +local function ekddivs_totei(str) + str = gsub(str, dblbkslash * lpeg.Cs("ekddiv") * spce^-1 * bcbraces, + function(bkslash, cmd, space, arg) + if ekddivs + then + arg = string.sub(arg, 2, -2) + teitype = get_attr_value(arg, "type") + tein = get_attr_value(arg, "n") + teihead = get_attr_value(arg, "head") + teidepth = get_attr_value(arg, "depth") + if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end + if tein ~= "" then tein = " n=\""..tein.."\"" else end + if teidepth ~= "" + then + teidepth = " depth=\""..teidepth.."\"" + else + teidepth = " depth=\"1\"" + end + return string.format("\\p@rb <div%s%s%s><head>%s</head>\\p@ra ", + teitype, tein, teidepth, teihead) + else + return "" + end + end) + return str +end + +local function section_totei(str) + str = gsub(str, dblbkslash * sections * spce^-1 * bcbraces, "%1%2%3[]%4") + str = gsub(str, dblbkslash * sections * spce^-1 * bsqbrackets * bcbraces, + function(bkslash, secname, space, opt, arg) + if ekddivs + then + return "" + else + ctr = divdepth[secname] + arg = string.sub(arg, 2, -2) + return string.format("\\p@rb <div%s type=\"%s\"><head>%s</head>\\p@ra ", + ctr, secname, arg) + end + end) + return str +end + +local used_ndivs = {} + +local function close_ekddivs_at_end(str) + local isdiv = false + if string.find(str, "</div>$") + then + isdiv = true + str = string.gsub(str, "(.*)(</div>)$", "%1") + else + end + -- collect used depth numbers + for i in string.gmatch(str, "<div .-depth%=\"%d\".->") + do + i = string.match(i, "depth=\"%d\"") + i = string.match(i, "%d") + if isintable(used_ndivs, i) + then + else + table.insert(used_ndivs, {a = i} ) + end + end + if next(used_ndivs) ~= nil + then + table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end) + else + end + local firstdiv = string.match(str, "<div .-depth%=\"%d\".->") or "" + firstdiv = string.match(firstdiv, "depth%=\"%d\"") or "" + firstdiv = string.match(firstdiv, "%d") or "" + local lastdiv = string.match(string.reverse(str), ">.-\"%d\"%=htped.- vid<") or "" + lastdiv = string.match(lastdiv, "\"%d\"%=htped") or "" + lastdiv = string.match(lastdiv, "%d") or "" + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if isintable(used_ndivs, firstdiv) + then + while lastdivindex >= firstdivindex + do + closedivs = closedivs.."</div>" + lastdivindex = lastdivindex - 1 + end + end + if isdiv + then + return str..closedivs.."</div>" + else + return str..closedivs + end +end + +local function close_ndivs_at_end(str) + local isdiv = false + if string.find(str, "</div>$") + then + isdiv = true + str = string.gsub(str, "(.*)(</div>)$", "%1") + else + end + -- collect used div numbers + for i in string.gmatch(str, "<div[1-6]") + do + i = string.match(i, "[1-6]") + if isintable(used_ndivs, i) + then + else + table.insert(used_ndivs, {a = i} ) + end + end + if next(used_ndivs) ~= nil + then + table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end) + else + end + local firstdiv = string.match(str, "<div[1-6]") or "" + firstdiv = string.match(firstdiv, "[1-6]") or "" + local lastdiv = string.match(string.reverse(str), "[1-6]vid<") or "" + lastdiv = string.match(lastdiv, "[1-6]") or "" + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if isintable(used_ndivs, firstdiv) + then + while lastdivindex >= firstdivindex + do + closedivs = closedivs.."</div"..used_ndivs[lastdivindex].a..">" + lastdivindex = lastdivindex - 1 + end + end + if isdiv + then + return str..closedivs.."</div>" + else + return str..closedivs + end +end + +local function close_ekddivs_in_between(str) + local maxdepth = 1 + for i in string.gmatch(str, "<div.-depth=\"(%d)\".->", "%1") + do + if tonumber(i) > tonumber(maxdepth) + then + maxdepth = i + else + end + end + for ndivi = 1, maxdepth + do + str = string.gsub(str, "(<div .-depth%=\")("..ndivi..")(\".->)(.-)(<div .-depth%=\")(%d)(\".->)", + function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) + local firstdiv = ndivi + local lastdiv = ndivii + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if firstdivindex >= lastdivindex + then + while firstdivindex >= lastdivindex + do + closedivs = closedivs.."</div>" + firstdivindex = firstdivindex - 1 + end + end + return string.format("%s%s%s%s%s%s%s%s", + bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) + end) + end + str = string.gsub(str, "(<div.-)(%sdepth%=\"%d\")(.->)", "%1%3") + used_ndivs = {} + return str +end + +local function close_ndivs_in_between(str) + for ndivi = 1, 6 + do + str = string.gsub(str, "(<div)("..ndivi..")(.->)(.-)(<div)([1-6])(.->)", + function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) + local firstdiv = ndivi + local lastdiv = ndivii + local firstdivindex = get_a_index(firstdiv, used_ndivs) + local lastdivindex = get_a_index(lastdiv, used_ndivs) + firstdivindex = tonumber(firstdivindex) + lastdivindex = tonumber(lastdivindex) + local closedivs = "" + if firstdivindex >= lastdivindex + then + while firstdivindex >= lastdivindex + do + closedivs = closedivs.."</div"..used_ndivs[firstdivindex].a..">" + firstdivindex = firstdivindex - 1 + end + end + return string.format("%s%s%s%s%s%s%s%s", + bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) + + end) + end + used_ndivs = {} + return str +end + +local function textotei(str) + str = xml_entities(str) + str = texpatttotei(str) + str = note_totei(str) + str = app_totei(str) + str = lem_rdg_totei(str) + str = relocate_notes(str) + str = versetotei(str) + str = envtotei(str) + str = ekddivs_totei(str) + str = section_totei(str) + str = cmdtotei(str) + str = self_close_tags(str) + str = partotei(str) + if ekddivs + then + str = close_ekddivs_at_end(str) + str = close_ekddivs_in_between(str) + else + str = close_ndivs_at_end(str) + str = close_ndivs_in_between(str) + end + return str +end + +local teifilename = tex.jobname.."-tei" + +function ekdosis.setteifilename(str) + teifilename = str + return true +end + +function ekdosis.openteistream() + local f = io.open(teifilename.."_tmp.xml", "a+") + f:write('<?xml version="1.0" encoding="utf-8"?>', "\n") + f:write("<TEI xmlns=\"http://www.tei-c.org/ns/1.0\">", "\n") + f:write("<teiHeader>", "\n") + f:write("<fileDesc>", "\n") + f:write("<titleStmt>", "\n") + f:write("<title><!-- Title --></title>", "\n") + f:write("<respStmt>", "\n") + f:write("<resp><!-- Edited by --></resp>", "\n") + f:write("<name><!-- Name --></name>", "\n") + f:write("</respStmt>", "\n") + f:write("</titleStmt>", "\n") + f:write("<publicationStmt>", "\n") + f:write("<distributor><!-- Distributor name --></distributor>", "\n") + f:write("</publicationStmt>", "\n") + f:write("<sourceDesc>", "\n") + f:write("<listWit>", "\n") + for i = 1,#listWit do + f:write('<witness xml:id=\"', listWit[i].xmlid, "\">", "\n") + f:write('<abbr type="siglum">', textotei(listWit[i].abbr), "</abbr>", "\n") + f:write(textotei(listWit[i].detailsDesc), "\n") + f:write("<msDesc>", "\n") + if listWit[i].msIdentifier.settlement == "" + and listWit[i].msIdentifier.institution == "" + and listWit[i].msIdentifier.repository == "" + and listWit[i].msIdentifier.collection == "" + and listWit[i].msIdentifier.idno == "" + and listWit[i].msIdentifier.msName == "" + then + f:write("<msIdentifier/>", "\n") + else + f:write("<msIdentifier>", "\n") + if listWit[i].msIdentifier.settlement ~= "" then + f:write("<settlement>", textotei(listWit[i].msIdentifier.settlement), "</settlement>", "\n") + else end + if listWit[i].msIdentifier.institution ~= "" then + f:write("<institution>", textotei(listWit[i].msIdentifier.institution), "</institution>", "\n") + else end + if listWit[i].msIdentifier.repository ~= "" then + f:write("<repository>", textotei(listWit[i].msIdentifier.repository), "</repository>", "\n") + else end + if listWit[i].msIdentifier.collection ~= "" then + f:write("<collection>", textotei(listWit[i].msIdentifier.collection), "</collection>", "\n") + else end + if listWit[i].msIdentifier.idno ~= "" then + f:write("<idno>", textotei(listWit[i].msIdentifier.idno), "</idno>", "\n") + else end + if listWit[i].msIdentifier.msName ~= "" then + f:write("<msName>", textotei(listWit[i].msIdentifier.msName), "</msName>", "\n") + else end + f:write("</msIdentifier>", "\n") + end + if listWit[i].handDesc ~= nil then + f:write("<physDesc>", "\n") + f:write("<handDesc hands=\"", #listWit[i].handDesc, "\">", "\n") + local j = 1 + while listWit[i].handDesc[j] + do + f:write("<handNote xml:id=\"", listWit[i].handDesc[j].xmlid, "\">", "\n") + f:write('<abbr type="siglum">', textotei(listWit[i].handDesc[j].abbr), "</abbr>", "\n") + f:write("<p>", textotei(listWit[i].handDesc[j].detailsDesc), "</p>", "\n") + f:write("</handNote>", "\n") + j = j + 1 + end + f:write("</handDesc>", "\n") + f:write("</physDesc>", "\n") + else end + if listWit[i].history ~= nil then + f:write("<history>", "\n") + f:write("<origin>", "\n") + f:write("<origDate>", textotei(listWit[i].history.origin.origDate), "</origDate>", "\n") + f:write("</origin>", "\n") + f:write("</history>", "\n") + end + f:write("</msDesc>", "\n") + f:write("</witness>", "\n") + end + f:write("</listWit>", "\n") + f:write("</sourceDesc>", "\n") + f:write("</fileDesc>", "\n") + f:write("<encodingDesc>", "\n") + f:write('<variantEncoding method="parallel-segmentation" location="internal"/>', "\n") + f:write("</encodingDesc>", "\n") + f:write("</teiHeader>", "\n") + f:write("<text>", "\n") + f:write("<body>", "\n") + f:close() + return true +end + +local tidy = nil + +local function cleanup_tei() + local f = assert(io.open(teifilename.."_tmp.xml", "r")) + t = f:read("*a") + t = string.gsub(t, "%<p%>%s?%</p%>", "") + t = string.gsub(t, "^\n", "") + f:close() + local fw = assert(io.open(teifilename.."_tmp.xml", "w")) + fw:write(t) + fw:close() + return true +end + +function ekdosis.closeteistream(opt) + local f = io.open(teifilename.."_tmp.xml", "a+") + f:write("\n", "</body>", "\n") + if xmlbibresource ~= nil then + bibf = assert(io.open(xmlbibresource, "r")) + t = bibf:read("*a") + t = string.gsub(t, "%s+corresp%=%b\"\"", "") + t = string.gsub(t, "\n\n", "\n") + f:write("<back>", "\n") + f:write("<listBibl>", "\n") + for i in string.gmatch(t, "<biblStruct.->.-</biblStruct>") + do + f:write(i, "\n") + end + f:write("</listBibl>", "\n") + f:write("</back>", "\n") + bibf:close() + else + end + f:write("</text>", "\n") + f:write("</TEI>", "\n") + f:close() + cleanup_tei() + os.remove(teifilename..".xml") + os.rename(teifilename.."_tmp.xml", teifilename..".xml") + if opt == "tidy" then + os.execute("tidy -qmi -xml --output-xml yes "..teifilename..".xml") + else + end + return true +end + +function ekdosis.exporttei(str) + local f = io.open(teifilename.."_tmp.xml", "a+") + -- f:write("\n<p>") + str = textotei(str) + f:write(str) + f:close() + return true +end +-- end totei functions + +-- begin basic TeX Conspectus siglorum +function ekdosis.basic_cs(msid) + local indexwit = getindex(msid, listWit) + siglum = listWit[indexwit].abbr + -- if listWit[indexwit].detailsDesc == "" + -- then + -- name = listWit[indexwit].msIdentifier.msName + -- else + -- name = listWit[indexwit].msIdentifier.msName + -- .."\\thinspace\\newline\\bgroup\\footnotesize{}".. + -- listWit[indexwit].detailsDesc + -- .."\\egroup{}" + -- end + name = listWit[indexwit].detailsDesc + if listWit[indexwit].history ~= nil + and + listWit[indexwit].history.origin ~= nil + then + date = listWit[indexwit].history.origin.origDate + else + date = "" + end + return siglum.."&"..name.."&"..date +end +-- end basic TeX Conspectus siglorum + +function ekdosis.removesp(str) + str = gsub(str, cmd * cmdargs * spcenc^-1, "%1%2") + return str +end + +function ekdosis.closestream() + os.remove(tex.jobname..".ekd") + os.rename(tex.jobname.."_tmp.ekd", tex.jobname..".ekd") + return true +end + +local cur_abs_pg = 0 +local pg_i = nil +local pg_ii = nil +local prevcol = nil +local curcol = "x" + +local check_resetlineno = {} + +function ekdosis.update_abspg(n) -- not used + cur_abs_pg = n + return true +end + +function ekdosis.storeabspg(n, pg) + if pg == "pg_i" then + pg_i = n + elseif pg == "pg_ii" then + pg_ii = n + table.insert(check_resetlineno, curcol.."-"..pg_ii) + end + cur_abs_pg = n + return true +end + +function ekdosis.checkresetlineno() + if isfound(check_resetlineno, curcol.."-"..pg_i) + then + return "" + else + return "\\resetlinenumber" + end +end + +-- +-- Build environments to be aligned +-- + +local cur_alignment = "-" +local cur_alignment_patt = "%-" +local cur_alignment_cnt = 1 + +local newalignment = false +function ekdosis.newalignment(str) + if str == "set" + then + newalignment = true + cur_alignment = "-"..cur_alignment_cnt.."-" + cur_alignment_patt = "%-"..cur_alignment_cnt.."%-" + cur_alignment_cnt = cur_alignment_cnt + 1 + elseif str == "reset" + then + newalignment = false + cur_alignment = "-" + cur_alignment_patt = "-" + end + return true +end + +local aligned_texts = {} +local texts_w_apparatus = {} +local coldata_totei = {} + +local function sanitize_envdata(str) -- look for a better way to achieve this + str = string.gsub(str, "(%a+)%s+(%b[])", "%1%2") + str = string.gsub(str, "(%a+)(%b[])%s+", "%1%2") + str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") + str = gsub(str, lpeg.Cs(letters^1) + * spcenc^-1 + * -bsqbrackets + * lpeg.Cs(";"), "%1[]%2") + str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") + return str +end + +function ekdosis.mkenvdata(str, opt) + if not string.find(str, "%;", -1) then str = str .. ";" else end + -- str = str ..";" + -- str = string.gsub(str, "%s+", "") + local fieldstart = 1 + local col = 0 + if opt == "texts" then + str = sanitize_envdata(str) + repeat + local _s, nexti = string.find(str, "%b[]%s-%;", fieldstart) + local namediv = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%1") + local attr = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%2") + attr = string.sub(attr, 2, -2) + if forbid_xmlid + then + attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here + else + end + table.insert(aligned_texts, { text = namediv, + attribute = attr, + column = col }) + table.insert(coldata_totei, { environment = namediv, + data = {} }) + col = col + 1 + fieldstart = nexti + 1 + until fieldstart > string.len(str) + return aligned_texts + elseif opt == "apparatus" then + repeat + local nexti = string.find(str, "%;", fieldstart) + table.insert(texts_w_apparatus, string.sub(str, fieldstart, nexti-1)) + fieldstart = nexti +1 + until fieldstart > string.len(str) + return texts_w_apparatus + end +end + +-- Reminder: the following two variables are already set above +-- local prevcol = nil +-- local curcol = "x" + +function ekdosis.storecurcol(n) + curcol = n + return true +end + +function ekdosis.flushcolnums() + prevcol = nil + curcol = "x" + return true +end + +function ekdosis.flushenvdata() + aligned_texts = {} + texts_w_apparatus = {} + coldata_totei = {} + return true +end + +function ekdosis.storecoldata(nthcol, chunk) + local tindex = tonumber(nthcol) + 1 + table.insert(coldata_totei[tindex].data, chunk) + return true +end + +local environment_div = {} + +function ekdosis.newscholar(id, siglum) + if xmlidfound(id) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..id.. + "\" already exists as a xml:id. " + .. + "Please pick another id.}}") + else + table.insert(xmlids, {xmlid = id}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + table.insert(idsRend, {xmlid = id, abbr = siglum}) + table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) + end + return true +end + +local function build_envdiv(str) + if not environment_div[str] + then + environment_div[str] = 1 + else + environment_div[str] = environment_div[str] + 1 + end + local div = "div-"..str.."_"..environment_div[str] + if xmlidfound(div) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..div.. + "\" already exists as a xml:id. " + .. + "ekdosis has generated some random id.}}") + return "div-"..math.random(1000,9999) + else + table.insert(xmlids, {xmlid = div}) + table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) + return div + end +end + +function ekdosis.mkenv() + local environments = {} + for i = 1,#aligned_texts + do + if isfound(texts_w_apparatus, aligned_texts[i].text) + then + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" + .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" + .."\\par" + .."\\EkdosisColStart" + .."\\EkdosisOn#1" + .."}{\\EkdosisOff" + .."\\EkdosisColStop" + .."\\end{nthcolumn}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" + .."{\\begin{nthcolumn*}{".. aligned_texts[i].column.."}[]" + .."\\par" + .."\\EkdosisColStart" + .."\\EkdosisOn#1" + .."}{\\EkdosisOff" + .."\\EkdosisColStop" + .."\\end{nthcolumn*}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + else + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" + .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" + .."\\par" + .."#1" + .."}{\\end{nthcolumn}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" + .."{\\begin{nthcolumn*}{"..aligned_texts[i].column.."}[]" + .."\\par" + .."#1" + .."}{" + .."\\end{nthcolumn*}" + .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" + .. aligned_texts[i].column + ..", \\luastringN{\\par#1\\par})}\\fi" + .."}") + end + forbid_xmlid = false + if aligned_texts[i].attribute ~= "" + then + ekdosis.newenvtotag(aligned_texts[i].text, "div", + "xml:id=\"" + ..build_envdiv(aligned_texts[i].text) + .."\" " + ..aligned_texts[i].attribute) + else + ekdosis.newenvtotag(aligned_texts[i].text, "div", + "xml:id=\"" + ..build_envdiv(aligned_texts[i].text) + .."\"") + end + forbid_xmlid = true + end + str = table.concat(environments) + return str +end + +function ekdosis.export_coldata_totei() + for i = 1,#coldata_totei + do + ekdosis.exporttei("\\begin{".. coldata_totei[i].environment .."}" + .. table.concat(coldata_totei[i].data) + .. "\\end{".. coldata_totei[i].environment .."}") + end +end + +-- handle multiple layers in apparatuses +-- +local apparatuses = {} +local bagunits = {} + +function ekdosis.newapparatus(teitype, + appdir, + apprule, + appdelim, + appsep, + appbhook, + appehook) + if isintable(apparatuses, teitype) + then + tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" + ..teitype.. + "\" already exists.}}") + else + table.insert(apparatuses, {a = teitype, + direction = appdir, + rule = apprule, + delim = appdelim, + sep = appsep, + bhook = appbhook, + ehook = appehook}) + end + bagunits[teitype] = 1 + return true +end + +function ekdosis.getappdelim(str) + for i = 1,#apparatuses + do + if apparatuses[i].a == str then + delimfound = apparatuses[i].delim + break + end + end + return delimfound +end + +function ekdosis.get_bagunits(teitype) + return bagunits[teitype] +end + +function ekdosis.increment_bagunits(teitype) + bagunits[teitype] = (bagunits[teitype] or 0) + 1 +end + +local function reset_bagunits() + for i = 1,#apparatuses + do + bagunits[apparatuses[i].a] = 1 + end +end + +function ekdosis.appin(str, teitype) + local f = io.open(tex.jobname.."_tmp.ekd", "a+") + if next(apparatuses) == nil + then + f:write("<", cur_abs_pg, cur_alignment, curcol, "-0>", str, "</", + cur_abs_pg, cur_alignment, curcol, "-0>\n") + else + for i = 1,#apparatuses + do + if apparatuses[i].a == teitype then + appno = i + break + end + end + f:write("<", cur_abs_pg, cur_alignment, curcol, "-", + appno, ">", str, "</", cur_abs_pg, cur_alignment, curcol, "-", appno, ">\n") + end + f:close() + return true +end + +function ekdosis.appout() + local file = io.open(tex.jobname..".ekd", "r") + if file ~= nil then io.close(file) + f = assert(io.open(tex.jobname..".ekd", "r")) + t = f:read("*a") + local output = {} + if next(apparatuses) == nil then + -- table.insert(output, "BEGIN") + table.insert(output, "\\noindent\\csname ekd@default@rule\\endcsname\\NLS{}") +-- table.insert(output, "\\noindent ") + for i in string.gmatch(t, + "<"..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-0>.-</" + ..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-0>") + do + table.insert(output, i) + end + -- table.insert(output, "END") + else + local n = 1 + while apparatuses[n] + do + if string.match(t, "<"..cur_abs_pg.. + cur_alignment_patt + ..curcol.."%-"..n..">.-</" + ..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-"..n..">") + then + -- table.insert(output, "BEGIN") + table.insert(output, "\\bgroup{}") + if apparatuses[n].direction == "LR" + then + table.insert(output, "\\pardir TLT\\textdir TLT{}") + elseif apparatuses[n].direction == "RL" + then + table.insert(output, "\\pardir TRT\\textdir TRT{}") + end + if apparatuses[n].rule == "none" + then + if n > 1 + then + table.insert(output, "\\NLS{}") + else + table.insert(output, "\\noindent ") + end + elseif apparatuses[n].rule ~= "" + then + if n > 1 + then + table.insert(output, "\\NLS{}" .. apparatuses[n].rule .. "\\NLS{}") + else +-- table.insert(output, "\\noindent ") + table.insert(output, apparatuses[n].rule .. "\\NLS{}") + end + else + if n > 1 + then + table.insert(output, "\\NLS\\csname ekd@default@rule\\endcsname\\NLS{}") + else +-- table.insert(output, "\\noindent ") + table.insert(output, "\\csname ekd@default@rule\\endcsname\\NLS{}") + end + end + if apparatuses[n].sep ~= "" + then + table.insert(output, "\\edef\\ekdsep{" .. apparatuses[n].sep .. "}") + else + end + if apparatuses[n].bhook ~= "" + then + table.insert(output, apparatuses[n].bhook) + else + table.insert(output, "\\relax") + end + for i in string.gmatch(t, + "<"..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-"..n..">.-</" + ..cur_abs_pg + ..cur_alignment_patt + ..curcol.."%-"..n..">") + do + table.insert(output, i) + end + if apparatuses[n].ehook ~= "" + then + table.insert(output, apparatuses[n].ehook) + else + end + table.insert(output, "\\egroup{}") + -- table.insert(output, "END") + end + n = n + 1 + end + end + f:close() + str = table.concat(output) + str = string.gsub(str, "</"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", "") + str = string.gsub(str, "<"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", " ") + return str + else + end +end + +function ekdosis.appin_out(str, nl) + local f = io.open(tex.jobname.."_tmp.ekd", "a+") + if nl == "yes" then + f:write(str, "\n") + else + f:write(str) + end + f:close() + return true +end + +local curcol_curabspg = {} + +function ekdosis.testapparatus() + if isfound(curcol_curabspg, curcol.."-"..cur_abs_pg) + then + if newalignment + then + if next(apparatuses) ~= nil then + reset_bagunits() + end + newalignment = false + return "\\booltrue{do@app}" + else + return "\\boolfalse{do@app}" + end + else + table.insert(curcol_curabspg, curcol.."-"..cur_abs_pg) + if next(apparatuses) ~= nil then + reset_bagunits() + end + return "\\booltrue{do@app}" + end +end + +local lnlabs = {} +local lnlab_salt = 0 +local current_lnlab = nil +local prev_lnlab = nil +local current_notelab = nil +local prev_notelab = nil +local current_lemma = nil +local salt = 0 + +local function mdvisintable(table, value) + for _, v in pairs(table) do + if v == value then return true end + end + return false +end + +function ekdosis.dolnlab(str) + prev_lnlab = current_lnlab + current_lemma = str + i = md5.sumhexa(str) + if not mdvisintable(lnlabs, i) then + table.insert(lnlabs, i) + else + i = i..salt + table.insert(lnlabs, i) + salt = salt + 1 + end + current_lnlab = i + return true +end + +function ekdosis.getlnlab() + return current_lnlab +end + +function ekdosis.getprevlnlab() + return prev_lnlab +end + +function ekdosis.setnotelab(str) + current_notelab = str + return "\\linelabel{" .. current_notelab .. "}" +end + +function ekdosis.getnotelab() + return current_notelab +end + +function ekdosis.setprevnotelab(str) + prev_notelab = str + return true +end + +function ekdosis.getprevnotelab() + return prev_notelab +end + +local function remove_note(str) + str = gsub(str, dblbkslash * lpeg.P("note") * cmdargs, "") + return str +end + +function ekdosis.mdvappend(str, teitype) + if teitype == nil + then + return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" + .. + current_lemma + .. + "\\linelabel{" .. current_lnlab .. "-e}" + .. + "\\csname append@app\\endcsname{" + .. remove_note(str) .. "}" + else + return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" + .. + current_lemma + .. + "\\linelabel{" .. current_lnlab .. "-e}" + .. + "\\csname append@app\\endcsname" .. "[" .. teitype .. "]{" + .. remove_note(str) .. "}" + end +end + diff --git a/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.sty b/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.sty new file mode 100644 index 00000000000..ae7abb0f8dc --- /dev/null +++ b/Master/texmf-dist/tex/lualatex/ekdosis/ekdosis.sty @@ -0,0 +1,959 @@ +%% +%% This is file `ekdosis.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ekdosis.dtx (with options: `package') +%% -------:| ----------------------------------------------------------------- +%% ekdosis:| Typesetting TEI xml compliant critical editions +%% Author:| Robert Alessi +%% E-mail:| alessi@robertalessi.net +%% License:| Released under the GNU General Public License v3 or later +%% See:| http://www.gnu.org/licenses/ +%% +%% This file is part of the `ekdosis' package +%% +%% ekdosis -- Typesetting TEI xml compliant critical editions +%% Copyright (C) 2020 Robert Alessi +%% +%% Please send error reports and suggestions for improvements to Robert +%% Alessi <alessi@robertalessi.net> +%% +%% This program is free software: you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published by +%% the Free Software Foundation, either version 3 of the License, or +%% (at your option) any later version. +%% +%% This program is distributed in the hope that it will be useful, but +%% WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%% General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with this program. If not, see +%% <http://www.gnu.org/licenses/>. +%% +%% This work consists of the files ekdosis.dtx, ekdosis.el, this file and +%% a Makefile. +%% Running "make" generates the derived files README, ekdosis.pdf and +%% ekdosis.sty. +%% Running "make inst" installs the files in the user's TeX tree. +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{ekdosis} + [2020/07/08 v0.99a Typesetting TEI xml compliant critical editions] +\RequirePackage{iftex} +\RequireLuaTeX +\RequirePackage{expkv-opt} +\RequirePackage{expkv-def} +\newif\if@pkg@float +\newif\if@pkg@footins +\newif\if@pkg@ekddivs +\newif\if@parnotesroman +\newif\if@pkg@parnotes +\newif\iftei@export +\ekvdefinekeys{ekdosis}{ + choice layout = {float = {\@pkg@floattrue}, + footins = {\@pkg@footinstrue}}, + initial layout = float, + unknown-choice layout = \PackageError{ekdosis}{unknown + layout=#1}{`layout' must be either `float' or `footins'.}, + choice divs = {ekdosis = {\@pkg@ekddivstrue}, + latex = {\@pkg@ekddivsfalse + \AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}}}}, + initial divs = ekdosis, + unknown-choice divs = \PackageError{ekdosis}{unknown divs=#1}{`divs' + must be either `ekdosis' or `latex'.}, + choice parnotes = {false = {}, + true = {\@pkg@parnotestrue}, + roman = {\@pkg@parnotestrue\@parnotesromantrue}}, + default parnotes = true, + unknown-choice parnotes = \PackageError{ekdosis}{unknown + parnotes=#1}{`parnotes' must be either `true', or `false' or + `roman'.}, + choice teiexport = {false = {}, + true = {\tei@exporttrue + \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% + \AtEndDocument{\luadirect{ekdosis.closeteistream()}}}, + tidy = {\tei@exporttrue + \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% + \AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}}}}, + default teiexport = true, + unknown-choice teiexport = \PackageError{ekdosis}{unknown + teiexport=#1}{`teiexport' must be either `true', `false' or + `tidy'.} +} +\ekvoProcessLocalOptions{ekdosis} +\RequirePackage{luacode} +\RequirePackage{paracol} +\RequirePackage{xparse} +\RequirePackage{etoolbox} +\RequirePackage{lineno} +\RequirePackage{keyfloat} +\RequirePackage{refcount} +\RequirePackage[user,abspage]{zref} +\RequirePackage{ltxcmds} +\if@pkg@parnotes + \RequirePackage{parnotes} +\fi +\luadirect{dofile(kpse.find_file("ekdosis.lua"))} +\AtEndDocument{ + \luadirect{ekdosis.closestream()} +} +\renewcommand\linenumberfont{\normalfont\footnotesize} +\ekvdefinekeys{ekd@hooks}{ + store appfontsize = \ekd@appfontsize, + store refnumstyle = \ekd@refnumstyle, + store postrefnum = \ekd@postrefnum, + initial appfontsize = \footnotesize, + initial refnumstyle = \bfseries, + initial postrefnum = ~ +} +\NewDocumentCommand{\SetEkdosisHooks}{m}{\ekvset{ekd@hooks}{#1}} +\ekvdefinekeys{ekd@witness}{ + store settlement = \settlement@value, + store institution = \institution@value, + store repository = \repository@value, + store collection = \collection@value, + store idno = \idno@value, + store msName = \msName@value, + store origDate = \origDate@value +} +\NewDocumentCommand{\DeclareWitness}{m m m O{}}{% + \bgroup + \ekvset{ekd@witness}{#4} + \luadirect{ekdosis.newwitness( + \luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringO{\settlement@value}, + \luastringO{\institution@value}, + \luastringO{\repository@value}, + \luastringO{\collection@value}, + \luastringO{\idno@value}, + \luastringO{\msName@value}, + \luastringO{\origDate@value})} + \egroup + } +\@onlypreamble\DeclareWitness +\NewDocumentCommand{\DeclareHand}{m m m +O{}}{ + \luadirect{ekdosis.newhand(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringN{#4})} +} +\@onlypreamble\DeclareHand +\NewDocumentCommand{\DeclareScholar}{m m}{ + \luadirect{ekdosis.newscholar(\luastringN{#1}, + \luastringN{#2})} +} +\@onlypreamble\DeclareScholar +\NewDocumentCommand{\DeclareShorthand}{m m m}{ + \luadirect{ekdosis.newshorthand(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +\@onlypreamble\DeclareShorthand +\NewDocumentCommand{\getsiglum}{m}{% + \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% +} +\NewDocumentCommand{\SigLine}{m}{% + \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} +} +\NewDocumentCommand{\TeXtoTEI}{m m O{}}{% + \luadirect{ekdosis.newcmdtotag(\luastringN{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +\NewDocumentCommand{\EnvtoTEI}{s m m O{}}{% + \IfBooleanTF{#1}{% + \luadirect{ekdosis.newenvtotag(\luastringN{#2}, + \luastringN{#3}, + \luastringN{#4}, + "yes")} + }{% + \luadirect{ekdosis.newenvtotag(\luastringN{#2}, + \luastringN{#3}, + \luastringN{#4})} + } +} +\NewDocumentCommand{\TeXtoTEIPatt}{m m}{% + \luadirect{ekdosis.newpatttotag(\luastringN{#1}, \luastringN{#2})} +} +\NewDocumentCommand{\SetTEIFileName}{m}{ + \luadirect{ekdosis.setteifilename(\luastringN{#1})} +} +\@onlypreamble\SetTEIFileName +\NewDocumentCommand{\SetxmlBibResource}{m}{ + \luadirect{ekdosis.setxmlbibresource(\luastringN{#1})} +} +\@onlypreamble\SetxmlBibResource +\newif\ifekd@mapps +\ekvdefinekeys{ekd@newapp}{ + choice direction = {LR = \def\direction@val{LR}, + RL = \def\direction@val{RL}}, + unknown-choice direction = \PackageError{ekdosis}{unknown + direction=#1}{`direction' must be either `LR' or `RL'.}, + store rule = \rule@val, + store delim = \delim@val, + store sep = \sep@val, + store bhook = \bhook@val, + store ehook = \ehook@val, + initial direction = LR, + initial ehook = {\csname ekd@end@apparatus\endcsname} +} +\NewDocumentCommand{\DeclareApparatus}{m O{}}{ + \newbool{subsq@unit@#1} + \booltrue{subsq@unit@#1} + \unless\ifekd@mapps\global\ekd@mappstrue\fi + \bgroup + \ekvset{ekd@newapp}{#2} + \luadirect{ekdosis.newapparatus( + \luastringN{#1}, + \luastring{\direction@val}, + \luastringO{\rule@val}, + \luastringO{\delim@val}, + \luastringO{\sep@val}, + \luastringO{\bhook@val}, + \luastringO{\ehook@val} + )} + \egroup +} +\@onlypreamble\DeclareApparatus +\newbool{do@app} +\newif\ifekd@state +\newif\ifekd@isinapp +\newif\ifekd@isinlem +\providebool{al@rlmode} +\@ifpackageloaded{arabluatex}{}{% + \def\setRL{\booltrue{al@rlmode}\pardir TRT\textdir TRT} + \def\setLR{\boolfalse{al@rlmode}\pardir TLT \textdir TLT} +} +\protected\def\LRnum#1{\bgroup\textdir TLT#1\egroup} +\newcounter{ekd@lab} +\globalcounter{ekd@lab} +\NewDocumentCommand{\unconditional@appin}{o m}{% + \IfNoValueTF{#1} + {\luadirect{ekdosis.appin(\luastringO{#2})}} + {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% +} + % \def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext} +\def\blfootnote{\gdef\@thefnmark{}\@blfootnotetext} +\long\def\@blfootnotetext#1{\insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark + }% + \color@begingroup + \@makeblfntext{% + \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% + \color@endgroup}}% +\newcommand\@makeblfntext[1]{% + \parindent 1em% + \noindent + \hb@xt@0em{\hss\@makefnmark}#1} +\newif\ifrtl@app +\NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue} +\NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse} +\edef\ekdsep{] } +\NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}} +\edef\ekd@end@apparatus{} +\NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}} +\def\ekd@unit@delim{} +\NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}} +\def\ekd@default@rule{\rule{2truein}{0.5pt}} +\newif\iffootnoterule +\footnoteruletrue +\let\dflt@footnoterule\footnoterule +\let\dflt@pcol@footnoterule\pcol@footnoterule +\renewcommand\footnoterule{% + \iffootnoterule + \dflt@footnoterule% + \fi +} +\renewcommand\pcol@footnoterule{% + \iffootnoterule + \dflt@pcol@footnoterule% + \fi +} +\NewDocumentCommand{\SetDefaultRule}{m}{% + \def\@tempa{#1} + \ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}% + \else% + \def\ekd@default@rule{#1}% + \fi} +\newcommand*{\NLS}{% + \par% + \nobreak% + \vspace{-\parskip}% + \noindent% + \ignorespaces} +\newif\ifsubsq@unit +\subsq@unittrue +\def\add@@apparatus{% + \if@pkg@parnotes\parnotes\else\fi% + \if@pkg@footins% + \bgroup% + \ifrtl@app\setRL\else\setLR\fi% + \blfootnote{% + \if@pkg@parnotes% + \if@parnotesroman% + \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% + \parnoteclear\else\fi% + \footnotesize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% + \if@pkg@parnotes\parnotes\parnotereset\else\fi% + }% + \egroup% + \fi% + \if@pkg@float% + \keyparbox[!b]{}{\ifrtl@app\setRL\else\setLR\fi% + \if@pkg@parnotes% + \if@parnotesroman% + \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% + \parnoteclear\else\fi% + \ekd@appfontsize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% + \if@pkg@parnotes\parnotes\parnotereset\else\fi% + }% + \fi% +} +\def\add@apparatus{% + \test@apparatus% + \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}% +} +\NewDocumentCommand{\append@app}{o +m}{% + \ifekd@isinapp% + \ifekd@state% + \IfNoValueTF{#1}% + {\luadirect{ekdosis.appin(\luastringO{#2})}}% + {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% + \fi% + \fi} +\NewDocumentCommand{\append@ln@app}{o +m}{% + \IfNoValueTF{#1} + {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}} + {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}, + \luastringO{#1}))}}} +\ekvdefinekeys{appnote}{ + store type = \ekdan@type, + initial type = default + } +\NewDocumentCommand{\EkdosisDefaultApparatus}{m}{% + \ekvset{appnote}{type=#1}} +\NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{% + \begingroup + \ekvset{appnote}{#1}% + \ekd@isinapptrue% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{ekdosis.storeabspg( + \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% + \ifekd@state\add@apparatus\fi% + \luadirect{tex.sprint(ekdosis.removesp(\luastringN{#2}))}% + \ekd@isinappfalse% + \endgroup} +\def\current@ref@arg#1#2{{%\textdir TLT% + \unexpanded\expandafter{\ekd@refnumstyle}% + \ifnum% + \getpagerefnumber{#1} + = + \getpagerefnumber{#2} + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{#2} + % + \ifekd@mapps% + \ifbool{subsq@unit@\ekdan@type}{% + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi% + }% + {\LRnum{\getrefnumber{#1}}}% issue the no + \else + \ifsubsq@unit% + % + \ifnum% + \getrefnumber{#1} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi + % + \else + \LRnum{\getrefnumber{#1}}% issue the no + \fi + \fi + % + \else + \LRnum{\getrefnumber{#1}}--% + \LRnum{\getrefnumber{#2}}% issue the nos + \fi% + \else + \LRnum{\getrefnumber{#1}}--% + \LRnum{\getpagerefnumber{#2}}.% + \LRnum{\getrefnumber{#2}}% issue pg and ln nos + \fi% + }\unexpanded\expandafter{\ekd@postrefnum}% +} +\def\current@ref{{%\textdir TLT% + \unexpanded\expandafter{\ekd@refnumstyle}% + \ifnum% + \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} + % + \ifekd@mapps% + \ifbool{subsq@unit@\ekdan@type}{% + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi% + }{\LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}}% issue the no + \else + \ifsubsq@unit% + % + \ifnum% + \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} + = + \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi + % + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no + \fi + \fi + % + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue the nos + \fi% + \else + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% + \LRnum{\getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}.% + \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue pg and ln nos + \fi% + }\unexpanded\expandafter{\ekd@postrefnum}% +} +\ekvdefinekeys{lem}{ + code wit = \def\ekdlr@wit{#1}, + code alt = \def\ekdlr@alt{#1}, + code pre = \def\ekdlr@pre{#1}, + code post = \def\ekdlr@post{#1}, + code prewit = \def\ekdlr@prewit{#1}, + code postwit = \def\ekdlr@postwit{#1}, + store type = \ekdlr@type, + store sep = \ekdl@sep, + bool nolem = \ifekdl@nolem, + bool nosep = \ifekdl@nosep, + initial sep = \ekdsep +} +\ekvdefinekeys{rdg}{ + code wit = \def\ekdlr@wit{#1}, + code alt = \def\ekdlr@alt{#1}, + code pre = \def\ekdlr@pre{#1}, + code post = \def\ekdlr@post{#1}, + code prewit = \def\ekdlr@prewit{#1}, + code postwit = \def\ekdlr@postwit{#1}, + store type = \ekdlr@type, + bool nordg = \ifekdr@nordg +} +\NewDocumentCommand{\lem}{O{} m}{% + \ekd@isinlemtrue% + \luadirect{ekdosis.dolnlab(\luastringN{#2})}% + \bgroup% + \ekvset{lem}{#1}% + \ifekd@mapps% + \ifnum% + \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} + = 1 + \boolfalse{subsq@unit@\ekdan@type}% + \fi% + \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% + \def\ekd@munit@delim{% + \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% + \fi% + \ifekdl@nolem\edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref}%\hskip .25em}% + \else% + \ifbool{al@rlmode}{% + \edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref%\hskip .25em + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \else + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded{#2}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi + }% + }% + {% + \edef\lem@app{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref%\hskip .25em + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdlr@alt}}% + {\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \else + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi + }% + }% + \fi% + \ifekd@mapps% + \append@ln@app[\ekdan@type]{\lem@app}% + \else% + \append@ln@app{\lem@app}% + \fi% + \egroup% + \ekd@isinlemfalse% + \subsq@unittrue% +} +\NewDocumentCommand{\rdg}{O{} m}{% + \bgroup% + \ekvset{rdg}{#1}% + % \ifekdr@nordg\append@app{}\else% do we need \append@app{} here? If + % % so, keep in mind \ifekd@mapps, + % like so: + \ifekdr@nordg% + \ifekd@mapps% + \append@app[\ekdan@type]{}% + \else% + \append@app{}% + \fi% + \else% + \ifbool{al@rlmode}{% + \edef\rdg@app{% + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \else + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + {\textdir TRT\unexpanded{#2}}% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + }% + }% + {% + \edef\rdg@app{% + \ifdefined\ekdlr@alt% + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdlr@alt}}% + {\unexpanded\expandafter{\ekdlr@alt}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \else + \ifdefined\ekdlr@pre% + \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}% + \ifdefined\ekdlr@post% + \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi + \fi + \ifdefined\ekdlr@prewit% + \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi + \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi + \ifdefined\ekdlr@postwit% + \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi + }% + }% + \ifekd@mapps% + \append@app[\ekdan@type]{\rdg@app}% + \else% + \append@app{\rdg@app}% + \fi% + \fi% + \egroup% +} +\ekvdefinekeys{note}{ + store type = \ekdan@type, + store lem = \ekdn@lem, + code labelb = \def\ekdn@labelb{#1}, + code labele = \def\ekdn@labele{#1}, + store sep = \ekdn@sep, + initial type = default, + initial sep = \ekdsep +} +\NewDocumentCommand{\note@noapp}{O{} +m}{% + \bgroup% + \ekvset{note}{#1}% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{ekdosis.storeabspg( + \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% + \ifekd@state\add@apparatus\fi% + \ifekd@mapps% + \ifnum% + \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} + = 1 + \boolfalse{subsq@unit@\ekdan@type}% + \fi% + \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% + \def\ekd@munit@delim{% + \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% + \fi% + \ifdefined\ekdn@labelb% + \luadirect{tex.sprint(ekdosis.setnotelab(\luastringO{\ekdn@labelb}))}% + \ifdefined\ekdn@labele\else\def\ekdn@labele{\ekdn@labelb}\fi% + \else\PackageError{ekdosis}{missing labelb}{`labelb' must be + set.}\fi% + \ifbool{al@rlmode}% + {\edef\note@contents{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em + \ifdefined\ekdn@lem% + {\textdir TRT\unexpanded\expandafter{\ekdn@lem}}% + \unexpanded\expandafter{\ekdn@sep}\else\fi% + {\textdir TRT\unexpanded{#2}}}}% + {\edef\note@contents{% + % \hskip .75em + \ifekd@mapps + \ifbool{subsq@unit@\ekdan@type}% + {\ekd@munit@delim}{}% + \else% + \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% + \fi% + \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em + \ifdefined\ekdn@lem + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}% + \unexpanded\expandafter{\ekdn@lem}}% + {\unexpanded\expandafter{\ekdn@lem}}% + \unexpanded\expandafter{\ekdn@sep}\else\fi% + \ltx@ifpackageloaded{babel}% + {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% + \unexpanded{#2}}}}% + \ifekd@mapps% + \unconditional@appin[\ekdan@type]{\note@contents}% + \else% + \unconditional@appin{\note@contents}% + \fi% + \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}% + \egroup% + \subsq@unittrue% +} +\ekvdefinekeys{ekd@note}{ + store pre = \pre@value, + store post = \post@value +} +\NewDocumentCommand{\ekd@note}{O{} m}{% + \bgroup% + \ekvset{ekd@note}{#1}% + \edef\note@contents{% + \ekvifdefinedNoVal{note}{pre}{}{% + \unexpanded\expandafter{\pre@value}}% + \unexpanded{#2}% + \ekvifdefinedNoVal{note}{post}{}{% + \unexpanded\expandafter{\post@value}}% + }% + \append@app{\note@contents}% + \egroup% +} +\NewDocumentCommand{\ekd@note@star}{O{} m}{% + \if@pkg@parnotes + \bgroup% + \ekvset{ekd@note}{#1}% + \edef\note@contents{% + \ekvifdefinedNoVal{note}{pre}{}{% + \unexpanded\expandafter{\pre@value}}% + \unskip\noexpand\parnote{#2}% + \ekvifdefinedNoVal{note}{post}{}{% + \unexpanded\expandafter{\post@value}}% + }% + \append@app{\note@contents}% + \egroup% + \else + \append@app{\unskip\footnote{#2}}% + \fi% +} +\NewDocumentCommand{\note@app}{s O{} +m}{% + \ifbool{al@rlmode}{% + \IfBooleanTF{#1}{\ekd@note@star[#2]{% + {\textdir TRT#3}}} + {\ekd@note[#2]{{\textdir TRT#3}}}% + }{% + \IfBooleanTF{#1}{\ekd@note@star[#2]{#3}} + {\ekd@note[#2]{#3}}% + }% +} +\NewDocumentCommand{\note}{s O{} +m}{% + \ifekd@state% + \ifekd@isinapp% + \ifekd@isinlem% + \note@noapp[#2]{#3}% + \else% + \IfBooleanTF{#1}{\note@app*[#2]{#3}}{\note@app[#2]{#3}}% + \fi% + \else% + \note@noapp[#2]{#3}% + \fi% + \fi% +} +\NewDocumentCommand{\apparatus}{}{% + \luadirect{tex.sprint(ekdosis.appout())}} +\NewDocumentCommand{\test@apparatus}{}{% + \luadirect{tex.sprint(ekdosis.testapparatus())}} +\NewDocumentCommand{\ekd@storecol}{}{% + \luadirect{ekdosis.storecurcol(\luastring{\thecolumn})}% +} +\NewDocumentCommand{\EkdosisOn}{}{% + \ekd@statetrue} +\NewDocumentCommand{\EkdosisOff}{}{% + \ekd@statefalse% +} +\def\ekd@setlineno{% + \let\setpagewiselinenumbers\relax% + \let\pagewiselinenumbers\relax% + \let\endpagewiselinenumbers\relax% + \let\runningpagewiselinenumbers\relax% + \let\realpagewiselinenumbers\relax% +} +\NewDocumentEnvironment{ekdosis}{+b}{% + \ekd@setlineno% + \runninglinenumbers + \EkdosisOn#1}{% + \EkdosisOff + \endrunninglinenumbers% + \iftei@export + \luadirect{ekdosis.exporttei(\luastringN{\par #1\par })}\fi} +\newif\ifekd@pagelineation +\ekvdefinekeys{ekd@align}{ + store tcols = \tcols@num, + store lcols = \lcols@num, + store texts = \texts@value, + store apparatus = \apparatus@value, + bool paired = \ifekd@paired, + choice lineation = {page = \ekd@pagelineationtrue, + document = \ekd@pagelineationfalse}, + unknown-choice lineation = \PackageError{ekdosis}{unknown + lineation=#1}{`lineation' must be either `page' or `document'.}, + choice segmentation = {auto = \def\segmentation@val{auto}, + noauto = \def\segmentation@val{noauto}}, + unknown-choice segmentation = \PackageError{ekdosis}{unknown + segmentation=#1}{`segmentation' must be either `auto' or + `noauto'.}, + bool flush = \ifekd@flushapp, + initial tcols = 2, + initial lcols = 1, + initial texts = edition;translation, + initial apparatus = edition, + default segmentation = auto +} +\NewDocumentCommand{\SetEkdosisAlignment}{m}{ + \ekvset{ekd@align}{#1} +} +\patchcmd{\pcol@nextpage}{% + \endgroup}{% + \ifekd@pagelineation\resetlinenumber\fi + \endgroup}{}{} +\NewDocumentCommand{\EkdosisColStart}{}{% + \ekd@setlineno% + \runninglinenumbers + \ekd@storecol% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{% + ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, + "pg_i")}% + \ifekd@pagelineation + \luadirect{tex.sprint(ekdosis.checkresetlineno())} + \fi +} +\NewDocumentCommand{\EkdosisColStop}{}{% + \stepcounter{ekd@lab}% + \zlabel{ekd:\theekd@lab}% + \luadirect{% + ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, + "pg_ii")}% + \endrunninglinenumbers% +} +\NewDocumentEnvironment{alignment}{O{}} +{% + \ekvset{ekd@align}{#1}% + \luadirect{ekdosis.mkenvdata( + \luastring{\texts@value}, + "texts" + )} + \ifekd@flushapp + \luadirect{ekdosis.newalignment("set")} + \fi + \luadirect{ekdosis.mkenvdata( + \luastring{\apparatus@value}, "apparatus" + )} + \setrunninglinenumbers + \luadirect{tex.sprint(ekdosis.mkenv())} + \ifekd@paired + \begin{paracol}[\lcols@num]{\tcols@num} + \else + \begin{paracol}[\lcols@num]*{\tcols@num} + \fi + } + {\end{paracol} + \iftei@export\luadirect{ekdosis.export_coldata_totei()}\fi + \ifekd@flushapp + \luadirect{ekdosis.newalignment("reset")} + \fi + \luadirect{ekdosis.flushenvdata()} + \luadirect{ekdosis.flushcolnums()} + } +\NewDocumentCommand{\MkBodyDivs}{mmmmmm}{ + \luadirect{ekdosis.mkdivdepths( + \luastringN{#1}, + \luastringN{#2}, + \luastringN{#3}, + \luastringN{#4}, + \luastringN{#5}, + \luastringN{#6} + ) + } +} +\ekvdefinekeys{ekd@div}{ + code type = \def\type@value{#1}, + code n = \def\n@value{#1}, + code head = \def\head@value{#1}, + code barehead = \def\barehead@value{#1}, + store depth = \depth@value, + choice toc = {book = \def\toc@value{book}, + part = \def\toc@value{part}, + chapter = \def\toc@value{chapter}, + section = \def\toc@value{section}, + subsection = \def\toc@value{subsection}, + subsubsection = \def\toc@value{subsubsection}, + paragraph = \def\toc@value{paragraph}, + subparagraph = \def\toc@value{subparagraph}}, + unknown-choice toc = \PackageError{ekdosis}{unknown toc=#1}{`toc' + must be either `book', `part', `chapter', `section', `subsection', + \MessageBreak `subsubsection', `paragraph' or `subparagraph'.}, + initial depth = 1 +} +\NewDocumentCommand{\ekdfmtdiv}{m m m}{ + \luadirect{ekdosis.fmtdiv(\luastring{#1}, + \luastringN{#2}, + \luastringN{#3})} +} +\NewDocumentCommand{\ekd@getfmtdiv}{m m}{% + \luadirect{tex.sprint(ekdosis.getfmtdiv(\luastringO{#1}, + \luastringN{#2}))}% +} +\NewDocumentCommand{\ekddiv}{m}{ + \begingroup + \ekvset{ekd@div}{#1}% + \ifdefined\head@value + \bgroup + \ekd@getfmtdiv{\depth@value}{b}% + \head@value + \ekd@getfmtdiv{\depth@value}{e}% + \egroup + \ifdefined\toc@value + \ltx@ifpackageloaded{hyperref}{\phantomsection}{}% + \ifdefined\barehead@value + \addcontentsline{toc}{\toc@value}{\barehead@value}% + \else + \addcontentsline{toc}{\toc@value}{\head@value}% + \fi + \fi + \fi + \endgroup +} +\newlength{\ekdverseindentlength} +\setlength{\ekdverseindentlength}{\parindent} +\newenvironment*{ekdverse}[1][\ekdverseindentlength]{ + \begin{list}{}{% + \setlength{\leftmargin}{#1} + \setlength{\itemsep}{0pt} + \setlength{\topsep}{0pt} + \setlength{\partopsep}{0pt} + } + \item[] + }{\end{list}} +\endinput +%% +%% End of file `ekdosis.sty'. |