% \iffalse meta-comment % vim: textwidth=75 %<*internal> \iffalse % %<*readme> | -------:| ----------------------------------------------------------------- ekdosis:| Typesetting TEI xml compliant critical editions Author:| Robert Alessi E-mail:| alessi@robertalessi.net License:| Released under the GNU General Public License v3 or later See:| http://www.gnu.org/licenses/ Short description: Some text about the package: probably the same as the abstract. % %<*luapre> --[[ This file is part of the `ekdosis' package ekdosis -- Typesetting TEI xml compliant critical editions Copyright (C) 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 \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble -------:| ----------------------------------------------------------------- ekdosis:| Typesetting TEI xml compliant critical editions Author:| Robert Alessi E-mail:| alessi@robertalessi.net License:| Released under the GNU General Public License v3 or later See:| http://www.gnu.org/licenses/ This file is part of the `ekdosis' package ekdosis -- Typesetting TEI xml compliant critical editions Copyright (C) 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 . This work consists of the file ekdosis.dtx and a Makefile. Running "make" generates the derived files README, ekdosis.pdf and ekdosis.sty. Running "make inst" installs the files in the user's TeX tree. Running "make install" installs the files in the local TeX tree. \endpreamble \usedir{tex/lualatex/ekdosis} \generate{ \file{\jobname.sty}{\from{\jobname.dtx}{package}} } \nopreamble\nopostamble \usedir{tex/lualatex/ekdosis} \bgroup \catcode9=12 \generate{ \file{\jobname.lua}{ \from{\jobname.dtx}{luapre} \from{\jobname.dtx}{lua} } } \egroup % %\endbatchfile %<*internal> \usedir{source/lualatex/ekdosis} \generate{ \file{\jobname.ins}{\from{\jobname.dtx}{install}} } \nopreamble\nopostamble \usedir{doc/lualatex/ekdosis} \generate{ \file{README.txt}{\from{\jobname.dtx}{readme}} } \ifx\fmtname\nameofplainTeX \expandafter\endbatchfile \else \expandafter\endgroup \fi % % \fi % % \iffalse %<*driver> \ProvidesFile{ekdosis.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{ekdosis} %<*package> [2020/06/03 v0.99 Typesetting TEI xml compliant critical editions] % %<*driver> \documentclass{ltxdoc} \usepackage[letterpaper,margin=25mm,left=50mm,nohead]{geometry} \usepackage{fontspec} \usepackage[english]{babel} \babelfont{rm}{Old Standard} \babelfont{sf}{NewComputerModern Sans} \babelfont{tt}{NewComputerModern Mono} \usepackage{metalogox} \usepackage{hologo} \usepackage{latexcolors} \usepackage{hyperxmp} \usepackage{uri} \usepackage[numbered]{hypdoc} \hypersetup{unicode=true, colorlinks, allcolors=cinnamon, keeppdfinfo, linktocpage=true, pdfauthor={Robert Alessi}, pdftitle={The ekdosis package}, pdfcontactemail={alessi@robertalessi.net}, pdfcontacturl={http://www.robertalessi.net/ekdosis}, pdfcopyright={Copyright (C) 2018 Robert Alessi . This document is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.}, pdflicenseurl={https://creativecommons.org/licenses/by-sa/4.0/legalcode}, pdfmetalang={en-US}, pdftype={Text}, pdfkeywords={Arabic language, arabtex, luatex}} \usepackage[lot]{multitoc} \usepackage{ekdosis} \usepackage{arabluatex} \usepackage{relsize} \usepackage{units} \usepackage[newfloat=true]{minted} \newminted[ekdlua]{lua}{linenos, fontsize=\relsize{-0.5}, xleftmargin=12pt, breaklines, numberblanklines=false, numbersep=3pt, firstnumber=last} \renewcommand{\theFancyVerbLine}{\rmfamily\smaller\arabic{FancyVerbLine}} \usepackage[contents]{colordoc} \newcommand{\package}[1]{\textsf{#1}\index{#1=#1 (package)}} \usepackage{tikz} \usepackage[breakable, skins, xparse, minted]{tcolorbox} \usepackage{etoc} \etocsettocdepth{paragraph} \newcommand{\ekdtableofcontents}{% \begingroup \etocsetstyle{section}{}{} {\etocsavedsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{} \etocsetstyle{subsection}{}{} {\etocsavedsubsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{}% \etocsetstyle{subsubsection}{}{} {\etocsavedsubsubsectiontocline{% \numberline{\etocnumber}\etocname}{\etocpage}}{}% \etocsetstyle{paragraph}{}{\leftskip2cm\rightskip 2.2em \parfillskip 0pt plus 1fil\relax \nobreak} {\noindent\etocname{} \etocpage{} }{\par}% \etocmulticolstyle[2]{\section*{Contents}} \pdfbookmark[1]{Contents}{toc} \tableofcontents \endgroup} \EnableCrossrefs \CodelineIndex \RecordChanges % \OnlyDescription \begin{document} \DocInput{\jobname.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \GetFileInfo{\jobname.dtx} % \DoNotIndex{\newcommand,\newenvironment} % % \title{\tcbox[colframe=black, enhanced, tikznode, drop lifted % shadow, colback=white, boxrule=.25mm]% % {ἔκδοσις\\ % Typesetting \texttt{TEI xml} compliant critical editions\\ % \fileversion\ --- \filedate}} % % \author{Robert Alessi \\ % \href{mailto:alessi@robertalessi.net?Subject=ekdosis package}% % {\texttt{alessi@robertalessi.net}}} % % \date{} % % \maketitle % \footnotesize % \ekdtableofcontents % \normalsize % %\changes{v1.00}{2020/07/01}{First public release} % % \begin{abstract} % ==== Put abstract text here. ==== % \end{abstract} % % \section{Usage} % % ==== Put descriptive text here. ==== % % \DescribeMacro{\dummyMacro} % This macro does nothing.\index{doing nothing|usage} It is merely an % example. If this were a real macro, you would put a paragraph here % describing what the macro is supposed to do, what its mandatory and % optional arguments are, and so forth. % % \DescribeEnv{dummyEnv} % This environment does nothing. It is merely an example. % If this were a real environment, you would put a paragraph here % describing what the environment is supposed to do, what its % mandatory and optional arguments are, and so forth. % % \section{Grid} % \begin{keyfigure}[H]{c={Grid % typesetting},l={fig:grid-typesetting},t={Each square in the grid % has a side length of \unit[10]{pt}. Therefore, the distance % between the last line of the text and the first line of the % apparatus is here approximately \unit[25]{pt}.}} % \begin{tikzpicture} % \draw[lightgray,thin] (0.5,0.5) grid [step=10pt] (10,5); % % \path node [align=justify, text width=8cm] at (5.5,3) {% % I saw my friend Peter at the station yesterday. I saw my friend % Peter at the station yesterday. I saw my friend Peter at the % station yesterday. I saw my friend Peter at the station % yesterday.\par % \rule{3cm}{0.01cm}\par\footnotesize% % \textbf{1}~Peter A: John B \textbf{2}~Peter A: John B % \textbf{3}~Peter A: John B \textbf{4}~Peter A: John B}; \node at % (0,3) {\scriptsize $\approx$ \unit[25]{pt}}; \draw [->] (0,2.9) % -- (0,2); % \end{tikzpicture} % \end{keyfigure} % % \StopEventually{} % \section{Implementation} % % \iffalse %<*package> % \fi % % \package{ekdosis} relies on Lua functions and tables. Read the % |.lua| files that accompany \package{ekdosis} for more % information. % \begin{macrocode} \RequirePackage{iftex} % \end{macrocode} % \package{ekdosis} requires {\LuaLaTeX} of course. Issue an error % if the document is processed with another engine. % \begin{macrocode} \RequireLuaTeX % \end{macrocode} % Packages that are required by \package{ekdosis}: % \begin{macrocode} \RequirePackage{xkeyval} \newif\if@pkg@float \newif\if@pkg@footins \define@choicekey{ekdosis.sty}{layout}{float, footins}[float]{% \edef\layout@float{float} \edef\layout@footins{footins} \edef\@tempa{#1} \ifx\@tempa\layout@float\@pkg@floattrue\fi \ifx\@tempa\layout@footins\@pkg@floatfalse\@pkg@footinstrue\fi } \newif\if@pkg@ekddivs \define@choicekey+{ekdosis.sty}{divs}{ekdosis, latex}[ekdosis]{ \edef\divs@ekdosis{ekdosis} \edef\divs@latex{latex} \edef\@tempa{#1} \ifx\@tempa\divs@ekdosis\@pkg@ekddivstrue\fi \ifx\@tempa\divs@latex \@pkg@ekddivsfalse \AtBeginDocument{\luadirect{ekdosis.setekddivsfalse()}} \fi }{\PackageError{ekdosis}{divs option must be either 'ekdosis' or 'latex'}} \newif\if@parnotesroman \newif\if@pkg@parnotes \define@choicekey+{ekdosis.sty}{parnotes}{true, false, roman}[true]{% \edef\@pntrue{true}\edef\@pnfalse{false}\edef\@pnrm{roman} \edef\@tempa{#1} \ifx\@tempa\@pnfalse \else \ifx\@tempa\@pntrue\@pkg@parnotestrue \else \ifx\@tempa\@pnrm \@pkg@parnotestrue\@parnotesromantrue \fi\fi\fi }{\PackageWarning{ekdosis}{parnotes: erroneous input (ignored)}} \newif\iftei@export \define@choicekey{ekdosis.sty}{teiexport}{true, false, tidy}[true]{% \edef\@exptrue{true}\edef\@expfalse{false}\edef\@exptidy{tidy} \edef\@tempa{#1} \ifx\@tempa\@expfalse \else \ifx\@tempa\@exptrue \tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream()}} \else \ifx\@tempa\@exptidy \tei@exporttrue \AtBeginDocument{\luadirect{ekdosis.openteistream()}}% \AtEndDocument{\luadirect{ekdosis.closeteistream("tidy")}} \else\fi\fi\fi} \ExecuteOptionsX{layout,divs} \ProcessOptionsX\relax \RequirePackage{luacode} \RequirePackage{paracol} \RequirePackage{expkv-def} \RequirePackage{xparse} \RequirePackage{etoolbox} \RequirePackage{lineno} \RequirePackage{keyfloat} \RequirePackage{refcount} \RequirePackage[user,abspage]{zref} \RequirePackage{ltxcmds} \if@pkg@parnotes \RequirePackage{parnotes} \fi % \end{macrocode} % Here begins the real work: load |ekdosis.lua|: % \begin{macrocode} \luadirect{dofile(kpse.find_file("ekdosis.lua"))} % \end{macrocode} % \begin{macrocode} \AtEndDocument{ \luadirect{ekdosis.closestream()} } % \end{macrocode} % Hooks % \begin{macrocode} \ekvdefinekeys{ekd@hooks}{ store appfontsize = \ekd@appfontsize, store refnumstyle = \ekd@refnumstyle, store postrefnum = \ekd@postrefnum, initial appfontsize = \footnotesize, initial refnumstyle = \bfseries, initial postrefnum = ~ } \NewDocumentCommand{\SetEkdosisHooks}{m}{\ekvset{ekd@hooks}{#1}} % \end{macrocode} % Build and process the list of witnesses and hands. % \begin{macrocode} \ekvdefinekeys{ekd@witness}{ store settlement = \settlement@value, store repository = \repository@value, store idno = \idno@value, store msName = \msName@value, store origDate = \origDate@value } \NewDocumentCommand{\DeclareWitness}{m m m O{}}{% \bgroup \ekvset{ekd@witness}{#4} \luadirect{ekdosis.newwitness( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringO{\settlement@value}, \luastringO{\repository@value}, \luastringO{\idno@value}, \luastringO{\msName@value}, \luastringO{\origDate@value})} \egroup } \@onlypreamble\DeclareWitness \NewDocumentCommand{\DeclareHand}{m m m +O{}}{ \luadirect{ekdosis.newhand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } \@onlypreamble\DeclareHand \NewDocumentCommand{\DeclareScholar}{m m}{ \luadirect{ekdosis.newscholar(\luastringN{#1}, \luastringN{#2})} } \@onlypreamble\DeclareScholar \NewDocumentCommand{\DeclareShorthand}{m m m}{ \luadirect{ekdosis.newshorthand(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \@onlypreamble\DeclareShorthand \NewDocumentCommand{\getsiglum}{m}{% \luadirect{tex.sprint(ekdosis.getsiglum(\luastringN{#1}))}% } \NewDocumentCommand{\SigLine}{m}{% \luadirect{tex.sprint(ekdosis.basic_cs(\luastringN{#1}))} } % \end{macrocode} % Add a \hologo{(La)TeX} command to be processed as a |TEI xml| tag: % \begin{macrocode} \NewDocumentCommand{\TeXtoTEI}{m m O{}}{% \luadirect{ekdosis.newcmdtotag(\luastringN{#1}, \luastringN{#2}, \luastringN{#3})} } \NewDocumentCommand{\EnvtoTEI}{s m m O{}}{% \IfBooleanTF{#1}{% \luadirect{ekdosis.newenvtotag(\luastringN{#2}, \luastringN{#3}, \luastringN{#4}, "yes")} }{% \luadirect{ekdosis.newenvtotag(\luastringN{#2}, \luastringN{#3}, \luastringN{#4})} } } \NewDocumentCommand{\TeXtoTEIPatt}{m m}{% \luadirect{ekdosis.newpatttotag(\luastringN{#1}, \luastringN{#2})} } % \end{macrocode} % Set |TEI| file name % \begin{macrocode} \NewDocumentCommand{\SetTEIFileName}{m}{ \luadirect{ekdosis.setteifilename(\luastringN{#1})} } \@onlypreamble\SetTEIFileName \NewDocumentCommand{\SetxmlBibResource}{m}{ \luadirect{ekdosis.setxmlbibresource(\luastringN{#1})} } \@onlypreamble\SetxmlBibResource % \end{macrocode} % Multi-layer apparatuses % \begin{macrocode} \newif\ifekd@mapps \ekvdefinekeys{ekd@newapp}{ choice direction = {LR = \def\direction@val{LR}, RL = \def\direction@val{RL}}, store rule = \rule@val, store delim = \delim@val, store sep = \sep@val, store bhook = \bhook@val, store ehook = \ehook@val, initial direction = LR, initial ehook = {\csname ekd@end@apparatus\endcsname} } \NewDocumentCommand{\DeclareApparatus}{m O{}}{ \newbool{subsq@unit@#1} \booltrue{subsq@unit@#1} \unless\ifekd@mapps\global\ekd@mappstrue\fi \bgroup \ekvset{ekd@newapp}{#2} \luadirect{ekdosis.newapparatus( \luastringN{#1}, \luastring{\direction@val}, \luastringO{\rule@val}, \luastringO{\delim@val}, \luastringO{\sep@val}, \luastringO{\bhook@val}, \luastringO{\ehook@val} )} \egroup } \@onlypreamble\DeclareApparatus % \end{macrocode} % \begin{macrocode} \newbool{do@app} \newif\ifekd@state \newif\ifekd@isinapp \newif\ifekd@isinlem \providebool{al@rlmode} \@ifpackageloaded{arabluatex}{}{% \def\setRL{\booltrue{al@rlmode}\pardir TRT\textdir TRT} \def\setLR{\boolfalse{al@rlmode}\pardir TLT \textdir TLT} } \protected\def\LRnum#1{\bgroup\textdir TLT#1\egroup} \newcounter{ekd@lab} \globalcounter{ekd@lab} % \def\unconditional@appin#1{% % \luadirect{ekdosis.appin(\luastringN{#1})}% % } \NewDocumentCommand{\unconditional@appin}{o m}{% \IfNoValueTF{#1} {\luadirect{ekdosis.appin(\luastringO{#2})}} {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% } % \def\blfootnote{\gdef\@thefnmark{\relax}\@footnotetext} \def\blfootnote{\gdef\@thefnmark{}\@blfootnotetext} \long\def\@blfootnotetext#1{\insert\footins{% \reset@font\footnotesize \interlinepenalty\interfootnotelinepenalty \splittopskip\footnotesep \splitmaxdepth \dp\strutbox \floatingpenalty \@MM \hsize\columnwidth \@parboxrestore \protected@edef\@currentlabel{% \csname p@footnote\endcsname\@thefnmark }% \color@begingroup \@makeblfntext{% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% \color@endgroup}}% \newcommand\@makeblfntext[1]{% \parindent 1em% \noindent \hb@xt@0em{\hss\@makefnmark}#1} \newif\ifrtl@app \NewDocumentCommand{\SetRTLapp}{}{\rtl@apptrue} \NewDocumentCommand{\SetLTRapp}{}{\rtl@appfalse} \edef\ekdsep{] } \NewDocumentCommand{\SetSeparator}{m}{\edef\ekdsep{#1}} \edef\ekd@end@apparatus{} \NewDocumentCommand{\SetEndApparatus}{m}{\edef\ekd@end@apparatus{#1}} \def\ekd@unit@delim{} \NewDocumentCommand{\SetUnitDelimiter}{m}{\def\ekd@unit@delim{#1}} \def\ekd@default@rule{\rule{2truein}{0.5pt}} % \def\ekd@default@rule{\vskip-\baselineskip\mbox{}\newline% % \rule{2truein}{0.5pt}} % \def\footnoterule{\vskip-\baselineskip} % \def\pcol@footnoterule{} \newif\iffootnoterule \let\dflt@footnoterule\footnoterule \let\dflt@pcol@footnoterule\pcol@footnoterule \renewcommand\footnoterule{% \iffootnoterule \dflt@footnoterule% \else % \noindent\ekd@default@rule% % \advance\skip\footins 4\p@\@plus2\p@\relax% \fi } \renewcommand\pcol@footnoterule{% \iffootnoterule \dflt@pcol@footnoterule% \else % \noindent\ekd@default@rule% % \advance\skip\footins 4\p@\@plus2\p@\relax% \fi } \newcommand*{\NLS}{% \par% \nobreak% \vspace{-\parskip}% \noindent% \ignorespaces} \NewDocumentCommand{\SetDefaultRule}{m}{% \def\@tempa{#1} \ifx\@tempa\empty\def\ekd@default@rule{\mbox{}}% \else% \def\ekd@default@rule{#1}% \fi} \newif\ifsubsq@unit \subsq@unittrue \def\add@@apparatus{% \if@pkg@parnotes\parnotes\else\fi% \if@pkg@footins% \bgroup% \ifrtl@app\setRL\else\setLR\fi% \blfootnote{% \if@pkg@parnotes% \if@parnotesroman% \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% \parnoteclear\else\fi% \footnotesize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% \if@pkg@parnotes\parnotes\parnotereset\else\fi% }% \egroup% \fi% \if@pkg@float% \keyparbox[!b]{}{\ifrtl@app\setRL\else\setLR\fi% \if@pkg@parnotes% \if@parnotesroman% \renewcommand*{\theparnotemark}{\roman{parnotemark}}\else\fi% \parnoteclear\else\fi% \ekd@appfontsize\apparatus\unless\ifekd@mapps\ekd@end@apparatus\fi% \if@pkg@parnotes\parnotes\parnotereset\else\fi% }% \fi% % \unless\ifekd@mapps\unconditional@appin{% % \expandafter{\ekd@default@rule}\newline}\fi } \def\add@apparatus{% \test@apparatus% \ifbool{do@app}{\subsq@unitfalse\add@@apparatus}{}% } \NewDocumentCommand{\append@app}{o +m}{% \ifekd@isinapp% \ifekd@state% \IfNoValueTF{#1}% {\luadirect{ekdosis.appin(\luastringO{#2})}}% {\luadirect{ekdosis.appin(\luastringO{#2}, \luastringO{#1})}}% \fi% \fi} \NewDocumentCommand{\append@ln@app}{o +m}{% \IfNoValueTF{#1} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}))}} {\luadirect{tex.sprint(ekdosis.mdvappend(\luastringO{#2}, \luastringO{#1}))}}} \define@cmdkey[ekd]{appnote}[ekdan@]{type}{} \NewDocumentCommand{\app}{O{} > { \TrimSpaces } +m}{% \presetkeys[ekd]{appnote}{type=default}{}% \setkeys[ekd]{appnote}{#1}% \ekd@isinapptrue% \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{ekdosis.storeabspg( \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% \ifekd@state\add@apparatus\fi% \luadirect{tex.sprint(ekdosis.removesp(\luastringN{#2}))}% \ekd@isinappfalse} \def\current@ref@arg#1#2{{%\textdir TLT% \unexpanded\expandafter{\ekd@refnumstyle}% \ifnum% \getpagerefnumber{#1} = \getpagerefnumber{#2} \ifnum% \getrefnumber{#1} = \getrefnumber{#2} % \ifekd@mapps% \ifbool{subsq@unit@\ekdan@type}{% \ifnum% \getrefnumber{#1} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} \else \LRnum{\getrefnumber{#1}}% issue the no \fi% }% {\LRnum{\getrefnumber{#1}}}% issue the no \else \ifsubsq@unit% % \ifnum% \getrefnumber{#1} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevnotelab())}} \else \LRnum{\getrefnumber{#1}}% issue the no \fi % \else \LRnum{\getrefnumber{#1}}% issue the no \fi \fi % \else \LRnum{\getrefnumber{#1}}--% \LRnum{\getrefnumber{#2}}% issue the nos \fi% \else \LRnum{\getrefnumber{#1}}--% \LRnum{\getpagerefnumber{#2}}.% \LRnum{\getrefnumber{#2}}% issue pg and ln nos \fi% }\unexpanded\expandafter{\ekd@postrefnum}% }% \def\current@ref{{%\textdir TLT% \unexpanded\expandafter{\ekd@refnumstyle}% \ifnum% \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e} % \ifekd@mapps% \ifbool{subsq@unit@\ekdan@type}{% \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi% }{\LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}}% issue the no \else \ifsubsq@unit% % \ifnum% \getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b} = \getrefnumber{\luadirect{tex.sprint(ekdosis.getprevlnlab())}-b} \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi % \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}% issue the no \fi \fi % \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue the nos \fi% \else \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-b}}--% \LRnum{\getpagerefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}.% \LRnum{\getrefnumber{\luadirect{tex.sprint(ekdosis.getlnlab())}-e}}% issue pg and ln nos \fi% }\unexpanded\expandafter{\ekd@postrefnum}% }% \define@cmdkeys[ekd]{lemrdg}[ekdlr@]{wit, alt, pre, post, prewit, postwit, 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% } \define@cmdkeys[ekd]{note}[ekdn@]{lem, labelb, labele} \define@cmdkey[ekd]{note}[ekdn@]{sep}{} \presetkeys[ekd]{note}{sep=\ekdsep}{} \NewDocumentCommand{\note@noapp}{O{} +m}{% \presetkeys[ekd]{appnote}{type=default}{}% \bgroup% \setkeys[ekd]{appnote,note}{#1}% \stepcounter{ekd@lab}% \zlabel{ekd:\theekd@lab}% \luadirect{ekdosis.storeabspg( \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}% \ifekd@state\add@apparatus\fi% \ifekd@mapps% \ifnum% \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} = 1 \boolfalse{subsq@unit@\ekdan@type}% \fi% \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% \def\ekd@munit@delim{% \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% \fi% \ifdefined\ekdn@labelb% \luadirect{tex.sprint(ekdosis.setnotelab(\luastringO{\ekdn@labelb}))}% \ifdefined\ekdn@labele\else\def\ekdn@labele{\ekdn@labelb}\fi% \else\PackageError{ekdosis}{missing labelb}{`labelb' must be set.}\fi% \ifbool{al@rlmode}% {\edef\note@contents{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em \ifdefined\ekdn@lem% {\textdir TRT\unexpanded\expandafter{\ekdn@lem}}% \unexpanded\expandafter{\ekdn@sep}\else\fi% {\textdir TRT\unexpanded{#2}}}}% {\edef\note@contents{% % \hskip .75em \ifekd@mapps \ifbool{subsq@unit@\ekdan@type}% {\ekd@munit@delim}{}% \else% \ifsubsq@unit\unexpanded\expandafter{\ekd@unit@delim}\fi% \fi% \current@ref@arg{\ekdn@labelb}{\ekdn@labele}%\hskip .25em \ifdefined\ekdn@lem \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}% \unexpanded\expandafter{\ekdn@lem}}% {\unexpanded\expandafter{\ekdn@lem}}% \unexpanded\expandafter{\ekdn@sep}\else\fi% \ltx@ifpackageloaded{babel}% {\noexpand\selectlanguage{\languagename}\unexpanded{#2}}{% \unexpanded{#2}}}}% \ifekd@mapps% \unconditional@appin[\ekdan@type]{\note@contents}% \else% \unconditional@appin{\note@contents}% \fi% \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}% \egroup% \subsq@unittrue% } \ekvdefinekeys{ekd@note}{ store pre = \pre@value, store post = \post@value } \NewDocumentCommand{\ekd@note}{O{} m}{% \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unexpanded{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% } \NewDocumentCommand{\ekd@note@star}{O{} m}{% \if@pkg@parnotes \bgroup% \ekvset{ekd@note}{#1}% \edef\note@contents{% \ekvifdefinedNoVal{note}{pre}{}{% \unexpanded\expandafter{\pre@value}}% \unskip\noexpand\parnote{#2}% \ekvifdefinedNoVal{note}{post}{}{% \unexpanded\expandafter{\post@value}}% }% \append@app{\note@contents}% \egroup% \else \append@app{\unskip\footnote{#2}}% \fi% } \NewDocumentCommand{\note@app}{s O{} +m}{% \ifbool{al@rlmode}{% \IfBooleanTF{#1}{\ekd@note@star[#2]{\unexpanded{% {\textdir TRT#3}}}} {\ekd@note[#2]{\unexpanded{{\textdir TRT#3}}}}% }{% \IfBooleanTF{#1}{\ekd@note@star[#2]{\unexpanded{#3}}} {\ekd@note[#2]{\unexpanded{#3}}}% }% } \NewDocumentCommand{\note}{s O{} +m}{% \ifekd@state% \ifekd@isinapp% \ifekd@isinlem% \note@noapp[#2]{#3}% \else% \IfBooleanTF{#1}{\note@app*[#2]{#3}}{\note@app[#2]{#3}}% \fi% \else% \note@noapp[#2]{#3}% \fi% \fi% } \NewDocumentCommand{\apparatus}{}{% \luadirect{tex.sprint(ekdosis.appout())}} \NewDocumentCommand{\test@apparatus}{}{% \luadirect{tex.sprint(ekdosis.testapparatus())}} \NewDocumentCommand{\ekd@storecol}{}{% \luadirect{ekdosis.storecurcol(\luastring{\thecolumn})}% } \NewDocumentCommand{\EkdosisOn}{}{% \ekd@statetrue} \NewDocumentCommand{\EkdosisOff}{}{% \ekd@statefalse% } \def\ekd@setlineno{% \let\setpagewiselinenumbers\relax% \let\pagewiselinenumbers\relax% \let\endpagewiselinenumbers\relax% \let\runningpagewiselinenumbers\relax% \let\realpagewiselinenumbers\relax% } \NewDocumentEnvironment{ekdosis}{+b}{% \ekd@setlineno% \runninglinenumbers % \EkdosisColStart \EkdosisOn#1}{% \EkdosisOff % \EkdosisColStop \endrunninglinenumbers% \iftei@export\luadirect{ekdosis.exporttei(\luastringN{\par #1\par })}\else\fi} % \end{macrocode} % Alignment:--- % \begin{macrocode} \ekvdefinekeys{ekd@align}{ store tcols = \tcols@num, store lcols = \lcols@num, store texts = \texts@value, store apparatus = \apparatus@value, bool paired = \ifekd@paired, bool pagelineation = \ifekd@pagelineation, choice segmentation = {auto = \def\segmentation@val{auto}, noauto = \def\segmentation@val{noauto}}, 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" )} \luadirect{ekdosis.mkenvdata( \luastring{\apparatus@value}, "apparatus" )} \setrunninglinenumbers \luadirect{tex.sprint(ekdosis.mkenv())} \ifekd@paired \begin{paracol}[\lcols@num]{\tcols@num} \else \begin{paracol}[\lcols@num]*{\tcols@num} \fi } {\end{paracol} \iftei@export\luadirect{ekdosis.export_coldata_totei()}\fi \luadirect{ekdosis.flushenvdata()} \luadirect{ekdosis.flushcolnums()} } % \end{macrocode} % Divisions of the Body % \begin{macrocode} \NewDocumentCommand{\MkBodyDivs}{mmmmmm}{ \luadirect{ekdosis.mkdivdepths( \luastringN{#1}, \luastringN{#2}, \luastringN{#3}, \luastringN{#4}, \luastringN{#5}, \luastringN{#6} ) } } % \end{macrocode} % Divisions specific to ekdosis:--- % \begin{macrocode} \ekvdefinekeys{ekd@div}{ code type = \def\type@value{#1}, code n = \def\n@value{#1}, code head = \def\head@value{#1}, code barehead = \def\barehead@value{#1}, store depth = \depth@value, choice toc = {book = \def\toc@value{book}, part = \def\toc@value{part}, chapter = \def\toc@value{chapter}, section = \def\toc@value{section}, subsection = \def\toc@value{subsection}, subsubsection = \def\toc@value{subsubsection}, paragraph = \def\toc@value{paragraph}, subparagraph = \def\toc@value{subparagraph}}, initial depth = 1 } \NewDocumentCommand{\ekdfmtdiv}{m m m}{ \luadirect{ekdosis.fmtdiv(\luastring{#1}, \luastringN{#2}, \luastringN{#3})} } \NewDocumentCommand{\ekd@getfmtdiv}{m m}{% \luadirect{tex.sprint(ekdosis.getfmtdiv(\luastringO{#1}, \luastringN{#2}))}% } \NewDocumentCommand{\ekddiv}{m}{ \begingroup \ekvset{ekd@div}{#1}% \ifdefined\head@value \bgroup \ekd@getfmtdiv{\depth@value}{b}% \head@value \ekd@getfmtdiv{\depth@value}{e}% \egroup \ifdefined\toc@value \ltx@ifpackageloaded{hyperref}{\phantomsection}{}% \ifdefined\barehead@value \addcontentsline{toc}{\toc@value}{\barehead@value}% \else \addcontentsline{toc}{\toc@value}{\head@value}% \fi \fi \fi \endgroup } % \end{macrocode} % Very basic implementation of poetry lines:--- % \begin{macrocode} \newlength{\ekdverseindentlength} \setlength{\ekdverseindentlength}{\parindent} \newenvironment*{ekdverse}[1][\ekdverseindentlength]{ \begin{list}{}{% \setlength{\leftmargin}{#1} \setlength{\itemsep}{0pt} \setlength{\topsep}{0pt} \setlength{\partopsep}{0pt} } \item[] }{\end{list}} % \end{macrocode} % % \iffalse % % \fi % % \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 }) 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("}") * 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("}") * 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("}") * 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) cur_abs_pg = n return true end function ekdosis.storeabspg(n, pg) if pg == "pg_i" then pg_i = n elseif pg == "pg_ii" then pg_ii = n table.insert(check_resetlineno, curcol.."-"..pg_ii) end cur_abs_pg = n return true end function ekdosis.checkresetlineno() if isfound(check_resetlineno, curcol.."-"..pg_i) then return "" else return "\\resetlinenumber" end end -- -- Build environments to be aligned -- local aligned_texts = {} local texts_w_apparatus = {} local coldata_totei = {} local function sanitize_envdata(str) -- look for a better way to achieve this str = string.gsub(str, "(%a+)%s+(%b[])", "%1%2") str = string.gsub(str, "(%a+)(%b[])%s+", "%1%2") str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") str = gsub(str, lpeg.Cs(letters^1) * spcenc^-1 * -bsqbrackets * lpeg.Cs(";"), "%1[]%2") str = string.gsub(str, "%s+(%a+)(%b[])", "%1%2") return str end function ekdosis.mkenvdata(str, opt) if not string.find(str, "%;", -1) then str = str .. ";" else end -- str = str ..";" -- str = string.gsub(str, "%s+", "") local fieldstart = 1 local col = 0 if opt == "texts" then str = sanitize_envdata(str) repeat local _s, nexti = string.find(str, "%b[]%s-%;", fieldstart) local namediv = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%1") local attr = string.gsub(string.sub(str, fieldstart, nexti-1), "(%a+)%s-(%b[])", "%2") attr = string.sub(attr, 2, -2) 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, "-", 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, "-", 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.."%-"..curcol.."%-0>.-") do table.insert(output, i) end -- table.insert(output, "END") else local n = 1 while apparatuses[n] do if string.match(t, "<"..cur_abs_pg.."%-"..curcol.."%-"..n..">.-") then -- table.insert(output, "BEGIN") table.insert(output, "\\bgroup{}") if apparatuses[n].direction == "LR" then table.insert(output, "\\pardir TLT\\textdir TLT{}") elseif apparatuses[n].direction == "RL" then table.insert(output, "\\pardir TRT\\textdir TRT{}") end if apparatuses[n].rule == "none" then if n > 1 then table.insert(output, "\\NLS{}") else table.insert(output, "\\noindent ") end elseif apparatuses[n].rule ~= "" then if n > 1 then table.insert(output, "\\NLS{}" .. apparatuses[n].rule .. "\\NLS{}") else -- table.insert(output, "\\noindent ") table.insert(output, apparatuses[n].rule .. "\\NLS{}") end else if n > 1 then table.insert(output, "\\NLS\\csname ekd@default@rule\\endcsname\\NLS{}") else -- table.insert(output, "\\noindent ") table.insert(output, "\\csname ekd@default@rule\\endcsname\\NLS{}") end end if apparatuses[n].sep ~= "" then table.insert(output, "\\edef\\ekdsep{" .. apparatuses[n].sep .. "}") else end if apparatuses[n].bhook ~= "" then table.insert(output, apparatuses[n].bhook) else table.insert(output, "\\relax") end for i in string.gmatch(t, "<"..cur_abs_pg.."%-"..curcol.."%-"..n..">.-") 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.."%-"..curcol.."%-[0-9]>", " ") return str else end end function ekdosis.appin_out(str, nl) local f = io.open(tex.jobname.."_tmp.ekd", "a+") if nl == "yes" then f:write(str, "\n") else f:write(str) end f:close() return true end local curcol_curabspg = {} function ekdosis.testapparatus() if isfound(curcol_curabspg, curcol.."-"..cur_abs_pg) then return "\\boolfalse{do@app}" else table.insert(curcol_curabspg, curcol.."-"..cur_abs_pg) if next(apparatuses) ~= nil then reset_bagunits() end return "\\booltrue{do@app}" end end local lnlabs = {} local lnlab_salt = 0 local current_lnlab = nil local prev_lnlab = nil local current_notelab = nil local prev_notelab = nil local current_lemma = nil local salt = 0 local function mdvisintable(table, value) for _, v in pairs(table) do if v == value then return true end end return false end function ekdosis.dolnlab(str) prev_lnlab = current_lnlab current_lemma = str i = md5.sumhexa(str) if not mdvisintable(lnlabs, i) then table.insert(lnlabs, i) else i = i..salt table.insert(lnlabs, i) salt = salt + 1 end current_lnlab = i return true end function ekdosis.getlnlab() return current_lnlab end function ekdosis.getprevlnlab() return prev_lnlab end function ekdosis.setnotelab(str) current_notelab = str return "\\linelabel{" .. current_notelab .. "}" end function ekdosis.getnotelab() return current_notelab end function ekdosis.setprevnotelab(str) prev_notelab = str return true end function ekdosis.getprevnotelab() return prev_notelab end local function remove_note(str) str = gsub(str, dblbkslash * lpeg.P("note") * cmdargs, "") return str end function ekdosis.mdvappend(str, teitype) if teitype == nil then return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" .. current_lemma .. "\\linelabel{" .. current_lnlab .. "-e}" .. "\\csname append@app\\endcsname{" .. remove_note(str) .. "}" else return "\\linelabel{" .. current_lnlab .. "-b}\\wordboundary{}" .. current_lemma .. "\\linelabel{" .. current_lnlab .. "-e}" .. "\\csname append@app\\endcsname" .. "[" .. teitype .. "]{" .. remove_note(str) .. "}" end end % \end{ekdlua} % \iffalse % % \fi \endinput