% \iffalse meta-comment
% vim: textwidth=75
%<*internal>
\iffalse
%
%<*readme>
|
-------:| -----------------------------------------------------------------
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/
Short description:
Some text about the package: probably the same as the abstract.
%
%<*luapre>
--[[
This file is part of the `ekdosis' package
ekdosis -- Typesetting TEI xml compliant critical editions
Copyright (C) 2016 Robert Alessi
Please send error reports and suggestions for improvements to Robert
Alessi
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
.
--]]
%
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
\expandafter\begingroup
\fi
%
%<*install>
\input docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble
-------:| -----------------------------------------------------------------
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) 2016 Robert Alessi
Please send error reports and suggestions for improvements to Robert
Alessi
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
.
This work consists of the file ekdosis.dtx 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.
Running "make install" installs the files in the local TeX tree.
\endpreamble
\usedir{tex/lualatex/ekdosis}
\generate{
\file{\jobname.sty}{\from{\jobname.dtx}{package}}
}
\nopreamble\nopostamble
\usedir{tex/lualatex/ekdosis}
\bgroup
\catcode9=12
\generate{
\file{\jobname.lua}{
\from{\jobname.dtx}{luapre}
\from{\jobname.dtx}{lua}
}
}
\egroup
%
%\endbatchfile
%<*internal>
\usedir{source/lualatex/ekdosis}
\generate{
\file{\jobname.ins}{\from{\jobname.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/lualatex/ekdosis}
\generate{
\file{README.txt}{\from{\jobname.dtx}{readme}}
}
\ifx\fmtname\nameofplainTeX
\expandafter\endbatchfile
\else
\expandafter\endgroup
\fi
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{ekdosis.dtx}
%
%\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%\ProvidesPackage{ekdosis}
%<*package>
[2016/08/03 v1.0 Typesetting TEI xml compliant critical editions]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry}
\usepackage{metalogox}
\usepackage{hologo}
\usepackage{hyperxmp}
\usepackage{uri}
\usepackage[numbered]{hypdoc}
\hypersetup{unicode=true, colorlinks, allcolors=blue,
linktocpage=true, pdfauthor={Robert Alessi}, pdftitle={The
ekdosis package}, pdfcontactemail={alessi@robertalessi.net},
pdfcontacturl={http://www.robertalessi.net/ekdosis},
pdfcopyright={Copyright (C) 2018 Robert Alessi
. This document is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International
License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to
Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.},
pdflicenseurl={https://creativecommons.org/licenses/by-sa/4.0/legalcode},
pdfmetalang={en-US}, pdftype={Text}, pdfkeywords={Arabic language,
arabtex, luatex}}
\usepackage[lot]{multitoc}
\usepackage{ekdosis}
\usepackage{fontspec}
\setmainfont{Old Standard}[RawFeature={+ss05;+ss06}]
\usepackage{newunicodechar}
\newunicodechar{ǧ}{ǧ} % Old Standard does not include ǧ/Ǧ
\newunicodechar{Ǧ}{Ǧ} %
\usepackage{arabluatex}
\usepackage{relsize}
\usepackage{units}
\usepackage[newfloat=true]{minted}
\newminted[ekdlua]{lua}{linenos, fontsize=\relsize{-0.5},
xleftmargin=12pt, breaklines,
numberblanklines=false, numbersep=3pt, firstnumber=last}
\renewcommand{\theFancyVerbLine}{\rmfamily\smaller\arabic{FancyVerbLine}}
\usepackage[contents]{colordoc}
\newcommand{\package}[1]{\textsf{#1}\index{#1=#1 (package)}}
\usepackage{tikz}
\usepackage[breakable, skins, xparse, minted]{tcolorbox}
\usepackage{etoc}
\etocsettocdepth{paragraph}
\newcommand{\ekdtableofcontents}{%
\begingroup
\etocsetstyle{section}{}{}
{\etocsavedsectiontocline{%
\numberline{\etocnumber}\etocname}{\etocpage}}{}
\etocsetstyle{subsection}{}{}
{\etocsavedsubsectiontocline{%
\numberline{\etocnumber}\etocname}{\etocpage}}{}%
\etocsetstyle{subsubsection}{}{}
{\etocsavedsubsubsectiontocline{%
\numberline{\etocnumber}\etocname}{\etocpage}}{}%
\etocsetstyle{paragraph}{}{\leftskip2cm\rightskip 2.2em \parfillskip
0pt plus 1fil\relax \nobreak}
{\noindent\etocname{} \etocpage{} }{\par}%
\etocmulticolstyle[2]{\section*{Contents}}
\pdfbookmark[1]{Contents}{toc}
\tableofcontents
\endgroup}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
%\OnlyDescription
\begin{document}
\DocInput{\jobname.dtx}
\PrintChanges
\PrintIndex
\end{document}
%
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
% {Upper-case \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
% Lower-case \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
% Digits \0\1\2\3\4\5\6\7\8\9
% Exclamation \! Double quote \" Hash (number) \#
% Dollar \$ Percent \% Ampersand \&
% Acute accent \' Left paren \( Right paren \)
% Asterisk \* Plus \+ Comma \,
% Minus \- Point \. Solidus \/
% Colon \: Semicolon \; Less than \<
% Equals \= Greater than \> Question mark \?
% Commercial at \@ Left bracket \[ Backslash \\
% Right bracket \] Circumflex \^ Underscore \_
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
% \GetFileInfo{\jobname.dtx}
% \DoNotIndex{\newcommand,\newenvironment}
%
% \title{\tcbox[colframe=black, enhanced, tikznode, drop lifted
% shadow, colback=white, boxrule=.25mm]%
% {ἔκδοσις\\
% Typesetting \texttt{TEI xml} compliant critical editions\\
% \fileversion\ --- \filedate}}
%
% \author{Robert Alessi \\
% \href{mailto:alessi@robertalessi.net?Subject=ekdosis package}%
% {\texttt{alessi@robertalessi.net}}}
%
% \date{}
%
% \maketitle
% \footnotesize
% \ekdtableofcontents
% \normalsize
%
%\changes{v1.00}{2016/08/03}{First public release}
%
% \begin{abstract}
% ==== Put abstract text here. ====
% \end{abstract}
%
% \section{Usage}
%
% ==== Put descriptive text here. ====
%
% \DescribeMacro{\dummyMacro}
% This macro does nothing.\index{doing nothing|usage} It is merely an
% example. If this were a real macro, you would put a paragraph here
% describing what the macro is supposed to do, what its mandatory and
% optional arguments are, and so forth.
%
% \DescribeEnv{dummyEnv}
% This environment does nothing. It is merely an example.
% If this were a real environment, you would put a paragraph here
% describing what the environment is supposed to do, what its
% mandatory and optional arguments are, and so forth.
%
% \section{Grid}
% \begin{keyfigure}[H]{c={Grid
% typesetting},l={fig:grid-typesetting},t={Each square in the grid
% has a side length of \unit[10]{pt}. Therefore, the distance
% between the last line of the text and the first line of the
% apparatus is here approximately \unit[25]{pt}.}}
% \begin{tikzpicture}
% \draw[lightgray,thin] (0.5,0.5) grid [step=10pt] (10,5); %
% \path node [align=justify, text width=8cm] at (5.5,3) {%
% I saw my friend Peter at the station yesterday. I saw my friend
% Peter at the station yesterday. I saw my friend Peter at the
% station yesterday. I saw my friend Peter at the station
% yesterday.\par
% \rule{3cm}{0.01cm}\par\footnotesize%
% \textbf{1}~Peter A: John B \textbf{2}~Peter A: John B
% \textbf{3}~Peter A: John B \textbf{4}~Peter A: John B}; \node at
% (0,3) {\scriptsize $\approx$ \unit[25]{pt}}; \draw [->] (0,2.9) --
% (0,2);
% \end{tikzpicture}
% \end{keyfigure}
%
% \section{Implementation}
%
% \iffalse
%<*package>
% \fi
%
% \package{ekdosis} relies on Lua functions and tables. Read the
% |.lua| files that accompany \package{ekdosis} for more
% information.
% \begin{macrocode}
\RequirePackage{ifluatex}
% \end{macrocode}
% \package{ekdosis} requires {\LuaLaTeX} of course. Issue an error
% if the document is processed with another engine.
% \begin{macrocode}
\ifluatex\else
\PackageError{ekdosis}{lualatex needed}{%
Package `ekdosis' needs LuaTeX.\MessageBreak
So you should use `lualatex' to process your document.\MessageBreak
See documentation of `ekdosis' for further information.}%
\expandafter\expandafter\expandafter\csname endinput\endcsname
\fi
% \end{macrocode}
% Packages that are required by \package{ekdosis}:
% \begin{macrocode}
\RequirePackage{xkeyval}
\newif\if@parnotesroman
\newif\if@pkg@parnotes
\define@choicekey+{ekdosis.sty}{parnotes}{true, false, roman}[true]{%
\edef\@pntrue{true}\edef\@pnfalse{false}\edef\@pnrm{roman}
\edef\@tempa{#1}
\ifx\@tempa\@pnfalse
\else
\ifx\@tempa\@pntrue\@pkg@parnotestrue
\else
\ifx\@tempa\@pnrm
\@pkg@parnotestrue\@parnotesromantrue
\fi\fi\fi
}{\PackageWarning{ekdosis}{parnotes: erroneous input (ignored)}}
\newif\iftei@export
% \define@boolkey{ekdosis.sty}[@pkg@]{teiexport}[true]{%
% \if@pkg@teiexport
% \tei@exporttrue
% \AtBeginDocument{\luadirect{ekdosis.openteistream()}}%
% \AtEndDocument{\luadirect{ekdosis.closeteistream()}}
% \else\fi}
\define@choicekey{ekdosis.sty}{teiexport}{true, false, tidy}[true]{%
\edef\@exptrue{true}\edef\@expfalse{false}\edef\@exptidy{tidy}
\edef\@tempa{#1}
\ifx\@tempa\@expfalse
\else
\ifx\@tempa\@exptrue
\tei@exporttrue
\AtBeginDocument{\luadirect{ekdosis.openteistream()}}%
\AtEndDocument{\luadirect{ekdosis.closeteistream()}}
\else
\ifx\@tempa\@exptidy
\tei@exporttrue
\AtBeginDocument{\luadirect{ekdosis.openteistream()}}%
\AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}}
\else\fi\fi\fi}
\ExecuteOptionsX{}
\ProcessOptionsX\relax
\RequirePackage{luacode}
\RequirePackage{paracol}
\RequirePackage{keycommand}
\RequirePackage{xparse}
\RequirePackage{etoolbox}
\PassOptionsToPackage{addpageno}{lineno}
\RequirePackage{lineno}
\RequirePackage{keyfloat}
\RequirePackage{refcount}
\RequirePackage{xspace}
\RequirePackage[user,abspage]{zref}
\if@pkg@parnotes
\RequirePackage{parnotes}
\fi
% \end{macrocode}
% Here begins the real work: load |ekdosis.lua|:
% \begin{macrocode}
\luadirect{dofile(kpse.find_file("ekdosis.lua"))}
% \end{macrocode}
% \begin{macrocode}
\AtEndDocument{
\luadirect{ekdosis.closestream()}
}
% \end{macrocode}
% Build and process the list of witnesses and hands.
% \begin{macrocode}
\newkeycommand+[\|]{\declare@new@witness}[settlement={}, repository={},
idno={}, msName={}, origDate={}][3]{%
|\luadirect|{%
ekdosis.newwitness(
|\luastringN|{#1},
|\luastringN|{#2},
|\luastringN|{#3},
|\luastringN|{\commandkey{settlement}},
|\luastringN|{\commandkey{repository}},
|\luastringN|{\commandkey{idno}},
|\luastringN|{\commandkey{msName}},
|\luastringN|{\commandkey{origDate}})}
}
\NewDocumentCommand{\DeclareNewWitness}{m m O{} +O{}}{%
\declare@new@witness[#3]{#1}{#2}{#4}
}
\@onlypreamble\DeclareNewWitness
\NewDocumentCommand{\DeclareNewHand}{m m m +O{}}{
\luadirect{ekdosis.newhand(\luastringN{#1},
\luastringN{#2},
\luastringN{#3},
\luastringN{#4})}
}
\@onlypreamble\DeclareNewHand
\NewDocumentCommand{\getsiglum}{m}{%
\luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}%
}
\NewDocumentCommand{\SigLine}{m}{%
\luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))}
}
% \end{macrocode}
% Add a \hologo{(La)TeX} command to be processed as a |TEI xml| tag:
% \begin{macrocode}
\NewDocumentCommand{\TeXtoTEI}{m m m}{%
\luadirect{ekdosis.newcmdtotag(\luastringN{#1},
\luastringN{#2},
\luastringN{#3})}
}
% \end{macrocode}
% Set |TEI| file name
% \begin{macrocode}
\NewDocumentCommand{\SetTEIFileName}{m}{
\luadirect{ekdosis.setteifilename(\luastringN{#1})}
}
\@onlypreamble\SetTEIFileName
% \end{macrocode}
% \begin{macrocode}
\newbool{ekd@started}
\newbool{do@app}
\newbool{ekd@state}
\newif\ifekd@isinapp
\providebool{al@rlmode}
\@ifpackageloaded{arabluatex}{}{%
\def\setRL{\booltrue{al@rlmode} \pardir TRT \textdir TRT}}
\newcounter{ekd@lab}
\def\unconditional@appin#1{%
\luadirect{ekdosis.appin(
\luastring{<\zref@extract{ekd:\theekd@lab}{abspage}>},
"no")}%
\luadirect{ekdosis.appin(\luastringN{#1}, "no")}%
\luadirect{ekdosis.appin(
\luastring{\zref@extract{ekd:\theekd@lab}{abspage}>},
"yes")}%
}
\def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext}
\def\add@@apparatus{%
% \blfootnote{\apparatus}%
\if@pkg@parnotes\parnotes\else\fi%
\keyparbox[b!]{}{%
\if@pkg@parnotes%
\if@parnotesroman%
\renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi%
\parnoteclear\else\fi%
\footnotesize\apparatus%
\if@pkg@parnotes\parnotes\parnotereset\else\fi%
}%
\unconditional@appin{\rule{5cm}{0.5pt}\newline}
}
\def\add@apparatus{%
\notbool{ekd@started}{\add@@apparatus%
\global\setbool{ekd@started}{true}}
{\test@apparatus%
\ifbool{do@app}{\add@@apparatus}{}}%
}
\NewDocumentCommand{\append@app}{+m}{%
\ifekd@isinapp%
\ifbool{ekd@state}{%
\luadirect{ekdosis.appin(
\luastring{<\zref@extract{ekd:\theekd@lab}{abspage}>},
"no")}%
\luadirect{ekdosis.appin(\luastringN{#1}, "no")}%
\luadirect{ekdosis.appin(
\luastring{\zref@extract{ekd:\theekd@lab}{abspage}>},
"yes")}%
}{}\else\fi}
\NewDocumentCommand{\append@ln@app}{+m}%
{\luadirect{tex.sprint(ekdosis.mdvappend(\luastringN{#1}))}}
\NewDocumentCommand{\app}{+m}{%
\ekd@isinapptrue%
\stepcounter{ekd@lab}%
\zlabel{ekd:\theekd@lab}%
\luadirect{%
ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}},
"pg_ii")}%
\ifbool{ekd@state}{\add@apparatus}{}%
\luadirect{tex.sprint(ekdosis.removesp(\luastringN{#1}))}%
\ekd@isinappfalse}
\edef\@sep{: }
\NewDocumentCommand{\SetSeparator}{m}{\edef\@sep{#1}}
\newkeycommand+[\|]{\lem}[wit, alt, pre, post, prewit, postwit,
sep={\csname @sep\endcsname},
choice nosep={false,,true}, choice nolem={false,,true}][1]{%
#1%
|\ifnum|%
\commandkey{nolem}>0%
\append@ln@app{}%
|\else|%
|\ifbool{al@rlmode}|%
{\append@ln@app{%
\bgroup%
\setRL%
\ifcommandkey{alt}{%
\ifcommandkey{post}{ \commandkey{post} }{}%
\commandkey{alt}%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
}{%
\ifcommandkey{post}{ \commandkey{post} }{}%
#1%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
}%
\egroup{}%
\ifcommandkey{prewit}{ \commandkey{prewit} }{}%
\ifcommandkey{wit}{ \getsiglum{\commandkey{wit}}}{}%
\ifcommandkey{postwit}{ \commandkey{postwit}}{}%
|\ifnum|
\commandkey{nosep}>0%
|\else|
\commandkey{sep}%
|\fi|%
}}%
{\append@ln@app{%
\ifcommandkey{alt}{%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
\commandkey{alt}%
\ifcommandkey{post}{ \commandkey{post} }{}%
}{%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
#1%
\ifcommandkey{post}{ \commandkey{post} }{}%
}%
\ifcommandkey{prewit}{ \commandkey{prewit} }{}%
\ifcommandkey{wit}{ \getsiglum{\commandkey{wit}}}{}%
\ifcommandkey{postwit}{ \commandkey{postwit}}{}%
|\ifnum|
\commandkey{nosep}>0%
|\else|
\commandkey{sep}%
|\fi|%
}}%
|\fi|}
\newkeycommand+[\|]{\rdg}[wit, alt, pre, post, prewit, postwit][1]{%
|\ifbool{al@rlmode}|%
{\append@app{%
\bgroup%
\setRL%
\ifcommandkey{alt}{%
\ifcommandkey{post}{ \commandkey{post} }{}%
\commandkey{alt}%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
}{%
\ifcommandkey{post}{ \commandkey{post} }{}%
#1%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
}%
\egroup{}%
\ifcommandkey{prewit}{ \commandkey{prewit} }{}%
\ifcommandkey{wit}{ \getsiglum{\commandkey{wit}}}{}%
\ifcommandkey{postwit}{ \commandkey{postwit}}{}%
}}%
{\append@app{%
\ifcommandkey{alt}{%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
\commandkey{alt}%
\ifcommandkey{post}{ \commandkey{post} }{}%
}{%
\ifcommandkey{pre}{ \commandkey{pre} }{}%
#1%
\ifcommandkey{post}{ \commandkey{post} }{}%
}%
\ifcommandkey{prewit}{ \commandkey{prewit} }{}%
\ifcommandkey{wit}{ \getsiglum{\commandkey{wit}}}{}%
\ifcommandkey{postwit}{ \commandkey{postwit}}{}%
}}%
}
\NewDocumentCommand{\note}{s +m}{%
\IfBooleanTF{#1}{%
\if@pkg@parnotes\append@app{\parnote{#2}}%
\else\append@app{\footnote{#2}}\fi}{\append@app{#2}}%
}
\NewDocumentCommand{\apparatus}{}{\luadirect{tex.sprint(ekdosis.appout())}}
\NewDocumentCommand{\test@apparatus}{}{%
\luadirect{tex.sprint(ekdosis.testapparatus())}}
\NewDocumentCommand{\EkdosisStart}{}{%
\stepcounter{ekd@lab}%
\zlabel{ekd:\theekd@lab}%
\luadirect{%
ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}},
"pg_i")}%
}
\NewDocumentCommand{\EkdosisOn}{}{\setbool{ekd@state}{true}}
\NewDocumentCommand{\EkdosisOff}{}{%
\setbool{ekd@state}{false}%
}
\NewDocumentEnvironment{ekdosis}{+b}{%
\begin{linenumbers}
\ifbool{ekd@started}{}%
{\EkdosisStart\add@apparatus}%
\EkdosisOn#1}{%
\EkdosisOff
\end{linenumbers}%
\iftei@export\luadirect{ekdosis.exporttei(\luastringN{#1})}\else\fi}
% \end{macrocode}
% \iffalse
%
% \fi
% \StopEventually{}
% \Finale
% \iffalse `'
%<*lua>
% \fi
% \begin{ekdlua}
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 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 lemrdg = lpeg.Cs(lpeg.Cs("lem") + lpeg.Cs("rdg"))
-- 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 = {}
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 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,
Repository,
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, head = siglum})
table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end)
table.insert(listWit, {xmlid = id,
head = siglum,
msIdentifier = {
settlement = Settlement,
repository = Repository,
idno = Idno,
msName = MsName
},
detailsDesc = description})
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, head = siglum})
table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end)
local indexwit = getindex(witid, listWit)
-- listWit[indexwit].handDesc = {xmlid = id, head = siglum, detailsDesc = description}
if listWit[indexwit].handDesc == nil
then
listWit[indexwit].handDesc = {}
else
end
table.insert(listWit[indexwit].handDesc, {xmlid = id, head = siglum, detailsDesc = description})
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,#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].head)
ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "")
end
end
if string.find(ctrl, "[A-Za-z0-9]")
then
return "?>"
else
return str
end
end
-- begin totei functions
local cmdtotags = {
{a="footnote", b="note", c=" place=\"bottom\""},
{a="textsuperscript", b="hi", c=" rend=\"sup\""},
{a="textsubscript", b="hi", c=" rend=\"sub\""},
{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="foreign", c=" xml:lang=\"arb\""},
{a="arb", b="foreign", c=" xml:lang=\"arb-Latn\" type=\"arabtex\""}
}
function ekdosis.newcmdtotag(cmd, tag, attr)
if isintable(cmdtotags, cmd)
then
tex.print([[\unexpanded{\PackageWarning{ekdosis}{"]]
..cmd..
[[" already exists as a known command to be processed to TEI. ]]
..
[[Please pick another command.}}]])
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
local function xml_entities(str)
str = string.gsub(str, "%<", "<")
str = string.gsub(str, "%>", ">")
return str
end
local function lem_rdg_totei(str)
str = gsub(str, 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 = string.match(opt, "%f[%w]wit%s?%=%s?%b{}") or ""
opt = string.gsub(opt, "wit%s?%=%s?(%b{})", function(bbraces)
bbraces = string.sub(bbraces, 2, -2)
bbraces = ekdosis.getsiglum(bbraces, "tei")
return string.format("%s", bbraces)
end)
return string.format("<%s wit=\"%s\">%s%s>", cmd, opt, arg, cmd)
end)
return str
end
local function textotei(str)
for i = 1,#cmdtotags
do
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 = textotei(body)
-- return string.format("<"..cmdtotags[i].b..cmdtotags[i].c.." %s>%s"..cmdtotags[i].b..">", arg, body)
return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s"..cmdtotags[i].b..">", body)
end)
end
str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})",
function(cmd, opt, body)
body = string.sub(body, 2, -2)
body = textotei(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 = textotei(body)
return string.format("<%s>%s%s>", cmd, body, cmd)
end)
str = string.gsub(str, "(%s)(%>)", "%2")
return str
end
function ekdosis.textotei(str)
str = xml_entities(str)
str = string.gsub(str, "%s?\\par%s?", "
\n")
str = string.gsub(str, "%s?\\unskip%s?", "")
str = lem_rdg_totei(str)
str = textotei(str)
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("", "\n")
f:write("", "\n")
f:write("", "\n")
for i = 1,#listWit do
f:write("", "\n")
f:write("", ekdosis.textotei(listWit[i].head), "", "\n")
if listWit[i].msIdentifier.settlement == ""
and listWit[i].msIdentifier.repository == ""
and listWit[i].msIdentifier.idno == ""
and listWit[i].msIdentifier.msName == ""
then
f:write("", "\n")
else
f:write("", "\n")
if listWit[i].msIdentifier.settlement ~= "" then
f:write("", ekdosis.textotei(listWit[i].msIdentifier.settlement), "", "\n")
else end
if listWit[i].msIdentifier.repository ~= "" then
f:write("", ekdosis.textotei(listWit[i].msIdentifier.repository), "", "\n")
else end
if listWit[i].msIdentifier.idno ~= "" then
f:write("", ekdosis.textotei(listWit[i].msIdentifier.idno), "", "\n")
else end
if listWit[i].msIdentifier.msName ~= "" then
f:write("", ekdosis.textotei(listWit[i].msIdentifier.msName), "", "\n")
else end
f:write("", "\n")
end
if listWit[i].handDesc ~= nil then
f:write("", "\n")
local j = 1
while listWit[i].handDesc[j]
do
f:write("", "\n")
f:write("", ekdosis.textotei(listWit[i].handDesc[j].head), "", "\n")
if listWit[i].handDesc[j].detailsDesc == "" then else
f:write("", ekdosis.textotei(listWit[i].handDesc[j].detailsDesc), "
", "\n")
end
j = j + 1
f:write("", "\n")
end
f:write("", "\n")
else end
if listWit[i].history ~= nil then
f:write("", "\n")
f:write("", "\n")
f:write("", ekdosis.textotei(listWit[i].history.origin.origDate), "", "\n")
f:write("", "\n")
f:write("", "\n")
end
if listWit[i].detailsDesc == "" then else
f:write("", ekdosis.textotei(listWit[i].detailsDesc), "
", "\n")
end
f:write("", "\n")
end
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:close()
return true
end
local tidy = nil
function ekdosis.closeteistream(opt)
local f = io.open(teifilename.."_tmp.xml", "a+")
f:write("\n", "", "\n")
f:write("", "\n")
f:write("", "\n")
f:close()
os.remove(teifilename..".xml")
os.rename(teifilename.."_tmp.xml", teifilename..".xml")
if opt == "tidy" then
os.execute("tidy -qmi -xml "..teifilename..".xml")
else
end
return true
end
function ekdosis.exporttei(str)
local f = io.open(teifilename.."_tmp.xml", "a+")
str = ekdosis.textotei(str)
f:write("\n
")
f:write(str)
f:write("
")
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].head
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
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 pg_i = 0
local pg_ii = 0
local cur_abs_pg = 0
function ekdosis.update_abspg(n)
cur_abs_pg = n
return true
end
function ekdosis.get_abs_page()
return cur_abs_pg
end
function ekdosis.storeabspg(n, pg)
if pg == "pg_i" then
pg_i = n
elseif pg == "pg_ii" then
pg_ii = n
end
cur_abs_pg = n
return true
end
ekdosis.getabspg = function(pg) --not used
if pg == "pg_i" then
return pg_i
elseif pg == "pg_ii" then
return pg_ii
end
end
local function mdvisintable(table, value)
for _, v in pairs(table) do
if v == value then return true end
end
return false
end
function ekdosis.appin(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
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 = {}
for i in string.gmatch(t,
"<"..cur_abs_pg..">.-"..cur_abs_pg..">")
do
table.insert(output, i)
end
f:close()
str = table.concat(output, "\n")
str = string.gsub(str, ""..cur_abs_pg..">", " ")
str = string.gsub(str, "<"..cur_abs_pg..">", "")
return str
else end
end
function ekdosis.testapparatus()
if tonumber(pg_ii) == tonumber(pg_i) then
return "\\boolfalse{do@app}"
elseif tonumber(pg_ii) > tonumber(pg_i) then
pg_i = pg_ii
return "\\booltrue{do@app}"
else
return "\\boolfalse{do@app}"
end
end
md5items = {}
local salt = 0
function ekdosis.mdvappend(str)
i = md5.sumhexa(str)
if not mdvisintable(md5items, i) then
table.insert(md5items, i)
else
i = i..salt
table.insert(md5items, i)
salt = salt + 1
end
return "\\linelabel{"..i.."}"
..
"\\csname append@app\\endcsname{\\textbf{\\getrefnumber{"..i.."}} "..str.."}"
end
% \end{ekdlua}
% \iffalse
%
% \fi
\endinput