% \iffalse meta-comment % % ekdosis -- Typesetting TEI xml compliant critical editions % Copyright (C) 2020 Robert Alessi % % Please send error reports and suggestions for improvements to Robert % Alessi % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see % . % %<*internal> \iffalse % %<*readme> | -------:| ----------------------------------------------------------------- ekdosis:| Typesetting TEI xml compliant critical editions Author:| Robert Alessi E-mail:| alessi@robertalessi.net License:| Released under the GNU General Public License v3 or later See:| http://www.gnu.org/licenses/ Short description: Some text about the package: probably the same as the abstract. % %<*luapre> --[[ This file is part of the `ekdosis' package ekdosis -- Typesetting TEI xml compliant critical editions Copyright (C) 2020 Robert Alessi Please send error reports and suggestions for improvements to Robert Alessi This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . --]] % %<*internal> \fi % % \fi % % \iffalse %<*driver> \ProvidesFile{ekdosis.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{ekdosis} %<*package> [2020/06/03 v0.99 Typesetting TEI xml compliant critical editions] % %<*driver> \documentclass{ltxdoc} \usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry} \usepackage{dox} \doxitem{Option}{option}{options} \usepackage{microtype} \usepackage{fontspec} \usepackage[english]{babel} \babelfont{rm}{Old Standard} \babelfont{sf}{NewComputerModern Sans} \babelfont{tt}{NewComputerModern Mono} \usepackage{arabluatex} \usepackage{ekdosis} \usepackage{enumitem} \setlist{nosep} \setlist[itemize]{label=\textendash} \setlist[enumerate,1]{label=(\alph*)} \usepackage{metalogox} \usepackage{hologo} \usepackage{xcolor} \definecolor{ekdcolor}{RGB}{243,241,235} \definecolor{cinnamon}{rgb}{0.82, 0.41, 0.12} \definecolor{gainsboro}{RGB}{222,222,222} \PassOptionsToPackage{bookmarks=true}{hyperref} \usepackage{xurl} \usepackage[numbered]{hypdoc} \usepackage[loadlang=en]{metastr} \hypersetup{ colorlinks, allcolors=cinnamon, linktocpage=true, pdftype={Text} } \usepackage{uri} \usepackage[nospace]{varioref} \labelformat{section}{sect.~#1} \metaset{titletext}{% \metapick[#1]{title}% \metacompose[#1]{subtitle}{\metaget[sep]{subtitle}}{}{}} \metaset[print]{titletext}{% \metatitleline[print]{title}% \metatitleline[print]{subtitle}% \metatitleline[print]{author}% \metatitleline[print]{contactemail}% \metatitlelinetwo[print]{date}[print]{draft}} \metaset[skip]{subtitle}{\vspace{1ex}} \metaset[skip]{author}{\vspace{2ex}} \metaset[skip]{date}{\vspace{1ex}} \metaset[style]{title}{\LARGE} \metaset[style]{author}{\large} \metaset[sep]{draft}{ -- } \metasetlang{en-US} \metaset{title}{ἔκδοσις} \metaset{date}{\filedate} \metaset{draft}{\fileversion} \metaset{subject}{TEI xml compliant critical editions} \metaset{subtitle}{Typesetting TEI xml Compliant Critical Editions} \metaset[print]{subtitle}{Typesetting \texttt{TEI xml} Compliant Critical Editions} \metaset{author}{Robert Alessi} \metaset{keywords}{LaTeX, Lua, TEI xml, multilingual critical editions, alignment, segmentation} \metaset{contactemail}{alessi@roberalessi.net} \metaset[print]{contactemail}{\mailto[ekdosis]{alessi@robertalessi.net}} \metaset{contacturl}{http://www.roberalessi.net} \metaset{partof}{The ekdosis Package} \metaset[print]{partof}{The \textsf{ekdosis} Package} \metaset{copyrightowner}{\metapick[#1]{author}} \metaset{copyrightdate}{2020} \metaset{licensemessage}{Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.} \metaset{licenseurl}{https://www.gnu.org/licenses/fdl-1.3.html} \metaset[print]{licenseurl}{% \url{https://www.gnu.org/licenses/fdl-1.3.html}} \metaset[cmd]{licenselogo}{\includegraphics[scale=0.75]{#1}} \metawritepdfinfo \metawritepdfaux \metawritepdfpreamble \metawritepdfcontact \metawritepdfrights \usepackage[lot]{multitoc} \usepackage{relsize} \usepackage{units} \usepackage{tikz} \usepackage[breakable, skins, xparse]{tcolorbox} \usepackage[newfloat]{minted} \setminted{bgcolor=ekdcolor,linenos, fontsize=\small} \newminted[ekdlua]{lua}{bgcolor={}, linenos, fontsize=\relsize{-0.5}, xleftmargin=12pt, breaklines, numberblanklines=false, numbersep=3pt, firstnumber=last} \renewcommand{\theFancyVerbLine}{\rmfamily\smaller\arabic{FancyVerbLine}} \usepackage[contents]{colordoc} \newcommand{\package}[1]{\textsf{#1}\index{#1=#1 (package)}} \backgroundcolor{c}{ekdcolor} \usepackage{caption} \captionsetup[listing]{position=above,skip=-1ex} \usepackage{needspace} \NewDocumentCommand{\captof}{O{listing} m O{}}{% \bgroup \needspace{5\baselineskip}% \vskip 1ex plus 2pt minus 2pt% \captionof{#1}{#2}% #3% \egroup} \usepackage{etoc} \etocsettocdepth{paragraph} \newcommand{\ekdtableofcontents}{% \begingroup \etocsetstyle{section}{}{} {\etocsavedsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{} \etocsetstyle{subsection}{}{} {\etocsavedsubsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{}% \etocsetstyle{subsubsection}{}{} {\etocsavedsubsubsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{}% \etocsetstyle{paragraph}{}{\leftskip2cm\rightskip 2.2em \parfillskip 0pt plus 1fil\relax \nobreak} {\noindent\etocname{} \etocpage{} }{\par}% \etocmulticolstyle[2]{\section*{Contents}} \pdfbookmark[1]{Contents}{toc} \tableofcontents \endgroup} \EnableCrossrefs \CodelineIndex \RecordChanges % \OnlyDescription \begin{document} \DocInput{\jobname.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \GetFileInfo{\jobname.dtx} % \DoNotIndex{\newcommand,\newenvironment} % % \pdfbookmark[1]{\metaterm{title}}{title} % \begin{tcolorbox}[ % colframe=black, % enhanced, % drop lifted shadow, % colback=white, % boxrule=.25mm, % halign=center, % center % ] % \metapick[print]{titletext} % \end{tcolorbox} % % \footnotesize % \ekdtableofcontents % \normalsize % %\changes{v1.00}{2020/07/01}{First public release} % % \begin{abstract}% % \package{ekdosis} is a Lua\LaTeX{} package designed for % multilingual critical editions. It can be used to typeset texts % and different layers of critical notes in any direction accepted % by Lua\TeX. Texts can be arranged in running paragraphs or on % facing pages, in any number of columns which in turn can be % synchronized or not. In addition to printed texts, % \package{ekdosis} can convert \texttt{.tex} source files so as to % produce \texttt{TEI xml} compliant critical % editions. Database-driven encoding under \LaTeX{} then allows % extraction of texts entered segment by segment according to % various criteria: main edited text, variant readings, translations % or annotated borrowings between texts. It is published under the % terms of the GNU General Public License (GPL) version 3. % \end{abstract} % % \section*{License and disclaimer} % \addcontentsline{toc}{section}{License and disclamer} % \subsection*{License applicable to this document} % \pdfbookmark[2]{Licence applicable to this document}{copyright-doc} % \leavevmode\marginpar{\hfill\texttt{fdl1.3}} % \metapick[print]{rightstext} (See below \vref{sec:fdl}.) % % \subsection*{License applicable to the software} % \pdfbookmark[2]{Licence applicable to the software}{copyright-soft} % \label{sec:license-software} % % \package{ekdosis} --- \metapick[print]{subtitle} % \metapick[print]{copyrightstatement} % % Please send error reports and suggestions for improvements to Robert % Alessi: % \begin{itemize} % \item email: \mailto[ekdosis package]{alessi@roberalessi.net} % \item website: \url{http://www.robertalessi.net/ekdosis} % \item development: \url{http://git.robertalessi.net/ekdosis} % \item comments, feature requests, bug reports: % \url{https://gitlab.com/ralessi/eksodis/issues} % \end{itemize} % % \leavevmode\marginpar{\hfill\texttt{gpl3+}} % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see % \href{http://www.gnu.org/licenses}{\texttt{}}. % % This release of \package{ekdosis} consists of the following % source files: % \begin{itemize} % \item |ekdosis.ins| % \item |ekdosis.dtx| % \item |ekdosis.el| % \end{itemize} % % \section{Introduction} % \begin{keyfigure}{c={Grid Typesetting (which never came into existence)}, % t={Each square in the grid has a side length of \unit[10]{pt}. Therefore, % the distance between the last line of the text and the first line of the % apparatus is here approximately \unit[25]{pt}.}} % \centering % \begin{tikzpicture} % \draw[gainsboro,thin] (0.5,0.5) grid [step=10pt] (10,5); % % \path node [align=justify, text width=8cm] at (5.5,3) {% % I saw my friend Peter at the station yesterday. I saw my friend % Peter at the station yesterday. I saw my friend Peter at the % station yesterday. I saw my friend Peter at the station % yesterday.\par % \rule{3cm}{0.01cm}\par\footnotesize% % \textbf{1}~Peter A: John B\ \ \textbf{2}~Peter A: John B \ \ % \textbf{3}~Peter A: John B\ \ \textbf{4}~Peter A: John B}; \node % at (0,3) {\scriptsize $\approx$ \unit[25]{pt}}; \draw [->] % (0,2.875) -- (0,2.025); % \end{tikzpicture} % \end{keyfigure} % % % % \captof{The Peter and John example} % \iffalse %<*example> % \fi \begin{minted}[linenos=false]{latex} \begin{ekdosis} I saw my friend \app{ \lem{Peter} \rdg{John} } at the station yesterday. \end{ekdosis} \end{minted} % \iffalse % % \fi % \begin{alignment}[flush,tcols=1,texts=specimen,apparatus=specimen] % \begin{specimen} % I saw my friend % \app{ % \lem{Peter} % \rdg{John} % } % at the station yesterday. % \end{specimen} % \end{alignment} % % \section{GNU Free Documentation License} % \label{sec:fdl} % \textbf{Version 1.3, 3 November 2008} % % \begin{center} % % Version 1.3, 3 November 2008 % % % Copyright \copyright{} 2000, 2001, 2002, 2007, 2008 Free % Software Foundation, Inc. % % \bigskip % % \url{https://fsf.org/} % % \bigskip % % Everyone is permitted to copy and distribute verbatim copies % of this license document, but changing it is not allowed. % \end{center} % % % \needspace{\baselineskip} % \begin{center} % {\bf\large Preamble} % \end{center} % % The purpose of this License is to make a manual, textbook, or other % functional and useful document ``free'' in the sense of freedom: to % assure everyone the effective freedom to copy and redistribute it, % with or without modifying it, either commercially or noncommercially. % Secondarily, this License preserves for the author and publisher a way % to get credit for their work, while not being considered responsible % for modifications made by others. % % This License is a kind of ``copyleft'', which means that derivative % works of the document must themselves be free in the same sense. It % complements the GNU General Public License, which is a copyleft % license designed for free software. % % We have designed this License in order to use it for manuals for free % software, because free software needs free documentation: a free % program should come with manuals providing the same freedoms that the % software does. But this License is not limited to software manuals; % it can be used for any textual work, regardless of subject matter or % whether it is published as a printed book. We recommend this License % principally for works whose purpose is instruction or reference. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 1. APPLICABILITY AND DEFINITIONS\par} % \end{center} % % This License applies to any manual or other work, in any medium, that % contains a notice placed by the copyright holder saying it can be % distributed under the terms of this License. Such a notice grants a % world-wide, royalty-free license, unlimited in duration, to use that % work under the conditions stated herein. The ``\textbf{Document}'', below, % refers to any such manual or work. Any member of the public is a % licensee, and is addressed as ``\textbf{you}''. You accept the license if you % copy, modify or distribute the work in a way requiring permission % under copyright law. % % A ``\textbf{Modified Version}'' of the Document means any work containing the % Document or a portion of it, either copied verbatim, or with % modifications and/or translated into another language. % % A ``\textbf{Secondary Section}'' is a named appendix or a front-matter section of % the Document that deals exclusively with the relationship of the % publishers or authors of the Document to the Document's overall subject % (or to related matters) and contains nothing that could fall directly % within that overall subject. (Thus, if the Document is in part a % textbook of mathematics, a Secondary Section may not explain any % mathematics.) The relationship could be a matter of historical % connection with the subject or with related matters, or of legal, % commercial, philosophical, ethical or political position regarding % them. % % The ``\textbf{Invariant Sections}'' are certain Secondary Sections whose titles % are designated, as being those of Invariant Sections, in the notice % that says that the Document is released under this License. If a % section does not fit the above definition of Secondary then it is not % allowed to be designated as Invariant. The Document may contain zero % Invariant Sections. If the Document does not identify any Invariant % Sections then there are none. % % The ``\textbf{Cover Texts}'' are certain short passages of text that are listed, % as Front-Cover Texts or Back-Cover Texts, in the notice that says that % the Document is released under this License. A Front-Cover Text may % be at most 5 words, and a Back-Cover Text may be at most 25 words. % % A ``\textbf{Transparent}'' copy of the Document means a machine-readable copy, % represented in a format whose specification is available to the % general public, that is suitable for revising the document % straightforwardly with generic text editors or (for images composed of % pixels) generic paint programs or (for drawings) some widely available % drawing editor, and that is suitable for input to text formatters or % for automatic translation to a variety of formats suitable for input % to text formatters. A copy made in an otherwise Transparent file % format whose markup, or absence of markup, has been arranged to thwart % or discourage subsequent modification by readers is not Transparent. % An image format is not Transparent if used for any substantial amount % of text. A copy that is not ``Transparent'' is called ``\textbf{Opaque}''. % % Examples of suitable formats for Transparent copies include plain % ASCII without markup, Texinfo input format, LaTeX input format, SGML % or XML using a publicly available DTD, and standard-conforming simple % HTML, PostScript or PDF designed for human modification. Examples of % transparent image formats include PNG, XCF and JPG. Opaque formats % include proprietary formats that can be read and edited only by % proprietary word processors, SGML or XML for which the DTD and/or % processing tools are not generally available, and the % machine-generated HTML, PostScript or PDF produced by some word % processors for output purposes only. % % The ``\textbf{Title Page}'' means, for a printed book, the title page itself, % plus such following pages as are needed to hold, legibly, the material % this License requires to appear in the title page. For works in % formats which do not have any title page as such, ``Title Page'' means % the text near the most prominent appearance of the work's title, % preceding the beginning of the body of the text. % % The ``\textbf{publisher}'' means any person or entity that distributes % copies of the Document to the public. % % A section ``\textbf{Entitled XYZ}'' means a named subunit of the Document whose % title either is precisely XYZ or contains XYZ in parentheses following % text that translates XYZ in another language. (Here XYZ stands for a % specific section name mentioned below, such as ``\textbf{Acknowledgements}'', % ``\textbf{Dedications}'', ``\textbf{Endorsements}'', or ``\textbf{History}''.) % To ``\textbf{Preserve the Title}'' % of such a section when you modify the Document means that it remains a % section ``Entitled XYZ'' according to this definition. % % The Document may include Warranty Disclaimers next to the notice which % states that this License applies to the Document. These Warranty % Disclaimers are considered to be included by reference in this % License, but only as regards disclaiming warranties: any other % implication that these Warranty Disclaimers may have is void and has % no effect on the meaning of this License. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 2. VERBATIM COPYING\par} % \end{center} % % You may copy and distribute the Document in any medium, either % commercially or noncommercially, provided that this License, the % copyright notices, and the license notice saying this License applies % to the Document are reproduced in all copies, and that you add no other % conditions whatsoever to those of this License. You may not use % technical measures to obstruct or control the reading or further % copying of the copies you make or distribute. However, you may accept % compensation in exchange for copies. If you distribute a large enough % number of copies you must also follow the conditions in section~3. % % You may also lend copies, under the same conditions stated above, and % you may publicly display copies. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 3. COPYING IN QUANTITY\par} % \end{center} % % % If you publish printed copies (or copies in media that commonly have % printed covers) of the Document, numbering more than 100, and the % Document's license notice requires Cover Texts, you must enclose the % copies in covers that carry, clearly and legibly, all these Cover % Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on % the back cover. Both covers must also clearly and legibly identify % you as the publisher of these copies. The front cover must present % the full title with all words of the title equally prominent and % visible. You may add other material on the covers in addition. % Copying with changes limited to the covers, as long as they preserve % the title of the Document and satisfy these conditions, can be treated % as verbatim copying in other respects. % % If the required texts for either cover are too voluminous to fit % legibly, you should put the first ones listed (as many as fit % reasonably) on the actual cover, and continue the rest onto adjacent % pages. % % If you publish or distribute Opaque copies of the Document numbering % more than 100, you must either include a machine-readable Transparent % copy along with each Opaque copy, or state in or with each Opaque copy % a computer-network location from which the general network-using % public has access to download using public-standard network protocols % a complete Transparent copy of the Document, free of added material. % If you use the latter option, you must take reasonably prudent steps, % when you begin distribution of Opaque copies in quantity, to ensure % that this Transparent copy will remain thus accessible at the stated % location until at least one year after the last time you distribute an % Opaque copy (directly or through your agents or retailers) of that % edition to the public. % % It is requested, but not required, that you contact the authors of the % Document well before redistributing any large number of copies, to give % them a chance to provide you with an updated version of the Document. % % \needspace{\baselineskip} % \begin{center} % {\large\bf 4. MODIFICATIONS\par} % \end{center} % % You may copy and distribute a Modified Version of the Document under % the conditions of sections 2 and 3 above, provided that you release % the Modified Version under precisely this License, with the Modified % Version filling the role of the Document, thus licensing distribution % and modification of the Modified Version to whoever possesses a copy % of it. In addition, you must do these things in the Modified Version: % % \begin{itemize} % \item[A.] % Use in the Title Page (and on the covers, if any) a title distinct % from that of the Document, and from those of previous versions % (which should, if there were any, be listed in the History section % of the Document). You may use the same title as a previous version % if the original publisher of that version gives permission. % % \item[B.] % List on the Title Page, as authors, one or more persons or entities % responsible for authorship of the modifications in the Modified % Version, together with at least five of the principal authors of the % Document (all of its principal authors, if it has fewer than five), % unless they release you from this requirement. % % \item[C.] % State on the Title page the name of the publisher of the % Modified Version, as the publisher. % % \item[D.] % Preserve all the copyright notices of the Document. % % \item[E.] % Add an appropriate copyright notice for your modifications % adjacent to the other copyright notices. % % \item[F.] % Include, immediately after the copyright notices, a license notice % giving the public permission to use the Modified Version under the % terms of this License, in the form shown in the Addendum below. % % \item[G.] % Preserve in that license notice the full lists of Invariant Sections % and required Cover Texts given in the Document's license notice. % % \item[H.] % Include an unaltered copy of this License. % % \item[I.] % Preserve the section Entitled ``History'', Preserve its Title, and add % to it an item stating at least the title, year, new authors, and % publisher of the Modified Version as given on the Title Page. If % there is no section Entitled ``History'' in the Document, create one % stating the title, year, authors, and publisher of the Document as % given on its Title Page, then add an item describing the Modified % Version as stated in the previous sentence. % % \item[J.] % Preserve the network location, if any, given in the Document for % public access to a Transparent copy of the Document, and likewise % the network locations given in the Document for previous versions % it was based on. These may be placed in the ``History'' section. % You may omit a network location for a work that was published at % least four years before the Document itself, or if the original % publisher of the version it refers to gives permission. % % \item[K.] % For any section Entitled ``Acknowledgements'' or ``Dedications'', % Preserve the Title of the section, and preserve in the section all % the substance and tone of each of the contributor acknowledgements % and/or dedications given therein. % % \item[L.] % Preserve all the Invariant Sections of the Document, % unaltered in their text and in their titles. Section numbers % or the equivalent are not considered part of the section titles. % % \item[M.] % Delete any section Entitled ``Endorsements''. Such a section % may not be included in the Modified Version. % % \item[N.] % Do not retitle any existing section to be Entitled ``Endorsements'' % or to conflict in title with any Invariant Section. % % \item[O.] % Preserve any Warranty Disclaimers. % \end{itemize} % % If the Modified Version includes new front-matter sections or % appendices that qualify as Secondary Sections and contain no material % copied from the Document, you may at your option designate some or all % of these sections as invariant. To do this, add their titles to the % list of Invariant Sections in the Modified Version's license notice. % These titles must be distinct from any other section titles. % % You may add a section Entitled ``Endorsements'', provided it contains % nothing but endorsements of your Modified Version by various % parties---for example, statements of peer review or that the text has % been approved by an organization as the authoritative definition of a % standard. % % You may add a passage of up to five words as a Front-Cover Text, and a % passage of up to 25 words as a Back-Cover Text, to the end of the list % of Cover Texts in the Modified Version. Only one passage of % Front-Cover Text and one of Back-Cover Text may be added by (or % through arrangements made by) any one entity. If the Document already % includes a cover text for the same cover, previously added by you or % by arrangement made by the same entity you are acting on behalf of, % you may not add another; but you may replace the old one, on explicit % permission from the previous publisher that added the old one. % % The author(s) and publisher(s) of the Document do not by this License % give permission to use their names for publicity for or to assert or % imply endorsement of any Modified Version. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 5. COMBINING DOCUMENTS\par} % \end{center} % % % You may combine the Document with other documents released under this % License, under the terms defined in section~4 above for modified % versions, provided that you include in the combination all of the % Invariant Sections of all of the original documents, unmodified, and % list them all as Invariant Sections of your combined work in its % license notice, and that you preserve all their Warranty Disclaimers. % % The combined work need only contain one copy of this License, and % multiple identical Invariant Sections may be replaced with a single % copy. If there are multiple Invariant Sections with the same name but % different contents, make the title of each such section unique by % adding at the end of it, in parentheses, the name of the original % author or publisher of that section if known, or else a unique number. % Make the same adjustment to the section titles in the list of % Invariant Sections in the license notice of the combined work. % % In the combination, you must combine any sections Entitled ``History'' % in the various original documents, forming one section Entitled % ``History''; likewise combine any sections Entitled ``Acknowledgements'', % and any sections Entitled ``Dedications''. You must delete all sections % Entitled ``Endorsements''. % % \needspace{\baselineskip} % \begin{center} % {\large\bf 6. COLLECTIONS OF DOCUMENTS\par} % \end{center} % % You may make a collection consisting of the Document and other documents % released under this License, and replace the individual copies of this % License in the various documents with a single copy that is included in % the collection, provided that you follow the rules of this License for % verbatim copying of each of the documents in all other respects. % % You may extract a single document from such a collection, and distribute % it individually under this License, provided you insert a copy of this % License into the extracted document, and follow this License in all % other respects regarding verbatim copying of that document. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 7. AGGREGATION WITH INDEPENDENT WORKS\par} % \end{center} % % % A compilation of the Document or its derivatives with other separate % and independent documents or works, in or on a volume of a storage or % distribution medium, is called an ``aggregate'' if the copyright % resulting from the compilation is not used to limit the legal rights % of the compilation's users beyond what the individual works permit. % When the Document is included in an aggregate, this License does not % apply to the other works in the aggregate which are not themselves % derivative works of the Document. % % If the Cover Text requirement of section~3 is applicable to these % copies of the Document, then if the Document is less than one half of % the entire aggregate, the Document's Cover Texts may be placed on % covers that bracket the Document within the aggregate, or the % electronic equivalent of covers if the Document is in electronic form. % Otherwise they must appear on printed covers that bracket the whole % aggregate. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 8. TRANSLATION\par} % \end{center} % % % Translation is considered a kind of modification, so you may % distribute translations of the Document under the terms of section~4. % Replacing Invariant Sections with translations requires special % permission from their copyright holders, but you may include % translations of some or all Invariant Sections in addition to the % original versions of these Invariant Sections. You may include a % translation of this License, and all the license notices in the % Document, and any Warranty Disclaimers, provided that you also include % the original English version of this License and the original versions % of those notices and disclaimers. In case of a disagreement between % the translation and the original version of this License or a notice % or disclaimer, the original version will prevail. % % If a section in the Document is Entitled ``Acknowledgements'', % ``Dedications'', or ``History'', the requirement (section~4) to Preserve % its Title (section~1) will typically require changing the actual % title. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 9. TERMINATION\par} % \end{center} % % % You may not copy, modify, sublicense, or distribute the Document % except as expressly provided under this License. Any attempt % otherwise to copy, modify, sublicense, or distribute it is void, and % will automatically terminate your rights under this License. % % However, if you cease all violation of this License, then your license % from a particular copyright holder is reinstated (a) provisionally, % unless and until the copyright holder explicitly and finally % terminates your license, and (b) permanently, if the copyright holder % fails to notify you of the violation by some reasonable means prior to % 60 days after the cessation. % % Moreover, your license from a particular copyright holder is % reinstated permanently if the copyright holder notifies you of the % violation by some reasonable means, this is the first time you have % received notice of violation of this License (for any work) from that % copyright holder, and you cure the violation prior to 30 days after % your receipt of the notice. % % Termination of your rights under this section does not terminate the % licenses of parties who have received copies or rights from you under % this License. If your rights have been terminated and not permanently % reinstated, receipt of a copy of some or all of the same material does % not give you any rights to use it. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 10. FUTURE REVISIONS OF THIS LICENSE\par} % \end{center} % % % The Free Software Foundation may publish new, revised versions % of the GNU Free Documentation License from time to time. Such new % versions will be similar in spirit to the present version, but may % differ in detail to address new problems or concerns. See % \url{https://www.gnu.org/licenses/}. % % Each version of the License is given a distinguishing version number. % If the Document specifies that a particular numbered version of this % License ``or any later version'' applies to it, you have the option of % following the terms and conditions either of that specified version or % of any later version that has been published (not as a draft) by the % Free Software Foundation. If the Document does not specify a version % number of this License, you may choose any version ever published (not % as a draft) by the Free Software Foundation. If the Document % specifies that a proxy can decide which future versions of this % License can be used, that proxy's public statement of acceptance of a % version permanently authorizes you to choose that version for the % Document. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf 11. RELICENSING\par} % \end{center} % % % ``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any % World Wide Web server that publishes copyrightable works and also % provides prominent facilities for anybody to edit those works. A % public wiki that anybody can edit is an example of such a server. A % ``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the % site means any set of copyrightable works thus published on the MMC % site. % % ``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 % license published by Creative Commons Corporation, a not-for-profit % corporation with a principal place of business in San Francisco, % California, as well as future copyleft versions of that license % published by that same organization. % % ``Incorporate'' means to publish or republish a Document, in whole or % in part, as part of another Document. % % An MMC is ``eligible for relicensing'' if it is licensed under this % License, and if all works that were first published under this License % somewhere other than this MMC, and subsequently incorporated in whole % or in part into the MMC, (1) had no cover texts or invariant sections, % and (2) were thus incorporated prior to November 1, 2008. % % The operator of an MMC Site may republish an MMC contained in the site % under CC-BY-SA on the same site at any time before August 1, 2009, % provided the MMC is eligible for relicensing. % % % \needspace{\baselineskip} % \begin{center} % {\large\bf ADDENDUM: How to use this License for your documents\par} % \end{center} % % To use this License in a document you have written, include a copy of % the License in the document and put the following copyright and % license notices just after the title page: % % \bigskip % \begin{quote} % Copyright \copyright{} YEAR YOUR NAME. % Permission is granted to copy, distribute and/or modify this document % under the terms of the GNU Free Documentation License, Version 1.3 % or any later version published by the Free Software Foundation; % with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. % A copy of the license is included in the section entitled ``GNU % Free Documentation License''. % \end{quote} % \bigskip % % If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, % replace the ``with \dots\ Texts.''\ line with this: % % \bigskip % \begin{quote} % with the Invariant Sections being LIST THEIR TITLES, with the % Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. % \end{quote} % \bigskip % % If you have Invariant Sections without Cover Texts, or some other % combination of the three, merge those two alternatives to suit the % situation. % % If your document contains nontrivial examples of program code, we % recommend releasing these examples in parallel under your choice of % free software license, such as the GNU General Public License, % to permit their use in free software. % % \section{Implementation} % % \iffalse %<*package> % \fi % % \package{ekdosis} relies on Lua functions and tables. Read the % |.lua| files that accompany \package{ekdosis} for more % information. % \begin{macrocode} \RequirePackage{iftex} % \end{macrocode} % \package{ekdosis} requires {\LuaLaTeX} of course. Issue an error % if the document is processed with another engine. % \begin{macrocode} \RequireLuaTeX % \end{macrocode} % Packages that are required by \package{ekdosis}: % \begin{macrocode} \RequirePackage{xkeyval} \newif\if@pkg@float \newif\if@pkg@footins \define@choicekey{ekdosis.sty}{layout}{float, footins}[float]{% \edef\layout@float{float} \edef\layout@footins{footins} \edef\@tempa{#1} \ifx\@tempa\layout@float\@pkg@floattrue\fi \ifx\@tempa\layout@footins\@pkg@floatfalse\@pkg@footinstrue\fi } \newif\if@pkg@ekddivs \define@choicekey+{ekdosis.sty}{divs}{ekdosis, latex}[ekdosis]{ \edef\divs@ekdosis{ekdosis} \edef\divs@latex{latex} \edef\@tempa{#1} \ifx\@tempa\divs@ekdosis\@pkg@ekddivstrue\fi \ifx\@tempa\divs@latex \@pkg@ekddivsfalse \AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}} \fi }{\PackageError{ekdosis}{divs option must be either 'ekdosis' or 'latex'}} \newif\if@parnotesroman \newif\if@pkg@parnotes \define@choicekey+{ekdosis.sty}{parnotes}{true, false, roman}[true]{% \edef\@pntrue{true}\edef\@pnfalse{false}\edef\@pnrm{roman} \edef\@tempa{#1} \ifx\@tempa\@pnfalse \else \ifx\@tempa\@pntrue\@pkg@parnotestrue \else \ifx\@tempa\@pnrm \@pkg@parnotestrue\@parnotesromantrue \fi\fi\fi }{\PackageWarning{ekdosis}{parnotes: erroneous input (ignored)}} \newif\iftei@export \define@choicekey{ekdosis.sty}{teiexport}{true, false, tidy}[true]{% \edef\@exptrue{true}\edef\@expfalse{false}\edef\@exptidy{tidy} \edef\@tempa{#1} \ifx\@tempa\@expfalse \else \ifx\@tempa\@exptrue \tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream()}} \else \ifx\@tempa\@exptidy \tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}} \else\fi\fi\fi} \ExecuteOptionsX{layout,divs} \ProcessOptionsX\relax \RequirePackage{luacode} \RequirePackage{paracol} \RequirePackage{expkv-def} \RequirePackage{xparse} \RequirePackage{etoolbox} \RequirePackage{lineno} \RequirePackage{keyfloat} \RequirePackage{refcount} \RequirePackage[user,abspage]{zref} \RequirePackage{ltxcmds} \if@pkg@parnotes \RequirePackage{parnotes} \fi % \end{macrocode} % Here begins the real work: load |ekdosis.lua|: % \begin{macrocode} \luadirect{dofile(kpse.find_file("ekdosis.lua"))} % \end{macrocode} % \begin{macrocode} \AtEndDocument{ \luadirect{ekdosis.closestream()} } % \end{macrocode} % General settings % \begin{macrocode} \renewcommand\linenumberfont{\normalfont\footnotesize} % \end{macrocode} % Hooks % \begin{macrocode} \ekvdefinekeys{ekd@hooks}{ store appfontsize = \ekd@appfontsize, store refnumstyle = \ekd@refnumstyle, store postrefnum = \ekd@postrefnum, initial appfontsize = \footnotesize, initial refnumstyle = \bfseries, initial postrefnum = ~ } \NewDocumentCommand{\SetEkdosisHooks}{m}{\ekvset{ekd@hooks}{#1}} % \end{macrocode} % Build and process the list of witnesses and hands. % \begin{macrocode} \ekvdefinekeys{ekd@witness}{ store settlement = \settlement@value, store repository = \repository@value, store idno = \idno@value, store msName = \msName@value, store origDate = \origDate@value } \NewDocumentCommand{\DeclareWitness}{m m m O{}}{% \bgroup \ekvset{ekd@witness}{#4} \luadirect{ekdosis.newwitness( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringO{\settlement@value}, \luastringO{\repository@value}, \luastringO{\idno@value}, \luastringO{\msName@value}, \luastringO{\origDate@value})} \egroup } \@onlypreamble\DeclareWitness \NewDocumentCommand{\DeclareHand}{m m m +O{}}{ \luadirect{ekdosis.newhand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } \@onlypreamble\DeclareHand \NewDocumentCommand{\DeclareScholar}{m m}{ \luadirect{ekdosis.newscholar(\luastringN{#1}, \luastringN{#2})} } \@onlypreamble\DeclareScholar \NewDocumentCommand{\DeclareShorthand}{m m m}{ \luadirect{ekdosis.newshorthand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \@onlypreamble\DeclareShorthand \NewDocumentCommand{\getsiglum}{m}{% \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% } \NewDocumentCommand{\SigLine}{m}{% \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} } % \end{macrocode} % Add a \hologo{(La)TeX} command to be processed as a |TEI xml| tag: % \begin{macrocode} \NewDocumentCommand{\TeXtoTEI}{m m O{}}{% \luadirect{ekdosis.newcmdtotag(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \NewDocumentCommand{\EnvtoTEI}{s m m O{}}{% \IfBooleanTF{#1}{% \luadirect{ekdosis.newenvtotag(\luastringN{#2}, \luastringN{#3}, \luastringN{#4}, "yes")} }{% \luadirect{ekdosis.newenvtotag(\luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } } \NewDocumentCommand{\TeXtoTEIPatt}{m m}{% \luadirect{ekdosis.newpatttotag(\luastringN{#1}, \luastringN{#2})} } % \end{macrocode} % Set |TEI| file name % \begin{macrocode} \NewDocumentCommand{\SetTEIFileName}{m}{ \luadirect{ekdosis.setteifilename(\luastringN{#1})} } \@onlypreamble\SetTEIFileName \NewDocumentCommand{\SetxmlBibResource}{m}{ \luadirect{ekdosis.setxmlbibresource(\luastringN{#1})} } \@onlypreamble\SetxmlBibResource % \end{macrocode} % Multi-layer apparatuses % \begin{macrocode} \newif\ifekd@mapps \ekvdefinekeys{ekd@newapp}{ choice direction = {LR = \def\direction@val{LR}, RL = \def\direction@val{RL}}, store rule = \rule@val, store delim = \delim@val, store sep = \sep@val, store bhook = \bhook@val, store ehook = \ehook@val, initial direction = LR, initial ehook = {\csname ekd@end@apparatus\endcsname} } \NewDocumentCommand{\DeclareApparatus}{m O{}}{ \newbool{subsq@unit@#1} \booltrue{subsq@unit@#1} \unless\ifekd@mapps\global\ekd@mappstrue\fi \bgroup \ekvset{ekd@newapp}{#2} \luadirect{ekdosis.newapparatus( \luastringN{#1}, \luastring{\direction@val}, \luastringO{\rule@val}, \luastringO{\delim@val}, \luastringO{\sep@val}, \luastringO{\bhook@val}, \luastringO{\ehook@val} )} \egroup } \@onlypreamble\DeclareApparatus % \end{macrocode} % \begin{macrocode} \newbool{do@app} \newif\ifekd@state \newif\ifekd@isinapp \newif\ifekd@isinlem \providebool{al@rlmode} \@ifpackageloaded{arabluatex}{}{% \def\setRL{\booltrue{al@rlmode}\pardir TRT\textdir TRT} \def\setLR{\boolfalse{al@rlmode}\pardir TLT \textdir TLT} } \protected\def\LRnum#1{\bgroup\textdir TLT#1\egroup} \newcounter{ekd@lab} \globalcounter{ekd@lab} \NewDocumentCommand{\unconditional@appin}{o m}{% \IfNoValueTF{#1} {\luadirect{ekdosis.appin(\luastringO{#2})}} {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% } % \def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext} \def\blfootnote{\gdef\@thefnmark{}\@blfootnotetext} \long\def\@blfootnotetext#1{\insert\footins{% \reset@font\footnotesize \interlinepenalty\interfootnotelinepenalty \splittopskip\footnotesep \splitmaxdepth \dp\strutbox \floatingpenalty \@MM \hsize\columnwidth \@parboxrestore \protected@edef\@currentlabel{% \csname p@footnote\endcsname\@thefnmark }% \color@begingroup \@makeblfntext{% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% \color@endgroup}}% \newcommand\@makeblfntext[1]{% \parindent 1em% \noindent \hb@xt@0em{\hss\@makefnmark}#1} \newif\ifrtl@app \NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue} \NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse} \edef\ekdsep{] } \NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}} \edef\ekd@end@apparatus{} \NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}} \def\ekd@unit@delim{} \NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}} \def\ekd@default@rule{\rule{2truein}{0.5pt}} \newif\iffootnoterule \let\dflt@footnoterule\footnoterule \let\dflt@pcol@footnoterule\pcol@footnoterule \renewcommand\footnoterule{% \iffootnoterule \dflt@footnoterule% \fi } \renewcommand\pcol@footnoterule{% \iffootnoterule \dflt@pcol@footnoterule% \fi } \newcommand*{\NLS}{% \par% \nobreak% \vspace{-\parskip}% \noindent% \ignorespaces} \NewDocumentCommand{\SetDefaultRule}{m}{% \def\@tempa{#1} \ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}% \else% \def\ekd@default@rule{#1}% \fi} \newif\ifsubsq@unit \subsq@unittrue \def\add@@apparatus{% \if@pkg@parnotes\parnotes\else\fi% \if@pkg@footins% \bgroup% \ifrtl@app\setRL\else\setLR\fi% \blfootnote{% \if@pkg@parnotes% \if@parnotesroman% \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% \parnoteclear\else\fi% \footnotesize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% \if@pkg@parnotes\parnotes\parnotereset\else\fi% }% \egroup% \fi% \if@pkg@float% \keyparbox[!b]{}{\ifrtl@app\setRL\else\setLR\fi% \if@pkg@parnotes% \if@parnotesroman% \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% \parnoteclear\else\fi% \ekd@appfontsize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% \if@pkg@parnotes\parnotes\parnotereset\else\fi% }% \fi% } \def\add@apparatus{% \test@apparatus% \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}% } \NewDocumentCommand{\append@app}{o +m}{% \ifekd@isinapp% \ifekd@state% \IfNoValueTF{#1}% {\luadirect{ekdosis.appin(\luastringO{#2})}}% {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% \fi% \fi} \NewDocumentCommand{\append@ln@app}{o +m}{% \IfNoValueTF{#1} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}, \luastringO{#1}))}}} \ekvdefinekeys{appnote}{ store type = \ekdan@type, initial type = default } \NewDocumentCommand{\EkdosisDefaultApparatus}{m}{% \ekvset{appnote}{type=#1}} \NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{% \begingroup \ekvset{appnote}{#1}% \ekd@isinapptrue% \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{ekdosis.storeabspg( \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% \ifekd@state\add@apparatus\fi% \luadirect{tex.sprint(ekdosis.removesp(\luastringN{#2}))}% \ekd@isinappfalse% \endgroup} \def\current@ref@arg#1#2{{%\textdir TLT% \unexpanded\expandafter{\ekd@refnumstyle}% \ifnum% \getpagerefnumber{#1} = \getpagerefnumber{#2} \ifnum% \getrefnumber{#1} = \getrefnumber{#2} % \ifekd@mapps% \ifbool{subsq@unit@\ekdan@type}{% \ifnum% \getrefnumber{#1} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} \else \LRnum{\getrefnumber{#1}}% issue the no \fi% }% {\LRnum{\getrefnumber{#1}}}% issue the no \else \ifsubsq@unit% % \ifnum% \getrefnumber{#1} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} \else \LRnum{\getrefnumber{#1}}% issue the no \fi % \else \LRnum{\getrefnumber{#1}}% issue the no \fi \fi % \else \LRnum{\getrefnumber{#1}}--% \LRnum{\getrefnumber{#2}}% issue the nos \fi% \else \LRnum{\getrefnumber{#1}}--% \LRnum{\getpagerefnumber{#2}}.% \LRnum{\getrefnumber{#2}}% issue pg and ln nos \fi% }\unexpanded\expandafter{\ekd@postrefnum}% }% \def\current@ref{{%\textdir TLT% \unexpanded\expandafter{\ekd@refnumstyle}% \ifnum% \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} % \ifekd@mapps% \ifbool{subsq@unit@\ekdan@type}{% \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi% }{\LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}}% issue the no \else \ifsubsq@unit% % \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi % \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi \fi % \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue the nos \fi% \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% \LRnum{\getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}.% \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue pg and ln nos \fi% }\unexpanded\expandafter{\ekd@postrefnum}% }% \define@cmdkeys[ekd]{lemrdg}[ekdlr@]{wit, alt, pre, post, prewit, postwit, type} \define@cmdkey[ekd]{lem}[ekdl@]{sep}{} \presetkeys[ekd]{lem}{sep=\ekdsep}{} \define@boolkeys[ekd]{lem}[ekdl@]{nolem, nosep}[true] \define@boolkeys[ekd]{rdg}[ekdr@]{nordg}[true] \NewDocumentCommand{\lem}{O{} m}{% \ekd@isinlemtrue% \luadirect{ekdosis.dolnlab(\luastringN{#2})}% \bgroup% \setkeys[ekd]{lemrdg,lem}{#1}% \ifekd@mapps% \ifnum% \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} = 1 \boolfalse{subsq@unit@\ekdan@type}% \fi% \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% \def\ekd@munit@delim{% \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% \fi% \ifekdl@nolem\edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref}%\hskip .25em}% \else% \ifbool{al@rlmode}{% \edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref%\hskip .25em \ifdefined\ekdlr@alt% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \else \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded{#2}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi }% }% {% \edef\lem@app{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref%\hskip .25em \ifdefined\ekdlr@alt% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdlr@alt}}% {\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \else \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifekdl@nosep\else\unexpanded\expandafter{\ekdl@sep}\fi }% }% \fi% \ifekd@mapps% \append@ln@app[\ekdan@type]{\lem@app}% \else% \append@ln@app{\lem@app}% \fi% \egroup% \ekd@isinlemfalse% \subsq@unittrue% } \NewDocumentCommand{\rdg}{O{} m}{% \bgroup% \setkeys[ekd]{lemrdg,rdg}{#1}% % \ifekdr@nordg\append@app{}\else% do we need \append@app{} here? If % % so, keep in mind \ifekd@mapps, % like so: \ifekdr@nordg% \ifekd@mapps% \append@app[\ekdan@type]{}% \else% \append@app{}% \fi% \else% \ifbool{al@rlmode}{% \edef\rdg@app{% \ifdefined\ekdlr@alt% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \else \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi {\textdir TRT\unexpanded{#2}}% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi }% }% {% \edef\rdg@app{% \ifdefined\ekdlr@alt% \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdlr@alt}}% {\unexpanded\expandafter{\ekdlr@alt}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \else \ifdefined\ekdlr@pre% \space\unexpanded\expandafter{\ekdlr@pre}\space\else\fi \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}% \ifdefined\ekdlr@post% \space\unexpanded\expandafter{\ekdlr@post}\space\else\fi \fi \ifdefined\ekdlr@prewit% \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi \ifdefined\ekdlr@postwit% \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi }% }% \ifekd@mapps% \append@app[\ekdan@type]{\rdg@app}% \else% \append@app{\rdg@app}% \fi% \fi% \egroup% } \ekvdefinekeys{note}{ store type = \ekdan@type, store lem = \ekdn@lem, code labelb = \def\ekdn@labelb{#1}, code labele = \def\ekdn@labele{#1}, store sep = \ekdn@sep, initial type = default, initial sep = \ekdsep } \NewDocumentCommand{\note@noapp}{O{} +m}{% \bgroup% \ekvset{note}{#1} \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{ekdosis.storeabspg( \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% \ifekd@state\add@apparatus\fi% \ifekd@mapps% \ifnum% \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} = 1 \boolfalse{subsq@unit@\ekdan@type}% \fi% \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% \def\ekd@munit@delim{% \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% \fi% \ifdefined\ekdn@labelb% \luadirect{tex.sprint(ekdosis.setnotelab(\luastringO{\ekdn@labelb}))}% \ifdefined\ekdn@labele\else\def\ekdn@labele{\ekdn@labelb}\fi% \else\PackageError{ekdosis}{missing labelb}{`labelb' must be set.}\fi% \ifbool{al@rlmode}% {\edef\note@contents{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em \ifdefined\ekdn@lem% {\textdir TRT\unexpanded\expandafter{\ekdn@lem}}% \unexpanded\expandafter{\ekdn@sep}\else\fi% {\textdir TRT\unexpanded{#2}}}}% {\edef\note@contents{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em \ifdefined\ekdn@lem \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdn@lem}}% {\unexpanded\expandafter{\ekdn@lem}}% \unexpanded\expandafter{\ekdn@sep}\else\fi% \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}}}% \ifekd@mapps% \unconditional@appin[\ekdan@type]{\note@contents}% \else% \unconditional@appin{\note@contents}% \fi% \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}% \egroup% \subsq@unittrue% } \ekvdefinekeys{ekd@note}{ store pre = \pre@value, store post = \post@value } \NewDocumentCommand{\ekd@note}{O{} m}{% \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unexpanded{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% } \NewDocumentCommand{\ekd@note@star}{O{} m}{% \if@pkg@parnotes \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unskip\noexpand\parnote{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% \else \append@app{\unskip\footnote{#2}}% \fi% } \NewDocumentCommand{\note@app}{s O{} +m}{% \ifbool{al@rlmode}{% \IfBooleanTF{#1}{\ekd@note@star[#2]{\unexpanded{% {\textdir TRT#3}}}} {\ekd@note[#2]{\unexpanded{{\textdir TRT#3}}}}% }{% \IfBooleanTF{#1}{\ekd@note@star[#2]{\unexpanded{#3}}} {\ekd@note[#2]{\unexpanded{#3}}}% }% } \NewDocumentCommand{\note}{s O{} +m}{% \ifekd@state% \ifekd@isinapp% \ifekd@isinlem% \note@noapp[#2]{#3}% \else% \IfBooleanTF{#1}{\note@app*[#2]{#3}}{\note@app[#2]{#3}}% \fi% \else% \note@noapp[#2]{#3}% \fi% \fi% } \NewDocumentCommand{\apparatus}{}{% \luadirect{tex.sprint(ekdosis.appout())}} \NewDocumentCommand{\test@apparatus}{}{% \luadirect{tex.sprint(ekdosis.testapparatus())}} \NewDocumentCommand{\ekd@storecol}{}{% \luadirect{ekdosis.storecurcol(\luastring{\thecolumn})}% } \NewDocumentCommand{\EkdosisOn}{}{% \ekd@statetrue} \NewDocumentCommand{\EkdosisOff}{}{% \ekd@statefalse% } \def\ekd@setlineno{% \let\setpagewiselinenumbers\relax% \let\pagewiselinenumbers\relax% \let\endpagewiselinenumbers\relax% \let\runningpagewiselinenumbers\relax% \let\realpagewiselinenumbers\relax% } \NewDocumentEnvironment{ekdosis}{+b}{% \ekd@setlineno% \runninglinenumbers \EkdosisOn#1}{% \EkdosisOff \endrunninglinenumbers% \iftei@export\luadirect{ekdosis.exporttei(\luastringN{\par #1\par })}\else\fi} % \end{macrocode} % Alignment:--- % \begin{macrocode} \ekvdefinekeys{ekd@align}{ store tcols = \tcols@num, store lcols = \lcols@num, store texts = \texts@value, store apparatus = \apparatus@value, bool paired = \ifekd@paired, bool pagelineation = \ifekd@pagelineation, choice segmentation = {auto = \def\segmentation@val{auto}, noauto = \def\segmentation@val{noauto}}, bool flush = \ifekd@flushapp, initial tcols = 2, initial lcols = 1, initial texts = edition;translation, initial apparatus = edition, default segmentation = auto } \NewDocumentCommand{\SetEkdosisAlignment}{m}{ \ekvset{ekd@align}{#1} } \patchcmd{\pcol@nextpage}{% \endgroup}{% \ifekd@pagelineation\resetlinenumber\fi \endgroup}{}{} \NewDocumentCommand{\EkdosisColStart}{}{% \ekd@setlineno% \runninglinenumbers \ekd@storecol% \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{% ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, "pg_i")}% \ifekd@pagelineation \luadirect{tex.sprint(ekdosis.checkresetlineno())} \fi } \NewDocumentCommand{\EkdosisColStop}{}{% \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{% ekdosis.storeabspg(\luastring{\zref@extract{ekd:\theekd@lab}{abspage}}, "pg_ii")}% \endrunninglinenumbers% } \NewDocumentEnvironment{alignment}{O{}} {% \ekvset{ekd@align}{#1}% \luadirect{ekdosis.mkenvdata( \luastring{\texts@value}, "texts" )} \ifekd@flushapp \luadirect{ekdosis.newalignment("set")} \fi \luadirect{ekdosis.mkenvdata( \luastring{\apparatus@value}, "apparatus" )} \setrunninglinenumbers \luadirect{tex.sprint(ekdosis.mkenv())} \ifekd@paired \begin{paracol}[\lcols@num]{\tcols@num} \else \begin{paracol}[\lcols@num]*{\tcols@num} \fi } {\end{paracol} \iftei@export\luadirect{ekdosis.export_coldata_totei()}\fi \ifekd@flushapp \luadirect{ekdosis.newalignment("reset")} \fi \luadirect{ekdosis.flushenvdata()} \luadirect{ekdosis.flushcolnums()} } % \end{macrocode} % Divisions of the Body % \begin{macrocode} \NewDocumentCommand{\MkBodyDivs}{mmmmmm}{ \luadirect{ekdosis.mkdivdepths( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4}, \luastringN{#5}, \luastringN{#6} ) } } % \end{macrocode} % Divisions specific to ekdosis:--- % \begin{macrocode} \ekvdefinekeys{ekd@div}{ code type = \def\type@value{#1}, code n = \def\n@value{#1}, code head = \def\head@value{#1}, code barehead = \def\barehead@value{#1}, store depth = \depth@value, choice toc = {book = \def\toc@value{book}, part = \def\toc@value{part}, chapter = \def\toc@value{chapter}, section = \def\toc@value{section}, subsection = \def\toc@value{subsection}, subsubsection = \def\toc@value{subsubsection}, paragraph = \def\toc@value{paragraph}, subparagraph = \def\toc@value{subparagraph}}, initial depth = 1 } \NewDocumentCommand{\ekdfmtdiv}{m m m}{ \luadirect{ekdosis.fmtdiv(\luastring{#1}, \luastringN{#2}, \luastringN{#3})} } \NewDocumentCommand{\ekd@getfmtdiv}{m m}{% \luadirect{tex.sprint(ekdosis.getfmtdiv(\luastringO{#1}, \luastringN{#2}))}% } \NewDocumentCommand{\ekddiv}{m}{ \begingroup \ekvset{ekd@div}{#1}% \ifdefined\head@value \bgroup \ekd@getfmtdiv{\depth@value}{b}% \head@value \ekd@getfmtdiv{\depth@value}{e}% \egroup \ifdefined\toc@value \ltx@ifpackageloaded{hyperref}{\phantomsection}{}% \ifdefined\barehead@value \addcontentsline{toc}{\toc@value}{\barehead@value}% \else \addcontentsline{toc}{\toc@value}{\head@value}% \fi \fi \fi \endgroup } % \end{macrocode} % Very basic implementation of poetry lines:--- % \begin{macrocode} \newlength{\ekdverseindentlength} \setlength{\ekdverseindentlength}{\parindent} \newenvironment*{ekdverse}[1][\ekdverseindentlength]{ \begin{list}{}{% \setlength{\leftmargin}{#1} \setlength{\itemsep}{0pt} \setlength{\topsep}{0pt} \setlength{\partopsep}{0pt} } \item[] }{\end{list}} % \end{macrocode} % % \iffalse % % \fi % % \Finale % \iffalse %<*lua> % \fi % \begin{ekdlua} -- `' -- This table will hold the functions: ekdosis = {} -- lpeg equivalent for string.gsub() local function gsub(s, patt, repl) patt = lpeg.P(patt) patt = lpeg.Cs((patt / repl + 1)^0) return lpeg.match(patt, s) end -- some basic patterns: local letters = lpeg.R("az", "AZ") local ascii = lpeg.R("az", "AZ", "@@") local dblbkslash = lpeg.Cs("\\") local bsqbrackets = lpeg.Cs{ "[" * ((1 - lpeg.S"[]") + lpeg.V(1))^0 * "]" } local bcbraces = lpeg.Cs{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" } local spce = lpeg.Cs(" ") local spcenc = lpeg.P(" ") local cmdstar = lpeg.Cs(spce * lpeg.P("*")) local bsqbracketsii = lpeg.Cs(bsqbrackets^-2) local bcbracesii = lpeg.Cs(bcbraces^-2) local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1) local rawcmd = lpeg.Cs(dblbkslash * ascii^1) local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) local app = lpeg.Cs("app") local lemrdg = lpeg.Cs(lpeg.Cs("lem") + lpeg.Cs("rdg")) local note = lpeg.Cs("note") local lnbrk = lpeg.Cs("\\\\") local poemline = lpeg.Cs(lnbrk * bsqbrackets^-1) local endpoem = lpeg.Cs(lnbrk * lpeg.S("*!") * bsqbrackets^-1) local sections = lpeg.Cs(lpeg.P("book") + lpeg.P("part") + lpeg.P("chapter") + lpeg.P("section") + lpeg.P("subsection") + lpeg.P("subsubsection")) local par = lpeg.P(lpeg.P("\\par") * spce^1) local parb = lpeg.P(lpeg.Cs("\\p@rb") * spce^1) local para = lpeg.P(lpeg.Cs("\\p@ra") * spce^1) -- Bind to local variables local next = next -- General xmlids = {} local function xmlidfound(element) for i = 1,#xmlids do if xmlids[i].xmlid == element then return true end end return false end -- Witnesses listWit = {} idsRend = {} shorthands = {} local function isfound(table, value) for i = 1,#table do if table[i] == value then return true end end return false end local function isintable(table, value) for i = 1,#table do if table[i].a == value then return true end end return false end local function get_a_index(id, table) local idfound = nil for i = 1,#table do if table[i].a == id then idfound = i break end end return idfound end local function getindex(id, table) local idfound = nil for i = 1,#table do if table[i].xmlid == id then idfound = i break end end return idfound end function ekdosis.newwitness(id, siglum, description, Settlement, Repository, Idno, MsName, OrigDate) if xmlidfound(id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(listWit, {xmlid = id, abbr = siglum, detailsDesc = description, msIdentifier = { settlement = Settlement, repository = Repository, idno = Idno, msName = MsName} }) local indexwit = getindex(id, listWit) if OrigDate ~= "" then listWit[indexwit].history = {} listWit[indexwit].history.origin = {origDate = OrigDate} end end return true end function ekdosis.newhand(id, witid, siglum, description) if xmlidfound(id) or not xmlidfound(witid) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) local indexwit = getindex(witid, listWit) -- listWit[indexwit].handDesc = {xmlid = id, abbr = siglum, handNote = description} if listWit[indexwit].handDesc == nil then listWit[indexwit].handDesc = {} else end table.insert(listWit[indexwit].handDesc, {xmlid = id, abbr = siglum, detailsDesc = description}) end return true end function ekdosis.newshorthand(id, rend, xmlids) if isintable(shorthands, id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a shorthand. " .. "Please pick another shorthand.}}") else table.insert(shorthands, { a = id, b = rend, c = xmlids }) table.sort(shorthands, function(a ,b) return(#a.a > #b.a) end) table.insert(idsRend, {xmlid = id, abbr = rend}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) end return true end local xmlbibresource = nil function ekdosis.setxmlbibresource(str) xmlbibresource = str..".xml" return true end function ekdosis.newscholar(id, siglum) if xmlidfound(id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) end return true end function ekdosis.getsiglum(str, opt) str = str.."," str = string.gsub(str, "%s-(%,)", "%1") ctrl = str if opt == "tei" then for i = 1,#shorthands do str = string.gsub(str, shorthands[i].a, shorthands[i].c) end for i = 1,#idsRend do str = string.gsub(str, "(%f[%w])"..idsRend[i].xmlid.."(%,)", "%1#"..idsRend[i].xmlid.."%2") ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") end str = string.gsub(str, "%,(%s-)([%#])", " %2") str = string.gsub(str, "%,$", "") else for i = 1,#idsRend do str = string.gsub(str, idsRend[i].xmlid.."%,", idsRend[i].abbr) ctrl = string.gsub(ctrl, idsRend[i].xmlid.."%,", "") end end -- if string.find(ctrl, "[A-Za-z0-9]") if string.find(ctrl, "%S") then return "" else return str end end -- begin totei functions local cmdtotags = { {a="textsuperscript", b="hi", c=" rend=\"sup\""}, {a="textsubscript", b="hi", c=" rend=\"sub\""}, {a="LRfootnote", b="note", c=" place=\"bottom\""}, {a="RLfootnote", b="note", c=" place=\"bottom\""}, {a="footnote", b="note", c=" place=\"bottom\""}, {a="txtrans", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, {a="textbf", b="hi", c=" rend=\"bold\""}, {a="textit", b="hi", c=" rend=\"italic\""}, {a="textsc", b="hi", c=" rend=\"smallcaps\""}, {a="textsf", b="hi", c=" rend=\"sf\""}, {a="arbup", b="hi", c=" rend=\"sup\""}, {a="txarb", b="s", c=" xml:lang=\"arb\""}, {a="arb", b="s", c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} } local texpatttotags = { {a="\\icite%s?%[(.-)%]%[(.-)%]{(.-)}", b="%1 %2"}, {a="\\icite%s?%[(.-)%]{(.-)}", b="%1"}, {a="\\icite%s?{(.-)}", b=""} } local envtotags = { {a="ekdverse", b="lg", c=""}, {a="txarabtr", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\""}, {a="txarab", b="p", c=" xml:lang=\"arb\""}, {a="center", b="p", c=" rend=\"centered\""}, {a="verse", b="lg", c=""}, {a="arab", b="p", c=" xml:lang=\"ar-Latn\" type=\"transliterated\" subtype=\"arabtex\""} } local close_p = { "p", "lg" } local forbid_xmlid = true function ekdosis.newcmdtotag(cmd, tag, attr) if forbid_xmlid then attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here else end if isintable(cmdtotags, cmd) then local index = get_a_index(cmd, cmdtotags) table.remove(cmdtotags, index) table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) else table.insert(cmdtotags, {a = cmd, b = tag, c = " "..attr}) table.sort(cmdtotags, function(a ,b) return(#a.a > #b.a) end) end return true end function ekdosis.newpatttotag(pat, repl) pat = string.gsub(pat, "([%[%]])", "%%%1") pat = string.gsub(pat, "%#[1-9]", "(.-)") repl = string.gsub(repl, "%#([1-9])", "%%%1") table.insert(texpatttotags, { a = pat, b = repl }) table.sort(texpatttotags, function(a ,b) return(#a.a > #b.a) end) return true end function ekdosis.newenvtotag(env, tag, attr, closep) if forbid_xmlid then attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here else end if isintable(envtotags, env) then local index = get_a_index(env, envtotags) table.remove(envtotags, index) table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) else table.insert(envtotags, {a = env, b = tag, c = " "..attr, d = closep}) table.sort(envtotags, function(a ,b) return(#a.a > #b.a) end) end return true end -- Get values of attributes local function get_attr_value(str, attr) str = str.."," local attrval = string.match(str, "%f[%w]"..attr.."%s?%=%s?%b{}") or string.match(str, "%f[%w]"..attr.."%s?%=%s?.-%,") or "" attrval = string.gsub(attrval, attr.."%s?%=%s?(%b{})", function(bbraces) bbraces = string.sub(bbraces, 2, -2) return string.format("%s", bbraces) end) attrval = string.gsub(attrval, attr.."%s?%=%s?(.-)%s?%,", "%1") return attrval end local function xml_entities(str) str = string.gsub(str, "%<", "<") str = string.gsub(str, "%>", ">") return str end local function note_totei(str) str = gsub(str, dblbkslash * note * spcenc^-1 * bsqbrackets * bcbraces * spcenc^-1, function(bkslash, cmd, opt, arg) opt = string.sub(opt, 2, -2) arg = string.sub(arg, 2, -2) teitype = get_attr_value(opt, "type") if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end right = get_attr_value(opt, "labelb") left = get_attr_value(opt, "labele") if left ~= "" then return string.format( "<%s%s target=\"#range(right(%s),left(%s))\">%s", cmd, teitype, right, left, arg, cmd, right) elseif left == "" then return string.format( "<%s%s target=\"#right(%s)\">%s", cmd, teitype, right, arg, cmd, right) end end) return str end local function app_totei(str) str = gsub(str, dblbkslash * app * spcenc^-1 * bsqbrackets * bcbraces * spcenc^-1, function(bkslash, cmd, opt, arg) opt = string.sub(opt, 2, -2) arg = string.sub(arg, 2, -2) opt = get_attr_value(opt, "type") if opt ~= "" then opt = " type=\""..opt.."\"" else end return app_totei(string.format("<%s%s>%s", cmd, opt, arg, cmd)) end) return str end local function lem_rdg_totei(str) str = gsub(str, spcenc^-1 * dblbkslash * lemrdg * spcenc^-1 * bsqbrackets * bcbraces * spcenc^-1, function(bkslash, cmd, opt, arg) opt = string.sub(opt, 2, -2) arg = string.sub(arg, 2, -2) -- opt = get_attr_value(opt, "wit") -- teiwit = get_attr_value(opt, "wit") if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end teitype = get_attr_value(opt, "type") if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end -- if opt == "" then return lem_rdg_totei(string.format("<%s>%s", cmd, arg, cmd)) else -- opt = ekdosis.getsiglum(opt, "tei") return lem_rdg_totei(string.format("<%s%s%s>%s", cmd, teiwit, teitype, arg, cmd)) end end) str = gsub(str, spcenc^-0 * dblbkslash * lemrdg * spcenc^-1 * bcbraces * spcenc^-1, function(bkslash, cmd, arg) arg = string.sub(arg, 2, -2) return lem_rdg_totei(string.format("<%s>%s", cmd, arg, cmd)) end) return str end local function relocate_notes(str) str = string.gsub(str, "(%.-)(%.-%<%/note%>)(.-%<%/lem%>)", "%1%3%2") return str end local function linestotei(str) -- str = "\n"..str str = string.gsub(str, "^%s?(.-)%s?$", "\n%1\n") -- str = gsub(str, endpoem, "\n") str = gsub(str, poemline * spcenc^-1 * lpeg.P(">"), "\n") str = gsub(str, poemline * spcenc^-1, "\n") -- str = str.."\n" return str end -- better use lpeg: look into this later local function versetotei(str) str = string.gsub(str, "(\\begin%s?%{ekdverse%})(%b[])(.-)(\\end%s?%{ekdverse%})", function(benv, opt, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s%s", benv, opt, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{ekdverse%})(.-)(\\end%s?%{ekdverse%})", function(benv, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s", benv, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{verse%})(%b[])(.-)(\\end%s?%{verse%})", function(benv, opt, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s%s", benv, opt, arg, eenv) end) str = string.gsub(str, "(\\begin%s?%{verse%})(.-)(\\end%s?%{verse%})", function(benv, arg, eenv) arg = linestotei(arg) return string.format("%s%s%s", benv, arg, eenv) end) return str end local function envtotei(str) for i = 1,#envtotags do if envtotags[i].b ~= "" then if isfound(close_p, envtotags[i].b) or envtotags[i].d == "yes" then str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}") * bsqbracketsii * bcbracesii * spcenc^-1, "\\p@rb <"..envtotags[i].b..envtotags[i].c..">") str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), "\\p@ra ") else str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}") * bsqbracketsii * bcbracesii * spcenc^-1, "<"..envtotags[i].b..envtotags[i].c..">") str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), "") end else str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}") * bsqbracketsii * bcbracesii * spcenc^-1, "") str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(envtotags[i].a) * lpeg.P("}"), "") end end str = gsub(str, lpeg.P("\\begin") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii * bcbracesii * spcenc^-1, "<%1>") str = gsub(str, spcenc^-1 * lpeg.P("\\end") * spcenc^-1 * lpeg.P("{") * lpeg.Cs(ascii^1) * lpeg.P("}") * bsqbracketsii * bcbracesii, "") return str end local function texpatttotei(str) for i = 1,#texpatttotags do str = string.gsub(str, texpatttotags[i].a, texpatttotags[i].b) end return str end local function cmdtotei(str) for i = 1,#cmdtotags do str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * bsqbrackets * -bcbraces, "\\%1%2{}") str = gsub(str, lpeg.P("\\") * lpeg.Cs(cmdtotags[i].a) * spcenc^-1 * -(bsqbrackets + bcbraces), "\\%1[]{}") str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b{})", "%1[]%2") str = string.gsub(str, "(\\"..cmdtotags[i].a..")%s?%*?(%b[])(%b{})", function(cmd, arg, body) body = string.sub(body, 2, -2) arg = string.sub(arg, 2, -2) arg = string.gsub(arg, "(%b{})", function(braces) braces = string.sub(braces, 2, -2) return string.format("\"%s\"", braces) end) body = cmdtotei(body) -- return string.format("<"..cmdtotags[i].b..cmdtotags[i].c.." %s>%s", arg, body) if cmdtotags[i].b ~= "" then return string.format("<"..cmdtotags[i].b..cmdtotags[i].c..">%s", body) else return "" end end) end -- temporarily: str = string.gsub(str, "\\(linelabel)%s?(%b{})", function(cmd, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("", body) end) str = string.gsub(str, "\\(%a+)%s?%*?(%b[])(%b{})", function(cmd, opt, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("<%s>%s", cmd, body, cmd) end) str = string.gsub(str, "\\(%a+)%s?%*?(%b{})", function(cmd, body) body = string.sub(body, 2, -2) body = cmdtotei(body) return string.format("<%s>%s", cmd, body, cmd) end) str = string.gsub(str, "(%s)(%>)", "%2") return str end local function partotei(str) str = gsub(str, lpeg.P(lpeg.P("\\par") * spcenc^1)^1, "\\par ") str = gsub(str, ((para + parb) * par^-1)^2, "\\p@r ") str = string.gsub(str, "\\p@ra%s+", "

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

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

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

") str = string.gsub(str, "

%s?

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

)%s?()", "%2%1") return str end local function self_close_tags(str) str = gsub(str, lpeg.P("<" * -lpeg.S("/")) * lpeg.Cs(letters^1) * lpeg.Cs((1 - lpeg.S"<>")^0) * lpeg.P(">") * lpeg.P(""), function(ftag, arg, ltag) if ftag == ltag then return string.format("<%s%s/>", ftag, arg) else end end) return str end local divdepth = { book = 1, part = 2, chapter = 3, section = 4, subsection = 5, subsubsection = 6 } function ekdosis.mkdivdepths(...) divdepth = {} local num = 1 for _, y in ipairs{...} do if y == "book" or "part" or "chapter" or "section" or "subsection" or "subsubsection" then divdepth[y] = num num = num + 1 else end end return true end -- LaTeX side: format the divisions local fmtdiv = {} function ekdosis.fmtdiv(n, fmtb, fmte) if isintable(fmtdiv, n) then local index = get_a_index(n, fmtdiv) table.remove(fmtdiv, index) else end table.insert(fmtdiv, { a = n, formatb = fmtb, formate = fmte} ) return true end function ekdosis.getfmtdiv(n, pos) local index = get_a_index(n, fmtdiv) if index ~= nil then if pos == "b" then return fmtdiv[index].formatb elseif pos == "e" then return fmtdiv[index].formate end else return "" end end local ekddivs = true function ekdosis.setekddivsfalse() ekddivs = false end local function ekddivs_totei(str) str = gsub(str, dblbkslash * lpeg.Cs("ekddiv") * spce^-1 * bcbraces, function(bkslash, cmd, space, arg) if ekddivs then arg = string.sub(arg, 2, -2) teitype = get_attr_value(arg, "type") tein = get_attr_value(arg, "n") teihead = get_attr_value(arg, "head") teidepth = get_attr_value(arg, "depth") if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end if tein ~= "" then tein = " n=\""..tein.."\"" else end if teidepth ~= "" then teidepth = " depth=\""..teidepth.."\"" else teidepth = " depth=\"1\"" end return string.format("\\p@rb %s\\p@ra ", teitype, tein, teidepth, teihead) else return "" end end) return str end local function section_totei(str) str = gsub(str, dblbkslash * sections * spce^-1 * bcbraces, "%1%2%3[]%4") str = gsub(str, dblbkslash * sections * spce^-1 * bsqbrackets * bcbraces, function(bkslash, secname, space, opt, arg) if ekddivs then return "" else ctr = divdepth[secname] arg = string.sub(arg, 2, -2) return string.format("\\p@rb %s\\p@ra ", ctr, secname, arg) end end) return str end local used_ndivs = {} local function close_ekddivs_at_end(str) local isdiv = false if string.find(str, "$") then isdiv = true str = string.gsub(str, "(.*)()$", "%1") else end -- collect used depth numbers for i in string.gmatch(str, "

") do i = string.match(i, "depth=\"%d\"") i = string.match(i, "%d") if isintable(used_ndivs, i) then else table.insert(used_ndivs, {a = i} ) end end if next(used_ndivs) ~= nil then table.sort(used_ndivs, function(a ,b) return(#a.a > #b.a) end) else end local firstdiv = string.match(str, "
") or "" firstdiv = string.match(firstdiv, "depth%=\"%d\"") or "" firstdiv = string.match(firstdiv, "%d") or "" local lastdiv = string.match(string.reverse(str), ">.-\"%d\"%=htped.- vid<") or "" lastdiv = string.match(lastdiv, "\"%d\"%=htped") or "" lastdiv = string.match(lastdiv, "%d") or "" local firstdivindex = get_a_index(firstdiv, used_ndivs) local lastdivindex = get_a_index(lastdiv, used_ndivs) firstdivindex = tonumber(firstdivindex) lastdivindex = tonumber(lastdivindex) local closedivs = "" if isintable(used_ndivs, firstdiv) then while lastdivindex >= firstdivindex do closedivs = closedivs.."
" lastdivindex = lastdivindex - 1 end end if isdiv then return str..closedivs.."
" else return str..closedivs end end local function close_ndivs_at_end(str) local isdiv = false if string.find(str, "$") then isdiv = true str = string.gsub(str, "(.*)()$", "%1") else end -- collect used div numbers for i in string.gmatch(str, " #b.a) end) else end local firstdiv = string.match(str, "= firstdivindex do closedivs = closedivs.."" lastdivindex = lastdivindex - 1 end end if isdiv then return str..closedivs.."" else return str..closedivs end end local function close_ekddivs_in_between(str) local maxdepth = 1 for i in string.gmatch(str, "", "%1") do if tonumber(i) > tonumber(maxdepth) then maxdepth = i else end end for ndivi = 1, maxdepth do str = string.gsub(str, "(
)(.-)(
)", function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) local firstdiv = ndivi local lastdiv = ndivii local firstdivindex = get_a_index(firstdiv, used_ndivs) local lastdivindex = get_a_index(lastdiv, used_ndivs) firstdivindex = tonumber(firstdivindex) lastdivindex = tonumber(lastdivindex) local closedivs = "" if firstdivindex >= lastdivindex then while firstdivindex >= lastdivindex do closedivs = closedivs.."
" firstdivindex = firstdivindex - 1 end end return string.format("%s%s%s%s%s%s%s%s", bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) end) end str = string.gsub(str, "()", "%1%3") used_ndivs = {} return str end local function close_ndivs_in_between(str) for ndivi = 1, 6 do str = string.gsub(str, "()(.-)()", function(bdivi, ndivi, edivi, between, bdivii, ndivii, edivii) local firstdiv = ndivi local lastdiv = ndivii local firstdivindex = get_a_index(firstdiv, used_ndivs) local lastdivindex = get_a_index(lastdiv, used_ndivs) firstdivindex = tonumber(firstdivindex) lastdivindex = tonumber(lastdivindex) local closedivs = "" if firstdivindex >= lastdivindex then while firstdivindex >= lastdivindex do closedivs = closedivs.."" firstdivindex = firstdivindex - 1 end end return string.format("%s%s%s%s%s%s%s%s", bdivi, ndivi, edivi, between, closedivs, bdivii, ndivii, edivii) end) end used_ndivs = {} return str end local function textotei(str) str = xml_entities(str) str = texpatttotei(str) str = note_totei(str) str = app_totei(str) str = lem_rdg_totei(str) str = relocate_notes(str) str = versetotei(str) str = envtotei(str) str = ekddivs_totei(str) str = section_totei(str) str = cmdtotei(str) str = self_close_tags(str) str = partotei(str) if ekddivs then str = close_ekddivs_at_end(str) str = close_ekddivs_in_between(str) else str = close_ndivs_at_end(str) str = close_ndivs_in_between(str) end return str end local teifilename = tex.jobname.."-tei" function ekdosis.setteifilename(str) teifilename = str return true end function ekdosis.openteistream() local f = io.open(teifilename.."_tmp.xml", "a+") f:write('', "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("<!-- Title -->", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") f:write("", "\n") for i = 1,#listWit do f:write('", "\n") f:write('', textotei(listWit[i].abbr), "", "\n") f:write(textotei(listWit[i].detailsDesc), "\n") f:write("", "\n") if listWit[i].msIdentifier.settlement == "" and listWit[i].msIdentifier.repository == "" and listWit[i].msIdentifier.idno == "" and listWit[i].msIdentifier.msName == "" then f:write("", "\n") else f:write("", "\n") if listWit[i].msIdentifier.settlement ~= "" then f:write("", textotei(listWit[i].msIdentifier.settlement), "", "\n") else end if listWit[i].msIdentifier.repository ~= "" then f:write("", textotei(listWit[i].msIdentifier.repository), "", "\n") else end if listWit[i].msIdentifier.idno ~= "" then f:write("", textotei(listWit[i].msIdentifier.idno), "", "\n") else end if listWit[i].msIdentifier.msName ~= "" then f:write("", textotei(listWit[i].msIdentifier.msName), "", "\n") else end f:write("", "\n") end if listWit[i].handDesc ~= nil then f:write("", "\n") f:write("", "\n") local j = 1 while listWit[i].handDesc[j] do f:write("", "\n") f:write('', textotei(listWit[i].handDesc[j].abbr), "", "\n") f:write("

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

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

") str = textotei(str) f:write(str) f:close() return true end -- end totei functions -- begin basic TeX Conspectus siglorum function ekdosis.basic_cs(msid) local indexwit = getindex(msid, listWit) siglum = listWit[indexwit].abbr -- if listWit[indexwit].detailsDesc == "" -- then -- name = listWit[indexwit].msIdentifier.msName -- else -- name = listWit[indexwit].msIdentifier.msName -- .."\\thinspace\\newline\\bgroup\\footnotesize{}".. -- listWit[indexwit].detailsDesc -- .."\\egroup{}" -- end name = listWit[indexwit].detailsDesc if listWit[indexwit].history ~= nil and listWit[indexwit].history.origin ~= nil then date = listWit[indexwit].history.origin.origDate else date = "" end return siglum.."&"..name.."&"..date end -- end basic TeX Conspectus siglorum function ekdosis.removesp(str) str = gsub(str, cmd * cmdargs * spcenc^-1, "%1%2") return str end function ekdosis.closestream() os.remove(tex.jobname..".ekd") os.rename(tex.jobname.."_tmp.ekd", tex.jobname..".ekd") return true end local cur_abs_pg = 0 local pg_i = nil local pg_ii = nil local prevcol = nil local curcol = "x" local check_resetlineno = {} function ekdosis.update_abspg(n) -- not used cur_abs_pg = n return true end function ekdosis.storeabspg(n, pg) if pg == "pg_i" then pg_i = n elseif pg == "pg_ii" then pg_ii = n table.insert(check_resetlineno, curcol.."-"..pg_ii) end cur_abs_pg = n return true end function ekdosis.checkresetlineno() if isfound(check_resetlineno, curcol.."-"..pg_i) then return "" else return "\\resetlinenumber" end end -- -- Build environments to be aligned -- local cur_alignment = "-" local cur_alignment_patt = "%-" local cur_alignment_cnt = 1 local newalignment = false function ekdosis.newalignment(str) if str == "set" then newalignment = true cur_alignment = "-"..cur_alignment_cnt.."-" cur_alignment_patt = "%-"..cur_alignment_cnt.."%-" cur_alignment_cnt = cur_alignment_cnt + 1 elseif str == "reset" then newalignment = false cur_alignment = "-" cur_alignment_patt = "-" end return true end local aligned_texts = {} local texts_w_apparatus = {} local coldata_totei = {} local function sanitize_envdata(str) -- look for a better way to achieve this str = string.gsub(str, "(%a+)%s+(%b[])", "%1%2") str = string.gsub(str, "(%a+)(%b[])%s+", "%1%2") str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") str = gsub(str, lpeg.Cs(letters^1) * spcenc^-1 * -bsqbrackets * lpeg.Cs(";"), "%1[]%2") str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") return str end function ekdosis.mkenvdata(str, opt) if not string.find(str, "%;", -1) then str = str .. ";" else end -- str = str ..";" -- str = string.gsub(str, "%s+", "") local fieldstart = 1 local col = 0 if opt == "texts" then str = sanitize_envdata(str) repeat local _s, nexti = string.find(str, "%b[]%s-%;", fieldstart) local namediv = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%1") local attr = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%2") attr = string.sub(attr, 2, -2) if forbid_xmlid then attr = string.gsub(attr, "xml:id", "n") -- xml:id is not allowed here else end table.insert(aligned_texts, { text = namediv, attribute = attr, column = col }) table.insert(coldata_totei, { environment = namediv, data = {} }) col = col + 1 fieldstart = nexti + 1 until fieldstart > string.len(str) return aligned_texts elseif opt == "apparatus" then repeat local nexti = string.find(str, "%;", fieldstart) table.insert(texts_w_apparatus, string.sub(str, fieldstart, nexti-1)) fieldstart = nexti +1 until fieldstart > string.len(str) return texts_w_apparatus end end -- Reminder: the following two variables are already set above -- local prevcol = nil -- local curcol = "x" function ekdosis.storecurcol(n) curcol = n return true end function ekdosis.flushcolnums() prevcol = nil curcol = "x" return true end function ekdosis.flushenvdata() aligned_texts = {} texts_w_apparatus = {} coldata_totei = {} return true end function ekdosis.storecoldata(nthcol, chunk) local tindex = tonumber(nthcol) + 1 table.insert(coldata_totei[tindex].data, chunk) return true end local environment_div = {} function ekdosis.newscholar(id, siglum) if xmlidfound(id) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..id.. "\" already exists as a xml:id. " .. "Please pick another id.}}") else table.insert(xmlids, {xmlid = id}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) table.insert(idsRend, {xmlid = id, abbr = siglum}) table.sort(idsRend, function(a ,b) return(#a.xmlid > #b.xmlid) end) end return true end local function build_envdiv(str) if not environment_div[str] then environment_div[str] = 1 else environment_div[str] = environment_div[str] + 1 end local div = "div-"..str.."_"..environment_div[str] if xmlidfound(div) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..div.. "\" already exists as a xml:id. " .. "ekdosis has generated some random id.}}") return "div-"..math.random(1000,9999) else table.insert(xmlids, {xmlid = div}) table.sort(xmlids, function(a ,b) return(#a.xmlid > #b.xmlid) end) return div end end function ekdosis.mkenv() local environments = {} for i = 1,#aligned_texts do if isfound(texts_w_apparatus, aligned_texts[i].text) then table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" .."\\par" .."\\EkdosisColStart" .."\\EkdosisOn#1" .."}{\\EkdosisOff" .."\\EkdosisColStop" .."\\end{nthcolumn}" .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" .. aligned_texts[i].column ..", \\luastringN{\\par#1\\par})}\\fi" .."}") table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" .."{\\begin{nthcolumn*}{".. aligned_texts[i].column.."}[]" .."\\par" .."\\EkdosisColStart" .."\\EkdosisOn#1" .."}{\\EkdosisOff" .."\\EkdosisColStop" .."\\end{nthcolumn*}" .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" .. aligned_texts[i].column ..", \\luastringN{\\par#1\\par})}\\fi" .."}") else table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."}{+b}" .."{\\begin{nthcolumn}{".. aligned_texts[i].column.."}" .."\\par" .."#1" .."}{\\end{nthcolumn}" .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" .. aligned_texts[i].column ..", \\luastringN{\\par#1\\par})}\\fi" .."}") table.insert(environments, "\\NewDocumentEnvironment{".. aligned_texts[i].text.."*}{+b}" .."{\\begin{nthcolumn*}{"..aligned_texts[i].column.."}[]" .."\\par" .."#1" .."}{" .."\\end{nthcolumn*}" .."\\csname iftei@export\\endcsname\\luadirect{ekdosis.storecoldata(" .. aligned_texts[i].column ..", \\luastringN{\\par#1\\par})}\\fi" .."}") end forbid_xmlid = false if aligned_texts[i].attribute ~= "" then ekdosis.newenvtotag(aligned_texts[i].text, "div", "xml:id=\"" ..build_envdiv(aligned_texts[i].text) .."\" " ..aligned_texts[i].attribute) else ekdosis.newenvtotag(aligned_texts[i].text, "div", "xml:id=\"" ..build_envdiv(aligned_texts[i].text) .."\"") end forbid_xmlid = true end str = table.concat(environments) return str end function ekdosis.export_coldata_totei() for i = 1,#coldata_totei do ekdosis.exporttei("\\begin{".. coldata_totei[i].environment .."}" .. table.concat(coldata_totei[i].data) .. "\\end{".. coldata_totei[i].environment .."}") end end -- handle multiple layers in apparatuses -- local apparatuses = {} local bagunits = {} function ekdosis.newapparatus(teitype, appdir, apprule, appdelim, appsep, appbhook, appehook) if isintable(apparatuses, teitype) then tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\"" ..teitype.. "\" already exists.}}") else table.insert(apparatuses, {a = teitype, direction = appdir, rule = apprule, delim = appdelim, sep = appsep, bhook = appbhook, ehook = appehook}) end bagunits[teitype] = 1 return true end function ekdosis.getappdelim(str) for i = 1,#apparatuses do if apparatuses[i].a == str then delimfound = apparatuses[i].delim break end end return delimfound end function ekdosis.get_bagunits(teitype) return bagunits[teitype] end function ekdosis.increment_bagunits(teitype) bagunits[teitype] = (bagunits[teitype] or 0) + 1 end local function reset_bagunits() for i = 1,#apparatuses do bagunits[apparatuses[i].a] = 1 end end function ekdosis.appin(str, teitype) local f = io.open(tex.jobname.."_tmp.ekd", "a+") if next(apparatuses) == nil then f:write("<", cur_abs_pg, cur_alignment, curcol, "-0>", str, "\n") else for i = 1,#apparatuses do if apparatuses[i].a == teitype then appno = i break end end f:write("<", cur_abs_pg, cur_alignment, curcol, "-", appno, ">", str, "\n") end f:close() return true end function ekdosis.appout() local file = io.open(tex.jobname..".ekd", "r") if file ~= nil then io.close(file) f = assert(io.open(tex.jobname..".ekd", "r")) t = f:read("*a") local output = {} if next(apparatuses) == nil then -- table.insert(output, "BEGIN") table.insert(output, "\\noindent\\csname ekd@default@rule\\endcsname\\NLS{}") -- table.insert(output, "\\noindent ") for i in string.gmatch(t, "<"..cur_abs_pg ..cur_alignment_patt ..curcol.."%-0>.-") do table.insert(output, i) end -- table.insert(output, "END") else local n = 1 while apparatuses[n] do if string.match(t, "<"..cur_abs_pg.. cur_alignment_patt ..curcol.."%-"..n..">.-") then -- table.insert(output, "BEGIN") table.insert(output, "\\bgroup{}") if apparatuses[n].direction == "LR" then table.insert(output, "\\pardir TLT\\textdir TLT{}") elseif apparatuses[n].direction == "RL" then table.insert(output, "\\pardir TRT\\textdir TRT{}") end if apparatuses[n].rule == "none" then if n > 1 then table.insert(output, "\\NLS{}") else table.insert(output, "\\noindent ") end elseif apparatuses[n].rule ~= "" then if n > 1 then table.insert(output, "\\NLS{}" .. apparatuses[n].rule .. "\\NLS{}") else -- table.insert(output, "\\noindent ") table.insert(output, apparatuses[n].rule .. "\\NLS{}") end else if n > 1 then table.insert(output, "\\NLS\\csname ekd@default@rule\\endcsname\\NLS{}") else -- table.insert(output, "\\noindent ") table.insert(output, "\\csname ekd@default@rule\\endcsname\\NLS{}") end end if apparatuses[n].sep ~= "" then table.insert(output, "\\edef\\ekdsep{" .. apparatuses[n].sep .. "}") else end if apparatuses[n].bhook ~= "" then table.insert(output, apparatuses[n].bhook) else table.insert(output, "\\relax") end for i in string.gmatch(t, "<"..cur_abs_pg ..cur_alignment_patt ..curcol.."%-"..n..">.-") do table.insert(output, i) end if apparatuses[n].ehook ~= "" then table.insert(output, apparatuses[n].ehook) else end table.insert(output, "\\egroup{}") -- table.insert(output, "END") end n = n + 1 end end f:close() str = table.concat(output) str = string.gsub(str, "", "") str = string.gsub(str, "<"..cur_abs_pg..cur_alignment_patt..curcol.."%-[0-9]>", " ") return str else end end function ekdosis.appin_out(str, nl) local f = io.open(tex.jobname.."_tmp.ekd", "a+") if nl == "yes" then f:write(str, "\n") else f:write(str) end f:close() return true end local curcol_curabspg = {} function ekdosis.testapparatus() if isfound(curcol_curabspg, curcol.."-"..cur_abs_pg) then if newalignment then if next(apparatuses) ~= nil then reset_bagunits() end newalignment = false return "\\booltrue{do@app}" else return "\\boolfalse{do@app}" end else table.insert(curcol_curabspg, curcol.."-"..cur_abs_pg) if next(apparatuses) ~= nil then reset_bagunits() end return "\\booltrue{do@app}" end end local lnlabs = {} local lnlab_salt = 0 local current_lnlab = nil local prev_lnlab = nil local current_notelab = nil local prev_notelab = nil local current_lemma = nil local salt = 0 local function mdvisintable(table, value) for _, v in pairs(table) do if v == value then return true end end return false end function ekdosis.dolnlab(str) prev_lnlab = current_lnlab current_lemma = str i = md5.sumhexa(str) if not mdvisintable(lnlabs, i) then table.insert(lnlabs, i) else i = i..salt table.insert(lnlabs, i) salt = salt + 1 end current_lnlab = i return true end function ekdosis.getlnlab() return current_lnlab end function ekdosis.getprevlnlab() return prev_lnlab end function ekdosis.setnotelab(str) current_notelab = str return "\\linelabel{" .. current_notelab .. "}" end function ekdosis.getnotelab() return current_notelab end function ekdosis.setprevnotelab(str) prev_notelab = str return true end function ekdosis.getprevnotelab() return prev_notelab end local function remove_note(str) str = gsub(str, dblbkslash * lpeg.P("note") * cmdargs, "") return str end function ekdosis.mdvappend(str, teitype) if teitype == nil then return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" .. current_lemma .. "\\linelabel{" .. current_lnlab .. "-e}" .. "\\csname append@app\\endcsname{" .. remove_note(str) .. "}" else return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" .. current_lemma .. "\\linelabel{" .. current_lnlab .. "-e}" .. "\\csname append@app\\endcsname" .. "[" .. teitype .. "]{" .. remove_note(str) .. "}" end end % \end{ekdlua} % \iffalse % % \fi % % \iffalse %<*examples> % \fi % \begin{minted}[firstnumber=last]{latex} \documentclass[12pt]{article} \usepackage{fontspec} \usepackage[english]{babel} \babelfont{rm}{Old Standard} \babelfont{sf}{NewComputerModern Sans} \babelfont{tt}{NewComputerModern Mono} \usepackage[teiexport=tidy]{ekdosis} \SetEkdosisAlignment{ tcols=1, lcols=1, texts=specimen[xml:lang="fr"], apparatus=specimen} \begin{document} \begin{alignment}[flush] \begin{specimen} I saw my friend \app{ \lem{Peter} \rdg{John}} at the station yesterday. \end{specimen} \end{alignment} \end{document} % \end{minted} % \iffalse % % \fi \endinput