% \iffalse meta-comment
% 
% ekdosis -- Typesetting TEI xml compliant critical editions
% Copyright (C) 2020  Robert Alessi
% 
% Please send error reports and suggestions for improvements to Robert
% Alessi <alessi@robertalessi.net>
% 
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
% 
% This program is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
% General Public License for more details.
% 
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see
% <http://www.gnu.org/licenses/>.
% 
%<*internal>
\iffalse
%</internal>
%<*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.
%</readme>
%<*luapre>
--[[
This file is part of the `ekdosis' package

ekdosis -- Typesetting TEI xml compliant critical editions
Copyright (C) 2020  Robert Alessi

Please send error reports and suggestions for improvements to Robert
Alessi <alessi@robertalessi.net>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see
<http://www.gnu.org/licenses/>.
--]]

%</luapre>
%<*internal>
\fi
%</internal>
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{ekdosis.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{ekdosis}
%<*package>
    [2020/06/03 v0.99 Typesetting TEI xml compliant critical editions]
%</package>
%<*driver>
\documentclass{ltxdoc}
\usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry}
\usepackage{dox}
\doxitem{Option}{option}{options}
\usepackage{microtype}
\usepackage{fontspec}
\usepackage[english]{babel}
\babelfont{rm}{Old Standard}
\babelfont{sf}{NewComputerModern Sans}
\babelfont{tt}{NewComputerModern Mono}
\usepackage{arabluatex}
\usepackage{ekdosis}
\usepackage{enumitem}
\setlist{nosep}
\setlist[itemize]{label=\textendash}
\setlist[enumerate,1]{label=(\alph*)}
\usepackage{metalogox}
\usepackage{hologo}
\usepackage{xcolor}
\definecolor{ekdcolor}{RGB}{243,241,235}
\definecolor{cinnamon}{rgb}{0.82, 0.41, 0.12}
\definecolor{gainsboro}{RGB}{222,222,222}
\PassOptionsToPackage{bookmarks=true}{hyperref}
\usepackage{xurl}
\usepackage[numbered]{hypdoc}
\usepackage[loadlang=en]{metastr}
\hypersetup{
  colorlinks,
  allcolors=cinnamon,
  linktocpage=true,
  pdftype={Text}
}
\usepackage{uri}
\usepackage[nospace]{varioref}
\labelformat{section}{sect.~#1}
\metaset{titletext}{%
  \metapick[#1]{title}%
  \metacompose[#1]{subtitle}{\metaget[sep]{subtitle}}{}{}}
\metaset[print]{titletext}{%
  \metatitleline[print]{title}%
  \metatitleline[print]{subtitle}%
  \metatitleline[print]{author}%
  \metatitleline[print]{contactemail}%
  \metatitlelinetwo[print]{date}[print]{draft}}
\metaset[skip]{subtitle}{\vspace{1ex}}
\metaset[skip]{author}{\vspace{2ex}}
\metaset[skip]{date}{\vspace{1ex}}
\metaset[style]{title}{\LARGE}
\metaset[style]{author}{\large}
\metaset[sep]{draft}{ -- }
\metasetlang{en-US}
\metaset{title}{ἔκδοσις}
\metaset{date}{\filedate}
\metaset{draft}{\fileversion}
\metaset{subject}{TEI xml compliant critical editions}
\metaset{subtitle}{Typesetting TEI xml Compliant Critical Editions}
\metaset[print]{subtitle}{Typesetting \texttt{TEI xml} Compliant
  Critical Editions}
\metaset{author}{Robert Alessi}
\metaset{keywords}{LaTeX, Lua, TEI xml, multilingual critical
  editions, alignment, segmentation}
\metaset{contactemail}{alessi@roberalessi.net}
\metaset[print]{contactemail}{\mailto[ekdosis]{alessi@robertalessi.net}}
\metaset{contacturl}{http://www.roberalessi.net}
\metaset{partof}{The ekdosis Package}
\metaset[print]{partof}{The \textsf{ekdosis} Package}
\metaset{copyrightowner}{\metapick[#1]{author}}
\metaset{copyrightdate}{2020}
\metaset{licensemessage}{Permission is granted to copy, distribute
  and/or modify this document under the terms of the GNU Free
  Documentation License, Version 1.3 or any later version published by
  the Free Software Foundation; with no Invariant Sections, no
  Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
  is included in the section entitled ``GNU Free Documentation
  License''.}
\metaset{licenseurl}{https://www.gnu.org/licenses/fdl-1.3.html}
\metaset[print]{licenseurl}{%
  \url{https://www.gnu.org/licenses/fdl-1.3.html}}
\metaset[cmd]{licenselogo}{\includegraphics[scale=0.75]{#1}}
\metawritepdfinfo
\metawritepdfaux
\metawritepdfpreamble
\metawritepdfcontact
\metawritepdfrights
\usepackage[lot]{multitoc}
\usepackage{relsize}
\usepackage{units}
\usepackage{tikz}
\usepackage[breakable, skins, xparse]{tcolorbox}
\usepackage[newfloat]{minted}
\setminted{bgcolor=ekdcolor,linenos, fontsize=\small}
\newminted[ekdlua]{lua}{bgcolor={}, 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)}}
\backgroundcolor{c}{ekdcolor}
\usepackage{caption}
\captionsetup[listing]{position=above,skip=-1ex}
\usepackage{needspace}
\NewDocumentCommand{\captof}{O{listing} m O{}}{%
  \bgroup
  \needspace{5\baselineskip}%
  \vskip 1ex plus 2pt minus 2pt%
  \captionof{#1}{#2}%
  #3%
  \egroup}
\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}
%</driver>
% \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}
%
% \pdfbookmark[1]{\metaterm{title}}{title}
% \begin{tcolorbox}[
%   colframe=black,
%   enhanced,
%   drop lifted shadow,
%   colback=white,
%   boxrule=.25mm,
%   halign=center,
%   center
%   ]
%   \metapick[print]{titletext}
% \end{tcolorbox}
%
% \footnotesize
% \ekdtableofcontents
% \normalsize
%
%\changes{v1.00}{2020/07/01}{First public release}
%
% \begin{abstract}%
%   \package{ekdosis} is a Lua\LaTeX{} package designed for
%   multilingual critical editions. It can be used to typeset texts
%   and different layers of critical notes in any direction accepted
%   by Lua\TeX. Texts can be arranged in running paragraphs or on
%   facing pages, in any number of columns which in turn can be
%   synchronized or not. In addition to printed texts,
%   \package{ekdosis} can convert \texttt{.tex} source files so as to
%   produce \texttt{TEI xml} compliant critical
%   editions. Database-driven encoding under \LaTeX{} then allows
%   extraction of texts entered segment by segment according to
%   various criteria: main edited text, variant readings, translations
%   or annotated borrowings between texts. It is published under the
%   terms of the GNU General Public License (GPL) version 3.
% \end{abstract}
%
% \section*{License and disclaimer}
% \addcontentsline{toc}{section}{License and disclamer}
% \subsection*{License applicable to this document}
% \pdfbookmark[2]{Licence applicable to this document}{copyright-doc}
% \leavevmode\marginpar{\hfill\texttt{fdl1.3}}
% \metapick[print]{rightstext} (See below \vref{sec:fdl}.)
%
% \subsection*{License applicable to the software}
% \pdfbookmark[2]{Licence applicable to the software}{copyright-soft}
% \label{sec:license-software}
%
% \package{ekdosis} --- \metapick[print]{subtitle}
% \metapick[print]{copyrightstatement}
%
% Please send error reports and suggestions for improvements to Robert
% Alessi:
% \begin{itemize}
% \item email: \mailto[ekdosis package]{alessi@roberalessi.net}
% \item website: \url{http://www.robertalessi.net/ekdosis}
% \item development: \url{http://git.robertalessi.net/ekdosis}
% \item comments, feature requests, bug reports:
% \url{https://gitlab.com/ralessi/eksodis/issues}
% \end{itemize}
%
% \leavevmode\marginpar{\hfill\texttt{gpl3+}}
% 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
% \href{http://www.gnu.org/licenses}{\texttt{<http://www.gnu.org/licenses/>}}.
%
% This release of \package{ekdosis} consists of the following
% source files:
% \begin{itemize}
% \item |ekdosis.ins|
% \item |ekdosis.dtx|
% \item |ekdosis.el|
% \end{itemize}
%
% \section{Introduction}
% \begin{keyfigure}{c={Grid Typesetting (which never came into existence)},
%   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}.}}
%   \centering
%   \begin{tikzpicture}
%     \draw[gainsboro,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.875) -- (0,2.025);
%   \end{tikzpicture}
% \end{keyfigure}
%
% 
%
% \captof{The Peter and John example}
% \iffalse
%<*example>
% \fi
\begin{minted}[linenos=false]{latex}
\begin{ekdosis}
  I saw my friend
  \app{
    \lem{Peter}
    \rdg{John}
  }
  at the station yesterday.
\end{ekdosis}
\end{minted}
% \iffalse
%</example>
% \fi
% \begin{alignment}[flush,tcols=1,texts=specimen,apparatus=specimen]
%   \begin{specimen}
%     I saw my friend
%     \app{
%     \lem{Peter}
%     \rdg{John}
%     }
%     at the station yesterday.
%   \end{specimen}
% \end{alignment}
%
% \section{GNU Free Documentation License}
% \label{sec:fdl}
% \textbf{Version 1.3, 3 November 2008}
% 
%  \begin{center}
% 
%        Version 1.3, 3 November 2008
% 
% 
%        Copyright \copyright{} 2000, 2001, 2002, 2007, 2008 Free
%        Software Foundation, Inc.
%  
%  \bigskip
%  
%      \url{https://fsf.org/}
%   
%  \bigskip
%  
%  Everyone is permitted to copy and distribute verbatim copies
%  of this license document, but changing it is not allowed.
% \end{center}
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\bf\large Preamble}
% \end{center}
% 
% The purpose of this License is to make a manual, textbook, or other
% functional and useful document ``free'' in the sense of freedom: to
% assure everyone the effective freedom to copy and redistribute it,
% with or without modifying it, either commercially or noncommercially.
% Secondarily, this License preserves for the author and publisher a way
% to get credit for their work, while not being considered responsible
% for modifications made by others.
% 
% This License is a kind of ``copyleft'', which means that derivative
% works of the document must themselves be free in the same sense.  It
% complements the GNU General Public License, which is a copyleft
% license designed for free software.
% 
% We have designed this License in order to use it for manuals for free
% software, because free software needs free documentation: a free
% program should come with manuals providing the same freedoms that the
% software does.  But this License is not limited to software manuals;
% it can be used for any textual work, regardless of subject matter or
% whether it is published as a printed book.  We recommend this License
% principally for works whose purpose is instruction or reference.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 1. APPLICABILITY AND DEFINITIONS\par}
% \end{center}
% 
% This License applies to any manual or other work, in any medium, that
% contains a notice placed by the copyright holder saying it can be
% distributed under the terms of this License.  Such a notice grants a
% world-wide, royalty-free license, unlimited in duration, to use that
% work under the conditions stated herein.  The ``\textbf{Document}'', below,
% refers to any such manual or work.  Any member of the public is a
% licensee, and is addressed as ``\textbf{you}''.  You accept the license if you
% copy, modify or distribute the work in a way requiring permission
% under copyright law.
% 
% A ``\textbf{Modified Version}'' of the Document means any work containing the
% Document or a portion of it, either copied verbatim, or with
% modifications and/or translated into another language.
% 
% A ``\textbf{Secondary Section}'' is a named appendix or a front-matter section of
% the Document that deals exclusively with the relationship of the
% publishers or authors of the Document to the Document's overall subject
% (or to related matters) and contains nothing that could fall directly
% within that overall subject.  (Thus, if the Document is in part a
% textbook of mathematics, a Secondary Section may not explain any
% mathematics.)  The relationship could be a matter of historical
% connection with the subject or with related matters, or of legal,
% commercial, philosophical, ethical or political position regarding
% them.
% 
% The ``\textbf{Invariant Sections}'' are certain Secondary Sections whose titles
% are designated, as being those of Invariant Sections, in the notice
% that says that the Document is released under this License.  If a
% section does not fit the above definition of Secondary then it is not
% allowed to be designated as Invariant.  The Document may contain zero
% Invariant Sections.  If the Document does not identify any Invariant
% Sections then there are none.
% 
% The ``\textbf{Cover Texts}'' are certain short passages of text that are listed,
% as Front-Cover Texts or Back-Cover Texts, in the notice that says that
% the Document is released under this License.  A Front-Cover Text may
% be at most 5 words, and a Back-Cover Text may be at most 25 words.
% 
% A ``\textbf{Transparent}'' copy of the Document means a machine-readable copy,
% represented in a format whose specification is available to the
% general public, that is suitable for revising the document
% straightforwardly with generic text editors or (for images composed of
% pixels) generic paint programs or (for drawings) some widely available
% drawing editor, and that is suitable for input to text formatters or
% for automatic translation to a variety of formats suitable for input
% to text formatters.  A copy made in an otherwise Transparent file
% format whose markup, or absence of markup, has been arranged to thwart
% or discourage subsequent modification by readers is not Transparent.
% An image format is not Transparent if used for any substantial amount
% of text.  A copy that is not ``Transparent'' is called ``\textbf{Opaque}''.
% 
% Examples of suitable formats for Transparent copies include plain
% ASCII without markup, Texinfo input format, LaTeX input format, SGML
% or XML using a publicly available DTD, and standard-conforming simple
% HTML, PostScript or PDF designed for human modification.  Examples of
% transparent image formats include PNG, XCF and JPG.  Opaque formats
% include proprietary formats that can be read and edited only by
% proprietary word processors, SGML or XML for which the DTD and/or
% processing tools are not generally available, and the
% machine-generated HTML, PostScript or PDF produced by some word
% processors for output purposes only.
% 
% The ``\textbf{Title Page}'' means, for a printed book, the title page itself,
% plus such following pages as are needed to hold, legibly, the material
% this License requires to appear in the title page.  For works in
% formats which do not have any title page as such, ``Title Page'' means
% the text near the most prominent appearance of the work's title,
% preceding the beginning of the body of the text.
% 
% The ``\textbf{publisher}'' means any person or entity that distributes
% copies of the Document to the public.
% 
% A section ``\textbf{Entitled XYZ}'' means a named subunit of the Document whose
% title either is precisely XYZ or contains XYZ in parentheses following
% text that translates XYZ in another language.  (Here XYZ stands for a
% specific section name mentioned below, such as ``\textbf{Acknowledgements}'',
% ``\textbf{Dedications}'', ``\textbf{Endorsements}'', or ``\textbf{History}''.)  
% To ``\textbf{Preserve the Title}''
% of such a section when you modify the Document means that it remains a
% section ``Entitled XYZ'' according to this definition.
% 
% The Document may include Warranty Disclaimers next to the notice which
% states that this License applies to the Document.  These Warranty
% Disclaimers are considered to be included by reference in this
% License, but only as regards disclaiming warranties: any other
% implication that these Warranty Disclaimers may have is void and has
% no effect on the meaning of this License.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 2. VERBATIM COPYING\par}
% \end{center}
% 
% You may copy and distribute the Document in any medium, either
% commercially or noncommercially, provided that this License, the
% copyright notices, and the license notice saying this License applies
% to the Document are reproduced in all copies, and that you add no other
% conditions whatsoever to those of this License.  You may not use
% technical measures to obstruct or control the reading or further
% copying of the copies you make or distribute.  However, you may accept
% compensation in exchange for copies.  If you distribute a large enough
% number of copies you must also follow the conditions in section~3.
% 
% You may also lend copies, under the same conditions stated above, and
% you may publicly display copies.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 3. COPYING IN QUANTITY\par}
% \end{center}
% 
% 
% If you publish printed copies (or copies in media that commonly have
% printed covers) of the Document, numbering more than 100, and the
% Document's license notice requires Cover Texts, you must enclose the
% copies in covers that carry, clearly and legibly, all these Cover
% Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
% the back cover.  Both covers must also clearly and legibly identify
% you as the publisher of these copies.  The front cover must present
% the full title with all words of the title equally prominent and
% visible.  You may add other material on the covers in addition.
% Copying with changes limited to the covers, as long as they preserve
% the title of the Document and satisfy these conditions, can be treated
% as verbatim copying in other respects.
% 
% If the required texts for either cover are too voluminous to fit
% legibly, you should put the first ones listed (as many as fit
% reasonably) on the actual cover, and continue the rest onto adjacent
% pages.
% 
% If you publish or distribute Opaque copies of the Document numbering
% more than 100, you must either include a machine-readable Transparent
% copy along with each Opaque copy, or state in or with each Opaque copy
% a computer-network location from which the general network-using
% public has access to download using public-standard network protocols
% a complete Transparent copy of the Document, free of added material.
% If you use the latter option, you must take reasonably prudent steps,
% when you begin distribution of Opaque copies in quantity, to ensure
% that this Transparent copy will remain thus accessible at the stated
% location until at least one year after the last time you distribute an
% Opaque copy (directly or through your agents or retailers) of that
% edition to the public.
% 
% It is requested, but not required, that you contact the authors of the
% Document well before redistributing any large number of copies, to give
% them a chance to provide you with an updated version of the Document.
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 4. MODIFICATIONS\par}
% \end{center}
% 
% You may copy and distribute a Modified Version of the Document under
% the conditions of sections 2 and 3 above, provided that you release
% the Modified Version under precisely this License, with the Modified
% Version filling the role of the Document, thus licensing distribution
% and modification of the Modified Version to whoever possesses a copy
% of it.  In addition, you must do these things in the Modified Version:
% 
% \begin{itemize}
% \item[A.] 
%    Use in the Title Page (and on the covers, if any) a title distinct
%    from that of the Document, and from those of previous versions
%    (which should, if there were any, be listed in the History section
%    of the Document).  You may use the same title as a previous version
%    if the original publisher of that version gives permission.
%    
% \item[B.]
%    List on the Title Page, as authors, one or more persons or entities
%    responsible for authorship of the modifications in the Modified
%    Version, together with at least five of the principal authors of the
%    Document (all of its principal authors, if it has fewer than five),
%    unless they release you from this requirement.
%    
% \item[C.]
%    State on the Title page the name of the publisher of the
%    Modified Version, as the publisher.
%    
% \item[D.]
%    Preserve all the copyright notices of the Document.
%    
% \item[E.]
%    Add an appropriate copyright notice for your modifications
%    adjacent to the other copyright notices.
%    
% \item[F.]
%    Include, immediately after the copyright notices, a license notice
%    giving the public permission to use the Modified Version under the
%    terms of this License, in the form shown in the Addendum below.
%    
% \item[G.]
%    Preserve in that license notice the full lists of Invariant Sections
%    and required Cover Texts given in the Document's license notice.
%    
% \item[H.]
%    Include an unaltered copy of this License.
%    
% \item[I.]
%    Preserve the section Entitled ``History'', Preserve its Title, and add
%    to it an item stating at least the title, year, new authors, and
%    publisher of the Modified Version as given on the Title Page.  If
%    there is no section Entitled ``History'' in the Document, create one
%    stating the title, year, authors, and publisher of the Document as
%    given on its Title Page, then add an item describing the Modified
%    Version as stated in the previous sentence.
%    
% \item[J.]
%    Preserve the network location, if any, given in the Document for
%    public access to a Transparent copy of the Document, and likewise
%    the network locations given in the Document for previous versions
%    it was based on.  These may be placed in the ``History'' section.
%    You may omit a network location for a work that was published at
%    least four years before the Document itself, or if the original
%    publisher of the version it refers to gives permission.
%    
% \item[K.]
%    For any section Entitled ``Acknowledgements'' or ``Dedications'',
%    Preserve the Title of the section, and preserve in the section all
%    the substance and tone of each of the contributor acknowledgements
%    and/or dedications given therein.
%    
% \item[L.]
%    Preserve all the Invariant Sections of the Document,
%    unaltered in their text and in their titles.  Section numbers
%    or the equivalent are not considered part of the section titles.
%    
% \item[M.]
%    Delete any section Entitled ``Endorsements''.  Such a section
%    may not be included in the Modified Version.
%    
% \item[N.]
%    Do not retitle any existing section to be Entitled ``Endorsements''
%    or to conflict in title with any Invariant Section.
%    
% \item[O.]
%    Preserve any Warranty Disclaimers.
% \end{itemize}
% 
% If the Modified Version includes new front-matter sections or
% appendices that qualify as Secondary Sections and contain no material
% copied from the Document, you may at your option designate some or all
% of these sections as invariant.  To do this, add their titles to the
% list of Invariant Sections in the Modified Version's license notice.
% These titles must be distinct from any other section titles.
% 
% You may add a section Entitled ``Endorsements'', provided it contains
% nothing but endorsements of your Modified Version by various
% parties---for example, statements of peer review or that the text has
% been approved by an organization as the authoritative definition of a
% standard.
% 
% You may add a passage of up to five words as a Front-Cover Text, and a
% passage of up to 25 words as a Back-Cover Text, to the end of the list
% of Cover Texts in the Modified Version.  Only one passage of
% Front-Cover Text and one of Back-Cover Text may be added by (or
% through arrangements made by) any one entity.  If the Document already
% includes a cover text for the same cover, previously added by you or
% by arrangement made by the same entity you are acting on behalf of,
% you may not add another; but you may replace the old one, on explicit
% permission from the previous publisher that added the old one.
% 
% The author(s) and publisher(s) of the Document do not by this License
% give permission to use their names for publicity for or to assert or
% imply endorsement of any Modified Version.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 5. COMBINING DOCUMENTS\par}
% \end{center}
% 
% 
% You may combine the Document with other documents released under this
% License, under the terms defined in section~4 above for modified
% versions, provided that you include in the combination all of the
% Invariant Sections of all of the original documents, unmodified, and
% list them all as Invariant Sections of your combined work in its
% license notice, and that you preserve all their Warranty Disclaimers.
% 
% The combined work need only contain one copy of this License, and
% multiple identical Invariant Sections may be replaced with a single
% copy.  If there are multiple Invariant Sections with the same name but
% different contents, make the title of each such section unique by
% adding at the end of it, in parentheses, the name of the original
% author or publisher of that section if known, or else a unique number.
% Make the same adjustment to the section titles in the list of
% Invariant Sections in the license notice of the combined work.
% 
% In the combination, you must combine any sections Entitled ``History''
% in the various original documents, forming one section Entitled
% ``History''; likewise combine any sections Entitled ``Acknowledgements'',
% and any sections Entitled ``Dedications''.  You must delete all sections
% Entitled ``Endorsements''.
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 6. COLLECTIONS OF DOCUMENTS\par}
% \end{center}
% 
% You may make a collection consisting of the Document and other documents
% released under this License, and replace the individual copies of this
% License in the various documents with a single copy that is included in
% the collection, provided that you follow the rules of this License for
% verbatim copying of each of the documents in all other respects.
% 
% You may extract a single document from such a collection, and distribute
% it individually under this License, provided you insert a copy of this
% License into the extracted document, and follow this License in all
% other respects regarding verbatim copying of that document.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 7. AGGREGATION WITH INDEPENDENT WORKS\par}
% \end{center}
% 
% 
% A compilation of the Document or its derivatives with other separate
% and independent documents or works, in or on a volume of a storage or
% distribution medium, is called an ``aggregate'' if the copyright
% resulting from the compilation is not used to limit the legal rights
% of the compilation's users beyond what the individual works permit.
% When the Document is included in an aggregate, this License does not
% apply to the other works in the aggregate which are not themselves
% derivative works of the Document.
% 
% If the Cover Text requirement of section~3 is applicable to these
% copies of the Document, then if the Document is less than one half of
% the entire aggregate, the Document's Cover Texts may be placed on
% covers that bracket the Document within the aggregate, or the
% electronic equivalent of covers if the Document is in electronic form.
% Otherwise they must appear on printed covers that bracket the whole
% aggregate.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 8. TRANSLATION\par}
% \end{center}
% 
% 
% Translation is considered a kind of modification, so you may
% distribute translations of the Document under the terms of section~4.
% Replacing Invariant Sections with translations requires special
% permission from their copyright holders, but you may include
% translations of some or all Invariant Sections in addition to the
% original versions of these Invariant Sections.  You may include a
% translation of this License, and all the license notices in the
% Document, and any Warranty Disclaimers, provided that you also include
% the original English version of this License and the original versions
% of those notices and disclaimers.  In case of a disagreement between
% the translation and the original version of this License or a notice
% or disclaimer, the original version will prevail.
% 
% If a section in the Document is Entitled ``Acknowledgements'',
% ``Dedications'', or ``History'', the requirement (section~4) to Preserve
% its Title (section~1) will typically require changing the actual
% title.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 9. TERMINATION\par}
% \end{center}
% 
% 
% You may not copy, modify, sublicense, or distribute the Document
% except as expressly provided under this License.  Any attempt
% otherwise to copy, modify, sublicense, or distribute it is void, and
% will automatically terminate your rights under this License.
% 
% However, if you cease all violation of this License, then your license
% from a particular copyright holder is reinstated (a) provisionally,
% unless and until the copyright holder explicitly and finally
% terminates your license, and (b) permanently, if the copyright holder
% fails to notify you of the violation by some reasonable means prior to
% 60 days after the cessation.
% 
% Moreover, your license from a particular copyright holder is
% reinstated permanently if the copyright holder notifies you of the
% violation by some reasonable means, this is the first time you have
% received notice of violation of this License (for any work) from that
% copyright holder, and you cure the violation prior to 30 days after
% your receipt of the notice.
% 
% Termination of your rights under this section does not terminate the
% licenses of parties who have received copies or rights from you under
% this License.  If your rights have been terminated and not permanently
% reinstated, receipt of a copy of some or all of the same material does
% not give you any rights to use it.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 10. FUTURE REVISIONS OF THIS LICENSE\par}
% \end{center}
% 
% 
% The Free Software Foundation may publish new, revised versions
% of the GNU Free Documentation License from time to time.  Such new
% versions will be similar in spirit to the present version, but may
% differ in detail to address new problems or concerns.  See
% \url{https://www.gnu.org/licenses/}.
% 
% Each version of the License is given a distinguishing version number.
% If the Document specifies that a particular numbered version of this
% License ``or any later version'' applies to it, you have the option of
% following the terms and conditions either of that specified version or
% of any later version that has been published (not as a draft) by the
% Free Software Foundation.  If the Document does not specify a version
% number of this License, you may choose any version ever published (not
% as a draft) by the Free Software Foundation.  If the Document
% specifies that a proxy can decide which future versions of this
% License can be used, that proxy's public statement of acceptance of a
% version permanently authorizes you to choose that version for the
% Document.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf 11. RELICENSING\par}
% \end{center}
% 
% 
% ``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
% World Wide Web server that publishes copyrightable works and also
% provides prominent facilities for anybody to edit those works.  A
% public wiki that anybody can edit is an example of such a server.  A
% ``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
% site means any set of copyrightable works thus published on the MMC
% site.
% 
% ``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
% license published by Creative Commons Corporation, a not-for-profit
% corporation with a principal place of business in San Francisco,
% California, as well as future copyleft versions of that license
% published by that same organization.
% 
% ``Incorporate'' means to publish or republish a Document, in whole or
% in part, as part of another Document.
% 
% An MMC is ``eligible for relicensing'' if it is licensed under this
% License, and if all works that were first published under this License
% somewhere other than this MMC, and subsequently incorporated in whole
% or in part into the MMC, (1) had no cover texts or invariant sections,
% and (2) were thus incorporated prior to November 1, 2008.
% 
% The operator of an MMC Site may republish an MMC contained in the site
% under CC-BY-SA on the same site at any time before August 1, 2009,
% provided the MMC is eligible for relicensing.
% 
% 
% \needspace{\baselineskip}
% \begin{center}
% {\large\bf ADDENDUM: How to use this License for your documents\par}
% \end{center}
% 
% To use this License in a document you have written, include a copy of
% the License in the document and put the following copyright and
% license notices just after the title page:
% 
% \bigskip
% \begin{quote}
%     Copyright \copyright{}  YEAR  YOUR NAME.
%     Permission is granted to copy, distribute and/or modify this document
%     under the terms of the GNU Free Documentation License, Version 1.3
%     or any later version published by the Free Software Foundation;
%     with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
%     A copy of the license is included in the section entitled ``GNU
%     Free Documentation License''.
% \end{quote}
% \bigskip
%     
% If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
% replace the ``with \dots\ Texts.''\ line with this:
% 
% \bigskip
% \begin{quote}
%     with the Invariant Sections being LIST THEIR TITLES, with the
%     Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
% \end{quote}
% \bigskip
%     
% If you have Invariant Sections without Cover Texts, or some other
% combination of the three, merge those two alternatives to suit the
% situation.
% 
% If your document contains nontrivial examples of program code, we
% recommend releasing these examples in parallel under your choice of
% free software license, such as the GNU General Public License,
% to permit their use in free software.
%
% \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}
% General settings
%    \begin{macrocode}
\renewcommand\linenumberfont{\normalfont\footnotesize}
%    \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}
\NewDocumentCommand{\unconditional@appin}{o m}{%
  \IfNoValueTF{#1}
  {\luadirect{ekdosis.appin(\luastringO{#2})}}
  {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}%
}
 % \def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext}
\def\blfootnote{\gdef\@thefnmark{}\@blfootnotetext}
\long\def\@blfootnotetext#1{\insert\footins{%
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splittopskip\footnotesep
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\columnwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makeblfntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%
\newcommand\@makeblfntext[1]{%
    \parindent 1em%
    \noindent
    \hb@xt@0em{\hss\@makefnmark}#1}
\newif\ifrtl@app
\NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue}
\NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse}
\edef\ekdsep{] }
\NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}}
\edef\ekd@end@apparatus{}
\NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}}
\def\ekd@unit@delim{}
\NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}}
\def\ekd@default@rule{\rule{2truein}{0.5pt}}
\newif\iffootnoterule
\let\dflt@footnoterule\footnoterule
\let\dflt@pcol@footnoterule\pcol@footnoterule
\renewcommand\footnoterule{%
  \iffootnoterule
  \dflt@footnoterule%
  \fi
}
\renewcommand\pcol@footnoterule{%
  \iffootnoterule
  \dflt@pcol@footnoterule%
  \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%
}
\def\add@apparatus{%
  \test@apparatus%
  \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}%
}
\NewDocumentCommand{\append@app}{o +m}{%
  \ifekd@isinapp%
    \ifekd@state%
    \IfNoValueTF{#1}%
      {\luadirect{ekdosis.appin(\luastringO{#2})}}%
      {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}%
    \fi%
  \fi}
\NewDocumentCommand{\append@ln@app}{o +m}{%
  \IfNoValueTF{#1}
  {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}}
  {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2},
      \luastringO{#1}))}}}
\ekvdefinekeys{appnote}{
   store type = \ekdan@type,
   initial type = default
 }
\NewDocumentCommand{\EkdosisDefaultApparatus}{m}{%
  \ekvset{appnote}{type=#1}}
\NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{%
  \begingroup
  \ekvset{appnote}{#1}%
  \ekd@isinapptrue%
  \stepcounter{ekd@lab}%
  \zlabel{ekd:\theekd@lab}%
  \luadirect{ekdosis.storeabspg(
    \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}%
  \ifekd@state\add@apparatus\fi%
  \luadirect{tex.sprint(ekdosis.removesp(\luastringN{#2}))}%
  \ekd@isinappfalse%
  \endgroup}
\def\current@ref@arg#1#2{{%\textdir TLT%
    \unexpanded\expandafter{\ekd@refnumstyle}%
    \ifnum%
    \getpagerefnumber{#1}
    =
    \getpagerefnumber{#2}
      \ifnum%
      \getrefnumber{#1}
      =
      \getrefnumber{#2}
      %
      \ifekd@mapps%
      \ifbool{subsq@unit@\ekdan@type}{%
        \ifnum%
        \getrefnumber{#1}
        =
        \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}}
        \else
        \LRnum{\getrefnumber{#1}}% issue the no
        \fi%
      }%
      {\LRnum{\getrefnumber{#1}}}% issue the no
      \else
      \ifsubsq@unit%
      %
      \ifnum%
      \getrefnumber{#1}
      =
      \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}}
      \else
      \LRnum{\getrefnumber{#1}}% issue the no
      \fi
      %
      \else
      \LRnum{\getrefnumber{#1}}% issue the no
      \fi
      \fi
      %
      \else
      \LRnum{\getrefnumber{#1}}--%
      \LRnum{\getrefnumber{#2}}% issue the nos
      \fi%
      \else
      \LRnum{\getrefnumber{#1}}--%
      \LRnum{\getpagerefnumber{#2}}.%
      \LRnum{\getrefnumber{#2}}% issue pg and ln nos
      \fi%
    }\unexpanded\expandafter{\ekd@postrefnum}%
  }%
  \def\current@ref{{%\textdir TLT%
      \unexpanded\expandafter{\ekd@refnumstyle}%
    \ifnum%
    \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}
    =
    \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}
      \ifnum%
      \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}
      =
      \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}
      %
      \ifekd@mapps%
      \ifbool{subsq@unit@\ekdan@type}{%
        \ifnum%
        \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}
        =
        \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b}
        \else
        \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no
        \fi%
      }{\LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}}% issue the no
      \else
      \ifsubsq@unit%
      %
      \ifnum%
      \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}
      =
      \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b}
      \else
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no
      \fi
      %
      \else
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no
      \fi
      \fi
      %
      \else
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--%
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue the nos
      \fi%
      \else
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--%
      \LRnum{\getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}.%
      \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue pg and ln nos
      \fi%
    }\unexpanded\expandafter{\ekd@postrefnum}%
  }%
\define@cmdkeys[ekd]{lemrdg}[ekdlr@]{wit, alt, pre, post, prewit,
  postwit, type}
\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%
}
\ekvdefinekeys{note}{
  store type = \ekdan@type,
  store lem = \ekdn@lem,
  code labelb = \def\ekdn@labelb{#1},
  code labele = \def\ekdn@labele{#1},
  store sep = \ekdn@sep,
  initial type = default,
  initial sep = \ekdsep
 }
\NewDocumentCommand{\note@noapp}{O{} +m}{%
  \bgroup%
  \ekvset{note}{#1}
  \stepcounter{ekd@lab}%
  \zlabel{ekd:\theekd@lab}%
  \luadirect{ekdosis.storeabspg(
    \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}%
  \ifekd@state\add@apparatus\fi%
  \ifekd@mapps%
    \ifnum%
      \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))}
      = 1
      \boolfalse{subsq@unit@\ekdan@type}%
    \fi%
  \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}%
    \def\ekd@munit@delim{%
      \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}%
  \fi%  
  \ifdefined\ekdn@labelb%
    \luadirect{tex.sprint(ekdosis.setnotelab(\luastringO{\ekdn@labelb}))}%
    \ifdefined\ekdn@labele\else\def\ekdn@labele{\ekdn@labelb}\fi%
  \else\PackageError{ekdosis}{missing labelb}{`labelb' must be
    set.}\fi%
  \ifbool{al@rlmode}%
  {\edef\note@contents{%
      % \hskip .75em
      \ifekd@mapps
        \ifbool{subsq@unit@\ekdan@type}%
        {\ekd@munit@delim}{}%
      \else%
        \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi%
      \fi%
      \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em
      \ifdefined\ekdn@lem%
          {\textdir TRT\unexpanded\expandafter{\ekdn@lem}}%
          \unexpanded\expandafter{\ekdn@sep}\else\fi%
            {\textdir TRT\unexpanded{#2}}}}%
  {\edef\note@contents{%
      % \hskip .75em
      \ifekd@mapps
        \ifbool{subsq@unit@\ekdan@type}%
        {\ekd@munit@delim}{}%
      \else%
        \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi%
      \fi%
      \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em
      \ifdefined\ekdn@lem
        \ltx@ifpackageloaded{babel}%
          {\noexpand\selectlanguage{\languagename}%
            \unexpanded\expandafter{\ekdn@lem}}%
          {\unexpanded\expandafter{\ekdn@lem}}%
          \unexpanded\expandafter{\ekdn@sep}\else\fi%
          \ltx@ifpackageloaded{babel}%
          {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{%
            \unexpanded{#2}}}}%
  \ifekd@mapps%
  \unconditional@appin[\ekdan@type]{\note@contents}%
  \else%
  \unconditional@appin{\note@contents}%
  \fi%
    \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}%
  \egroup%
  \subsq@unittrue%
}
\ekvdefinekeys{ekd@note}{
  store pre = \pre@value,
  store post = \post@value
}
\NewDocumentCommand{\ekd@note}{O{} m}{%
  \bgroup%
  \ekvset{ekd@note}{#1}%
  \edef\note@contents{%
    \ekvifdefinedNoVal{note}{pre}{}{%
      \unexpanded\expandafter{\pre@value}}%
    \unexpanded{#2}%
    \ekvifdefinedNoVal{note}{post}{}{%
      \unexpanded\expandafter{\post@value}}%
  }%
  \append@app{\note@contents}%
  \egroup%
}
\NewDocumentCommand{\ekd@note@star}{O{} m}{%
  \if@pkg@parnotes
    \bgroup%
      \ekvset{ekd@note}{#1}%
      \edef\note@contents{%
        \ekvifdefinedNoVal{note}{pre}{}{%
          \unexpanded\expandafter{\pre@value}}%
        \unskip\noexpand\parnote{#2}%
        \ekvifdefinedNoVal{note}{post}{}{%
          \unexpanded\expandafter{\post@value}}%
      }%
      \append@app{\note@contents}%
    \egroup%
  \else
    \append@app{\unskip\footnote{#2}}%
  \fi%
}
\NewDocumentCommand{\note@app}{s O{} +m}{%
  \ifbool{al@rlmode}{%
    \IfBooleanTF{#1}{\ekd@note@star[#2]{\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
    \EkdosisOn#1}{%
    \EkdosisOff
  \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,
  choice segmentation = {auto = \def\segmentation@val{auto},
                         noauto = \def\segmentation@val{noauto}},
  bool flush = \ifekd@flushapp,
  initial tcols = 2,
  initial lcols = 1,
  initial texts = edition;translation,
  initial apparatus = edition,
  default segmentation = auto
}
\NewDocumentCommand{\SetEkdosisAlignment}{m}{
  \ekvset{ekd@align}{#1}
}
\patchcmd{\pcol@nextpage}{%
  \endgroup}{%
  \ifekd@pagelineation\resetlinenumber\fi
  \endgroup}{}{}
\NewDocumentCommand{\EkdosisColStart}{}{%
  \ekd@setlineno%
  \runninglinenumbers
  \ekd@storecol%
  \stepcounter{ekd@lab}%
  \zlabel{ekd:\theekd@lab}%
  \luadirect{%
    ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}},
    "pg_i")}%
  \ifekd@pagelineation
    \luadirect{tex.sprint(ekdosis.checkresetlineno())}
  \fi
}
\NewDocumentCommand{\EkdosisColStop}{}{%
  \stepcounter{ekd@lab}%
  \zlabel{ekd:\theekd@lab}%
  \luadirect{%
    ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}},
    "pg_ii")}%
  \endrunninglinenumbers%
}
\NewDocumentEnvironment{alignment}{O{}}
{%
  \ekvset{ekd@align}{#1}%
  \luadirect{ekdosis.mkenvdata(
    \luastring{\texts@value},
    "texts"
    )}
  \ifekd@flushapp
    \luadirect{ekdosis.newalignment("set")}
  \fi
  \luadirect{ekdosis.mkenvdata(
    \luastring{\apparatus@value}, "apparatus"
    )}
  \setrunninglinenumbers
  \luadirect{tex.sprint(ekdosis.mkenv())}
  \ifekd@paired
  \begin{paracol}[\lcols@num]{\tcols@num}
  \else
  \begin{paracol}[\lcols@num]*{\tcols@num}
  \fi
  }
  {\end{paracol}
  \iftei@export\luadirect{ekdosis.export_coldata_totei()}\fi
  \ifekd@flushapp
    \luadirect{ekdosis.newalignment("reset")}
  \fi
  \luadirect{ekdosis.flushenvdata()}
  \luadirect{ekdosis.flushcolnums()}
  }
%    \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
%</package>
% \fi
% 
% \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"))
local par =  lpeg.P(lpeg.P("\\par") * spce^1)
local parb = lpeg.P(lpeg.Cs("\\p@rb") * spce^1)
local para = lpeg.P(lpeg.Cs("\\p@ra") * spce^1)

-- Bind to local variables
local next = next

-- General
xmlids = {}

local function xmlidfound(element)
   for i = 1,#xmlids do
      if xmlids[i].xmlid == element then
	 return true
      end
   end
   return false
end

-- Witnesses
listWit = {}
idsRend = {}
shorthands = {}

local function isfound(table, value)
   for i = 1,#table do
      if table[i] == value then
	 return true
      end
   end
   return false
end

local function isintable(table, value)
   for i = 1,#table do
      if table[i].a == value then
	 return true
      end
   end
   return false
end

local function get_a_index(id, table)
   local idfound = nil
   for i = 1,#table
   do
      if table[i].a == id then
	 idfound = i
	 break
      end
   end
   return idfound
end

local function getindex(id, table)
   local idfound = nil
   for i = 1,#table
   do
      if table[i].xmlid == id then
	 idfound = i
	 break
      end
   end
   return idfound
end

function ekdosis.newwitness(id,
			    siglum,
			    description,
			    Settlement,
			    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=\"ar-Latn\" type=\"transliterated\""},
   {a="textbf", b="hi", c=" rend=\"bold\""},
   {a="textit", b="hi", c=" rend=\"italic\""},
   {a="textsc", b="hi", c=" rend=\"smallcaps\""},
   {a="textsf", b="hi", c=" rend=\"sf\""},
   {a="arbup", b="hi", c=" rend=\"sup\""},
   {a="txarb", b="s", c=" xml:lang=\"arb\""},
   {a="arb", b="s",
    c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""}
}

local texpatttotags = {
   {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 <ref target=\"#%3\">%2</ref>"},
   {a="\\icite%s?%[(.-)%]{(.-)}", b="<ref target=\"#%2\">%1</ref>"},
   {a="\\icite%s?{(.-)}", b="<ptr target=\"#%1\"/>"}
}

local envtotags = {
   {a="ekdverse", b="lg", c=""},
   {a="txarabtr", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""},
   {a="txarab", b="p", c=" xml:lang=\"arb\""},
   {a="center", b="p", c=" rend=\"centered\""},
   {a="verse", b="lg", c=""},
   {a="arab", b="p",
    c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""}
}

local close_p = {
   "p",
   "lg"
}

local forbid_xmlid = true

function ekdosis.newcmdtotag(cmd, tag, attr)
   if forbid_xmlid
   then
      attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here
   else
   end
   if isintable(cmdtotags, cmd)
   then
      local index = get_a_index(cmd, cmdtotags)
      table.remove(cmdtotags, index)
      table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr})
      table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end)
   else
      table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr})
      table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end)
   end
   return true
end

function ekdosis.newpatttotag(pat, repl)
   pat = string.gsub(pat, "([%[%]])", "%%%1")
   pat = string.gsub(pat, "%#[1-9]", "(.-)")
   repl = string.gsub(repl, "%#([1-9])", "%%%1")
   table.insert(texpatttotags, { a = pat, b = repl })
   table.sort(texpatttotags, function(a ,b) return(#a.a > #b.a) end)
   return true
end

function ekdosis.newenvtotag(env, tag, attr, closep)
   if forbid_xmlid
   then
      attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here
   else
   end
   if isintable(envtotags, env)
   then
      local index = get_a_index(env, envtotags)
      table.remove(envtotags, index)
      table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep})
      table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end)
   else
      table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep})
      table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end)
   end
   return true
end

-- Get values of attributes
local function get_attr_value(str, attr)
   str = str..","
   local attrval = string.match(str, "%f[%w]"..attr.."%s?%=%s?%b{}")
      or string.match(str, "%f[%w]"..attr.."%s?%=%s?.-%,")
      or ""
   attrval = string.gsub(attrval, attr.."%s?%=%s?(%b{})", function(bbraces)
			    bbraces = string.sub(bbraces, 2, -2)
			    return string.format("%s", bbraces)
   end)
   attrval = string.gsub(attrval, attr.."%s?%=%s?(.-)%s?%,", "%1")
   return attrval
end

local function xml_entities(str)
   str = string.gsub(str, "%<", "&lt;")
   str = string.gsub(str, "%>", "&gt;")
   return str
end

local function note_totei(str)
   str = gsub(str,
	      dblbkslash *
		 note *
		 spcenc^-1 *
		 bsqbrackets *
		 bcbraces *
		 spcenc^-1,
	      function(bkslash, cmd, opt, arg)
		 opt = string.sub(opt, 2, -2)
		 arg = string.sub(arg, 2, -2)
		 teitype = get_attr_value(opt, "type")
		 if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end
		 right = get_attr_value(opt, "labelb")
		 left = get_attr_value(opt, "labele")
		 if left ~= ""
		 then
		    return string.format(
		       "<%s%s target=\"#range(right(%s),left(%s))\">%s</%s><anchor xml:id=\"%s\"/>",
		       cmd, teitype, right, left, arg, cmd, right)
		 elseif left == ""
		 then
		    return string.format(
		       "<%s%s target=\"#right(%s)\">%s</%s><anchor xml:id=\"%s\"/>",
		       cmd, teitype, right, arg, cmd, right)
		 end
   end)
   return str
end

local function app_totei(str)
   str = gsub(str,
	      dblbkslash *
		 app *
		 spcenc^-1 *
		 bsqbrackets *
		 bcbraces *
		 spcenc^-1,
	      function(bkslash, cmd, opt, arg)
		 opt = string.sub(opt, 2, -2)
		 arg = string.sub(arg, 2, -2)
		 opt = get_attr_value(opt, "type")
		 if opt ~= "" then opt = " type=\""..opt.."\"" else end
		 return app_totei(string.format("<%s%s>%s</%s>",
						cmd, opt, arg, cmd))
   end)
   return str
end

local function lem_rdg_totei(str)
   str = gsub(str,
	      spcenc^-1 *
		 dblbkslash *
		 lemrdg *
		 spcenc^-1 *
		 bsqbrackets *
		 bcbraces *
		 spcenc^-1,
	      function(bkslash, cmd, opt, arg)
		 opt = string.sub(opt, 2, -2)
		 arg = string.sub(arg, 2, -2)
		 -- opt = get_attr_value(opt, "wit")
		 --
		 teiwit = get_attr_value(opt, "wit")
		 if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end
		 teitype = get_attr_value(opt, "type")
		 if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end
		 --
		 if opt == ""
		 then
		    return lem_rdg_totei(string.format("<%s>%s</%s>",
						       cmd, arg, cmd))
		 else
		    -- opt = ekdosis.getsiglum(opt, "tei")
		    return lem_rdg_totei(string.format("<%s%s%s>%s</%s>",
						       cmd, teiwit, teitype, arg, cmd))
		 end
   end)
   str = gsub(str, spcenc^-0 * dblbkslash * lemrdg * spcenc^-1 * bcbraces * spcenc^-1,
	      function(bkslash, cmd, arg)
		 arg = string.sub(arg, 2, -2)
		 return lem_rdg_totei(string.format("<%s>%s</%s>", cmd, arg, cmd))
   end)
   return str
end

local function relocate_notes(str)
   str = string.gsub(str, "(%<lem.-%>.-)(%<note.->.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2")
   return str
end

local function linestotei(str)
--   str = "\n<l>"..str
   str = string.gsub(str, "^%s?(.-)%s?$", "\n<l>%1</l>\n")
--   str = gsub(str, endpoem, "</l>\n")
   str = gsub(str, poemline * spcenc^-1 * lpeg.P("&gt;"), "\n<lb/>")
   str = gsub(str, poemline * spcenc^-1, "</l>\n<l>")
--   str = str.."</l>\n"
   return str
end

-- better use lpeg: look into this later
local function versetotei(str)
   str = string.gsub(str, "(\\begin%s?%{ekdverse%})(%b[])(.-)(\\end%s?%{ekdverse%})", function(benv, opt, arg, eenv)
			arg = linestotei(arg)
			return string.format("%s%s%s%s", benv, opt, arg, eenv)
   end)
   str = string.gsub(str, "(\\begin%s?%{ekdverse%})(.-)(\\end%s?%{ekdverse%})", function(benv, arg, eenv)
			arg = linestotei(arg)
			return string.format("%s%s%s", benv, arg, eenv)
   end)
   str = string.gsub(str, "(\\begin%s?%{verse%})(%b[])(.-)(\\end%s?%{verse%})", function(benv, opt, arg, eenv)
			arg = linestotei(arg)
			return string.format("%s%s%s%s", benv, opt, arg, eenv)
   end)
   str = string.gsub(str, "(\\begin%s?%{verse%})(.-)(\\end%s?%{verse%})", function(benv, arg, eenv)
			arg = linestotei(arg)
			return string.format("%s%s%s", benv, arg, eenv)
   end)
   return str
end

local function envtotei(str)
   for i = 1,#envtotags
   do
      if envtotags[i].b ~= ""
      then
	 if isfound(close_p, envtotags[i].b) or envtotags[i].d == "yes"
	 then
	    str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
			  * lpeg.Cs(envtotags[i].a) * lpeg.P("}")
			  * bsqbracketsii * bcbracesii * spcenc^-1,
		       "\\p@rb <"..envtotags[i].b..envtotags[i].c..">")
	    str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{")
			  * lpeg.Cs(envtotags[i].a) * lpeg.P("}"),
		       "</"..envtotags[i].b..">\\p@ra ")
	 else
	    str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
			  * lpeg.Cs(envtotags[i].a) * lpeg.P("}")
			  * bsqbracketsii * bcbracesii * spcenc^-1,
		       "<"..envtotags[i].b..envtotags[i].c..">")
	    str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{")
			  * lpeg.Cs(envtotags[i].a) * lpeg.P("}"),
		       "</"..envtotags[i].b..">")
	 end
      else
	 str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
		       * lpeg.Cs(envtotags[i].a) * lpeg.P("}")
		       * bsqbracketsii * bcbracesii * spcenc^-1,
		    "")
	 str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{")
		       * lpeg.Cs(envtotags[i].a) * lpeg.P("}"),
		    "")
      end
   end
   str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{")
		 * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii
		 * bcbracesii * spcenc^-1,
	      "<%1>")
   str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{")
		 * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii
		 * bcbracesii,
	      "</%1>")
   return str
end

local function texpatttotei(str)
   for i = 1,#texpatttotags do
      str = string.gsub(str, texpatttotags[i].a, texpatttotags[i].b)
   end
   return str
end

local function cmdtotei(str)
   for i = 1,#cmdtotags
   do
      str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * bsqbrackets * -bcbraces, "\\%1%2{}")
      str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * -(bsqbrackets + bcbraces), "\\%1[]{}")
      str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b{})", "%1[]%2")
      str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b[])(%b{})",
			function(cmd, arg, body)
			   body = string.sub(body, 2, -2)
			   arg = string.sub(arg, 2, -2)
			   arg = string.gsub(arg, "(%b{})", function(braces)
						braces = string.sub(braces, 2, -2)
						return string.format("\"%s\"", braces)
			   end)
			   body = cmdtotei(body)
			   -- return string.format("<"..cmdtotags[i].b..cmdtotags[i].c.." %s>%s</"..cmdtotags[i].b..">", arg, body)
			   if cmdtotags[i].b ~= ""
			   then
			      return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s</" ..
						   cmdtotags[i].b..">", body)
			   else
			      return ""
			   end
      end)
   end
   -- temporarily:
   str = string.gsub(str, "\\(linelabel)%s?(%b{})",
		     function(cmd, body)
			body = string.sub(body, 2, -2)
			body = cmdtotei(body)
			return string.format("<anchor xml:id=\"%s\"/>", 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 = gsub(str, ((para + parb) * par^-1)^2, "\\p@r ")
   str = string.gsub(str, "\\p@ra%s+", "<p>")
   str = string.gsub(str, "\\p@rb%s+", "</p>")
   str = string.gsub(str, "\\p@r%s+", "")   
   str = string.gsub(str, "%s?\\par%s?", "<p>", 1)
   str = string.gsub(str, "(%<p%>)(%s-)(%<%/?div%d?)", "%3")
   str = string.gsub(str, "%s?\\par%s?", "</p><p>")
   str = string.gsub(str, "<p>%s?</p>", "")
   str = string.gsub(str, "(%<p%>)%s?(%</div%>)$", "%2")
   str = string.gsub(str, "(%<p%>)%s?$", "")
   str = string.gsub(str, "(<p>)%s?(<div.->)", "%2%1")
   return str
end

local function self_close_tags(str)
   str = gsub(str, lpeg.P("<" * -lpeg.S("/"))
		 * lpeg.Cs(letters^1)
		 * lpeg.Cs((1 - lpeg.S"<>")^0)
		 * lpeg.P(">")
		 * lpeg.P("</")
		 * lpeg.Cs(letters^1)
		 * lpeg.P(">"), function(ftag, arg, ltag)
		    if ftag == ltag
		    then
		       return string.format("<%s%s/>", ftag, arg)
		    else
		    end
   end)
   return str
end

local divdepth = {
   book = 1,
   part = 2,
   chapter = 3,
   section = 4,
   subsection = 5,
   subsubsection = 6
}

function ekdosis.mkdivdepths(...)
   divdepth = {}
   local num = 1
   for _, y in ipairs{...}
   do
      if y == "book" or "part" or "chapter"
	 or "section" or "subsection" or "subsubsection"
      then
	 divdepth[y] = num
	 num = num + 1
      else
      end
   end
   return true
end

-- LaTeX side: format the divisions
local fmtdiv = {}

function ekdosis.fmtdiv(n, fmtb, fmte)
   if isintable(fmtdiv, n)
   then
      local index = get_a_index(n, fmtdiv)
      table.remove(fmtdiv, index)
   else
   end
   table.insert(fmtdiv, { a = n, formatb = fmtb, formate = fmte} )
   return true
end

function ekdosis.getfmtdiv(n, pos)
   local index = get_a_index(n, fmtdiv)
   if index ~= nil
   then
      if pos == "b"
      then
	 return fmtdiv[index].formatb
      elseif pos == "e"
      then
	 return fmtdiv[index].formate
      end
   else
      return ""
   end
end

local ekddivs = true

function ekdosis.setekddivsfalse()
   ekddivs = false
end

local function ekddivs_totei(str)
   str = gsub(str, dblbkslash * lpeg.Cs("ekddiv") * spce^-1 * bcbraces,
	      function(bkslash, cmd, space, arg)
		 if ekddivs
		 then
		    arg = string.sub(arg, 2, -2)
		    teitype = get_attr_value(arg, "type")
		    tein = get_attr_value(arg, "n")
		    teihead = get_attr_value(arg, "head")
		    teidepth = get_attr_value(arg, "depth")
		    if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end
		    if tein ~= "" then tein = " n=\""..tein.."\"" else end
		    if teidepth ~= ""
		    then
		       teidepth = " depth=\""..teidepth.."\""
		    else
		       teidepth = " depth=\"1\""
		    end
		    return string.format("\\p@rb <div%s%s%s><head>%s</head>\\p@ra ",
					 teitype, tein, teidepth, teihead)
		 else
		    return ""
		 end
   end)
   return str
end

local function section_totei(str)
   str = gsub(str, dblbkslash * sections * spce^-1 * bcbraces, "%1%2%3[]%4")
   str = gsub(str, dblbkslash * sections * spce^-1 * bsqbrackets * bcbraces,
	      function(bkslash, secname, space, opt, arg)
		 if ekddivs
		 then
		    return ""
		 else
		    ctr = divdepth[secname]
		    arg = string.sub(arg, 2, -2)
		    return string.format("\\p@rb <div%s type=\"%s\"><head>%s</head>\\p@ra ",
					 ctr, secname, arg)
		 end
   end)
   return str
end

local used_ndivs = {}

local function close_ekddivs_at_end(str)
   local isdiv = false
   if string.find(str, "</div>$")
   then
      isdiv = true
      str = string.gsub(str, "(.*)(</div>)$", "%1")
   else
   end
   -- collect used depth numbers
   for i in string.gmatch(str, "<div .-depth%=\"%d\".->")
   do
      i = string.match(i, "depth=\"%d\"")
      i = string.match(i, "%d")
      if isintable(used_ndivs, i)
      then
      else
	 table.insert(used_ndivs, {a = i} )
      end
   end
   if next(used_ndivs) ~= nil
   then
      table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end)
   else
   end
   local firstdiv = string.match(str, "<div .-depth%=\"%d\".->") or ""
   firstdiv = string.match(firstdiv, "depth%=\"%d\"") or ""
   firstdiv = string.match(firstdiv, "%d") or ""
   local lastdiv = string.match(string.reverse(str), ">.-\"%d\"%=htped.- vid<") or ""
   lastdiv = string.match(lastdiv, "\"%d\"%=htped") or ""
   lastdiv = string.match(lastdiv, "%d") or ""
   local firstdivindex = get_a_index(firstdiv, used_ndivs)
   local lastdivindex = get_a_index(lastdiv, used_ndivs)
   firstdivindex = tonumber(firstdivindex)
   lastdivindex = tonumber(lastdivindex)
   local closedivs = ""
   if isintable(used_ndivs, firstdiv)
   then
      while lastdivindex >= firstdivindex
      do
	 closedivs = closedivs.."</div>"
	 lastdivindex = lastdivindex - 1
      end
   end
   if isdiv
   then
      return str..closedivs.."</div>"
   else
      return str..closedivs
   end
end

local function close_ndivs_at_end(str)
   local isdiv = false
   if string.find(str, "</div>$")
   then
      isdiv = true
      str = string.gsub(str, "(.*)(</div>)$", "%1")
   else
   end
   -- collect used div numbers
   for i in string.gmatch(str, "<div[1-6]")
   do
      i = string.match(i, "[1-6]")
      if isintable(used_ndivs, i)
      then
      else
   	 table.insert(used_ndivs, {a = i} )
      end
   end
   if next(used_ndivs) ~= nil
   then
      table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end)
   else
   end
   local firstdiv = string.match(str, "<div[1-6]") or ""
   firstdiv = string.match(firstdiv, "[1-6]") or ""
   local lastdiv = string.match(string.reverse(str), "[1-6]vid<") or ""
   lastdiv = string.match(lastdiv, "[1-6]") or ""
   local firstdivindex = get_a_index(firstdiv, used_ndivs)
   local lastdivindex = get_a_index(lastdiv, used_ndivs)
   firstdivindex = tonumber(firstdivindex)
   lastdivindex = tonumber(lastdivindex)
   local closedivs = ""
   if isintable(used_ndivs, firstdiv)
   then
      while lastdivindex >= firstdivindex
      do
	 closedivs = closedivs.."</div"..used_ndivs[lastdivindex].a..">"
	 lastdivindex = lastdivindex - 1
      end
   end
   if isdiv
   then
      return str..closedivs.."</div>"
   else
      return str..closedivs
   end
end

local function close_ekddivs_in_between(str)
   local maxdepth = 1
   for i in string.gmatch(str, "<div.-depth=\"(%d)\".->", "%1")
   do
      if tonumber(i) > tonumber(maxdepth)
      then
	 maxdepth = i
      else
      end
   end
   for ndivi = 1, maxdepth
   do
      str = string.gsub(str, "(<div .-depth%=\")("..ndivi..")(\".->)(.-)(<div .-depth%=\")(%d)(\".->)",
			function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii)
			   local firstdiv = ndivi
			   local lastdiv = ndivii
			   local firstdivindex = get_a_index(firstdiv, used_ndivs)
			   local lastdivindex = get_a_index(lastdiv, used_ndivs)
			   firstdivindex = tonumber(firstdivindex)
			   lastdivindex = tonumber(lastdivindex)
			   local closedivs = ""
			   if firstdivindex >= lastdivindex
			   then
			      while firstdivindex >= lastdivindex
			      do
				 closedivs = closedivs.."</div>"
				 firstdivindex = firstdivindex - 1
			      end
			   end
			   return string.format("%s%s%s%s%s%s%s%s",
						bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii)
      end)
   end
   str = string.gsub(str, "(<div.-)(%sdepth%=\"%d\")(.->)", "%1%3")
   used_ndivs = {}
   return str
end

local function close_ndivs_in_between(str)
   for ndivi = 1, 6
   do
      str = string.gsub(str, "(<div)("..ndivi..")(.->)(.-)(<div)([1-6])(.->)",
			function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii)
			   local firstdiv = ndivi
			   local lastdiv = ndivii
			   local firstdivindex = get_a_index(firstdiv, used_ndivs)
			   local lastdivindex = get_a_index(lastdiv, used_ndivs)
			   firstdivindex = tonumber(firstdivindex)
			   lastdivindex = tonumber(lastdivindex)
			   local closedivs = ""
			   if firstdivindex >= lastdivindex
			   then
			      while firstdivindex >= lastdivindex
			      do
			   	 closedivs = closedivs.."</div"..used_ndivs[firstdivindex].a..">"
			   	 firstdivindex = firstdivindex - 1
			      end
			   end
			   return string.format("%s%s%s%s%s%s%s%s",
						bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii)
			
   end)
   end
   used_ndivs = {}
   return str
end

local function textotei(str)
   str = xml_entities(str)
   str = texpatttotei(str)
   str = note_totei(str)
   str = app_totei(str)
   str = lem_rdg_totei(str)
   str = relocate_notes(str)
   str = versetotei(str)
   str = envtotei(str)
   str = ekddivs_totei(str)
   str = section_totei(str)
   str = cmdtotei(str)
   str = self_close_tags(str)
   str = partotei(str)
   if ekddivs
   then
      str = close_ekddivs_at_end(str)
      str = close_ekddivs_in_between(str)
   else
      str = close_ndivs_at_end(str)
      str = close_ndivs_in_between(str)
   end
   return str
end

local teifilename = tex.jobname.."-tei"

function ekdosis.setteifilename(str)
   teifilename = str
   return true
end

function ekdosis.openteistream()
   local f = io.open(teifilename.."_tmp.xml", "a+")
   f:write('<?xml version="1.0" encoding="utf-8"?>', "\n")
   f:write("<TEI xmlns=\"http://www.tei-c.org/ns/1.0\">", "\n")
   f:write("<teiHeader>", "\n")
   f:write("<fileDesc>", "\n")
   f:write("<titleStmt>", "\n")
   f:write("<title><!-- Title --></title>", "\n")
   f:write("<respStmt>", "\n")
   f:write("<resp><!-- Edited by --></resp>", "\n")
   f:write("<name><!-- Name --></name>", "\n")
   f:write("</respStmt>", "\n")
   f:write("</titleStmt>", "\n")
   f:write("<publicationStmt>", "\n")
   f:write("<distributor><!-- Distributor name  --></distributor>", "\n")
   f:write("</publicationStmt>", "\n")
   f:write("<sourceDesc>", "\n")
   f:write("<listWit>", "\n")
   for i = 1,#listWit do
      f:write('<witness xml:id=\"', listWit[i].xmlid, "\">", "\n")
      f:write('<abbr type="siglum">', textotei(listWit[i].abbr), "</abbr>", "\n")
      f:write(textotei(listWit[i].detailsDesc), "\n")
      f:write("<msDesc>", "\n")
      if listWit[i].msIdentifier.settlement == ""
	 and listWit[i].msIdentifier.repository == ""
	 and listWit[i].msIdentifier.idno == ""
	 and listWit[i].msIdentifier.msName == ""
      then
	 f:write("<msIdentifier/>", "\n")
      else
	 f:write("<msIdentifier>", "\n")
	 if listWit[i].msIdentifier.settlement ~= "" then
	    f:write("<settlement>", textotei(listWit[i].msIdentifier.settlement), "</settlement>", "\n")
	 else end
	 if listWit[i].msIdentifier.repository ~= "" then
	    f:write("<repository>", textotei(listWit[i].msIdentifier.repository), "</repository>", "\n")
	 else end
	 if listWit[i].msIdentifier.idno ~= "" then
	    f:write("<idno>", textotei(listWit[i].msIdentifier.idno), "</idno>", "\n")
	 else end
	 if listWit[i].msIdentifier.msName ~= "" then
	    f:write("<msName>", textotei(listWit[i].msIdentifier.msName), "</msName>", "\n")
	 else end
	 f:write("</msIdentifier>", "\n")
      end
      if listWit[i].handDesc ~= nil then
	 f:write("<physDesc>", "\n")
	 f:write("<handDesc hands=\"", #listWit[i].handDesc, "\">", "\n")
	 local j = 1
	 while listWit[i].handDesc[j]
	 do
	    f:write("<handNote xml:id=\"", listWit[i].handDesc[j].xmlid, "\">", "\n")
	    f:write('<abbr type="siglum">', textotei(listWit[i].handDesc[j].abbr), "</abbr>", "\n")
	    f:write("<p>", textotei(listWit[i].handDesc[j].detailsDesc), "</p>", "\n")
	    f:write("</handNote>", "\n")
	    j = j + 1
	 end
	 f:write("</handDesc>", "\n")
	 f:write("</physDesc>", "\n")
      else end
      if listWit[i].history ~= nil then
	 f:write("<history>", "\n")
	 f:write("<origin>", "\n")
	 f:write("<origDate>", textotei(listWit[i].history.origin.origDate), "</origDate>", "\n")
	 f:write("</origin>", "\n")
	 f:write("</history>", "\n")
      end
      f:write("</msDesc>", "\n")
      f:write("</witness>", "\n")
   end
   f:write("</listWit>", "\n")
   f:write("</sourceDesc>", "\n")
   f:write("</fileDesc>", "\n")
   f:write("<encodingDesc>", "\n")
   f:write('<variantEncoding method="parallel-segmentation" location="internal"/>', "\n")
   f:write("</encodingDesc>", "\n")
   f:write("</teiHeader>", "\n")
   f:write("<text>", "\n")
   f:write("<body>", "\n")
   f:close()
   return true
end

local tidy = nil

local function cleanup_tei()
   local f = assert(io.open(teifilename.."_tmp.xml", "r"))
   t = f:read("*a")
   t = string.gsub(t, "%<p%>%s?%</p%>", "")
   t = string.gsub(t, "^\n", "")
   f:close()
   local fw = assert(io.open(teifilename.."_tmp.xml", "w"))
   fw:write(t)
   fw:close()
   return true
end

function ekdosis.closeteistream(opt)
   local f = io.open(teifilename.."_tmp.xml", "a+")
   f:write("\n", "</body>", "\n")
   if xmlbibresource ~= nil then
      bibf = assert(io.open(xmlbibresource, "r"))
      t = bibf:read("*a")
      t = string.gsub(t, "%s+corresp%=%b\"\"", "")
      t = string.gsub(t, "\n\n", "\n")
      f:write("<back>", "\n")
      f:write("<listBibl>", "\n")
      for i in string.gmatch(t, "<biblStruct.->.-</biblStruct>")
      do
	 f:write(i, "\n")
      end
      f:write("</listBibl>", "\n")
      f:write("</back>", "\n")
      bibf:close()
   else
   end
   f:write("</text>", "\n")
   f:write("</TEI>", "\n")
   f:close()
   cleanup_tei()
   os.remove(teifilename..".xml")
   os.rename(teifilename.."_tmp.xml", teifilename..".xml")
   if opt == "tidy" then
      os.execute("tidy -qmi -xml --output-xml yes "..teifilename..".xml")
   else
   end
   return true
end

function ekdosis.exporttei(str)
   local f = io.open(teifilename.."_tmp.xml", "a+")
   -- f:write("\n<p>")
   str = textotei(str)
   f:write(str)
   f:close()
   return true
end
-- end totei functions

-- begin basic TeX Conspectus siglorum
function ekdosis.basic_cs(msid)
   local indexwit = getindex(msid, listWit)
   siglum = listWit[indexwit].abbr
   -- if listWit[indexwit].detailsDesc == ""
   -- then
   -- name = listWit[indexwit].msIdentifier.msName
   -- else
   --    name = listWit[indexwit].msIdentifier.msName
   -- 	 .."\\thinspace\\newline\\bgroup\\footnotesize{}"..
   -- 	 listWit[indexwit].detailsDesc
   -- 	 .."\\egroup{}"
   -- end
   name = listWit[indexwit].detailsDesc
   if listWit[indexwit].history ~= nil
      and
      listWit[indexwit].history.origin ~= nil
   then
      date = listWit[indexwit].history.origin.origDate
   else
      date = ""
   end
   return siglum.."&"..name.."&"..date
end
-- end basic TeX Conspectus siglorum

function ekdosis.removesp(str)
   str = gsub(str, cmd * cmdargs * spcenc^-1, "%1%2")
   return str
end

function ekdosis.closestream()
   os.remove(tex.jobname..".ekd")
   os.rename(tex.jobname.."_tmp.ekd", tex.jobname..".ekd")
   return true
end

local cur_abs_pg = 0
local pg_i = nil
local pg_ii = nil
local prevcol = nil
local curcol = "x"

local check_resetlineno = {}

function ekdosis.update_abspg(n) -- not used
   cur_abs_pg = n
   return true
end

function ekdosis.storeabspg(n, pg)
   if pg == "pg_i" then
      pg_i = n
   elseif pg == "pg_ii" then
      pg_ii = n
      table.insert(check_resetlineno, curcol.."-"..pg_ii)
   end
   cur_abs_pg = n
   return true
end

function ekdosis.checkresetlineno()
   if isfound(check_resetlineno, curcol.."-"..pg_i)
   then
      return ""
   else
      return "\\resetlinenumber"
   end
end

--
-- Build environments to be aligned
--

local cur_alignment = "-"
local cur_alignment_patt = "%-"
local cur_alignment_cnt = 1

local newalignment = false
function ekdosis.newalignment(str)
   if str == "set"
   then
      newalignment = true
      cur_alignment = "-"..cur_alignment_cnt.."-"
      cur_alignment_patt = "%-"..cur_alignment_cnt.."%-"
      cur_alignment_cnt = cur_alignment_cnt + 1
   elseif str == "reset"
   then
      newalignment = false
      cur_alignment = "-"
      cur_alignment_patt = "-"
   end
   return true
end

local aligned_texts = {}
local texts_w_apparatus = {}
local coldata_totei = {}

local function sanitize_envdata(str)  -- look for a better way to achieve this
   str = string.gsub(str, "(%a+)%s+(%b[])", "%1%2")
   str = string.gsub(str, "(%a+)(%b[])%s+", "%1%2")
   str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2")
   str = gsub(str, lpeg.Cs(letters^1)
		 * spcenc^-1
		 * -bsqbrackets
		 * lpeg.Cs(";"), "%1[]%2")
   str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2")
   return str
end

function ekdosis.mkenvdata(str, opt)
   if not string.find(str, "%;", -1) then str = str .. ";" else end
   --   str = str ..";"
   --   str = string.gsub(str, "%s+", "")
   local fieldstart = 1
   local col = 0
   if opt == "texts" then
      str = sanitize_envdata(str)
      repeat
	 local _s, nexti = string.find(str, "%b[]%s-%;", fieldstart)
	 local namediv = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%1")
	 local attr = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%2")
	 attr = string.sub(attr, 2, -2)
	 if forbid_xmlid
	 then
	    attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here
	 else
	 end
	 table.insert(aligned_texts, { text = namediv,
				       attribute = attr,
				       column = col })
	 table.insert(coldata_totei, { environment = namediv,
				       data = {} })
	 col = col + 1
	 fieldstart = nexti + 1
      until fieldstart > string.len(str)
      return aligned_texts
   elseif opt == "apparatus" then
      repeat
	 local nexti = string.find(str, "%;", fieldstart)
	 table.insert(texts_w_apparatus, string.sub(str, fieldstart, nexti-1))
	 fieldstart = nexti +1
      until fieldstart > string.len(str)
      return texts_w_apparatus
   end
end

-- Reminder: the following two variables are already set above
-- local prevcol = nil
-- local curcol = "x"

function ekdosis.storecurcol(n)
      curcol = n
   return true
end

function ekdosis.flushcolnums()
   prevcol = nil
   curcol = "x"
   return true
end

function ekdosis.flushenvdata()
   aligned_texts = {}
   texts_w_apparatus = {}
   coldata_totei = {}
   return true
end

function ekdosis.storecoldata(nthcol, chunk)
   local tindex = tonumber(nthcol) + 1
   table.insert(coldata_totei[tindex].data, chunk)
   return true
end

local environment_div = {}

function ekdosis.newscholar(id, siglum)
   if xmlidfound(id)
   then
      tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
	    ..id..
	    "\" already exists as a xml:id. " 
	    ..
	    "Please pick another id.}}")
   else
      table.insert(xmlids, {xmlid = id})
      table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end)
      table.insert(idsRend, {xmlid = id, abbr = siglum})
      table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end)
   end
   return true
end


local function build_envdiv(str)
   if not environment_div[str]
   then
      environment_div[str] = 1
   else
      environment_div[str] = environment_div[str] + 1
   end
   local div = "div-"..str.."_"..environment_div[str]
   if xmlidfound(div)
   then
      tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
		   ..div..
		   "\" already exists as a xml:id. " 
		   ..
		   "ekdosis has generated some random id.}}")
      return "div-"..math.random(1000,9999)
   else
      table.insert(xmlids, {xmlid = div})
      table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end)
      return div
   end
end

function ekdosis.mkenv()
   local environments = {}
   for i = 1,#aligned_texts
   do
      if isfound(texts_w_apparatus, aligned_texts[i].text)
      then
	 table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}"
			 .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}"
			 .."\\par"
			 .."\\EkdosisColStart"
			 .."\\EkdosisOn#1"
		         .."}{\\EkdosisOff"
			 .."\\EkdosisColStop"
		         .."\\end{nthcolumn}"
			 .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata("
			 .. aligned_texts[i].column
			 ..", \\luastringN{\\par#1\\par})}\\fi"
			 .."}")
	 table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}"
			 .."{\\begin{nthcolumn*}{".. aligned_texts[i].column.."}[]"
			 .."\\par"
			 .."\\EkdosisColStart"
			 .."\\EkdosisOn#1"
		         .."}{\\EkdosisOff"
			 .."\\EkdosisColStop"
		         .."\\end{nthcolumn*}"
			 .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata("
			 .. aligned_texts[i].column
			 ..", \\luastringN{\\par#1\\par})}\\fi"
			 .."}")
      else
	 table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}"
			 .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}"
			 .."\\par"
			 .."#1"
		         .."}{\\end{nthcolumn}"
			 .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata("
			 .. aligned_texts[i].column
			 ..", \\luastringN{\\par#1\\par})}\\fi"
			 .."}")
	 table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}"
			 .."{\\begin{nthcolumn*}{"..aligned_texts[i].column.."}[]"
			 .."\\par"
			 .."#1"
			 .."}{"
		         .."\\end{nthcolumn*}"
			 .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata("
			 .. aligned_texts[i].column
			 ..", \\luastringN{\\par#1\\par})}\\fi"
			 .."}")
      end
      forbid_xmlid = false
      if aligned_texts[i].attribute ~= ""
      then
	 ekdosis.newenvtotag(aligned_texts[i].text, "div",
			     "xml:id=\""
				..build_envdiv(aligned_texts[i].text)
				.."\" "
				..aligned_texts[i].attribute)
      else
	 ekdosis.newenvtotag(aligned_texts[i].text, "div",
			     "xml:id=\""
				..build_envdiv(aligned_texts[i].text)
				.."\"")
      end
      forbid_xmlid = true
   end
   str = table.concat(environments)
   return str
end

function ekdosis.export_coldata_totei()
   for i = 1,#coldata_totei
   do
      ekdosis.exporttei("\\begin{".. coldata_totei[i].environment .."}"
			   .. table.concat(coldata_totei[i].data)
			.. "\\end{".. coldata_totei[i].environment .."}")
   end
end

-- handle multiple layers in apparatuses
--
local apparatuses = {}
local bagunits = {}

function ekdosis.newapparatus(teitype,
			      appdir,
			      apprule,
			      appdelim,
			      appsep,
			      appbhook,
			      appehook)
   if isintable(apparatuses, teitype)
   then
      tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
		   ..teitype..
		   "\" already exists.}}")
   else
      table.insert(apparatuses, {a = teitype,
				 direction = appdir,
				 rule = apprule,
				 delim = appdelim,
				 sep = appsep,
				 bhook = appbhook,
				 ehook = appehook})
   end
   bagunits[teitype] = 1
   return true
end

function ekdosis.getappdelim(str)
   for i = 1,#apparatuses
   do
      if apparatuses[i].a == str then
	 delimfound = apparatuses[i].delim
	 break
      end
   end
   return delimfound
end

function ekdosis.get_bagunits(teitype)
   return bagunits[teitype]
end

function ekdosis.increment_bagunits(teitype)
   bagunits[teitype] = (bagunits[teitype] or 0) + 1
end

local function reset_bagunits()
   for i = 1,#apparatuses
   do
      bagunits[apparatuses[i].a] = 1
   end
end

function ekdosis.appin(str, teitype)
   local f = io.open(tex.jobname.."_tmp.ekd", "a+")
   if next(apparatuses) == nil
   then
      f:write("<", cur_abs_pg, cur_alignment, curcol, "-0>", str, "</",
	      cur_abs_pg, cur_alignment, curcol, "-0>\n")
   else
      for i = 1,#apparatuses
      do
	 if apparatuses[i].a == teitype then
	    appno = i
	    break
	 end
      end
      f:write("<", cur_abs_pg, cur_alignment, curcol, "-",
	      appno, ">", str, "</", cur_abs_pg, cur_alignment, curcol, "-", appno, ">\n")
   end
   f:close()
   return true
end

function ekdosis.appout()
   local file = io.open(tex.jobname..".ekd", "r")
   if file ~= nil then io.close(file)
      f = assert(io.open(tex.jobname..".ekd", "r"))
      t = f:read("*a")
      local output = {}
      if next(apparatuses) == nil then
	 -- table.insert(output, "BEGIN")
	 table.insert(output, "\\noindent\\csname ekd@default@rule\\endcsname\\NLS{}")
--	 table.insert(output, "\\noindent ")
	 for i in string.gmatch(t,
				"<"..cur_abs_pg
				   ..cur_alignment_patt
				   ..curcol.."%-0>.-</"
				   ..cur_abs_pg
				   ..cur_alignment_patt
				   ..curcol.."%-0>")
	 do
	    table.insert(output, i)
	 end
	 -- table.insert(output, "END")
      else
	 local n = 1
	 while apparatuses[n]
	 do
	    if string.match(t, "<"..cur_abs_pg..
			       cur_alignment_patt
			       ..curcol.."%-"..n..">.-</"
			       ..cur_abs_pg
			       ..cur_alignment_patt
			       ..curcol.."%-"..n..">")
	    then
	       -- table.insert(output, "BEGIN")
	       table.insert(output, "\\bgroup{}")
	       if apparatuses[n].direction == "LR"
	       then
		  table.insert(output, "\\pardir TLT\\textdir TLT{}")
	       elseif apparatuses[n].direction == "RL"
	       then
		  table.insert(output, "\\pardir TRT\\textdir TRT{}")
	       end
	       if apparatuses[n].rule == "none"
	       then
		  if n > 1
		  then
		     table.insert(output, "\\NLS{}")
		  else
		     table.insert(output, "\\noindent ")
		  end
	       elseif apparatuses[n].rule ~= ""
	       then
		  if n > 1
		  then
		     table.insert(output, "\\NLS{}" .. apparatuses[n].rule .. "\\NLS{}")
		  else
--		     table.insert(output, "\\noindent ")
		     table.insert(output, apparatuses[n].rule .. "\\NLS{}")
		  end
	       else
		  if n > 1
		  then
		     table.insert(output, "\\NLS\\csname ekd@default@rule\\endcsname\\NLS{}")
		  else
--		     table.insert(output, "\\noindent ")
		     table.insert(output, "\\csname ekd@default@rule\\endcsname\\NLS{}")
		  end
	       end
	       if apparatuses[n].sep ~= ""
	       then
		  table.insert(output, "\\edef\\ekdsep{" .. apparatuses[n].sep .. "}")
	       else
	       end
	       if apparatuses[n].bhook ~= ""
	       then
		  table.insert(output, apparatuses[n].bhook)
	       else
		  table.insert(output, "\\relax")
	       end
	       for i in string.gmatch(t,
				      "<"..cur_abs_pg
					 ..cur_alignment_patt
					 ..curcol.."%-"..n..">.-</"
					 ..cur_abs_pg
					 ..cur_alignment_patt
					 ..curcol.."%-"..n..">")
	       do
		  table.insert(output, i)
	       end
	       if apparatuses[n].ehook ~= ""
	       then
		  table.insert(output, apparatuses[n].ehook)
	       else
	       end
	       table.insert(output, "\\egroup{}")
	       -- table.insert(output, "END")
	    end
	    n = n + 1
	 end
      end
      f:close()
      str = table.concat(output)
      str = string.gsub(str, "</"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", "")
      str = string.gsub(str, "<"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", " ")
      return str
   else
   end
end

function ekdosis.appin_out(str, nl)
   local f = io.open(tex.jobname.."_tmp.ekd", "a+")
   if nl == "yes" then
      f:write(str, "\n")
   else
      f:write(str)
   end
   f:close()
   return true
end

local curcol_curabspg = {}

function ekdosis.testapparatus()
   if isfound(curcol_curabspg, curcol.."-"..cur_abs_pg)
   then
      if newalignment
      then
	 if next(apparatuses) ~= nil then
	    reset_bagunits()
	 end
	 newalignment = false
	 return "\\booltrue{do@app}"
      else
	 return "\\boolfalse{do@app}"
      end
   else
      table.insert(curcol_curabspg, curcol.."-"..cur_abs_pg)
      if next(apparatuses) ~= nil then
	 reset_bagunits()
      end
      return "\\booltrue{do@app}"
   end
end

local lnlabs = {}
local lnlab_salt = 0
local current_lnlab = nil
local prev_lnlab = nil
local current_notelab = nil
local prev_notelab = nil
local current_lemma = nil
local salt = 0

local function mdvisintable(table, value)
   for _, v in pairs(table) do
      if v == value then return true end
   end
   return false
end

function ekdosis.dolnlab(str)
   prev_lnlab = current_lnlab
   current_lemma = str
   i = md5.sumhexa(str)
   if not mdvisintable(lnlabs, i) then
      table.insert(lnlabs, i)
   else
      i = i..salt
      table.insert(lnlabs, i)
      salt = salt + 1
   end
   current_lnlab = i
   return true
end

function ekdosis.getlnlab()
   return current_lnlab
end

function ekdosis.getprevlnlab()
   return prev_lnlab
end

function ekdosis.setnotelab(str)
   current_notelab = str
   return "\\linelabel{" .. current_notelab .. "}"
end

function ekdosis.getnotelab()
   return current_notelab
end

function ekdosis.setprevnotelab(str)
   prev_notelab = str
   return true
end

function ekdosis.getprevnotelab()
   return prev_notelab
end

local function remove_note(str)
   str = gsub(str, dblbkslash * lpeg.P("note") * cmdargs, "")
   return str
end

function ekdosis.mdvappend(str, teitype)
   if teitype == nil
   then
   return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}"
      ..
      current_lemma
      ..
      "\\linelabel{" .. current_lnlab .. "-e}"
      ..
      "\\csname append@app\\endcsname{"
      .. remove_note(str) .. "}"
   else
   return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}"
      ..
      current_lemma
      ..
      "\\linelabel{" .. current_lnlab .. "-e}"
      ..
      "\\csname append@app\\endcsname" .. "[" .. teitype ..  "]{"
      .. remove_note(str) .. "}"
   end
end

% \end{ekdlua}
% \iffalse
%</lua>
% \fi
% 
% \iffalse
%<*examples>
% \fi
% \begin{minted}[firstnumber=last]{latex}
\documentclass[12pt]{article}
\usepackage{fontspec}
\usepackage[english]{babel}
\babelfont{rm}{Old Standard}
\babelfont{sf}{NewComputerModern Sans}
\babelfont{tt}{NewComputerModern Mono}

\usepackage[teiexport=tidy]{ekdosis}
\SetEkdosisAlignment{
  tcols=1,
  lcols=1,
  texts=specimen[xml:lang="fr"],
  apparatus=specimen}

\begin{document}

\begin{alignment}[flush]
  \begin{specimen}
    I saw my friend \app{
      \lem{Peter}
      \rdg{John}}
    at the station yesterday.
  \end{specimen}
\end{alignment}

\end{document}
% \end{minted}
% \iffalse
%</examples>
% \fi
\endinput