% \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 % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see % . % %<*internal> \iffalse % %<*readme> | -------:| ----------------------------------------------------------------- ekdosis:| Typesetting TEI xml compliant critical editions Author:| Robert Alessi E-mail:| alessi@robertalessi.net License:| Released under the GNU General Public License v3 or later See:| http://www.gnu.org/licenses/ Short description: Some text about the package: probably the same as the abstract. % %<*luapre> --[[ This file is part of the `ekdosis' package ekdosis -- Typesetting TEI xml compliant critical editions Copyright (C) 2020 Robert Alessi Please send error reports and suggestions for improvements to Robert Alessi This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . --]] % %<*internal> \fi % % \fi % % \iffalse %<*driver> \ProvidesFile{ekdosis.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{ekdosis} %<*package> [2020/06/03 v0.99 Typesetting TEI xml compliant critical editions] % %<*driver> \begin{filecontents}[overwrite]{\jobname.bib} @Article{Alessi2020, author = {Alessi, Robert}, title = {ekdosis: Using Lua\LaTeX{} for Producing \texttt{TEI xml} Compliant Critical Editions and Highlighting Parallel Writings}, journaltitle = {Journal of Data Mining and Digital Humanities}, year = 2020, pubstate = {submitted}, issuetitle = {Collecting, Preserving, and Disseminating Endangered Cultural Heritage for New Understandings through Multilingual Approaches}, eprinttype = {hal}, eprint = {hal-02779803} } @Online{DLL-TC, author = {{Digital Latin Library}}, title = {Textual Criticism}, year = {nodate}, url = {https://digitallatin.org/library-digital-latin-texts/textual-criticism}, urldate = {2020-05-24} } @Online{Mastronarde.Tarrant2017, author = {Mastronarde, Donald J. and Tarrant, Richard J.}, title = {Review: Guidelines for Encoding Critical Editions for the Library of Digital Latin Texts}, date = {2017-12-04}, url = {https://classicalstudies.org/scs-blog/donald-j-mastronarde/review-guidelines-encoding-critical-editions-library-digital-latin}, organization = {Society for Classical Studies} } \end{filecontents} \begin{filecontents}[overwrite]{\jobname-cfg.tex} \footnotelayout{m} \DeclareApparatus{default}[ delim=\hskip0.75em, ehook=.] \DeclareWitness{M}{M}{\emph{Marcianus Gr.} 269}[ settlement=Venice, institution=Marciana Library, msName=\emph{Marcianus Gr.}, idno=269, origDate=s. X] \DeclareHand{M1}{M}{M\textsuperscript{1}}[Emendatio scribae ipsius] \DeclareHand{M2}{M}{M\textsuperscript{2}}[Manus posterior] \DeclareWitness{pjA}{A}{Manuscript A Call No 123} \DeclareWitness{pjB}{B}{Manuscript B Call No 456} \end{filecontents} \documentclass{ltxdoc} \usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry} \usepackage{dox} \doxitem{Option}{option}{options} \usepackage{microtype} \usepackage[no-math]{fontspec} \usepackage[greek.ancient,american]{babel} \babelfont{rm}[ SlantedFont={Old Standard}, SlantedFeatures={FakeSlant=0.25}, BoldSlantedFont={Old Standard}, BoldSlantedFeatures={FakeBold=1.5,FakeSlant=0.25}]{Old Standard} \babelfont{sf}{NewComputerModern Sans} \babelfont{tt}{NewComputerModern Mono} \babelfont[greek]{rm}[ Script=Greek, RawFeature={+ss05;+ss06}, SlantedFont={Old Standard}, SlantedFeatures={FakeSlant=0.25}, BoldSlantedFont={Old Standard}, BoldSlantedFeatures={FakeBold=1.5,FakeSlant=0.25}]{Old Standard} \babelfont[greek]{sf}[Script=Greek]{NewComputerModern Sans} \babelfont[greek]{tt}[Script=Greek]{NewComputerModern Mono} \babeltags{ancientgreek = greek} \def\sg#1{\textancientgreek{#1}} \usepackage[Old Standard]{mathfont} \usepackage{arabluatex} \usepackage[teiexport=tidy]{ekdosis} \input{ekdosis-cfg} \usepackage{xltabular} \usepackage[prevent-all]{widows-and-orphans} \usepackage[shortcuts,nospacearound]{extdash} \usepackage[american]{isodate} \usepackage{csquotes} \usepackage{enumitem} \setlist{nosep} \setlist[itemize]{label=\textendash} \setlist[enumerate,1]{label=(\alph*)} \usepackage{manfnt} \usepackage{lettrine} \newcommand\danger{\lettrine[loversize=-.5]{\textdbend}{\hskip6pt}} \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} \labelformat{section}{sect.~#1} \labelformat{subsection}{sect.~#1} \labelformat{subsubsection}{sect.~#1} \labelformat{figure}{fig.~#1} \usepackage[nospace,american]{varioref} \usepackage[style=ext-verbose-inote]{biblatex} \usepackage[symbolpackage=tikz]{biblatex-ext-oa} \DeclareDelimFormat[bib,biblist]{nametitledelim}{\addcomma\space} \DeclareDelimFormat[bib,biblist]{innametitledelim}{\addcomma\space} \renewcommand*\newunitpunct{\addcomma\space} \newcommand*{\halurl}[1]{http://hal.archives-ouvertes.fr/#1} \DeclareFieldFormat{eprint:hal}{% \ifhyperref {\href{\halurl{#1}}{hal:~\nolinkurl{#1}}} {hal:~\nolinkurl{#1}}} \DeclareFieldAlias{eprint:HAL}{eprint:hal} \DeclareOpenAccessEprintUrl[always]{hal}{% http://hal.archives-ouvertes.fr/\thefield{eprint}} \DeclareOpenAccessEprintAlias{HAL}{hal} \addbibresource{ekdosis.bib} \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{multicol} \usepackage{tocloft} \newlistof{listing}{lol}{List of listings} \renewcommand\cfttocprehook{\begin{multicols}{2}} \renewcommand\cfttocposthook{\end{multicols}} \renewcommand\cfttoctitlefont{\Large\bfseries} \renewcommand\cftlolprehook{\begin{multicols}{2}} \renewcommand\cftlolposthook{\end{multicols}} \renewcommand\cftloltitlefont{\Large\bfseries} \usepackage{relsize} \usepackage{units} \usepackage{fbox} \usepackage{tikz} \usetikzlibrary{tikzmark} \NewDocumentCommand{\pointto}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (1em,0.5ex) to ([shift={(0.5em,0pt)}]pic cs:#1);% \tikz[remember picture] \draw[color=gray, overlay] ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} \NewDocumentCommand{\pointtor}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (1em,0.5ex) to [bend left] ([shift={(0.5em,0pt)}]pic cs:#1);% \tikz[remember picture] \draw[color=gray, overlay] ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} \NewDocumentCommand{\pointtol}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (1em,0.5ex) to [bend right] ([shift={(0.5em,0pt)}]pic cs:#1);% \tikz[remember picture] \draw[color=gray, overlay] ([shift={(0.5em,0.5ex)}]pic cs:#1) circle [radius=8pt];} \NewDocumentCommand{\pointtoel}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (1em,0.5ex) to [bend right] ([shift={(0em,0pt)}]pic cs:#1);% \tikz[remember picture] \draw[color=gray, overlay] ([shift={(-0.5em,0.5ex)}]pic cs:#1) ellipse [x radius=45pt, y radius=6pt];} \usepackage[breakable, skins, xparse]{tcolorbox} \tcbset{colback=white, boxrule=.15mm, colframe=cinnamon, breakable} \usepackage[newfloat]{minted} \labelformat{listing}{listing~#1} \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{\pkg}[1]{\textsf{#1}\index{#1=#1 (package)}} \newcommand{\env}[1]{\texttt{#1}} \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} % % \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} % % \tableofcontents % \listoflistings % %\changes{v1.00}{2020/07/01}{First public release} % % \begin{abstract} % \pkg{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, % \pkg{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} % % \pkg{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{}}. % % This release of \pkg{ekdosis} consists of the following % source files: % \begin{itemize} % \item |ekdosis.ins| % \item |ekdosis.dtx| % \item |ekdosis.el| % \end{itemize} % % \section{Introduction} % \label{sec:introduction} % \begin{comment} % \begin{keyfigure}{l={fig:grid-typesetting},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. We were both % in a great mood. \enquote{How nice to find you here!} he % said. I chuckled to myself, recalling the last time we % met.\par % \rule{3cm}{0.01cm}\par\footnotesize% % \textbf{1}~saw A] met B\hskip1em Peter A] John B \hskip1em % \textbf{2}~great A] good B\hskip1em \textbf{2--3}~How % nice... said A] \emph{om.} B\hskip1em \textbf{4} \emph{post} % met \emph{add.} there B.}; \node at (0,3) {\scriptsize % $\approx$ \unit[25]{pt}}; \draw [->] (0,2.875) -- (0,2.025); % \end{tikzpicture} % \end{keyfigure} % \end{comment} % % The reader will find here, by way of introduction, a summarized % version of the first part of an article that the author submitted % some weeks ago to the \mkbibemph{\citefield{Alessi2020}{journaltitle}} as % a contribution to a Digital Humanities workshop held at Stanford % University (\printdate{2019-04-15}).\footcite{Alessi2020} % % The name of this package, \pkg{ekdosis}, derives from a Greek % action noun\---\sg{ἔκδοσις}\---the meaning of which is: % \enquote{publishing a book}, and also in concrete sense: \enquote{a % publication, treatise}. For us moderns, this term refers to a long % tradition of scholarly work consisting in establishing from % manuscript evidence the texts of Greek and Latin classics that were % handled down through the Middle Ages to the time of the first % printed editions. Of course, this definition is extendible to other % languages as well. The basic premise is that critical editions % exhibit reconstructed texts from manuscript evidence either under % the title of the edited text (direct tradition) or from explicit % citations or parallel passages or translations in other languages % (indirect tradition). % % Whether in print or digital, critical editions come with an % apparatus criticus in which is mentioned all the evidence that was % used to build the edited text. Arguably, it is precisely on this % common point that the two kind of editions part ways for reading a % traditional, well written apparatus criticus is only meant for % experienced readers. Getting oneself familiarized with its many % conventional rules is not unrelated to learning a language, equipped % with technical terms, grammar rules and style embellishments, which % came into existence out of over three centuries of scholarly % attainments. Nevertheless, whereas this language is immediately % accessible to human mind's ability to use language and interpret % conventional symbols, it is quite inaccessible to a computer unless % every item of information has been encoded in the rather dumb format % that is suited to machines. % % On the other hand, editions in print have their own limitations. For % example, every detail that editors of classical texts decide to % discard to save space, regardless to its relevance to the purpose of % the edition, is lost permanently as in the case of dialectal % coloring of ancient books. Furthermore, passages collected as % indirect tradition are only available as references in the % \emph{apparatus testium} and cannot be referred to the original % text. As a result, the reader is refrained from bestowing attention % upon major parallel passages to understand better difficult passages. % % To conclude on these issues, print publications and digital editions % are often contrasted as they belonged to two different % worlds.\footnote{For a good illustration of this point, see % \cite[\mkbibquote{Content, not Display}]{DLL-TC}.} It is commonly % said that the content of editions in print is the result of the % binding of the book itself as an object, whereas digital editions, % in which format and presentation are by definition separated from % content, are free from limitations coming from such bindings. To sum % up from the foregoing considerations, this statement is likely to be % qualified: as already seen above, the apparatus criticus must be % looked at as a brilliant production of mind refined by centuries of % scholarly tradition\---and surely tradition must go on\---arguably % not as compact paragraphs that require special and painful training % to be \enquote*{decoded}. On the other hand, what editions in print % do not provide are what \citename{Mastronarde.Tarrant2017}{author} % have called \enquote{actionable texts for use in digital % research},\footcite{Mastronarde.Tarrant2017} namely database-driven % texts allowing the reader to select annotations and display or % arrange translations, parallel passages or borrowings in a variety % of ways. % % \pkg{ekdosis} can be seen as an attempt at combining the two % approaches. % % \subsection{Features} % \label{sec:features} % A list of the main features of \pkg{ekdosis} follows:--- % \begin{enumerate} % \item \emph{Multilingual critical editions\/}: \pkg{ekdosis} can % be used to typeset any number of texts in any direction accepted % by \hologo{LuaTeX}. Running paragraphs of text can be arranged in % any number of columns, either on single or facing pages, which in % turn can be synchronized or not. \pkg{ekdosis} is also % suitable for complex layouts as in the case of Arabic poetry or % images where three-way alignment is required, or diagrams, % \emph{\&c}. % \item \emph{Apparatus criticus\/}: Edited texts can receive multiple % layers of apparatus, e.g.\ apparatus criticus (to record variant % readings), apparatus fontium (to collect references to texts quoted % or cited in the edited text), apparatus testium (to collect % testimonia or parallel passages), or any kind of short notes to be % printed on the same page as the edited text, \emph{\&c}. % \item \texttt{TEI xml} output: \pkg{ekdosis} can be instructed % to output both PDF and \texttt{TEI xml} files at the same time. % \item \emph{Database-driven encoding} under \LaTeX{} of texts % entered segment by segment allows for alignment of parallel texts % from multilingual corpora. % \end{enumerate} % % Before going into detail, the following simple example will give the % reader a general idea of the method of encoding with % \pkg{ekdosis} authoritative texts composed of lemmata, in a way % that is very close to \texttt{TEI xml} encoding:--- % % \captof{The \enquote{Peter/John} basic example}[\label{lst:pj1}] % \iffalse %<*example> % \fi \begin{minted}{latex} \begin{ekdosis} I \app{ \lem{saw} \rdg{met} } my friend \app{\lem{Peter}\rdg{John}} at the station yesterday. \end{ekdosis} \end{minted} % \iffalse % % \fi % % \needspace{4\baselineskip}PDF output:--- % \medskip % \begin{alignment}[tcols=1,texts=specimen,apparatus=specimen] % \begin{specimen} % I % \app{ % \lem{saw} % \rdg{met} % } % my friend % \app{ % \lem{Peter} % \rdg{John} % } % at the station yesterday. % \end{specimen} % \end{alignment} % % \texttt{TEI xml} output:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{xml}

I saw met my friend Peter John at the station yesterday.

\end{minted} % \iffalse % % \fi % % As can be seen from \vref{lst:pj1}, the edition text is inserted in % the \env{ekdosis} environment (l.~1 to 13). Then two % \cs{app}\marg{apparatus entry} commands (ll.~3 and 7) contain the % lemma (\cs{lem}\marg{lemma}), namely the reading that is accepted by % the editor, and at least one variant reading % (\cs{rdg}\marg{reading}, ll.~5 and 7). As the listing shows, the % editor is free to lay out the code in a legible manner to the eye: % the first lemma above spans several lines whereas the second one is % written in sequence without spaces. % % In the PDF ouput, the edition text is printed in the upper part of % the page, above the line, and naturally shows the accepted % readings. The margins are used for numeration. In the apparatus % criticus, below the line, reference to the text is made by % specifying the number of the line and if several items refer to the % same line, numbers are not repeated. Instead, items are separated % from one another by a broad horizontal space. Finally, a square % bracket is used inside items to distinguish the lemma from the % variant readings. % % Furthermore, as said above, if a \texttt{TEI xml} output is % required, \pkg{ekdosis} compiles an additional |.xml| file an % excerpt of which is provided above. % % \section{The Basics of \pkg{ekdosis}} % \label{sec:ekdosis-basics} % %\subsection{Loading the Package\---General Options} %\label{sec:load-general-options} % % \pkg{ekdosis} is loaded in the preamble like so:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \usepackage{ekdosis} \end{minted} % \iffalse % % \fi % % \pkg{ekdosis} may be loaded with four optional \enquote*{named % arguments} either of which is set using the syntax % \meta{key}$=$\meta{value}. The description of the optional arguments % follows. % % \danger The reader is invited to refer to the relevant sections of % this documentation for more information on how to use them. % % \DescribeOption{layout}\label{ref:layout-opt} % |layout|$=$\verb+float|footins+\hfill\tcboxverb{Default: float}\\ % By default, layers of critical notes are inserted as a floating % environment to be printed at the bottom of pages. |layout=footins| % can be set to insert critical notes in the default footnote block % which can be considered to be a special kind of float that is % printed at the bottom of pages. In this case, the apparatus criticus % will be inserted between regular numbered footnotes, but will carry % no footnote mark of its own. % % \DescribeOption{divs}\label{ref:divs-opt} % |divs|$=$\verb+ekdosis|latex+\hfill\tcboxverb{Default: ekdosis}\\ % In many occasions, \LaTeX{} standard textual divisions do not meet % the specific requirements of classical and literary texts, the % divisions of which may depend on many different received % traditions. \pkg{ekdosis} provides a flexible mechanism in which % format and presentation have been carefully separated. It is % designed to build un-numbered \texttt{TEI} divisions allowed to nest % recursively. However, if |divs| be set to |latex|, \LaTeX{} standard % textual divisions can be used and will be translated into % \texttt{TEI} numbered |
| elements. % % \danger It must be noted that the two styles are mutually exclusive. % \vskip\baselineskip % % \DescribeOption{parnotes}\label{ref:parnotes-opt} % |parnotes|$=$\verb+true|false|roman+% % \hfill\tcboxverb{Default: not set}\\ % This named argument does not need a value as it defaults to |true| % if it is used. Apparatus criticus typeset by \pkg{ekdosis} may % contain notes and footnotes. The latter can be laid out as % paragraphed notes below the block of critical notes by means of the % \pkg{parnotes} package. Additionally, |parnotes=roman| prints these % footnotes numbered with Roman numerals. % % \DescribeOption{teiexport}\label{ref:teiexport-option} % |teiexport|$=$\verb+true|false|tidy+% % \hfill\tcboxverb{Default: not set}\\ % This named argument does not need a value as it defaults to |true| % if it is used. If |teiexport| be set to |true|, \pkg{ekdosis} is % instructed to output both PDF and \texttt{TEI xml} files at the same % time. By default, the \texttt{TEI} file will receive the same % basename as the |.tex| source file, suffixed with |-tei.xml|. The % raw |.xml| file that is produced by \pkg{ekdosis} can be further % processed by the \textsf{tidy} console application.\footnote{See % \url{http://www.html-tidy.org}.} To make this happen, \textsf{tidy} % must be installed and the |.tex| source file must be compiled with % the |--shell-escape| facility so that spawning programs from % \LaTeX{} be allowed.\footnote{See % \url{https://texfaq.org/FAQ-spawnprog} for more information on how % to do this.} % % As an example, the following line loads \pkg{ekdosis} and instructs % it to output a \texttt{TEI xml} file (in addition of the PDF one) % and to use \pkg{parnotes} to format with Roman numerals the footnotes % that are inserted in the apparatus criticus:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \usepackage[teiexport, parnotes=roman]{ekdosis} \end{minted} % \iffalse % % \fi % % \subsection{Witnesses, Hands, Shorthands \& Scholars } % \label{sec:declarations} % Any reference that is to be used in the apparatus criticus must be % \enquote{declared} in the preamble beforehand, namely: manuscript % sigla (either for single manuscripts or manuscript families, primary % or later hands, \emph{\&c.}) or abbreviated last names of scholars. % To that effect, \pkg{ekdosis} provides the following preamble-only % commands:--- % \begin{comment} % \begin{xltabular}[c]{0.4\linewidth}{lXr} % \caption*{\textbf{Conspectus Siglorum}}\\ % \SigLine{M}\\ % \end{xltabular} % \end{comment} % % \paragraph{Witnesses} % \DescribeMacro{\DeclareWitness} \cs{DeclareWitness}\marg{unique % id}\marg{rendition}\marg{description}\oarg{options}\\ % This command requires three mandatory arguments enclosed between % curly braces used to specify consecutively: % \begin{enumerate} % \item The unique identifier of the witness to be used both in the % |.tex| source file and as an |xml:id| in the \texttt{TEI xml} % output if any. % \item The rendition to be used in the printed apparatus criticus, % which also will be found within the || element of the % \texttt{TEI} header where the description of the witness occurs, % within a || element. % \item A basic description of the manuscript to be found in a typical % printed Conspectus Siglorum, namely: the name of the manuscript % followed by its call number. % \end{enumerate} % Finally, the optional argument of \cs{DeclareWitness} accepts a % comma-separated list of the following \enquote{name=value} arguments % that are used to collect items of information to be found within % the || element in the \texttt{TEI} % header:---\footnote{See % \url{https://tei-c.org/release/doc/tei-p5-doc/en/html/MS.html\#msid} % for detailed information on these elements.}\\ % \DescribeOption{settlement} |settlement|$=$\meta{name}: The name of % a city or administrative unit.\\ % \DescribeOption{institution} |institution|$=$\meta{name}: The name % of an institution such as a university or library.\\ % \DescribeOption{repository} |repository|$=$\meta{name}: The name of % the repository within which the witness is stored.\\ % \DescribeOption{collection} |collection|$=$\meta{name}: The name of % a collection of manuscripts.\\ % \DescribeOption{idno} |idno|$=$\meta{call \#}: Any form of call % number.\\ % \DescribeOption{msName} |msName|$=$\meta{name}: The name commonly % used for the witness.\\ % \DescribeOption{origDate} |origDate|$=$\meta{date}: Any form of date % used to identify the date of origin for the witness. % % To take here one example, a witness such as the \emph{Marcianus % Graecus}~269, referred to as manuscript \enquote*{M} in the % editions, which contains sixty treatises from Hippocrates, could be % declared as follows:--- \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \DeclareWitness{M}{M}{\emph{Marcianus Gr.} 269}[ settlement=Venice, institution=Marciana Library, msName=\emph{Marcianus Gr.}, idno=269, origDate=s. X] \end{minted} % \iffalse % % \fi % % \paragraph{Hands} % \DescribeMacro{\DeclareHand} \cs{DeclareHand}\marg{unique % id}\marg{base ms.}\marg{rendition}\oarg{note}\\ % This command requires three mandatory arguments enclosed between % curly braces and one optional argument between square brackets used % to specify consecutively:--- % \begin{enumerate} % \item The unique identifier of the hand to be used both in the % |.tex| source file and as an |xml:id| in the \texttt{TEI xml} output % if any. % \item The unique idendifier of the witness the hand is related % to. Of course, this witness must have been previously declared. % \item The rendition to be used in the printed apparatus criticus, % which also will be found within the || element of the % \texttt{TEI} header where the description of the hand occurs, within % a || element. % \item Some further information about the hand. % \end{enumerate} % % To continue the preceding example, here is how additions and % corrections found in the \emph{Marcianus Gr.}~269 could be declared % after this witness has been declared itself:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \DeclareHand{M1}{M}{M\textsuperscript{1}}[Emendatio scribae ipsius] \DeclareHand{M2}{M}{M\textsuperscript{2}}[Manus posterior] \end{minted} % \iffalse % % \fi % % As can be seen, values such as |M|, |M1| and |M2| in the |.tex| % source file will be printed as \getsiglum{M}, \getsiglum{M1} and % \getsiglum{M2} respectively. Not only the code gains legibility, but % also flexibility for simply changing any declared rendition will % update corresponding sigla thoughout the entire edition. % % As a final example, here is how \pkg{ekdosis} would encode % information as declared above for the \emph{Marcianus Gr.}~269 % should a \texttt{TEI} output be required:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{xml} M Marcianus Gr.269 Venice Marciana Library 269 Marcianus Gr. M 1

Emendatio scribae ipius

M 2

Manus posterior

s. X
\end{minted} % \iffalse % % \fi % % \paragraph{Shorthands} % \DescribeMacro{\DeclareShorthand} \cs{DeclareShorthand}\marg{unique % id}\marg{rendition}\marg{csv list of witnesses}\\ % This command provides a convenient way to declare \emph{families} of % witnesses. It takes three mandatory arguments used to specify % consecutively:--- % \begin{enumerate} % \item The unique identifier of the family to be used in the |.tex| % source file. % \item The rendition to be used in the printed apparatus criticus. % \item A comma-separated list of previously declared witnesses. % \end{enumerate} % % As an example, the manuscripts of Caesar's \emph{Gallic War} are % divided into two families: α, which includes mss.\ A, M, B, R, S, L % and N, and β, which includes mss.\ T, f, U and l. Therefore, % provided that all theses witnesses have been already declared, here % is how the two families α and β could be declared:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \DeclareShorthand{a}{α}{A,M,B,R,S,L,N} \DeclareShorthand{b}{β}{T,f,U,l} \end{minted} % \iffalse % % \fi % % Then, symbols |a| and |b| can be used in the |.tex| source file in % place of manuscripts that belong to either family. % % \paragraph{Scholars} % \DescribeMacro{\DeclareScholar} \cs{DeclareScholar}\marg{unique % label}\marg{rendition}\\ % The \emph{Conspectus Siglorum} that is placed ahead of the edition % text is traditionally divided into two parts: a)~\emph{Codices}, % which provides the list of sigla used in the apparatus, % b)~\emph{Editiones uel Studia}, which provides references to % scholars whose published or unpublished works contain conjectures % used in the apparatus criticus. \cs{DeclareScholar} takes two % mandatory arguments used to specify consecutively:--- % \begin{enumerate} % \item A unique label used in the |.tex| source file to refer to the % work where the conjecture is found. % \item The rendition to be used in the printed apparatus criticus. % \end{enumerate} % % As \pkg{ekdosis} can include and use \texttt{TEI xml} compliant % lists of references, it is avisable to use Bib\hologo{(La)TeX} % labels in the first argument of \cs{DeclareScholar}. Likewise, % shorthands fields from the bibliographical database can be recalled % from within the second argument of \cs{DeclareScholar}:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \DeclareScholar{Wil}{Wilamowitz} % or for example: \DeclareScholar{Wil}{\citename{Wil}{shorteditor}} \end{minted} % \iffalse % % \fi % \label{sec:declarations-end} % % \subsection{Editing a Single Text With No Translation} % \label{sec:single-text-editing} % \DescribeEnv{ekdosis} % Running paragraphs of one single text to be edited should be % inserted in the \env{ekdosis} environment, like so:---\footnote{See % above \vref{lst:pj1}.} % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \begin{ekdosis} Edition text goes here. \end{ekdosis} \end{minted} % \iffalse % % \fi % % \paragraph{Apparatus Entries} % \DescribeMacro{\app} \cs{app}|[type=|\meta{type}|]|\marg{apparatus % entries}\\ % This command takes one mandatory argument and accepts one optional % argument. Once references to be used as witnesses in the apparatus % criticus have been declared in the preamble as described in % \ref{sec:declarations} % \vpagerefrange{sec:declarations}{sec:declarations-end}, the \cs{app} % command is used for inserting entries in the apparatus criticus, % either, lemmas, readings or notes, like so:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} I saw my friend \app{\lem{Peter}\rdg{John}} yesterday. or: I saw my friend \app{ \lem{Peter} \rdg{John} } yesterday. \end{minted} % \iffalse % % \fi % \cs{app} accepts one further optional argument:---\\ % \DescribeOption{type} |type|$=$\meta{type}\hfill% % \tcboxverb{Default: default}\\ % By default, \pkg{ekdosis} sets one layer of notes\--- the |default| % layer\---in the apparatus criticus. This layer is fit to receive % notes related to variant readings from witnesses and sources used by % the editor to establish the edition text. Additional layers can be % defined to receive other kinds of notes, such as references to texts % quoted or cited in the text of the edition (\emph{apparatus % fontium}), references to testimonia, or quotations of the edited % text by other authors (\emph{apparatus testium}), explanatory notes, % and so forth.\footnote{See below, \vpageref{ref:type-app}.} Once % additional layers have been defined and assigned to new % \enquote*{types}, such as \enquote*{testium} and the like, these % types can be used as values appended to the |type| \enquote*{named % option}. % % \paragraph{Readings} As can be seen in the example above, there are % two kinds of individual readings: the \emph{lemma}, which contains % the base text accepted by the editor, and the \emph{reading}, which % contains deviant readings rejected by the editor. % % \paragraph{Lemmas} \DescribeMacro{\lem} % \cs{lem}\oarg{options}\marg{lemma text} % % \begin{comment} % \captof{The \enquote{Peter/John} full example} % \iffalse %<*example> % \fi \begin{minted}{latex} \begin{ekdosis} I \app{ \lem[wit=A]{saw} \rdg[wit=B]{met}} my friend \app{ \lem{Peter} \rdg{John} } at the station yesterday. We were both in a \app{ \lem[wit=A]{great} \rdg[wit=B]{good}} mood. \app{ \lem[wit=A, alt={How nice... said}]{\enquote{How nice to find you here!} he said.} \rdg[wit=B, alt=\emph{om.}]{}} I chuckled to myself, recalling the last time we \app{ \lem[wit=A,nolem]{met} \rdg[wit=B, alt={\emph{post} met \emph{add.} there}]{met there}}. \end{ekdosis} \end{minted} % \iffalse % % \fi % % \begin{alignment}[tcols=1,texts=specimen,apparatus=specimen] % \begin{specimen} % I \app{\lem[wit=pjA]{saw}\rdg[wit=pjB]{met}} my friend % \app{ % \lem{Peter} % \rdg{John} % } % at the station yesterday. We were both in a % \app{ % \lem[wit=pjA]{great} % \rdg[wit=pjB]{good}} % mood. % \app{ % \lem[wit=pjA, alt={\textooquote How nice... said}]{\enquote{How % nice to find you here!} he said.} % \rdg[wit=pjB, alt=\emph{om.}]{}} % I chuckled to myself, recalling the last time we % \app{ % \lem[wit=pjA,nolem]{met} % \rdg[wit=pjB, alt={\emph{post} met \emph{add.} there}]{met % there}}. % \end{specimen} % \end{alignment} % \end{comment} % % \section{To be continued...} % \label{ref:type-app} % % \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{3\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 \enquote{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 \enquote{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{3\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 % \enquote{\textbf{Document}}, below, refers to any such manual or % work. Any member of the public is a licensee, and is addressed as % \enquote{\textbf{you}}. You accept the license if you copy, modify % or distribute the work in a way requiring permission under copyright % law. % % A \enquote{\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 \enquote{\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 \enquote{\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 \enquote{\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 \enquote{\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 \enquote{Transparent} is called \enquote{\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 \enquote{\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, \enquote{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 \enquote{\textbf{publisher}} means any person or entity that % distributes copies of the Document to the public. % % A section \enquote{\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 \enquote{\textbf{Acknowledgements}}, % \enquote{\textbf{Dedications}}, \enquote{\textbf{Endorsements}}, or % \enquote{\textbf{History}}.) To \enquote{\textbf{Preserve the % Title}} of such a section when you modify the Document means that it % remains a section \enquote{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{3\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{3\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{3\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 \enquote{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 % \enquote{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 % \enquote{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 \enquote{Acknowledgements} or % \enquote{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 \enquote{Endorsements}. % Such a section may not be included in the Modified Version. % % \item[N.] Do not retitle any existing section to be Entitled % \enquote{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 \enquote{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{3\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 % \enquote{History} in the various original documents, forming one % section Entitled \enquote{History}; likewise combine any sections % Entitled \enquote{Acknowledgements}, and any sections Entitled % \enquote{Dedications}. You must delete all sections Entitled % \enquote{Endorsements}. % % \needspace{3\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{3\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 \enquote{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{3\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 \enquote{Acknowledgements}, % \enquote{Dedications}, or \enquote{History}, the requirement % (section~4) to Preserve its Title (section~1) will typically require % changing the actual title. % % \needspace{3\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{3\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 \enquote{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{3\baselineskip} % \begin{center} % {\large\bf 11. RELICENSING\par} % \end{center} % % \enquote{Massive Multiauthor Collaboration Site} (or \enquote{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 \enquote{Massive Multiauthor Collaboration} (or % \enquote{MMC}) contained in the site means any set of copyrightable % works thus published on the MMC site. % % \enquote{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. % % \enquote{Incorporate} means to publish or republish a Document, in % whole or in part, as part of another Document. % % An MMC is \enquote{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{3\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 % \enquote{GNU Free Documentation License}. % \end{quote} % \bigskip % % If you have Invariant Sections, Front-Cover Texts and Back-Cover % Texts, replace the \enquote{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. % % \printbibliography[heading=bibintoc] % % \StopEventually{} % % \section{Implementation} % % \iffalse %<*package> % \fi % % \pkg{ekdosis} relies on Lua functions and tables. Read the % |.lua| files that accompany \pkg{ekdosis} for more % information. % \begin{macrocode} \RequirePackage{iftex} % \end{macrocode} % \pkg{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 \pkg{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 institution = \institution@value, store repository = \repository@value, store collection = \collection@value, store idno = \idno@value, store msName = \msName@value, store origDate = \origDate@value } \NewDocumentCommand{\DeclareWitness}{m m m O{}}{% \bgroup \ekvset{ekd@witness}{#4} \luadirect{ekdosis.newwitness( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringO{\settlement@value}, \luastringO{\institution@value}, \luastringO{\repository@value}, \luastringO{\collection@value}, \luastringO{\idno@value}, \luastringO{\msName@value}, \luastringO{\origDate@value})} \egroup } \@onlypreamble\DeclareWitness \NewDocumentCommand{\DeclareHand}{m m m +O{}}{ \luadirect{ekdosis.newhand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } \@onlypreamble\DeclareHand \NewDocumentCommand{\DeclareScholar}{m m}{ \luadirect{ekdosis.newscholar(\luastringN{#1}, \luastringN{#2})} } \@onlypreamble\DeclareScholar \NewDocumentCommand{\DeclareShorthand}{m m m}{ \luadirect{ekdosis.newshorthand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \@onlypreamble\DeclareShorthand \NewDocumentCommand{\getsiglum}{m}{% \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% } \NewDocumentCommand{\SigLine}{m}{% \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} } % \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 \footnoteruletrue \let\dflt@footnoterule\footnoterule \let\dflt@pcol@footnoterule\pcol@footnoterule \renewcommand\footnoterule{% \iffootnoterule \dflt@footnoterule% \fi } \renewcommand\pcol@footnoterule{% \iffootnoterule \dflt@pcol@footnoterule% \fi } \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 % % \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, Institution, Repository, Collection, Idno, MsName, OrigDate) if xmlidfound(id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(listWit, {xmlid = id, abbr = siglum, detailsDesc = description, msIdentifier = { settlement = Settlement, institution = Institution, repository = Repository, collection = Collection, idno = Idno, msName = MsName} }) local indexwit = getindex(id, listWit) if OrigDate ~= "" then listWit[indexwit].history = {} listWit[indexwit].history.origin = {origDate = OrigDate} end end return true end function ekdosis.newhand(id, witid, siglum, description) if xmlidfound(id) or not xmlidfound(witid) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) local indexwit = getindex(witid, listWit) -- listWit[indexwit].handDesc = {xmlid = id, abbr = siglum, handNote = description} if listWit[indexwit].handDesc == nil then listWit[indexwit].handDesc = {} else end table.insert(listWit[indexwit].handDesc, {xmlid = id, abbr = siglum, detailsDesc = description}) end return true end function ekdosis.newshorthand(id, rend, xmlids) if isintable(shorthands, id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a shorthand. " .. "Please pick another shorthand.}}") else table.insert(shorthands, { a = id, b = rend, c = xmlids }) table.sort(shorthands, function(a ,b) return(#a.a > #b.a) end) table.insert(idsRend, {xmlid = id, abbr = rend}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) end return true end local xmlbibresource = nil function ekdosis.setxmlbibresource(str) xmlbibresource = str..".xml" return true end function ekdosis.newscholar(id, siglum) if xmlidfound(id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) end return true end function ekdosis.getsiglum(str, opt) str = str.."," str = string.gsub(str, "%s-(%,)", "%1") ctrl = str if opt == "tei" then for i = 1,#shorthands do str = string.gsub(str, shorthands[i].a, shorthands[i].c) end for i = 1,#idsRend do str = string.gsub(str, "(%f[%w])"..idsRend[i].xmlid.."(%,)", "%1#"..idsRend[i].xmlid.."%2") ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") end str = string.gsub(str, "%,(%s-)([%#])", " %2") str = string.gsub(str, "%,$", "") else for i = 1,#idsRend do str = string.gsub(str, idsRend[i].xmlid.."%,", idsRend[i].abbr) ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") end end -- if string.find(ctrl, "[A-Za-z0-9]") if string.find(ctrl, "%S") then return "" else return str end end -- begin totei functions local cmdtotags = { {a="textsuperscript", b="hi", c=" rend=\"sup\""}, {a="textsubscript", b="hi", c=" rend=\"sub\""}, {a="LRfootnote", b="note", c=" place=\"bottom\""}, {a="RLfootnote", b="note", c=" place=\"bottom\""}, {a="footnote", b="note", c=" place=\"bottom\""}, {a="enquote *", b="quote", c=""}, {a="enquote", b="quote", c=""}, {a="txtrans", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, {a="textbf", b="hi", c=" rend=\"bold\""}, {a="textit", b="hi", c=" rend=\"italic\""}, {a="textsc", b="hi", c=" rend=\"smallcaps\""}, {a="textsf", b="hi", c=" rend=\"sf\""}, {a="arbup", b="hi", c=" rend=\"sup\""}, {a="txarb", b="s", c=" xml:lang=\"arb\""}, {a="arb", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} } local texpatttotags = { {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 %2"}, {a="\\icite%s?%[(.-)%]{(.-)}", b="%1"}, {a="\\icite%s?{(.-)}", b=""} } 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, "%<", "<") str = string.gsub(str, "%>", ">") return str end local function note_totei(str) str = gsub(str, dblbkslash * note * spcenc^-1 * bsqbrackets * bcbraces * spcenc^-1, function(bkslash, cmd, opt, arg) opt = string.sub(opt, 2, -2) arg = string.sub(arg, 2, -2) teitype = get_attr_value(opt, "type") if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end right = get_attr_value(opt, "labelb") left = get_attr_value(opt, "labele") if left ~= "" then return string.format( "<%s%s target=\"#range(right(%s),left(%s))\">%s", cmd, teitype, right, left, arg, cmd, right) elseif left == "" then return string.format( "<%s%s target=\"#right(%s)\">%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", 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", cmd, arg, cmd)) else -- opt = ekdosis.getsiglum(opt, "tei") return lem_rdg_totei(string.format("<%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", cmd, arg, cmd)) end) return str end local function relocate_notes(str) str = string.gsub(str, "(%.-)(%.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2") return str end local function linestotei(str) -- str = "\n"..str str = string.gsub(str, "^%s?(.-)%s?$", "\n%1\n") -- str = gsub(str, endpoem, "\n") str = gsub(str, poemline * spcenc^-1 * lpeg.P(">"), "\n") str = gsub(str, poemline * spcenc^-1, "\n") -- str = str.."\n" return str end -- better use lpeg: look into this later local function versetotei(str) str = string.gsub(str, "(\\begin%s?%{ekdverse%})(%b[])(.-)(\\end%s?%{ekdverse%})", function(benv, opt, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s%s", benv, opt, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{ekdverse%})(.-)(\\end%s?%{ekdverse%})", function(benv, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s", benv, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{verse%})(%b[])(.-)(\\end%s?%{verse%})", function(benv, opt, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s%s", benv, opt, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{verse%})(.-)(\\end%s?%{verse%})", function(benv, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s", benv, arg, eenv) end) return str end local function envtotei(str) for i = 1,#envtotags do if envtotags[i].b ~= "" then if isfound(close_p, envtotags[i].b) 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("}"), "\\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("}"), "") 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, "") 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", arg, body) if cmdtotags[i].b ~= "" then return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s", body) else return "" end end) end -- temporarily: str = string.gsub(str, "\\(linelabel)%s?(%b{})", function(cmd, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("", body) end) str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})", function(cmd, opt, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("<%s>%s", 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", 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+", "

") str = string.gsub(str, "\\p@rb%s+", "

") str = string.gsub(str, "\\p@r%s+", "") str = string.gsub(str, "%s?\\par%s?", "

", 1) str = string.gsub(str, "(%)(%s-)(%<%/?div%d?)", "%3") str = string.gsub(str, "%s?\\par%s?", "

") str = string.gsub(str, "

%s?

", "") str = string.gsub(str, "(%)%s?(%)$", "%2") str = string.gsub(str, "(%)%s?$", "") str = string.gsub(str, "(

)%s?()", "%2%1") 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(""), 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 %s\\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 %s\\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, "

$") then isdiv = true str = string.gsub(str, "(.*)()$", "%1") else end -- collect used depth numbers for i in string.gmatch(str, "
") 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, "
") 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.."
" lastdivindex = lastdivindex - 1 end end if isdiv then return str..closedivs.."
" else return str..closedivs end end local function close_ndivs_at_end(str) local isdiv = false if string.find(str, "$") then isdiv = true str = string.gsub(str, "(.*)()$", "%1") else end -- collect used div numbers for i in string.gmatch(str, " #b.a) end) else end local firstdiv = string.match(str, "= firstdivindex do closedivs = closedivs.."" lastdivindex = lastdivindex - 1 end end if isdiv then return str..closedivs.."" else return str..closedivs end end local function close_ekddivs_in_between(str) local maxdepth = 1 for i in string.gmatch(str, "", "%1") do if tonumber(i) > tonumber(maxdepth) then maxdepth = i else end end for ndivi = 1, maxdepth do str = string.gsub(str, "(
)(.-)(
)", function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) local firstdiv = ndivi local lastdiv = ndivii local firstdivindex = get_a_index(firstdiv, used_ndivs) local lastdivindex = get_a_index(lastdiv, used_ndivs) firstdivindex = tonumber(firstdivindex) lastdivindex = tonumber(lastdivindex) local closedivs = "" if firstdivindex >= lastdivindex then while firstdivindex >= lastdivindex do closedivs = closedivs.."
" firstdivindex = firstdivindex - 1 end end return string.format("%s%s%s%s%s%s%s%s", bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) end) end str = string.gsub(str, "()", "%1%3") used_ndivs = {} return str end local function close_ndivs_in_between(str) for ndivi = 1, 6 do str = string.gsub(str, "()(.-)()", function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) local firstdiv = ndivi local lastdiv = ndivii local firstdivindex = get_a_index(firstdiv, used_ndivs) local lastdivindex = get_a_index(lastdiv, used_ndivs) firstdivindex = tonumber(firstdivindex) lastdivindex = tonumber(lastdivindex) local closedivs = "" if firstdivindex >= lastdivindex then while firstdivindex >= lastdivindex do closedivs = closedivs.."" firstdivindex = firstdivindex - 1 end end return string.format("%s%s%s%s%s%s%s%s", bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) end) end used_ndivs = {} return str end local function textotei(str) str = xml_entities(str) str = texpatttotei(str) str = note_totei(str) str = app_totei(str) str = lem_rdg_totei(str) str = relocate_notes(str) str = versetotei(str) str = envtotei(str) str = ekddivs_totei(str) str = section_totei(str) str = cmdtotei(str) str = self_close_tags(str) str = partotei(str) 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('', "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("<!-- Title -->", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") for i = 1,#listWit do f:write('", "\n") f:write('', textotei(listWit[i].abbr), "", "\n") f:write(textotei(listWit[i].detailsDesc), "\n") f:write("", "\n") if listWit[i].msIdentifier.settlement == "" and listWit[i].msIdentifier.institution == "" and listWit[i].msIdentifier.repository == "" and listWit[i].msIdentifier.collection == "" and listWit[i].msIdentifier.idno == "" and listWit[i].msIdentifier.msName == "" then f:write("", "\n") else f:write("", "\n") if listWit[i].msIdentifier.settlement ~= "" then f:write("", textotei(listWit[i].msIdentifier.settlement), "", "\n") else end if listWit[i].msIdentifier.institution ~= "" then f:write("", textotei(listWit[i].msIdentifier.institution), "", "\n") else end if listWit[i].msIdentifier.repository ~= "" then f:write("", textotei(listWit[i].msIdentifier.repository), "", "\n") else end if listWit[i].msIdentifier.collection ~= "" then f:write("", textotei(listWit[i].msIdentifier.collection), "", "\n") else end if listWit[i].msIdentifier.idno ~= "" then f:write("", textotei(listWit[i].msIdentifier.idno), "", "\n") else end if listWit[i].msIdentifier.msName ~= "" then f:write("", textotei(listWit[i].msIdentifier.msName), "", "\n") else end f:write("", "\n") end if listWit[i].handDesc ~= nil then f:write("", "\n") f:write("", "\n") local j = 1 while listWit[i].handDesc[j] do f:write("", "\n") f:write('', textotei(listWit[i].handDesc[j].abbr), "", "\n") f:write("

", textotei(listWit[i].handDesc[j].detailsDesc), "

", "\n") f:write("
", "\n") j = j + 1 end f:write("
", "\n") f:write("
", "\n") else end if listWit[i].history ~= nil then f:write("", "\n") f:write("", "\n") f:write("", textotei(listWit[i].history.origin.origDate), "", "\n") f:write("", "\n") f:write("", "\n") end f:write("
", "\n") f:write("
", "\n") end f:write("
", "\n") f:write("
", "\n") f:write("
", "\n") f:write("", "\n") f:write('', "\n") f:write("", "\n") f:write("
", "\n") f:write("", "\n") f:write("", "\n") f:close() return true end local tidy = nil local function cleanup_tei() local f = assert(io.open(teifilename.."_tmp.xml", "r")) t = f:read("*a") t = string.gsub(t, "%%s?%", "") t = string.gsub(t, "^\n", "") f:close() local fw = assert(io.open(teifilename.."_tmp.xml", "w")) fw:write(t) fw:close() return true end function ekdosis.closeteistream(opt) local f = io.open(teifilename.."_tmp.xml", "a+") f:write("\n", "", "\n") if xmlbibresource ~= nil then bibf = assert(io.open(xmlbibresource, "r")) t = bibf:read("*a") t = string.gsub(t, "%s+corresp%=%b\"\"", "") t = string.gsub(t, "\n\n", "\n") f:write("", "\n") f:write("", "\n") for i in string.gmatch(t, ".-") do f:write(i, "\n") end f:write("", "\n") f:write("", "\n") bibf:close() else end f:write("", "\n") f:write("
", "\n") f:close() cleanup_tei() os.remove(teifilename..".xml") os.rename(teifilename.."_tmp.xml", teifilename..".xml") if opt == "tidy" then os.execute("tidy -qmi -xml --output-xml yes "..teifilename..".xml") else end return true end function ekdosis.exporttei(str) local f = io.open(teifilename.."_tmp.xml", "a+") -- f:write("\n

") str = textotei(str) f:write(str) f:close() return true end -- end totei functions -- begin basic TeX Conspectus siglorum function ekdosis.basic_cs(msid) local indexwit = getindex(msid, listWit) siglum = listWit[indexwit].abbr -- if listWit[indexwit].detailsDesc == "" -- then -- name = listWit[indexwit].msIdentifier.msName -- else -- name = listWit[indexwit].msIdentifier.msName -- .."\\thinspace\\newline\\bgroup\\footnotesize{}".. -- listWit[indexwit].detailsDesc -- .."\\egroup{}" -- end name = listWit[indexwit].detailsDesc if listWit[indexwit].history ~= nil and listWit[indexwit].history.origin ~= nil then date = listWit[indexwit].history.origin.origDate else date = "" end return siglum.."&"..name.."&"..date end -- end basic TeX Conspectus siglorum function ekdosis.removesp(str) str = gsub(str, cmd * cmdargs * spcenc^-1, "%1%2") return str end function ekdosis.closestream() os.remove(tex.jobname..".ekd") os.rename(tex.jobname.."_tmp.ekd", tex.jobname..".ekd") return true end local cur_abs_pg = 0 local pg_i = nil local pg_ii = nil local prevcol = nil local curcol = "x" local check_resetlineno = {} function ekdosis.update_abspg(n) -- 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, "\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, "\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>.-") 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..">.-") 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..">.-") 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, "", "") 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 % % \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 % % \fi \endinput