% \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 % %<*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/07/08 v0.99a 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}, date = 2020, pubstate = {submitted}, issuetitle = {Collecting, Preserving, and Disseminating Endangered Cultural Heritage for New Understandings through Multilingual Approaches}, eprinttype = {hal}, eprint = {hal-02779803} } @Book{Caesar-BG-v2, author = {{Caesar}}, title = {Gallic War}, origtitle = {Guerre des Gaules}, date = 1987, origdate = 1926, editor = {Constans, L.-A.}, volume = 2, pagination = {none}, series = {Collection des Universités de France}, publisher = {Les Belles Lettres}, location = {Paris} } @Book{CaesarTr, author = {{Caesar}}, title = {Gallic War}, date = 1869, editor = {McDevitte, W. A., and Bohn, W. S.}, edition = 1, series = {Harper's New Classical Library}, publisher = {Harper \& Brothers}, location = {New York}} @Online{DLL-TC, author = {{Digital Latin Library}}, title = {Textual Criticism}, 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] % Peter and John Story: \DeclareWitness{pjA}{A}{Manuscript A Call No 123} \DeclareWitness{pjB}{B}{Manuscript B Call No 456} % Caesar's Gallic War: \DeclareWitness{cA}{A}{\emph{Bongarsianus} 81}[ msName=\emph{Bongarsianus}, settlement=Amsterdam, idno=81, institution=University Library, origDate=s. IX--X] \DeclareHand{cA1}{cA}{A\textsuperscript{1}}[\emph{Emendationes scribae ipsius}] \DeclareWitness{cM}{M}{\emph{Parisinus Lat.} 5056}[ origDate={s. XII}] \DeclareWitness{cB}{B}{\emph{Parisinus Lat.} 5763}[ origDate={s. IX--X}] \DeclareWitness{cR}{R}{\emph{Vaticanus Lat.} 3864}[ origDate={s. X}] \DeclareWitness{cS}{S}{\emph{Laurentianus} R 33}[ origDate={s. X}] \DeclareWitness{cL}{L}{\emph{Londinensis} Br. Mus. 10084}[ origDate={s. XI}] \DeclareWitness{cN}{N}{\emph{Neapolitanus} IV, c. 11}[ origDate={s. XII}] \DeclareWitness{cT}{T}{\emph{Parisinus Lat.} 5764}[ origDate={s. XI}] \DeclareWitness{cf}{\emph{f}}{\emph{Vindobonensis} 95}[ origDate={s. XII}] \DeclareWitness{cU}{U}{\emph{Vaticanus Lat.} 3324}[ origDate={s. XI}] \DeclareWitness{cl}{\emph{l}}{\emph{Laurentianus} Riccard. 541}[ origDate={s. XI--XII}] \DeclareShorthand{ca}{α}{cA,cM,cB,cR,cS,cL,cN} \DeclareShorthand{cb}{β}{cT,cf,cU,cl} \end{filecontents} \documentclass{ltxdoc} %\usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry} \usepackage[letterpaper,margin=1.25in,left=50mm,nohead]{geometry} \usepackage{dox} \doxitem{Option}{option}{options} \usepackage{microtype} \usepackage[no-math]{fontspec} \usepackage[latin.classic,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[parnotes=roman,teiexport=tidy]{ekdosis} \input{ekdosis-cfg} \usepackage{xltabular} \usepackage[prevent-all]{widows-and-orphans} \usepackage[shortcuts,nospacearound]{extdash} \usepackage[american]{isodate} \usepackage{nextpage} \usepackage{spacingtricks} \usepackage{csquotes} \usepackage{relsize} \usepackage{enumitem} \setlist{nosep} \setlist[itemize]{label=\textendash} \setlist[enumerate,1]{label=(\alph*)} \newlist{remarks}{enumerate}{10} \setlist[remarks]{ label*=\textsc{Rem.} \arabic*, left=0.25in, before=\smaller} \usepackage{manfnt} \usepackage{lettrine} \newcommand\danger{\lettrine[loversize=-.5]{\textdbend}{\hskip6pt}} \usepackage{metalogox} \usepackage{hologo} \usepackage{xcolor} \newbool{nocolordoc} \definecolor{ekdcolor}{RGB}{243,241,235} \definecolor{cinnamon}{rgb}{0.82, 0.41, 0.12} \ifbool{nocolordoc}{ \colorlet{ekdcolor}{white} \colorlet{cinnamon}{black}}{} \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} \newcounter{dummy} \newcommand{\dummy}{\refstepcounter{dummy}} \usepackage[nospace,american]{varioref} \usepackage[style=oxnotes-inote,dashed]{biblatex} \DeclareSourcemap{ \maps[datatype=bibtex]{ \map{ \step[fieldsource=issuetitle] \step[fieldset=journalsubtitle,origfieldval] } } } \ifbool{nocolordoc} { \usepackage{fontawesome} \def\oasymbol{\faUnlock} \usepackage{biblatex-ext-oa} } {\usepackage[symbolpackage=l3draw]{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} \setlength\IndexMin{100pt} \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{units} \newcommand*\tred[1]{\textcolor{red}{#1}} \usepackage{fbox} \usepackage{tikz} \usetikzlibrary{tikzmark} \NewDocumentCommand{\pointto}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,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{\pointtol}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,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{\pointtor}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,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{\pointtoer}{m}{% \tikz[remember picture] \draw[>->,color=blue,overlay] (0em,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=0.4pt, colframe=cinnamon, breakable} \usepackage[newfloat]{minted} \labelformat{listing}{listing~#1} \ifbool{nocolordoc}{\usemintedstyle{bw}}{} \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}\index{#1=#1 (environment)}} \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{1522} % % \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,\begin,\begingroup} % \DoNotIndex{\bgroup,\def,\edef,\egroup,\else,\expandafter,\endgroup} % \DoNotIndex{\fi,\ifdefined,\luadirect,\luastring,\luastringN} % \DoNotIndex{\luastringO,\NewDocumentCommand,\space,\unexpanded} % % \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} % % \begin{tcolorbox}[title=Notice to the Gentle Reader] % The current state of this documentation covers the basics of % \pkg{ekdosis}, namely what should be enough to start a new % document and see how it works. v1.0 with a full documentation % should be out by the end of July. Until then, there is a web page % that can be accessed,\footnote{% % \url{http://www.robertalessi.net/ekdosis}} with a mailing list % that one can subscribe to and a section entitled % \enquote{Literature} where one will find some slides and a paper % submitted to a journal. % \end{tcolorbox} % % \tableofcontents % \listoflistings % % \changes{v0.99a}{2020/07/08}{First public release (documentation in % progress)} % % \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| % \item |Makefile| % \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{Requirements} % \label{sec:requirements} % Please refer to \vref{ref:ekdrequirements}. % % \subsection{Features} % \label{sec:features} % A list of the main features of \pkg{ekdosis} follows:--- % \begin{enumerate} % \item \label{it:multicol-feature}\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 8). 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 entries refer to % the same line, numbers are not repeated. Instead, entries are % separated from one another by a broad horizontal space. Finally, a % square bracket is used inside entries to distinguish the lemma from % the variant readings. % % Furthermore, as said above, if a \texttt{TEI xml} output be % 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 from % content. 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{} can 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 to 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 declared beforehand. % \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 these witnesses have been already declared, here % is how the two families α and β could be % declared:---\footnote{These witnesses are used in the example % provided below in \vref{lst:caesar-bg}.} % \label{ref:caesar-bg-sigla} % \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 lemmata, 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, \vref{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{Base text and variants} 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{Lemmata} \DescribeMacro{\lem} % \cs{lem}\oarg{options}\marg{lemma text}\\ % As \meta{lemma text} is a word or a phrase judged by the editor to % be authentic or authoritative, \cs{lem} prints it by default both in % the edition text and as the first part of a new entry in the % apparatus criticus, preceded by the line number where it occurs or a % broad space if the entry refers to the same line as the preceding % entry. \label{ref:lem-opts-b}The optional argument of \cs{lem} % accepts the following % comma-separated list of \enquote{name$=$value} arguments:---\\ % \DescribeOption{wit} |wit|$=$\meta{csv list of witnesses}\\ % While a single witness may be recorded as in |wit=A|, % comma-separated lists of multiple witnesses must obviously be % enclosed in curly braces, like so: % |wit={A,B,C}|. \label{ref:mss-sep-families}It must be noted % that witnesses can be grouped by using spaces as separators, like % so: \verb*|wit={A,B,C, D,E,F}|.\\ % \DescribeOption{alt} |alt|$=$\meta{alternate lemma}\\ % While the mandatory argument of \cs{lem}, \meta{lemma text}, is % always used to print the edition text in the upper part of the page, % \meta{alternate lemma}, if specified, supersedes what is printed in % the related entry of the apparatus criticus. This mechanism is useful % in more than one respect. For instance, it can be used to insert % abbreviated lemmata in the apparatus criticus, or to introduce an % alternate way of writing entries with Latin technical terms in the % apparatus criticus as will be demonstrated below in the example % provided by \vref{lst:pj2}.\\ % \DescribeOption{sep} |sep|$=$\meta{separator}\\ % |sep| allows to change the symbol used to separate the lemma text % from deviant readings, which is by default the closing square % bracket (|]|)\\ % \DescribeOption{nosep} |nosep|$=$\verb+true|false+\\ % This named argument does not need a value as it defaults to |true| % if it is used. Obviously, |nosep| removes the separator mentioned % above.\\ % \DescribeOption{nolem} |nolem|$=$\verb+true|false+\\ % This named argument does not need a value as it defaults to |true| % if it is used. |nolem| completely removes the lemma text from the % related % entry in the apparatus criticus.\\ % \DescribeOption{type} |type|$=$\meta{value}\\ % This named argument has no effect on the apparatus criticus of the % edition in print, but it is used in the \texttt{TEI xml} ouput to % classify the variation recorded in the entry according to some % convenient typology. Categories such as lexical, morphological, % orthographical and the like may apply. % % Finally, four named arguments can be used to insert words at the % following specific places in the lemma text:\\ % \noindent % \fparbox*{\centered{\textbf{1} \tikzmark{pre}\tred{pre} Peter % \tikzmark{post}\tred{post} \tikzmark{prewit}\tred{prewit} % \getsiglum{pjA} % \tikzmark{postwit}\tred{postwit}] John \getsiglum{pjB}}}\\ % \DescribeOption{pre} |pre|$=$\meta{words}\pointtol{pre}\\ % |pre| inserts \meta{words} \emph{before} the lemma text.\\ % \DescribeOption{post} |post|$=$\meta{words}\pointto{post}\\ % |post| inserts \meta{words} \emph{after} the lemma text.\\ % \DescribeOption{prewit} |prewit|$=$\meta{words}\pointto{prewit}\\ % |prewit| inserts \meta{words} \emph{before} the list of witnesses.\\ % \DescribeOption{postwit} |postwit|$=$\meta{words}\pointtor{postwit}\\ % |postwit| inserts \meta{words} \emph{after} the list of witnesses. % \label{ref:lem-opts-e} % % \paragraph{Readings} \DescribeMacro{\rdg} % \cs{rdg}\oarg{options}\marg{variant reading}\\ % As \meta{reading} is a word or a phrase judged by the editor to be % unsatisfactory or corrupted, \cs{rdg} prints it by default in the % last part of the corresponding entry in the apparatus criticus, % after the symbol that is used to separate words of the base text % (the lemma text) from words rejected by the editor. The optional % argument of \cs{rdg} accepts a comma-separated list of % \enquote{name$=$value} arguments that is almost identical to % \cs{app}. Therefore, emphasis will be placed here only on the % differences. The reader is invited to refer to the description % provided above \vpagerefrange{ref:lem-opts-b}{ref:lem-opts-e} for % more detailed information:---\\ % \DescribeOption{wit} |wit|$=$\meta{csv list of witnesses}\\ % \DescribeOption{alt} |alt|$=$\meta{alternate reading}\\ % \DescribeOption{nordg} |nordg|$=$\verb+true|false+\\ % This named argument does not need a value as it defaults to |true| % if it is used. |nordg| completely removes the variant reading from % the related entry in the apparatus criticus.\\ % \DescribeOption{type} |type|$=$\meta{value}\\ % \DescribeOption{pre} |pre|$=$\meta{words}\\ % \DescribeOption{post} |post|$=$\meta{words}\\ % \DescribeOption{prewit} |prewit|$=$\meta{words}\\ % \DescribeOption{postwit} |postwit|$=$\meta{words}\\ % % \paragraph{Notes} % \DescribeMacro{\note}\DescribeMacro{\note*} % \cs{note}\oarg{options}\marg{text} or % \cs{note*}\oarg{options}\marg{text}\\ % It may happen that editorial notes be needed to record short % comments of general nature \emph{between} lemmata and % readings. \cs{note} inserts inline comments while \cs{note*} places % comments below the entire apparatus block. Furthermore, if % \pkg{ekdosis} has been loaded with the |parnotes| option as % described above \vpageref{ref:parnotes-opt}, \cs{note*} will use the % \pkg{parnotes} package to lay out the notes as an additional % paragraph below the apparatus criticus. The optional argument of % \cs{note}/\cs{note*} accepts the following comma-separated list of % \enquote{name$=$value} % arguments:---\\ % \DescribeOption{pre} |pre|$=$\meta{words}\\ % |pre| inserts \meta{words} immediately before the note.\\ % \DescribeOption{post} |post|$=$\meta{words}\\ % |post| inserts \meta{words} immediately after the note.\\ % % \danger Under no circumstances is it permitted to insert the command % \cs{note} or \cs{note*} inside the argument of \cs{lem} or % \cs{rdg}. \cs{note}/\cs{note*} must go \emph{between} these % commands. As a general rule, within \cs{app}|{}| elements, notes % are inserted immediately \emph{after} the lemma or the variant % reading they are related to. % % \Vref{lst:pj2} provides an illustration of some of the possibilities % afforded by the commands just described:--- % % \captof{The \enquote{Peter/John} full example}[\label{lst:pj2}] % \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.} \note*{There are no quotation marks in the mss.} \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} \note*{Ms. \getsiglum{B} provides other additions of this kind.}}. \end{ekdosis} \end{minted} % \iffalse % % \fi % \resetlinenumber % \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.} % \note*{There are no quotation marks in the mss.} % \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} % \note*{Ms. \getsiglum{pjB} provides other additions of this kind.}}. % \end{specimen} % \end{alignment} % % \begin{remarks} % \item Close examination of lines~17--8 from \vref{lst:pj2} shows how % |alt| has been used to insert an abbridged lemma text in the % apparatus criticus in print while keeping safe what is to be found % in the \texttt{TEI xml} output. % \item The same technique has been used at line~24 to insert % alternate words, including Latin technical terms, in place of the % variant reading. Hence the use of |nolem| at line~23 to remove the % lemma text from the apparatus criticus in print. % \item \cs{note*} has been used to insert short annotations in two % places (ll.~19 and 26). % \item For an example of the use of |nordg|, see below % \vref{lst:caesar-bg}, l.~11. % \end{remarks} % % The corresponding \texttt{TEI xml} output produced by \pkg{ekdosis} % from the \LaTeX{} source file follows:--- % % \captof{The \enquote{Peter/John} full example: \texttt{TEI xml} % output}[\label{lst:pj2-tei}] % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{xml}

I saw met my friend Peter John at the station yesterday. We were both in a great good mood. How nice to find you here! he said. There are no quotation marks in the mss. I chuckled to myself, recalling the last time we met met there Ms. Bprovides other additions of this kind. .

\end{minted} % \iffalse % % \fi % % \section{Alignment of Parallel Texts} % \label{sec:alignment-basic} % As already said above,\footnote{See point % \vref{it:multicol-feature}.} \pkg{ekdosis} can arrange sundry texts % in parallel columns\---synchronized or not\---either on the same % page or on facing pages. Depending on what is needed, any text can % be equipped with an apparatus criticus. The most common example is % that of an edition of a classical text with an apparatus criticus % accompanied by a translation into a modern language on the facing % page. One can also imagine an edition of two classical texts or two % different recensions of the same text, each of which provides % variants recorded in separate apparatus crititus, laid out on the % left-hand pages, with one or more translations on the corresponding % right-hand pages, and so forth. % % \paragraph{The \env{alignment} Environment} % \DescribeEnv{alignment} \cs{begin}|{alignment}|\oarg{options}\dots % \cs{end}|{alignment}|\label{ref:alignment-syntax}\\ % This environment can be used as it is provided to typeset a standard % critical edition, namely an edition text, equipped with an apparatus % criticus and laid out on the left-hand pages, accompanied by a % translation into a modern language on the facing pages. % % \DescribeEnv{edition}\DescribeEnv{translation} Within % \env{alignment}, two environments are available by default: % \cs{begin}|{edition}|\allowbreak\dots % \cs{end}|{ed|\allowbreak|ition}| and \cs{begin}|{translation}|\dots % \cs{end}|{translation}|. Obviously, the former is used to typeset % the edition text with an apparatus criticus on the left, while the % latter is used to typeset the translation on the right, like so:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \begin{alignment} \begin{edition} First § of the edition text. \end{edition} \begin{translation} First § of the translation. \end{translation} \begin{edition} Second § of the edition text. \end{edition} \begin{translation} Second § of the translation. \end{translation} \end{alignment} \end{minted} % \iffalse % % \fi % % \DescribeEnv{edition*}\DescribeEnv{translation*} Furthermore, % so-called \enquote{starred} versions of these environments can be % used at any point to synchronize texts, that is to print them in % such a way that the tops of all paragraphs are vertically % aligned. To that effect, it must be noted that merely applying this % command on a single environment\---for instance the leftmost % one\---will have all other associated paragraphs printed aligned. % % \danger While the whole edition text and the whole translation can % be inserted in a single \env{edition}/\env{translation} environment % respectively, it is recommended to enter both texts paragraph by % paragraph as shown in the example above. Not only this method of % encoding allows not to lose sight of paragraphs that are meant to be % read together, but it is also the only way to align paragraphs in % print, and it is much more suitable to mark up correspondence % between spans of texts as will be demonstrated below in % \vref{ref:segmentation}. % % As an illustration, a short extract of Caesar's \emph{Gallic War}, % VI, XIII.1 follows.\footnote{Latin text: \cite{Caesar-BG-v2}; % English translation: \cite{CaesarTr}.} See the list of sigla for % manuscripts and manuscript families above % \vpageref{ref:caesar-bg-sigla}. As this document is not set for % duplex printing, both texts have been put together on the same % page. However, the reader will find the full |.tex| source file % in \vref{sec:caesar-gw-tex} and \texttt{TEI xml} output in % \vref{sec:caesar-gw-tei}. The corresponding PDF output is available % in \href{samples/Caesar_BG-6-13-1.pdf}{a separate file}:--- % % \captof{Caesar's \emph{Gallic War}, VI, 13.1}[\label{lst:caesar-bg}] % \iffalse %<*example> % \fi \begin{minted}{latex} \begin{alignment} \begin{edition} \ekddiv{head=XIII, depth=2, n=6.13, type=section} In omni Gallia eorum hominum qui \app{ \lem[wit=a]{aliquo} \rdg[wit=b, alt=in al-]{in aliquo}} sunt numero atque honore genera sunt duo. Nam plebes paene seruorum habetur loco, quae \app{ \lem[wit={A,M}, alt={nihil audet (aut et \getsiglum{A1}) per se}]{nihil audet per se} \rdg[wit=A1,nordg]{nihil aut et per se} \rdg[wit={R,S,L,N}]{nihil habet per se} \rdg[wit=b]{per se nihil audet}}, \app{ \lem[wit=a]{nullo} \rdg[wit=b]{nulli}} adhibetur \app{ \lem{consilio} \rdg[wit={T, U}, alt=conc-]{concilio}}. \end{edition} \begin{translation} \ekddiv{head=XIII, depth=2, n=6.13, type=section} Throughout all Gaul there are two orders of those men who are of any rank and dignity: for the commonality is held almost in the condition of slaves, and dares to undertake nothing of itself, and is admitted to no deliberation. \end{translation} \end{alignment} \end{minted} % \iffalse % % \fi % % \resetlinenumber % \ekdfmtdiv{2}{}{.} % \begin{alignment}[lcols=2, % texts=edition[xml:lang="la"]; % translation[xml:lang="en"]] % \AtBeginEnvironment{edition}{\selectlanguage{latin}} % \AtBeginEnvironment{translation}{\selectlanguage{american}} % \begin{edition} % \ekddiv{head=XIII, depth=2, n=6.13, type=section} % In omni Gallia eorum hominum qui \app{ % \lem[wit=ca]{aliquo} % \rdg[wit=cb, alt=in al-]{in aliquo}} % sunt numero atque honore genera sunt duo. Nam plebes paene % seruorum habetur loco, quae \app{ % \lem[wit={cA,cM}, alt={nihil audet (aut et \getsiglum{cA1}) % per se}]{nihil audet per se} % \rdg[wit=cA1,nordg]{nihil aut et per se} % \rdg[wit={cR,cS,cL,cN}]{nihil habet per se} % \rdg[wit=cb]{per se nihil audet}}, \app{ % \lem[wit=ca]{nullo} % \rdg[wit=cb]{nulli}} adhibetur \app{ % \lem{consilio} % \rdg[wit={cT, cU}, alt=conc-]{concilio}}. % \end{edition} % \begin{translation} % \ekddiv{head=XIII, depth=2, n=6.13, type=section} % Throughout all Gaul there are two orders of those men who are of % any rank and dignity: for the commonality is held almost in the % condition of slaves, and dares to undertake nothing of itself, % and is admitted to no deliberation. % \end{translation} % \end{alignment} % % \begin{remarks} % \item As can be seen from the apparatus entry related to l.~4 above, % a subvariant has been inserted in the lemma part: \enquote{(aut et % \getsiglum{cA1})}. This was done by using |alt| in % \vref{lst:caesar-bg}, ll.~9--10. But as this variant is already % recorded\---and printed\---in the lemma part, it was necessary to % remove the entire otherwise redundant variant from the apparatus % criticus in print. Hence the use of |nordg| at l.~11. % \item For examples of abbreviations, see ll.~6 and 17. % \item Line~17 shows how mss.\ T and U (which belong to two distinct % subfamilies) have been separated from one another: % % \verb*+wit={T, U}+. See above \vpageref{ref:mss-sep-families} for % more information on this technique. % \end{remarks} % % Finally, the corresponding \texttt{TEI xml} output follows:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{xml}
XIII

In omni Gallia eorum hominum qui aliquo in aliquo sunt numero atque honore genera sunt duo. Nam plebes paene seruorum habetur loco, quae nihil audet per se nihil aut et per se nihil habet per se per se nihil audet , nullo nulli adhibetur consilio concilio .

XIII

Throughout all Gaul there are two orders of those men who are of any rank and dignity: for the commonality is held almost in the condition of slaves, and dares to undertake nothing of itself, and is admitted to no deliberation.

\end{minted} % \iffalse % % \fi % % \subsection{Alignment of Several Texts} % \label{sec:multiple-alignment} % As described above \vpageref{ref:alignment-syntax}, the % \env{alignment} environment may receive an optional argument in which % the following \enquote{name$=$value} arguments are accepted:---\\ % \DescribeOption{tcols} % |tcols|$=$\meta{number}\hfill\tcboxverb{Default: 2}\\ % |tcols| stores the \underLine{t}otal number of % \underLine{col}umn\underLine{s} of text to be aligned.\\ % \DescribeOption{lcols} % |lcols|$=$\meta{number}\hfill\tcboxverb{Default: 1}\\ % |lcols| stores the number of \underLine{col}umn\underLine{s} to be % printed on the \underLine{l}eft-hand page, \emph{out of the total % number} of columns specified with |tcols|. As can be seen from the % preceding two default values, \env{alignment} initially sets two % columns of text on facing pages. Of course, for this setting to work % properly, one must ensure that the \env{alignment} environment is % started on a % left page.\\ % \DescribeOption{texts} % |texts|$=$\meta{\underLine{semicolon}-separated % values}\hfill\tcboxverb{Default: edition;translation}\\ % Depending on the total number of columns that has been specified % with |tcols| above, |texts| is then used to define the names of the % environments that shall receive edition texts, translations, % \emph{\&c.} Some very important points need to be emphasized in this % respect:--- % \begin{enumerate} % \item Only unaccented letters of the alphabet (whatever the case) % are allowed to compose the names of \LaTeX{} environments. % \item These names must be separated from one another by % \emph{semicolons}, as shown in red in the listing below at the end % of lines~1 and 2. % \begin{enumerate} % \item[\dbend] The colon at the end of line~3 closes the whole % value of |text| and acts as a higher level separator. % \end{enumerate} % \item Each name may be followed by a \enquote*{suboptional} argument % between square brackets which will then be used to insert % \texttt{TEI xml} attributes in the corresponding |
| % element. For example, % \iffalse %<*example> % \fi \begin{minted}[escapeinside=++]{latex} texts=latin[xml:lang="la"]+\textcolor{red}{;}+ english[xml:lang="en"]+\textcolor{red}{;}+ french[xml:lang="fr"]+\textcolor{red}{,}+ \end{minted} % \iffalse % % \fi % will be converted into \texttt{TEI xml} as follows:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{xml}
...
...
...
\end{minted} % \iffalse % % \fi % \begin{enumerate} % \item[\dbend] As can be seen, \pkg{ekdosis} takes care of % computing and inserting the |xml:id| attributes which are % therefore not accepted in the \enquote*{suboptional} arguments % of |texts|. % \end{enumerate} % \item The names of the environments must be specified in exactly the % same order as they are supposed to appear in the print edition, % from left to right. % \end{enumerate} % \DescribeOption{apparatus} % |apparatus|$=$\meta{\underLine{semicolon}-separated % values}\hfill\tcboxverb{Default: edition}\\ % Then, the |apparatus| option, just as |texts|, takes a % \underLine{semicolon}-separated list of previously defined % environments that shall receive at least one layer of apparatus % criticus.\\ % \DescribeOption{paired} |paired|$=$\verb+true|false+% % \hfill\tcboxverb{Default: true (initially not set)}\\ % This named argument does not need a value as it defaults to |true| % if it is used. By default, \pkg{ekdosis} follows the \LaTeX{} page % numbering scheme when multiple texts are arranged on facing % pages. The |paired| option leaves every right-hand page number % unchanged, so that both facing pages hold the same page number.\\ % \DescribeOption{lineation} |lineation|$=$\verb+page|document+ % \hfill\tcboxverb{Default: document}\\ % This option applies to edition texts initially set to receive an % apparatus criticus. By default, lines are continuously numbered % throughout the document. |lineation=page| sets the numbering to % start afresh at the top of each page.\\ % \DescribeOption{flush} |flush|$=$\verb+true|false+ % \hfill\tcboxverb{Default: false}\\ % This named argument does not need a value as it defaults to |true| % if it is used. This option applies on rare occasions only, when two % or more distinct \env{alignment} environments are started on the same % page. Should this happen, any subsequent \env{alignment} environment % must be set with the |flush| option so that every one of them % carry its own apparatus criticus. % % As an example, the alignment of the Latin edition text of Caesar's % \emph{Gallic War}, printed on left-hand pages, along with two % translations into English and French, printed on right-hand pages, % can be set as follows:--- % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \begin{alignment}[tcols=3, lcols=1, texts=latin[xml:lang="la"]; english[xml:lang="en"]; french[xml:lang="fr"], apparatus=latin, lineation=page] \begin{latin} Gallia est omnis divisa in partes tres quarum unam incolunt Belgae, [...] \end{latin} \begin{english} All Gaul is divided into three parts, one of which the Belgae inhabit, [...] \end{english} \begin{french} L'ensemble de la Gaule est divisé en trois parties: l'une est habitée par les Belges, [...] \end{french} \end{alignment} \end{minted} % \iffalse % % \fi % % \DescribeMacro{\SetEkdosisAlignment} % \cs{SetEkdosisAlignment}\marg{alignment settings}\\ % If the same alignment settings are to be shared by several % \env{alignment} environments, common settings can be collected in % the argument of \cs{SetEkdosisEnvironment}, like % so:---\\ % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \SetEkdosisAlignment{ tcols=3, lcols=1, texts=latin[xml:lang="la"]; english[xml:lang="en"]; french[xml:lang="fr"], apparatus=latin, lineation=page } \begin{alignment} ... \end{alignment} \end{minted} % \iffalse % % \fi % % \cs{SetEkdosisAlignment} can be used either in the preamble or at % any point of the document to set or to modify alignment settings. % % \section{To Be Continued...} % v1.0 of \pkg{ekdosis}, which should be available by the end of July % 2020, will include a full documentation. At the time of writing, the % author is working on this part of the package. % % \begin{comment} % \section{Multiple-Layer Apparatus Criticus} % \end{comment} % \label{sec:multilayer-apparatus} % % \label{ref:type-app} % \begin{comment} % \section{Correspondence and Alignment} % \end{comment} % \label{sec:correspondance-alignment} % % \label{ref:segmentation} % % \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} % \label{sec: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} % Of course, \pkg{ekdosis} requires {\LuaLaTeX}. Issue an error % if the document is processed with another engine. % \begin{macrocode} \RequireLuaTeX % \end{macrocode} % Set global options:--- % \begin{macrocode} \RequirePackage{expkv-opt} \RequirePackage{expkv-def} \newif\if@pkg@float \newif\if@pkg@footins \newif\if@pkg@ekddivs \newif\if@parnotesroman \newif\if@pkg@parnotes \newif\iftei@export \ekvdefinekeys{ekdosis}{ choice layout = {float = {\@pkg@floattrue}, footins = {\@pkg@footinstrue}}, initial layout = float, unknown-choice layout = \PackageError{ekdosis}{unknown layout=#1}{`layout' must be either `float' or `footins'.}, choice divs = {ekdosis = {\@pkg@ekddivstrue}, latex = {\@pkg@ekddivsfalse \AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}}}}, initial divs = ekdosis, unknown-choice divs = \PackageError{ekdosis}{unknown divs=#1}{`divs' must be either `ekdosis' or `latex'.}, choice parnotes = {false = {}, true = {\@pkg@parnotestrue}, roman = {\@pkg@parnotestrue\@parnotesromantrue}}, default parnotes = true, unknown-choice parnotes = \PackageError{ekdosis}{unknown parnotes=#1}{`parnotes' must be either `true', or `false' or `roman'.}, choice teiexport = {false = {}, true = {\tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream()}}}, tidy = {\tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}}}}, default teiexport = true, unknown-choice teiexport = \PackageError{ekdosis}{unknown teiexport=#1}{`teiexport' must be either `true', `false' or `tidy'.} } \ekvoProcessLocalOptions{ekdosis} % \end{macrocode} % \paragraph{Required Packages} \label{ref:ekdrequirements} In % addition to \pkg{iftex}, \pkg{expkv-opt} and \pkg{expkv-def}, a list % of the packages that are required by \pkg{ekdosis} follows:--- % \begin{macrocode} % \RequirePackage{iftex} % already loaded above % \RequirePackage{expkv-opt} % already loaded above % \RequirePackage{expkv-def} % already loaded above \RequirePackage{luacode} \RequirePackage{paracol} \RequirePackage{xparse} \RequirePackage{etoolbox} \RequirePackage{lineno} \RequirePackage{keyfloat} \RequirePackage{refcount} \RequirePackage[user,abspage]{zref} \RequirePackage{ltxcmds} \if@pkg@parnotes \RequirePackage{parnotes} \fi % \end{macrocode} % \paragraph{Lua} 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} % Use |\normalfont| for line numbers:--- % \begin{macrocode} \renewcommand\linenumberfont{\normalfont\footnotesize} % \end{macrocode} % \begin{macro}{\SetEkdosisHooks} \cs{SetEkdosisHooks} is used to set % hooks meant to be shared by all declared apparatuses, such as the % font size, the format of numerals, \emph{\&c.} This command can be % used in the preamble or at any point of the document. % \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} % \end{macro} % 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 } % \end{macrocode} % \begin{macro}{\DeclareWitness} \cs{DeclareWitness} is a % preamble-only command. It takes three mandatory arguments and one % optional argument. It is meant to collect data related to % witnesses to be used in the edition text. Data are stored in |Lua| % tables and are used to encode the || part of the |TEI| % header as well as the Conspectus Siglorum in the edition in print. % \begin{macrocode} \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 % \end{macrocode} % \end{macro} % \begin{macro}{\DeclareHand} As \cs{DeclareWitness}, \cs{DeclareHand} % is a preamble-only command meant to collect data and store them in % |Lua| tables. It takes three mandatory arguments and one optional % argument. The second argument is used to connect the hand to a % declared witness it is related to. Then the table in which this % witness is recorded can be fed with new data. % \begin{macrocode} \NewDocumentCommand{\DeclareHand}{m m m +O{}}{ \luadirect{ekdosis.newhand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } \@onlypreamble\DeclareHand % \end{macrocode} % \end{macro} % \begin{macro}{\DeclareScholar} There is also a table in which are % collected data related to scholars' names to be used in the % apparatus criticus. \cs{DeclareScholar} is a preamble-only command % and takes two mandatory arguments: a unique id and a shorthand to % be used in the apparatus criticus which can be extracted from a % bibliographic database. % \begin{macrocode} \NewDocumentCommand{\DeclareScholar}{m m}{ \luadirect{ekdosis.newscholar(\luastringN{#1}, \luastringN{#2})} } \@onlypreamble\DeclareScholar % \end{macrocode} % \end{macro} % \begin{macro}{\DeclareShorthand} \cs{DeclareShorthand} is a % preamble-only command that can be used to record manuscript % families or any kind of shorthand to be used to refer to % previously declared ids, for example the shorthand |codd| can be % used to point to all declared witnesses. This command takes three % mandatory arguments: a unique id, its rendition in print and a % csv-list of previously declared ids. % \begin{macrocode} \NewDocumentCommand{\DeclareShorthand}{m m m}{ \luadirect{ekdosis.newshorthand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \@onlypreamble\DeclareShorthand % \end{macrocode} % \end{macro} % \begin{macrocode} \NewDocumentCommand{\getsiglum}{m}{% \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% } \NewDocumentCommand{\SigLine}{m}{% \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} } % \end{macrocode} % \paragraph{\TeX\ to \texttt{TEI xml}} % The following three commands can be used to instruct \pkg{ekdosis} % how to convert unknown or unusual \hologo{(La)TeX} commands into % \texttt{TEI xml} equivalents. % \begin{macro}{\TeXtoTEI} % \cs{TeXtoTEI}\marg{csname}\marg{TEI element}\oarg{TEI attribute(s)} % takes two mandatory arguments and one optional argument, namely: the % control sequence name to be converted, the \texttt{TEI} element it % is to be converted into and any additional \texttt{xml} attributes % to be appended to the opening \texttt{TEI} element:--- % \begin{macrocode} \NewDocumentCommand{\TeXtoTEI}{m m O{}}{% \luadirect{ekdosis.newcmdtotag(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } % \end{macrocode} % \end{macro} % \begin{macro}{\EnvtoTEI} % \begin{macro}{\EnvtoTEI*} % \cs{EnvtoTEI}\meta{*}\marg{env name}\marg{TEI element}\oarg{TEI % attribute(s)} instructs how to convert \LaTeX{} environments into % \texttt{TEI xml} equivalents. It takes two mandatory arguments and % one optional argument, namely the name of the \LaTeX{} environment % to be converted, the \texttt{TEI} element it is to be converted into % and any additional attributes to be appended to the \texttt{TEI} % opening element. \cs{EnvtoTEI*} is restricted to \texttt{TEI} % elements that must never appear within |

| elements, such as % |

|, || and the like. % \begin{macrocode} \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})} } } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\TeXtoTEIPatt} % Finally, the more flexible\---and more delicate to % handle\---\cs{TeXtoTEIPatt}\marg{\TeX\ % pattern}\allowbreak\marg{\texttt{TEI} pattern} uses pattern matching % to instruct \pkg{ekdosis} how to convert \hologo{(La)TeX} commands % into \texttt{TEI} equivalents. % \begin{macrocode} \NewDocumentCommand{\TeXtoTEIPatt}{m m}{% \luadirect{ekdosis.newpatttotag(\luastringN{#1}, \luastringN{#2})} } % \end{macrocode} % \end{macro} % \begin{macro}{\SetTEIFilename} \cs{SetTEIFilename}\marg{basename} is % a preamble-only command. It is used to set the base name of the % |TEI xml| output file, to which the suffix |.xml| is appended. By % default, the base name is |\jobname-tei|:--- % \begin{macrocode} \NewDocumentCommand{\SetTEIFileName}{m}{ \luadirect{ekdosis.setteifilename(\luastringN{#1})} } \@onlypreamble\SetTEIFileName % \end{macrocode} % \end{macro} % \begin{macro}{\SetxmlBibResource} This is a preamble-only command. % If a base name for a \texttt{TEI xml} compliant bibliographical % database file is provided with % \cs{SetxmlBibResource}\marg{basename}, \pkg{ekdosis} will use % insert formatted data in the back matter section of its own % \texttt{TEI xml} output file, as || elements within a % || section. % \begin{macrocode} \NewDocumentCommand{\SetxmlBibResource}{m}{ \luadirect{ekdosis.setxmlbibresource(\luastringN{#1})} } \@onlypreamble\SetxmlBibResource % \end{macrocode} % \end{macro} % %\paragraph{Multi-layer apparatuses} % \pkg{ekdosis} must know is an entry is to be processed in a single- % or multiple-layer context:--- % \begin{macrocode} \newif\ifekd@mapps % \end{macrocode} % Now the key-value options can be defined:--- % \begin{macrocode} \ekvdefinekeys{ekd@newapp}{ choice direction = {LR = \def\direction@val{LR}, RL = \def\direction@val{RL}}, unknown-choice direction = \PackageError{ekdosis}{unknown direction=#1}{`direction' must be either `LR' or `RL'.}, store rule = \rule@val, store delim = \delim@val, store sep = \sep@val, store bhook = \bhook@val, store ehook = \ehook@val, initial direction = LR, initial ehook = {\csname ekd@end@apparatus\endcsname} } % \end{macrocode} % \begin{macro}{\DeclareApparatus} % \cs{DeclareApparatus}\marg{apparatus name}\oarg{options} is a % preamble-only command. As a mandatory argument, it takes the name of % the new layer of notes to be inserted in the apparatus block. Then, % the following six key-value options can be used to lay out the % layer: \verb+direction=LR|RL+, |rule|, |delim| (the delimiter between % entries), |sep| (the separator between lemma part and readings or % notes), |bhook| (\LaTeX{} code inserted as the layer begins), % |ehook| (\LaTeX{} code inserted as the layer ends):--- % \begin{macrocode} \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} % \end{macro} % Apparatus-related settings and functions. Some booleans to check if % an apparatus should be inserted and what is the current environment. % \begin{macrocode} \newbool{do@app} \newif\ifekd@state \newif\ifekd@isinapp \newif\ifekd@isinlem % \end{macrocode} % The next boolean is shared with \pkg{arabluatex}. \cs{LRnum} is used % internally to ensure that numerals referring to line spans are % displayed in the right order. % \begin{macrocode} \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} % \end{macrocode} % Set counter referring to line numbers and make it global. % \begin{macrocode} \newcounter{ekd@lab} \globalcounter{ekd@lab} % \end{macrocode} % This command inserts words in the apparatus criticus without % checking if both |ekd@isinapp| and |ekd@state| are set to |true|. % \begin{macrocode} \NewDocumentCommand{\unconditional@appin}{o m}{% \IfNoValueTF{#1} {\luadirect{ekdosis.appin(\luastringO{#2})}} {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% } % \end{macrocode} % \begin{macro}{\blfootnote} \cs{blfootnote}\marg{footnote} is used % internally to insert the apparatus in the footnote block should the % global optional argument |layout| be set to |footins|. Therefore, it % is not documented. % \begin{macrocode} % \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} % \end{macrocode} % \end{macro} % \paragraph{Single-layer apparatus} The following commands are for % general settings. All of them can be used in the preamble or at any % point of the document:--- % \begin{macro}{\SetLTRapp} % \begin{macro}{\SetRTLapp} % \cs{SetLTRapp} and \cs{SetRTLapp} are two argument-less commands to % set the direction of single-layer apparatus criticus, either LTR or % RTL:--- % \begin{macrocode} \newif\ifrtl@app \NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue} \NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\SetSeparator} % \cs{SetSeparator}\marg{separator} allows to change the separator % between lemma texts and variant readings, which is by default % a closing square bracket followed by a space (\verb*+] +):--- % \begin{macrocode} \edef\ekdsep{] } \NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\SetEndApparatus} % \cs{SetEndApparatus}\marg{characters} can be used to append % characters at the end of the apparatus block\---such as a full stop, % as it is customary in some editions. By default, nothing is % appended:--- % \begin{macrocode} \edef\ekd@end@apparatus{} \NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\SetUnitDelimiter} % \cs{SetUnitDelimiter}\marg{delimiter} can be used to set the % delimiter between entries in the apparatus criticus. By default, % there is no delimiter except a simple space. \cs{SetUnitDelimiter} % can be used to insert a broad space (with |\hskip| for instance, as % in the OCT series) or the divider-sign (‖, as in the Budé series):--- % \begin{macrocode} \def\ekd@unit@delim{} \NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\footnoteruletrue} % \begin{macro}{\footnoterulefalse} % As \pkg{ekdosis} takes care of drawing a rule separating the main % text from the apparatus block as well as layers of notes from each % other inside this block, it may not be desirable to have % the standard \LaTeX{} \enquote{footnoterule} printed on every page % of the edition text. \cs{footnoterulefalse} removes it while % \cs{footnoteruletrue} leaves it untouched. The latter is set by % default. % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\SetDefaultRule} % By default, \pkg{ekdosis} draws separating rules the definition of % which is |\rule{2truein}{0.5pt}|. This can be changed in the % preamble or at any point of the document with % \cs{SetDefaultRule}\marg{\allowbreak{}rule definition}. Leaving this % argument empty as in \cs{SetDefaultRule}|{}| removes the rule. % \begin{macrocode} \NewDocumentCommand{\SetDefaultRule}{m}{% \def\@tempa{#1} \ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}% \else% \def\ekd@default@rule{#1}% \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\NLS} % \cs{NLS} is adapted from a snippet written by Heiko Oberdiek. It is % used by \pkg{ekdosis} internally to prevent page breaks between % separating rules and subsequent notes. Therefore, it is not % documented. % \begin{macrocode} \newcommand*{\NLS}{% \par% \nobreak% \vspace{-\parskip}% \noindent% \ignorespaces} % \end{macrocode} % \end{macro} % This boolean is used to test if a given entry is to be preceded by a % numeral referring to the line of the edition text. % \begin{macrocode} \newif\ifsubsq@unit \subsq@unittrue % \end{macrocode} % \cs{add@@apparatus} inserts the apparatus block on a given page % either in the footnote floating block or in a float of its own, % depending on the value set in the |layout| global option. % \begin{macrocode} \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% } % \end{macrocode} % Before inserting any new entry, \cs{add@apparatus} is called % \cs{test@apparatus} to decide whether a new apparatus block must be % created on a given page. % \begin{macrocode} \def\add@apparatus{% \test@apparatus% \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}% } % \end{macrocode} % \cs{append@app} inserts a bare (sub)entry in the apparatus... % \begin{macrocode} \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} % \end{macrocode} % while \cs{append@ln@app} inserts a (sub)entry possibly preceded by a % line number. % \begin{macrocode} \NewDocumentCommand{\append@ln@app}{o +m}{% \IfNoValueTF{#1} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}, \luastringO{#1}))}}} % \end{macrocode} % \begin{macro}{\EkdosisDefaultApparatus} % By default, \pkg{ekdosis} defines one layer of critical notes which % is called |default|. This name can be changed at any point of the % document with \cs{EkdosisDefaultApparatus}\marg{name}. % \begin{macrocode} \ekvdefinekeys{appnote}{ store type = \ekdan@type, initial type = default } \NewDocumentCommand{\EkdosisDefaultApparatus}{m}{% \ekvset{appnote}{type=#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\app} % \cs{app}|[type=|\meta{type}|]|\marg{apparatus entries} takes one % mandatory argument and accepts one optional argument. |type=| refers % to the layer the note must go into and \meta{apparatus entries} % contains command used to insert the entries, either \cs{lem}, % \cs{rdg} or \cs{note}\meta{*}:--- % \begin{macrocode} \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} % \end{macrocode} % \end{macro} % \cs{current@ref@arg} is used outside \cs{app} by \cs{note}. It takes % two mandatory arguments: the beginning line label and the ending % line label\---which are manually inserted---and returns the formatted % reference to be inserted in the apparatus criticus. % \begin{macrocode} \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}% } % \end{macrocode} % \cs{current@ref} is pretty much the same as \cs{current@reg@arg}, % but takes no argument. It is used by commands such as \cs{lem} when % references to page and line numbers can be returned by \textsf{Lua}. % \begin{macrocode} \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}% } % \end{macrocode} % Define keys to be used by the optional arguments of \cs{lem} and % \cs{rdg}:--- % \begin{macrocode} \ekvdefinekeys{lem}{ code wit = \def\ekdlr@wit{#1}, code alt = \def\ekdlr@alt{#1}, code pre = \def\ekdlr@pre{#1}, code post = \def\ekdlr@post{#1}, code prewit = \def\ekdlr@prewit{#1}, code postwit = \def\ekdlr@postwit{#1}, store type = \ekdlr@type, store sep = \ekdl@sep, bool nolem = \ifekdl@nolem, bool nosep = \ifekdl@nosep, initial sep = \ekdsep } \ekvdefinekeys{rdg}{ code wit = \def\ekdlr@wit{#1}, code alt = \def\ekdlr@alt{#1}, code pre = \def\ekdlr@pre{#1}, code post = \def\ekdlr@post{#1}, code prewit = \def\ekdlr@prewit{#1}, code postwit = \def\ekdlr@postwit{#1}, store type = \ekdlr@type, bool nordg = \ifekdr@nordg } % \end{macrocode} % \begin{macro}{\lem} % \cs{lem}\oarg{options}\marg{lemma text} inserts \meta{lemma text} % both in the edition text and in the apparatus criticus by default, % preceded by the reference to the line number or a space if it is the % same number as the one of the previous entry. This command accepts % the optional key-value arguments just defined above. % \begin{macrocode} \NewDocumentCommand{\lem}{O{} m}{% \ekd@isinlemtrue% \luadirect{ekdosis.dolnlab(\luastringN{#2})}% \bgroup% \ekvset{lem}{#1}% \ifekd@mapps% \ifnum% \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} = 1 \boolfalse{subsq@unit@\ekdan@type}% \fi% \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% \def\ekd@munit@delim{% \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% \fi% \ifekdl@nolem\edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref}%\hskip .25em}% \else% \ifbool{al@rlmode}{% \edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref%\hskip .25em \ifdefined\ekdlr@alt% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \else \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded{#2}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi }% }% {% \edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref%\hskip .25em \ifdefined\ekdlr@alt% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdlr@alt}}% {\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \else \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi }% }% \fi% \ifekd@mapps% \append@ln@app[\ekdan@type]{\lem@app}% \else% \append@ln@app{\lem@app}% \fi% \egroup% \ekd@isinlemfalse% \subsq@unittrue% } % \end{macrocode} % \end{macro} % \begin{macro}{\rdg} % \cs{rdg}\oarg{options}\marg{variant reading} inserts \meta{variant % reading} in the second part of the entry, after the lemma text and % the separator, in the apparatus criticus. This command accepts the % optional key-value arguments defined above. % \begin{macrocode} \NewDocumentCommand{\rdg}{O{} m}{% \bgroup% \ekvset{rdg}{#1}% % \ifekdr@nordg\append@app{}\else% do we need \append@app{} here? If % % so, keep in mind \ifekd@mapps, % like so: \ifekdr@nordg% \ifekd@mapps% \append@app[\ekdan@type]{}% \else% \append@app{}% \fi% \else% \ifbool{al@rlmode}{% \edef\rdg@app{% \ifdefined\ekdlr@alt% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \else \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded{#2}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi }% }% {% \edef\rdg@app{% \ifdefined\ekdlr@alt% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdlr@alt}}% {\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \else \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi }% }% \ifekd@mapps% \append@app[\ekdan@type]{\rdg@app}% \else% \append@app{\rdg@app}% \fi% \fi% \egroup% } % \end{macrocode} % \end{macro} % Define keys to be used by the optional argument of \cs{note} when % this command is found outside \cs{app}:--- % \begin{macrocode} \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 } % \end{macrocode} % \cs{note@noapp} is used internally when a \cs{note} command is found % outside \cs{app}. This command is mostly used to insert short % comments or references to texts quoted or cited in the edition text % to go into additional layers of the apparatus criticus, e.g.\ the % \emph{apparatus testium}. It accepts the optional key-value % arguments just defined above. It must be noted that |labelb| must be % specified; otherwise \pkg{ekdosis} will issue an error message. % \begin{macrocode} \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% } % \end{macrocode} % Define keys to be used by the optional argument of \cs{note} when % this command is found inside \cs{app}:--- % \begin{macrocode} \ekvdefinekeys{ekd@note}{ store pre = \pre@value, store post = \post@value } % \end{macrocode} % The following three commands, \cs{note@app}, \cs{ekd@note} and % \cs{ekd@note@star} are used internally when a \cs{note} command is % found inside \cs{app}. These commands are used to insert short % comments after the lemma text or after any variant reading in the % apparatus criticus. \cs{note@app} and subsequently \cs{ekd@note} and % \cs{ekd@note@star} accept the optional key-value arguments just % defined above. % \begin{macrocode} \NewDocumentCommand{\ekd@note}{O{} m}{% \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unexpanded{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% } \NewDocumentCommand{\ekd@note@star}{O{} m}{% \if@pkg@parnotes \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unskip\noexpand\parnote{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% \else \append@app{\unskip\footnote{#2}}% \fi% } \NewDocumentCommand{\note@app}{s O{} +m}{% \ifbool{al@rlmode}{% \IfBooleanTF{#1}{\ekd@note@star[#2]{% {\textdir TRT#3}}} {\ekd@note[#2]{{\textdir TRT#3}}}% }{% \IfBooleanTF{#1}{\ekd@note@star[#2]{#3}} {\ekd@note[#2]{#3}}% }% } % \end{macrocode} % \begin{macro}{\note} % Finally, \cs{note} is a simple command designed to check whether % \cs{note} itself is called inside or outside \cs{app}. Then, unless % it is found inside \cs{lem}, it calls \cs{note@app} in the former % case and \cs{note@noapp} in the latter case:--- % \begin{macrocode} \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% } % \end{macrocode} % \end{macro} % \cs{apparatus} is used internally by \pkg{ekdosis} to print the % apparatus at the bottom of pages. Therefore, it is not documented, % but this may change in the future for it will be possible to have % apparatuses printed at other places. % \begin{macrocode} \NewDocumentCommand{\apparatus}{}{% \luadirect{tex.sprint(ekdosis.appout())}} % \end{macrocode} % The following two commands call \textsf{Lua} functions to check % whether an apparatus should be printed on a given page and to store % the current column id. % \begin{macrocode} \NewDocumentCommand{\test@apparatus}{}{% \luadirect{tex.sprint(ekdosis.testapparatus())}} \NewDocumentCommand{\ekd@storecol}{}{% \luadirect{ekdosis.storecurcol(\luastring{\thecolumn})}% } % \end{macrocode} % Start and stop |ekdosis|: % \begin{macrocode} \NewDocumentCommand{\EkdosisOn}{}{% \ekd@statetrue} \NewDocumentCommand{\EkdosisOff}{}{% \ekd@statefalse% } % \end{macrocode} % Neutralize unwanted commands provided by \pkg{lineno} within the % \env{ekdosis} environment:--- % \begin{macrocode} \def\ekd@setlineno{% \let\setpagewiselinenumbers\relax% \let\pagewiselinenumbers\relax% \let\endpagewiselinenumbers\relax% \let\runningpagewiselinenumbers\relax% \let\realpagewiselinenumbers\relax% } % \end{macrocode} % \begin{environment}{ekdosis} % Finally comes the \env{ekdosis} environment meant to receive the % edition text equipped with an apparatus criticus. This environment % collects its contents and delivers it to \textsf{Lua} functions if a % \texttt{TEI xml} output file be desired. % \begin{macrocode} \NewDocumentEnvironment{ekdosis}{+b}{% \ekd@setlineno% \runninglinenumbers \EkdosisOn#1}{% \EkdosisOff \endrunninglinenumbers% \iftei@export \luadirect{ekdosis.exporttei(\luastringN{\par #1\par })}\fi} % \end{macrocode} % \end{environment} % \paragraph{Alignment} What follows isto arrange texts in parallel % columns either on single pages or on facing pages. % % Define keys to be used by the \env{alignment} environment:--- % \begin{macrocode} \newif\ifekd@pagelineation \ekvdefinekeys{ekd@align}{ store tcols = \tcols@num, store lcols = \lcols@num, store texts = \texts@value, store apparatus = \apparatus@value, bool paired = \ifekd@paired, choice lineation = {page = \ekd@pagelineationtrue, document = \ekd@pagelineationfalse}, unknown-choice lineation = \PackageError{ekdosis}{unknown lineation=#1}{`lineation' must be either `page' or `document'.}, choice segmentation = {auto = \def\segmentation@val{auto}, noauto = \def\segmentation@val{noauto}}, unknown-choice segmentation = \PackageError{ekdosis}{unknown segmentation=#1}{`segmentation' must be either `auto' or `noauto'.}, bool flush = \ifekd@flushapp, initial tcols = 2, initial lcols = 1, initial texts = edition;translation, initial apparatus = edition, default segmentation = auto } % \end{macrocode} % \begin{macro}{\SetEkdosisAlignment} % \cs{SetEkdosisAlignment}\marg{settings} can be used either in the % preamble or at any point of the document to set or modify the % keys-value settings just defined above. % \begin{macrocode} \NewDocumentCommand{\SetEkdosisAlignment}{m}{ \ekvset{ekd@align}{#1} } % \end{macrocode} % \end{macro} % Patch \pkg{paracol} to insert a hook in \cs{pcol@nextpage}. This % hook is used to reset line numbers on new pages. % \begin{macrocode} \patchcmd{\pcol@nextpage}{% \endgroup}{% \ifekd@pagelineation\resetlinenumber\fi \endgroup}{}{} % \end{macrocode} % \cs{EkdosisColStart} and \cs{EkdosisColStop} initialize columns % meant to receive edition texts. These commands are used internally % by \pkg{ekdosis}. % \begin{macrocode} \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% } % \end{macrocode} % \begin{environment}{alignment} % \cs{begin}|{alignment}|\oarg{options}\dots\cs{end}|{alignment}| can % be used as it is provided to typeset a standard critical edition % text on the left-hand pages accompanied with a translation on the % right-hand pages. To that effect, it provides by default two new % environments, \env{edition} and \env{translation}, to be used to % typeset both texts. (Either whole texts or texts entered by % paragraphs alternately.) The optional argument of \env{aligment} % accepts the exact same key-value options as \cs{SetEkdosisAlignment} % described above. One may contrast these options with those accepted % by \cs{SetEkdosisAlignment} as \enquote{local settings}. % \begin{macrocode} \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} % \end{environment} % \paragraph{Divisions of the Body} % \pkg{ekdosis} can convert \cs{book}, \cs{part}, \cs{chapter}, % \cs{section}, \cs{subsec{\allowbreak}tion} and \cs{subsubsection} % into corresponding \texttt{TEI} \enquote*{numbered} % || elements, where $1\leq n\leq 6$. % \begin{macro}{\MkBodyDivs} % \cs{MkBodyDivs} is used to let \pkg{ekdosis} know which sectional % commands are actually being used in an edition text. This command % takes six mandatory arguments. For example, if \cs{section} and % \cs{subsection} are the only sectional commands being used, % |\MkBodyDivs{section}{subsection}{}{}{}{}| will have \cs{section} % and \cs{subsection} converted into || and || % respectively. % \begin{macrocode} \NewDocumentCommand{\MkBodyDivs}{mmmmmm}{ \luadirect{ekdosis.mkdivdepths( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4}, \luastringN{#5}, \luastringN{#6} ) } } % \end{macrocode} % \end{macro} % Divisions specific to \pkg{ekdosis}. Define keys to be used by % \cs{ekddiv}:--- % \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}}, unknown-choice toc = \PackageError{ekdosis}{unknown toc=#1}{`toc' must be either `book', `part', `chapter', `section', `subsection', \MessageBreak `subsubsection', `paragraph' or `subparagraph'.}, initial depth = 1 } % \end{macrocode} % \begin{macro}{\ekdfmtdiv} % \cs{ekdfmtdiv}\marg{n}\marg{code before}\marg{code after} is % used to lay out the heading of the title. It takes three mandatory % arguments: \emph{n}, namely the number referring to the particular % depth of the division, and then some \LaTeX{} formatting commands % to go before and after the heading itself:--- % \begin{macrocode} \NewDocumentCommand{\ekdfmtdiv}{m m m}{ \luadirect{ekdosis.fmtdiv(\luastring{#1}, \luastringN{#2}, \luastringN{#3})} } % \end{macrocode} % \end{macro} % \cs{ekd@getfmtdiv} gets the formatting commands that have been % stored by \cs{ekdfmtdiv}. % \begin{macrocode} \NewDocumentCommand{\ekd@getfmtdiv}{m m}{% \luadirect{tex.sprint(ekdosis.getfmtdiv(\luastringO{#1}, \luastringN{#2}))}% } % \end{macrocode} % \begin{macro}{\ekddiv} % \cs{ekddiv}\marg{key-value arguments} is the standard command % provided by \pkg{ekdosis} to meet the requirements of classical and % literary texts the divisions of which depend on many different % received traditions. It takes one optional argument in which the % key-value arguments defined above are accepted, and converts the % divisions into \texttt{TEI} \enquote*{un-numbered} |
| % elements. % \begin{macrocode} \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} % \end{macro} % A very basic and provisional implementation of poetry lines % follows:--- % \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{comment} % \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="enquote *", b="quote", c=""}, {a="footnote", b="note", c=" place=\"bottom\""}, {a="enquote", b="quote", c=""}, {a="txtrans", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, {a="textbf", b="hi", c=" rend=\"bold\""}, {a="textit", b="hi", c=" rend=\"italic\""}, {a="textsc", b="hi", c=" rend=\"smallcaps\""}, {a="textsf", b="hi", c=" rend=\"sf\""}, {a="arbup", b="hi", c=" rend=\"sup\""}, {a="txarb", b="s", c=" xml:lang=\"arb\""}, {a="arb", b="foreign", c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} } local texpatttotags = { {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 %2"}, {a="\\icite%s?%[(.-)%]{(.-)}", b="%1"}, {a="\\icite%s?{(.-)}", b=""}, {a="\\linelabel%s?{(.-)}", b=""}, {a="\\label%s?{(.-)}", b=""}, {a="\\v?pageref%s?{(.-)}", b=""}, {a="\\v?ref%s?{(.-)}", b=""} } local envtotags = { {a="flushright", b="p", c=" rend=\"align(right)\""}, {a="flushleft", b="p", c=" rend=\"align(left)\""}, {a="quotation", b="quote", c=""}, {a="ekdverse", b="lg", c=""}, {a="txarabtr", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, {a="txarab", b="p", c=" xml:lang=\"arb\""}, {a="center", b="p", c=" rend=\"align(center)\""}, {a="verse", b="lg", c=""}, {a="arab", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} } local close_p = { "p", "lg" } local forbid_xmlid = true function ekdosis.newcmdtotag(cmd, tag, attr) if forbid_xmlid then attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here else end if isintable(cmdtotags, cmd) then local index = get_a_index(cmd, cmdtotags) table.remove(cmdtotags, index) table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) else table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) end return true end function ekdosis.newpatttotag(pat, repl) pat = string.gsub(pat, "([%[%]])", "%%%1") pat = string.gsub(pat, "%#[1-9]", "(.-)") repl = string.gsub(repl, "%#([1-9])", "%%%1") table.insert(texpatttotags, { a = pat, b = repl }) table.sort(texpatttotags, function(a ,b) return(#a.a > #b.a) end) return true end function ekdosis.newenvtotag(env, tag, attr, closep) if forbid_xmlid then attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here else end if isintable(envtotags, env) then local index = get_a_index(env, envtotags) table.remove(envtotags, index) table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) else table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) end return true end -- Get values of attributes local function get_attr_value(str, attr) str = str.."," local attrval = string.match(str, "%f[%w]"..attr.."%s?%=%s?%b{}") or string.match(str, "%f[%w]"..attr.."%s?%=%s?.-%,") or "" attrval = string.gsub(attrval, attr.."%s?%=%s?(%b{})", function(bbraces) bbraces = string.sub(bbraces, 2, -2) return string.format("%s", bbraces) end) attrval = string.gsub(attrval, attr.."%s?%=%s?(.-)%s?%,", "%1") return attrval end local function xml_entities(str) str = string.gsub(str, "%<", "<") str = string.gsub(str, "%>", ">") return str end local function note_totei(str) str = gsub(str, dblbkslash * note * spcenc^-1 * bsqbrackets * bcbraces * spcenc^-1, function(bkslash, cmd, opt, arg) opt = string.sub(opt, 2, -2) arg = string.sub(arg, 2, -2) teitype = get_attr_value(opt, "type") if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end right = get_attr_value(opt, "labelb") left = get_attr_value(opt, "labele") if left ~= "" then return string.format( "<%s%s target=\"#range(right(%s),left(%s))\">%s", 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, "\\(getsiglum)%s?(%b{})", function(cmd, body) body = string.sub(body, 2, -2) teisiglum = ekdosis.getsiglum(body, "tei") printsiglum = ekdosis.getsiglum(body) -- body = cmdtotei(body) return string.format("%s", teisiglum, printsiglum) end) str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})", function(cmd, opt, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("<%s>%s", 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} % \end{comment} % \iffalse % % \fi % % \section{Sample: C. J. Caesar, \emph{Gallic War}, % VI, XIII.1} % \label{sec:caesar-gw-6-1-13} % \subsection{\texttt{.tex} Source File} % \label{sec:caesar-gw-tex} % \inputminted[linenos=false]{latex}{samples/Caesar_BG-6-13-1.tex} % \subsection{\texttt{TEI xml} Output} % \label{sec:caesar-gw-tei} % \inputminted[linenos=false]{xml}{samples/Caesar_BG-6-13-1-tei.xml} % \endinput