% \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>
[2019/04/01 v1.0 Typesetting TEI xml compliant critical editions]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry}
\usepackage{fontspec}
\usepackage[english]{babel}
\babelfont{rm}{Old Standard}
\babelfont{sf}{NewComputerModern Sans}
\babelfont{tt}{NewComputerModern Mono}
\usepackage{metalogox}
\usepackage{hologo}
\usepackage{latexcolors}
\usepackage{hyperxmp}
\usepackage{uri}
\usepackage[numbered]{hypdoc}
\hypersetup{unicode=true, colorlinks, allcolors=cinnamon, keeppdfinfo,
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{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{iftex}
% \end{macrocode}
% \package{ekdosis} requires {\LuaLaTeX} of course. Issue an error
% if the document is processed with another engine.
% \begin{macrocode}
\RequireLuaTeX
% \end{macrocode}
% Packages that are required by \package{ekdosis}:
% \begin{macrocode}
\RequirePackage{xkeyval}
\newif\if@pkg@float
\newif\if@pkg@footins
\define@choicekey{ekdosis.sty}{layout}{float, footins}[float]{%
\edef\layout@float{float}
\edef\layout@footins{footins}
\edef\@tempa{#1}
\ifx\@tempa\layout@float\@pkg@floattrue\fi
\ifx\@tempa\layout@footins\@pkg@floatfalse\@pkg@footinstrue\fi
}
\newif\if@pkg@ekddivs
\define@choicekey+{ekdosis.sty}{divs}{ekdosis, latex}[ekdosis]{
\edef\divs@ekdosis{ekdosis}
\edef\divs@latex{latex}
\edef\@tempa{#1}
\ifx\@tempa\divs@ekdosis\@pkg@ekddivstrue\fi
\ifx\@tempa\divs@latex
\@pkg@ekddivsfalse
\AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}}
\fi
}{\PackageError{ekdosis}{divs option must be either 'ekdosis' or 'latex'}}
\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@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{layout,divs}
\ProcessOptionsX\relax
\RequirePackage{luacode}
\RequirePackage{paracol}
\RequirePackage{expkv-def}
\RequirePackage{xparse}
\RequirePackage{etoolbox}
\RequirePackage{lineno}
\RequirePackage{keyfloat}
\RequirePackage{refcount}
\RequirePackage[user,abspage]{zref}
\RequirePackage{ltxcmds}
\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}
% Hooks
% \begin{macrocode}
\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}}
% \end{macrocode}
% Build and process the list of witnesses and hands.
% \begin{macrocode}
\ekvdefinekeys{ekd@witness}{
store settlement = \settlement@value,
store repository = \repository@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{\repository@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}))}
}
% \end{macrocode}
% Add a \hologo{(La)TeX} command to be processed as a |TEI xml| tag:
% \begin{macrocode}
\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})}
}
% \end{macrocode}
% Set |TEI| file name
% \begin{macrocode}
\NewDocumentCommand{\SetTEIFileName}{m}{
\luadirect{ekdosis.setteifilename(\luastringN{#1})}
}
\@onlypreamble\SetTEIFileName
\NewDocumentCommand{\SetxmlBibResource}{m}{
\luadirect{ekdosis.setxmlbibresource(\luastringN{#1})}
}
\@onlypreamble\SetxmlBibResource
% \end{macrocode}
% Multi-layer apparatuses
% \begin{macrocode}
\newif\ifekd@mapps
\ekvdefinekeys{ekd@newapp}{
choice direction = {LR = \def\direction@val{LR},
RL = \def\direction@val{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
% \end{macrocode}
% \begin{macrocode}
\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}
% \def\unconditional@appin#1{%
% \luadirect{ekdosis.appin(\luastringN{#1})}%
% }
\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}}
% \def\ekd@default@rule{\vskip-\baselineskip\mbox{}\newline%
% \rule{2truein}{0.5pt}}
% \def\footnoterule{\vskip-\baselineskip}
% \def\pcol@footnoterule{}
\newif\iffootnoterule
\let\dflt@footnoterule\footnoterule
\let\dflt@pcol@footnoterule\pcol@footnoterule
\renewcommand\footnoterule{%
\iffootnoterule
\dflt@footnoterule%
\else
% \noindent\ekd@default@rule%
% \advance\skip\footins 4\p@\@plus2\p@\relax%
\fi
}
\renewcommand\pcol@footnoterule{%
\iffootnoterule
\dflt@pcol@footnoterule%
\else
% \noindent\ekd@default@rule%
% \advance\skip\footins 4\p@\@plus2\p@\relax%
\fi
}
\newcommand*{\NLS}{%
\par%
\nobreak%
\vspace{-\parskip}%
\noindent%
\ignorespaces}
\NewDocumentCommand{\SetDefaultRule}{m}{%
\def\@tempa{#1}
\ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}%
\else%
\def\ekd@default@rule{#1}%
\fi}
\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%
% \unless\ifekd@mapps\unconditional@appin{%
% \expandafter{\ekd@default@rule}\newline}\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}))}}}
\define@cmdkey[ekd]{appnote}[ekdan@]{type}{}
\NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{%
\presetkeys[ekd]{appnote}{type=default}{}%
\setkeys[ekd]{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}
\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}%
}%
\define@cmdkeys[ekd]{lemrdg}[ekdlr@]{wit, alt, pre, post, prewit,
postwit}
\define@cmdkey[ekd]{lem}[ekdl@]{sep}{}
\presetkeys[ekd]{lem}{sep=\ekdsep}{}
\define@boolkeys[ekd]{lem}[ekdl@]{nolem, nosep}[true]
\define@boolkeys[ekd]{rdg}[ekdr@]{nordg}[true]
\NewDocumentCommand{\lem}{O{} m}{%
\ekd@isinlemtrue%
\luadirect{ekdosis.dolnlab(\luastringN{#2})}%
\bgroup%
\setkeys[ekd]{lemrdg,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%
\setkeys[ekd]{lemrdg,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%
}
\define@cmdkeys[ekd]{note}[ekdn@]{lem, labelb, labele}
\define@cmdkey[ekd]{note}[ekdn@]{sep}{}
\presetkeys[ekd]{note}{sep=\ekdsep}{}
\NewDocumentCommand{\note@noapp}{O{} +m}{%
\presetkeys[ekd]{appnote}{type=default}{}%
\bgroup%
\setkeys[ekd]{appnote,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]{\unexpanded{%
{\textdir TRT#3}}}}
{\ekd@note[#2]{\unexpanded{{\textdir TRT#3}}}}%
}{%
\IfBooleanTF{#1}{\ekd@note@star[#2]{\unexpanded{#3}}}
{\ekd@note[#2]{\unexpanded{#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
% \EkdosisColStart
\EkdosisOn#1}{%
\EkdosisOff
% \EkdosisColStop
\endrunninglinenumbers%
\iftei@export\luadirect{ekdosis.exporttei(\luastringN{\par#1\par})}\else\fi}
% \end{macrocode}
% Alignment:---
% \begin{macrocode}
\ekvdefinekeys{ekd@align}{
store tcols = \tcols@num,
store lcols = \lcols@num,
store texts = \texts@value,
store apparatus = \apparatus@value,
bool paired = \ifekd@paired,
bool pagelineation = \ifekd@pagelineation,
initial tcols = 2,
initial lcols = 1,
initial texts = edition;translation,
initial apparatus = edition
}
\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"
)}
\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
\luadirect{ekdosis.flushenvdata()}
\luadirect{ekdosis.flushcolnums()}
}
% \end{macrocode}
% Divisions of the Body
% \begin{macrocode}
\NewDocumentCommand{\MkBodyDivs}{mmmmmm}{
\luadirect{ekdosis.mkdivdepths(
\luastringN{#1},
\luastringN{#2},
\luastringN{#3},
\luastringN{#4},
\luastringN{#5},
\luastringN{#6}
)
}
}
% \end{macrocode}
% Divisions specific to ekdosis:---
% \begin{macrocode}
\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}},
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
}
% \end{macrocode}
% Very basic implementation of poetry lines:---
% \begin{macrocode}
\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}}
% \end{macrocode}
%
% \iffalse
%
% \fi
% \StopEventually{}
% \Finale
% \iffalse
%<*lua>
% \fi
% \begin{ekdlua}
-- `'
-- 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"))
-- 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,
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, 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,
repository = Repository,
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="footnote", b="note", c=" place=\"bottom\""},
{a="txtrans", b="s", c=" xml:lang=\"arb-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="s",
c=" xml:lang=\"arb-Latn\" type=\"transliterated\" subtype=\"arabtex\""}
}
local texpatttotags = {
{a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 [%2](\"#%3\")"},
{a="\\icite%s?%[(.-)%]{(.-)}", b="[%1](\"#%2\")"},
{a="\\icite%s?{(.-)}", b=""}
}
local envtotags = {
{a="ekdverse", b="lg", c=""},
{a="txarabtr", b="p", c=" xml:lang=\"arb-Latn\" type=\"transliterated\""},
{a="txarab", b="p", c=" xml:lang=\"arb\""},
{a="center", b="p", c=" rend=\"centered\""},
{a="verse", b="lg", c=""},
{a="arab", b="p",
c=" xml:lang=\"arb-Latn\" type=\"transliterated\" subtype=\"arabtex\""}
}
local close_p = {
"p",
"lg"
}
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.}}")
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 })
return true
end
function ekdosis.newenvtotag(env, tag, attr, closep)
if isintable(envtotags, env)
then
-- tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
-- ..cmd..
-- "\" already exists as a known environment to be processed to TEI. "
-- ..
-- "Please pick another environment name.}}")
local index = get_a_index(env, envtotags)
table.remove(envtotags, index)
table.insert(envtotags, {a = env, b = tag, c = " "..attr})
table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end)
if closep == "yes" then
table.insert(close_p, tag)
else end
else
table.insert(envtotags, {a = env, b = tag, c = " "..attr})
table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end)
if closep == "yes" then
table.insert(close_p, tag)
else end
end
return true
end
-- Get values of attributes
local function get_attr_value(str, attr)
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 = string.match(opt, "%f[%w]type%s?%=%s?%b{}")
or string.match(opt, "%f[%w]type%s?%=%s?%w+%f[%W]")
or ""
teitype = string.gsub(teitype, "type%s?%=%s?(%b{})", function(bbraces)
bbraces = string.sub(bbraces, 2, -2)
return string.format("%s", bbraces)
end)
teitype = string.gsub(teitype, "(type%s?%=%s?)(%w+%f[%W])", "%2")
right = string.match(opt, "%f[%w]labelb%s?%=%s?%b{}")
or string.match(opt, "%f[%w]labelb%s?%=%s?%w+%f[%W]")
or ""
right = string.gsub(right, "labelb%s?%=%s?(%b{})", function(bbraces)
bbraces = string.sub(bbraces, 2, -2)
return string.format("%s", bbraces)
end)
right = string.gsub(right, "(labelb%s?%=%s?)(%w+%f[%W])", "%2")
left = string.match(opt, "%f[%w]labele%s?%=%s?%b{}")
or string.match(opt, "%f[%w]labele%s?%=%s?%w+%f[%W]")
or ""
left = string.gsub(left, "labele%s?%=%s?(%b{})", function(bbraces)
bbraces = string.sub(bbraces, 2, -2)
return string.format("%s", bbraces)
end)
left = string.gsub(left, "(labele%s?%=%s?)(%w+%f[%W])", "%2")
if left ~= "" and teitype ~= ""
then
return string.format(
"<%s type=\"%s\" target=\"#range(right(%s),left(%s))\">%s%s>",
cmd, teitype, right, left, arg, cmd, right)
elseif left ~= "" and teitype == ""
then
return string.format(
"<%s target=\"#range(right(%s),left(%s))\">%s%s>",
cmd, right, left, arg, cmd, right)
elseif left == "" and teitype ~= ""
then
return string.format(
"<%s type=\"%s\" target=\"#right(%s)\">%s%s>",
cmd, teitype, right, arg, cmd, right)
else
return string.format("<%s target=\"#right(%s)\">%s%s>",
cmd, 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 = string.match(opt, "%f[%w]type%s?%=%s?%b{}")
or string.match(opt, "%f[%w]type%s?%=%s?%w+%f[%W]")
or ""
opt = string.gsub(opt, "type%s?%=%s?(%b{})", function(bbraces)
bbraces = string.sub(bbraces, 2, -2)
return string.format("%s", bbraces)
end)
opt = string.gsub(opt, "(type%s?%=%s?)(%w+%f[%W])", "%2")
return app_totei(string.format("<%s type=\"%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 = string.match(opt, "%f[%w]wit%s?%=%s?%b{}")
or string.match(opt, "%f[%w]wit%s?%=%s?%w+%f[%W]")
or ""
if opt == ""
then
return lem_rdg_totei(string.format("<%s>%s%s>",
cmd, arg, cmd))
else
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)
opt = string.gsub(opt, "(wit%s?%=%s?)(%w+%f[%W])", function(attr, value)
value = ekdosis.getsiglum(value, "tei")
return string.format("%s", value)
end)
return lem_rdg_totei(string.format("<%s wit=\"%s\">%s%s>",
cmd, opt, 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)
-- str = string.gsub(str, "(%.-)(%)(.-%<%/lem%>)", "%1%3%2")
return str
end
local function relocate_notes(str)
str = string.gsub(str, "(%.-)(%.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2")
return str
end
local function linestotei(str)
-- str = "\n"..str
str = string.gsub(str, "^%s?(.-)%s?$", "\n%1\n")
-- str = gsub(str, endpoem, "\n")
str = gsub(str, poemline * spcenc^-1 * lpeg.P(">"), "\n
")
str = gsub(str, poemline * spcenc^-1, "\n")
-- str = str.."\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)
then
-- if envtotags[i].b == "p"
-- then
str = gsub(str, (lpeg.P("\\par") + lpeg.P("")) * spcenc^-1 * lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
* lpeg.Cs(envtotags[i].a) * lpeg.P("}")
* bcbracesii * spcenc^-1,
"\n<"..envtotags[i].b..envtotags[i].c..">")
-- else
-- str = gsub(str, (lpeg.P("\\par") + lpeg.P("
")) * spcenc^-1 * lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
-- * lpeg.Cs(envtotags[i].a) * lpeg.P("}")
-- * bcbracesii * spcenc^-1,
-- "
\n<"..envtotags[i].b..envtotags[i].c..">")
-- end
str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{")
* lpeg.Cs(envtotags[i].a) * lpeg.P("}") * spcenc^-1 * (lpeg.P("\\par") + lpeg.P("
")),
""..envtotags[i].b..">\n")
str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
* lpeg.Cs(envtotags[i].a) * lpeg.P("}")
* 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..">\n
")
else
str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
* lpeg.Cs(envtotags[i].a) * lpeg.P("}")
* 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("}")
* 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, "\\(linelabel)%s?(%b{})",
function(cmd, body)
body = string.sub(body, 2, -2)
body = cmdtotei(body)
return string.format("", body)
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 = string.gsub(str, "%s?\\par%s?", "", 1)
str = string.gsub(str, "%s?\\par%s?", "
")
str = string.gsub(str, "
%s?
", "")
str = string.gsub(str, "(%)%s?(%)$", "%2")
str = string.gsub(str, "(%
)%s?$", "")
str = string.gsub(str, "(
)%s?(
)", "%2%1")
str = string.gsub(str, "(%)%s?(
.-)", "%2%1")
return str
end
local function checkpars(str)
for i = 1,#envtotags
do
if isfound(close_p, envtotags[i].b)
then
str = string.gsub(str, "(%%s])(.-<"..envtotags[i].b.."[%>%s])", function(par, substr_tag)
substr_tag = checkpars(substr_tag)
substr = string.gsub(substr_tag, "(.-)(<"..envtotags[i].b.."[%>%s])", "%1")
tag = string.gsub(substr_tag, "(.-)(<"..envtotags[i].b.."[%>%s])", "%2")
if string.find(substr, "<%/p[%>%s]")
then
return string.format("%s%s%s", par, substr, tag)
else
return string.format("%s%s
%s", par, substr, tag)
end
end)
else
end
end
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)
arg = arg..","
--
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 end
return string.format("\\par %s",
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("\\par %s",
ctr, secname, arg)
end
end)
return str
end
local used_ndivs = {}
local function close_ndivs_at_end(str)
local isdiv = false
if string.find(str, "
$")
then
isdiv = true
str = string.gsub(str, "(.*)()$", "%1")
else
end
-- collect used div numbers
for i in string.gmatch(str, " #b.a) end)
else
end
local firstdiv = string.match(str, "
= firstdivindex
do
closedivs = closedivs.."
"
lastdivindex = lastdivindex - 1
end
end
-- str = string.gsub(str, "(
)", "%1%3")
if isdiv
then
return str..closedivs.."
"
else
return str..closedivs
end
end
local function close_ndivs_in_between(str)
for ndivi = 0, 9
do
str = string.gsub(str, "(
)(.-)(
)",
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.."
"
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)
str = checkpars(str)
if ekddivs
then
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('', "\n")
f:write("
", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
for i = 1,#listWit do
f:write('", "\n")
f:write('', textotei(listWit[i].abbr), "", "\n")
f:write(textotei(listWit[i].detailsDesc), "\n")
f:write("", "\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("", textotei(listWit[i].msIdentifier.settlement), "", "\n")
else end
if listWit[i].msIdentifier.repository ~= "" then
f:write("", textotei(listWit[i].msIdentifier.repository), "", "\n")
else end
if listWit[i].msIdentifier.idno ~= "" then
f:write("", textotei(listWit[i].msIdentifier.idno), "", "\n")
else end
if listWit[i].msIdentifier.msName ~= "" then
f:write("", textotei(listWit[i].msIdentifier.msName), "", "\n")
else end
f:write("", "\n")
end
if listWit[i].handDesc ~= nil then
f:write("", "\n")
f:write("", "\n")
local j = 1
while listWit[i].handDesc[j]
do
f:write("", "\n")
f:write('', textotei(listWit[i].handDesc[j].abbr), "", "\n")
f:write("", textotei(listWit[i].handDesc[j].detailsDesc), "
", "\n")
f:write("", "\n")
j = j + 1
end
f:write("", "\n")
f:write("", "\n")
else end
if listWit[i].history ~= nil then
f:write("", "\n")
f:write("", "\n")
f:write("", textotei(listWit[i].history.origin.origDate), "", "\n")
f:write("", "\n")
f:write("", "\n")
end
f:write("", "\n")
f:write("", "\n")
end
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write('', "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\n")
f:write("", "\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, "%%s?%
", "")
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", "", "\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("", "\n")
f:write("", "\n")
for i in string.gmatch(t, ".-")
do
f:write(i, "\n")
end
f:write("", "\n")
f:write("", "\n")
bibf:close()
else
end
f:write("", "\n")
f:write("", "\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
")
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)
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 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)
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
if aligned_texts[i].attribute ~= ""
then
table.insert(environments, "\\EnvtoTEI{"
.. aligned_texts[i].text
.."}{div}"
.."[xml:id=\""
.. build_envdiv(aligned_texts[i].text)
.. "\" "
.. aligned_texts[i].attribute
.. "]")
else
table.insert(environments, "\\EnvtoTEI{"
.. aligned_texts[i].text
.."}{div}"
.."[xml:id=\""
.. build_envdiv(aligned_texts[i].text)
.. "\"]")
end
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, "-", curcol, "-0>", str, "", cur_abs_pg, "-", 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, "-", curcol, "-", appno, ">", str, "", cur_abs_pg, "-", 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.."%-"..curcol.."%-0>.-"..cur_abs_pg.."%-"..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.."%-"..curcol.."%-"..n..">.-"..cur_abs_pg.."%-"..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.."%-"..curcol.."%-"..n..">.-"..cur_abs_pg.."%-"..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.."%-"..curcol.."%-[0-9]>", "")
str = string.gsub(str, "<"..cur_abs_pg.."%-"..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
return "\\boolfalse{do@app}"
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
% \end{ekdlua}
% \iffalse
%
% \fi
\endinput