aboutsummaryrefslogtreecommitdiff
path: root/ekdosis.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'ekdosis.dtx')
-rw-r--r--ekdosis.dtx596
1 files changed, 389 insertions, 207 deletions
diff --git a/ekdosis.dtx b/ekdosis.dtx
index 6673d37..5d7876a 100644
--- a/ekdosis.dtx
+++ b/ekdosis.dtx
@@ -59,7 +59,7 @@ Alessi <alessi@robertalessi.net>
59%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] 59%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
60%<package>\ProvidesPackage{ekdosis} 60%<package>\ProvidesPackage{ekdosis}
61%<*package> 61%<*package>
62 [2025/04/19 v1.5-dev Typesetting TEI xml-compliant critical editions] 62 [2025/04/21 v1.5-dev Typesetting TEI xml-compliant critical editions]
63%</package> 63%</package>
64%<*driver> 64%<*driver>
65\begin{filecontents}[noheader,overwrite]{bibdata.xml} 65\begin{filecontents}[noheader,overwrite]{bibdata.xml}
@@ -2056,6 +2056,20 @@ yesterday.
2056% used as values of the |wit| optional argument, it is recommended to 2056% used as values of the |wit| optional argument, it is recommended to
2057% use |sources| and |resp| to refer to either category 2057% use |sources| and |resp| to refer to either category
2058% respectively as described below.\\ 2058% respectively as described below.\\
2059% \DescribeOption{nowit} \newfeature[v1.5]
2060% |nowit|$=$\verb+true|false+\\
2061% This named argument does not need a value as it defaults to |true|
2062% if used. When used in a positive apparatus, |nowit| instructs
2063% \pkg{ekdosis} to remove the witnesses attached to the lemma text
2064% with the result of printing a negative entry. In a positive
2065% apparatus, this can be a way of suggesting an aberration. In a
2066% negative apparatus, |nowit=false| inserts a positive entry, which
2067% implies that the rejected variant is well attested or judged worthy
2068% of consideration as a serious alternative. For details on the method
2069% of encoding positive or negative apparatus criticus, the reader is
2070% invited to refer to the commands and options described
2071% \vpagerefrange{ref:set-neg-app}{ref:apparatus-settings-e} and
2072% \vnref{sec:layout-layers}.\\
2059% \DescribeOption{source} |source|$=$\meta{csv list of 2073% \DescribeOption{source} |source|$=$\meta{csv list of
2060% sources}\phts\label{ref:lem-source}\newfeature[v1.1]\\ 2074% sources}\phts\label{ref:lem-source}\newfeature[v1.1]\\
2061% A \enquote{source} refers to any type of document consulted by the 2075% A \enquote{source} refers to any type of document consulted by the
@@ -3891,6 +3905,23 @@ texts=latin[xml:lang="la"]+\textcolor{red}{;}+
3891% \vref{ref:type-note}\===namely 3905% \vref{ref:type-note}\===namely
3892% \cs{note}\oarg{options}\marg{text}\===a language different from the 3906% \cs{note}\oarg{options}\marg{text}\===a language different from the
3893% one that is selected in the edition text. 3907% one that is selected in the edition text.
3908%
3909% \DescribeMacro{\SetNegativeApparatus}
3910% \phts\label{ref:set-neg-app}\newfeature[v1.5]
3911% \cs{SetNegativeApparatus} removes the witnesses
3912% attached to the lemma text and sets the apparatus criticus in
3913% negative form, leaving the reading of lemma text to be understood.
3914%
3915% \DescribeMacro{\SetPositiveApparatus}
3916% \newfeature[v1.5] \cs{SetPositiveApparatus} prints the witnesses
3917% attached to the lemma text and sets the apparatus criticus in
3918% positive form, which is the default.
3919%
3920% \DescribeMacro{\SetTEINegativeApparatus}
3921% \DescribeMacro{\SetTEIPositiveApparatus}
3922% \newfeature[v1.5] \cs{SetTEINegativeApparatus} and
3923% \cs{SetTEIPositiveApparatus} do the same as described above for the
3924% apparatus criticus converted in \texttt{TEI xml}.
3894% 3925%
3895% \paragraph{General Command} 3926% \paragraph{General Command}
3896% \DescribeMacro{\SetApparatus} \cs{SetApparatus}\marg{csv list of 3927% \DescribeMacro{\SetApparatus} \cs{SetApparatus}\marg{csv list of
@@ -3944,7 +3975,21 @@ texts=latin[xml:lang="la"]+\textcolor{red}{;}+
3944% command as described in \vref{ref:type-note}\===namely 3975% command as described in \vref{ref:type-note}\===namely
3945% \cs{note}\oarg{options}\marg{text}\===a language different from the 3976% \cs{note}\oarg{options}\marg{text}\===a language different from the
3946% one that is selected in the edition text. |languagename| can be any 3977% one that is selected in the edition text. |languagename| can be any
3947% value accepted by \pkg{babel} or \pkg{polyglossia}. 3978% value accepted by \pkg{babel} or \pkg{polyglossia}.\\
3979% \DescribeOption{negative} \verb+negative=true|false+
3980% \hfill\tcboxverb{Default: false}\\
3981% \addlines
3982% This named argument does not need a value as it defaults to |true|
3983% if used. |negative=true| sets the apparatus criticus in print in
3984% negative form as described above \vpageref{ref:set-neg-app}, whereas
3985% |negative=false| can set it back in positive form, which is the
3986% default.\\
3987% \DescribeOption{TEInegative} \verb+TEInegative=true|false+
3988% \hfill\tcboxverb{Default: false}\\
3989% This named argument does not need a value as it defaults to |true|
3990% if used. |TEINegative=true| has the \texttt{TEI xml} apparatus
3991% converted in negative form, whereas |TEINegative=true| can be used
3992% to set it back in positive form, which is the default.
3948% \phts\label{ref:apparatus-settings-e} 3993% \phts\label{ref:apparatus-settings-e}
3949% 3994%
3950% As an example, an apparatus criticus with references to line numbers 3995% As an example, an apparatus criticus with references to line numbers
@@ -4043,6 +4088,8 @@ texts=latin[xml:lang="la"]+\textcolor{red}{;}+
4043% \DescribeOption{norule} 4088% \DescribeOption{norule}
4044% \DescribeOption{lang}\phts\label{ref:apps-lang-opt} 4089% \DescribeOption{lang}\phts\label{ref:apps-lang-opt}
4045% \DescribeOption{notelang} 4090% \DescribeOption{notelang}
4091% \DescribeOption{negative}
4092% \DescribeOption{TEInegative}
4046% With regard to layout, any declared layer inherits the default values 4093% With regard to layout, any declared layer inherits the default values
4047% described above in \vref{sec:single-layer-app}. That said, as the 4094% described above in \vref{sec:single-layer-app}. That said, as the
4048% optional argument of \cs{DeclareApparatus} accepts the exact same 4095% optional argument of \cs{DeclareApparatus} accepts the exact same
@@ -8534,7 +8581,7 @@ Sample text with a \textcolor{red}{word} in red.
8534% \end{macrocode} 8581% \end{macrocode}
8535% \paragraph{\textsf{ekdosis} Symbol} 8582% \paragraph{\textsf{ekdosis} Symbol}
8536% \begin{macro}{\eKd} 8583% \begin{macro}{\eKd}
8537% \changes{v1.5}{2025/04/19}{Prints \textsf{ekdosis} indentifying 8584% \changes{v1.5}{2025/04/21}{Prints \textsf{ekdosis} indentifying
8538% symbol} As of v1.5, \pkg{ekdosis} has its own identifying 8585% symbol} As of v1.5, \pkg{ekdosis} has its own identifying
8539% symbol. It is produced by \cs{eKd} and best printed with the Old 8586% symbol. It is produced by \cs{eKd} and best printed with the Old
8540% Standard Greek font. 8587% Standard Greek font.
@@ -8799,7 +8846,7 @@ Sample text with a \textcolor{red}{word} in red.
8799% \begin{macro}{\teidirectE} 8846% \begin{macro}{\teidirectE}
8800% \changes{v1.3}{2021/08/18}{direct insertion of elements in the 8847% \changes{v1.3}{2021/08/18}{direct insertion of elements in the
8801% \texttt{TEI xml} file} 8848% \texttt{TEI xml} file}
8802% \changes{v1.5}{2025/04/19}{direct insertion of empty elements in the 8849% \changes{v1.5}{2025/04/21}{direct insertion of empty elements in the
8803% \texttt{TEI xml} file} 8850% \texttt{TEI xml} file}
8804% \cs{teidirect}\oarg{xml attributes}\marg{xml element}\marg{code} 8851% \cs{teidirect}\oarg{xml attributes}\marg{xml element}\marg{code}
8805% does nothing in \LaTeX. It is only used to insert elements in the 8852% does nothing in \LaTeX. It is only used to insert elements in the
@@ -8814,7 +8861,7 @@ Sample text with a \textcolor{red}{word} in red.
8814% \end{macro} 8861% \end{macro}
8815% \end{macro} 8862% \end{macro}
8816% \begin{macro}{\getTEIxmlid} 8863% \begin{macro}{\getTEIxmlid}
8817% \changes{v1.5}{2025/04/19}{returns \texttt{TEI xml:ids} from a 8864% \changes{v1.5}{2025/04/21}{returns \texttt{TEI xml:ids} from a
8818% csv-list of ids} This command returns from a csv-list of unique 8865% csv-list of ids} This command returns from a csv-list of unique
8819% identifiers declared in commands such as \cs{DeclareWitness} and the 8866% identifiers declared in commands such as \cs{DeclareWitness} and the
8820% like a space-separated list of their corresponding |xml:id|s, each 8867% like a space-separated list of their corresponding |xml:id|s, each
@@ -8908,6 +8955,7 @@ Sample text with a \textcolor{red}{word} in red.
8908% or multiple-layer context:--- 8955% or multiple-layer context:---
8909% \begin{macrocode} 8956% \begin{macrocode}
8910\newif\ifekd@mapps 8957\newif\ifekd@mapps
8958\newif\ifekdl@nowit
8911% \end{macrocode} 8959% \end{macrocode}
8912% Now the key-value options can be defined:--- 8960% Now the key-value options can be defined:---
8913% \begin{macrocode} 8961% \begin{macrocode}
@@ -8928,24 +8976,40 @@ Sample text with a \textcolor{red}{word} in red.
8928 store notelang = \notelang@val, 8976 store notelang = \notelang@val,
8929 initial direction = LR, 8977 initial direction = LR,
8930 initial delim = {}, 8978 initial delim = {},
8931 initial ehook = {\csname ekd@end@apparatus\endcsname} 8979 initial ehook = {\csname ekd@end@apparatus\endcsname},
8980 choice negative = {true=\def\negative@val{yes},
8981 false=\def\negative@val{no}},
8982 initial negative = false,
8983 default negative = true,
8984 unknown-choice negative = \PackageError{ekdosis}{unknown
8985 negative=#1}{`negative' must be either `true' or `false'.},
8986 choice TEInegative = {true=\def\TEInegative@val{yes},
8987 false=\def\TEInegative@val{no}},
8988 initial TEInegative = false,
8989 default TEInegative = true,
8990 unknown-choice TEInegative = \PackageError{ekdosis}{unknown
8991 TEInegative=#1}{`TEInegative' must be either `true' or `false'.}
8932} 8992}
8933% \end{macrocode} 8993% \end{macrocode}
8934% \begin{macro}{\DeclareApparatus} 8994% \begin{macro}{\DeclareApparatus}
8935% \cs{DeclareApparatus}\marg{apparatus name}\oarg{options} is a 8995% \cs{DeclareApparatus}\marg{apparatus name}\oarg{options} is a
8936% preamble-only command. As a mandatory argument, it takes the name of 8996% preamble-only command. As a mandatory argument, it takes the name
8937% the new layer of notes to be inserted in the apparatus block. Then, 8997% of the new layer of notes to be inserted in the apparatus
8938% the following seven key-value options can be used to lay out the 8998% block. Then, the following eleven key-value options can be used to
8939% layer: \verb+direction=LR|RL+, |rule|, |delim| (the delimiter between 8999% lay out the layer: \verb+direction=LR|RL+, |rule| |norule|,
8940% entries), |sep| (the separator between lemma part and readings or 9000% |delim| (the delimiter between entries), |sep| (the separator
8941% notes), |bhook| (\LaTeX{} code inserted as the layer begins), 9001% between lemma part and readings or notes), |bhook| (\LaTeX{} code
8942% |ehook| (\LaTeX{} code inserted as the layer ends), |maxentries| 9002% inserted as the layer begins), |ehook| (\LaTeX{} code inserted as
8943% (if set and |maxentries >= 10|, the number of entries at which a 9003% the layer ends), |maxentries| (if set and |maxentries >= 10|, the
8944% \cs{pagebreak} is issued):--- 9004% number of entries at which a \cs{pagebreak} is issued), |lang|,
9005% |notelang| (the language to be applied) |negative|, |TEInegative|
9006% (the form of the apparatus criticus, either positive or
9007% negative):---
8945% \begin{macrocode} 9008% \begin{macrocode}
8946\NewDocumentCommand{\DeclareApparatus}{m O{}}{ 9009\NewDocumentCommand{\DeclareApparatus}{m O{}}{
8947 \newbool{subsq@unit@#1} 9010 \newbool{subsq@unit@#1}
8948 \booltrue{subsq@unit@#1} 9011 \booltrue{subsq@unit@#1}
9012 \newbool{ekdl@nowit@#1}
8949 \unless\ifekd@mapps\global\ekd@mappstrue\fi 9013 \unless\ifekd@mapps\global\ekd@mappstrue\fi
8950 \bgroup 9014 \bgroup
8951 \ekvset{ekd@newapp}{#2} 9015 \ekvset{ekd@newapp}{#2}
@@ -8960,7 +9024,9 @@ Sample text with a \textcolor{red}{word} in red.
8960 \luastringO{\ehook@val}, 9024 \luastringO{\ehook@val},
8961 \luastringO{\limit@val}, 9025 \luastringO{\limit@val},
8962 \luastringO{\lang@val}, 9026 \luastringO{\lang@val},
8963 \luastringO{\notelang@val} 9027 \luastringO{\notelang@val},
9028 \luastringO{\negative@val},
9029 \luastringO{\TEInegative@val}
8964 )} 9030 )}
8965 \egroup 9031 \egroup
8966} 9032}
@@ -9119,7 +9185,20 @@ Sample text with a \textcolor{red}{word} in red.
9119 \ltx@ifpackageloaded{polyglossia}{\languagename}{}}, 9185 \ltx@ifpackageloaded{polyglossia}{\languagename}{}},
9120 store notelang = \ekd@singleapp@note@lang, 9186 store notelang = \ekd@singleapp@note@lang,
9121 initial notelang = \ltx@ifpackageloaded{babel}{\languagename}{% 9187 initial notelang = \ltx@ifpackageloaded{babel}{\languagename}{%
9122 \ltx@ifpackageloaded{polyglossia}{\languagename}{}} 9188 \ltx@ifpackageloaded{polyglossia}{\languagename}{}},
9189 choice negative = {true=\ekdl@nowittrue,
9190 false=\ekdl@nowitfalse},
9191 initial negative = false,
9192 default negative = true,
9193 unknown-choice negative = \PackageError{ekdosis}{unknown
9194 negative=#1}{`negative' must be either `true' or `false'.},
9195 choice TEInegative = {
9196 true=\luadirect{ekdosis.set_negpos_apparatus("neg")},
9197 false=\luadirect{ekdosis.set_negpos_apparatus("pos")}},
9198 initial TEInegative = false,
9199 default TEInegative = true,
9200 unknown-choice TEInegative = \PackageError{ekdosis}{unknown
9201 TEInegative=#1}{`TEInegative' must be either `true' or `false'.}
9123} 9202}
9124% \end{macrocode} 9203% \end{macrocode}
9125% \begin{macro}{\SetApparatus} 9204% \begin{macro}{\SetApparatus}
@@ -9211,13 +9290,47 @@ Sample text with a \textcolor{red}{word} in red.
9211% \end{macro} 9290% \end{macro}
9212% \begin{macro}{\footnoteruletrue} 9291% \begin{macro}{\footnoteruletrue}
9213% \begin{macro}{\footnoterulefalse} 9292% \begin{macro}{\footnoterulefalse}
9214% As \pkg{ekdosis} takes care of drawing a rule separating the main 9293% As \pkg{ekdosis} takes care of drawing a rule separating the main
9215% text from the apparatus block as well as layers of notes from each 9294% text from the apparatus block as well as layers of notes from each
9216% other inside this block, it may not be desirable to have 9295% other inside this block, it may not be desirable to have the
9217% the standard \LaTeX{} \enquote{footnoterule} printed on every page 9296% standard \LaTeX{} \enquote{footnoterule} printed on every page of
9218% of the edition text. \cs{footnoterulefalse} removes it while 9297% the edition text. \cs{footnoterulefalse} removes it while
9219% \cs{footnoteruletrue} leaves it untouched. The latter is set by 9298% \cs{footnoteruletrue} leaves it untouched. The latter is set by
9220% default. 9299% default.
9300% \begin{macro}{\SetNegativeApparatus}
9301% \changes{v1.5}{2025/04/21}{sets the apparatus criticus in negative
9302% form.}
9303% \begin{macro}{\SetPositiveApparatus}
9304% \changes{v1.5}{2025/04/21}{sets the apparatus criticus in positive
9305% form.}
9306% \cs{SetNegativeApparatus} and \cs{SetPositiveApparatus} are two
9307% argument-less commands. The former has the witnesses attached to
9308% the lemma text removed from the apparatus criticus in print, while
9309% the latter prints the apparatus criricus in positive form, which
9310% is the default.
9311% \begin{macro}{\SetTEINegativeApparatus}
9312% \changes{v1.5}{2025/04/21}{sets the \texttt{TEI xml} apparatus
9313% criticus in negative form.}
9314% \begin{macro}{\SetTEIPositiveApparatus}
9315% \changes{v1.5}{2025/04/21}{sets the \texttt{TEI xml} apparatus
9316% criticus in positive form.}
9317% \cs{SetTEINegativeApparatus} and \cs{SetTEIPositiveApparatus} do
9318% the same as described above for the apparatus criticus converted
9319% in \texttt{TEI xml}.
9320% \begin{macrocode}
9321\NewDocumentCommand{\SetNegativeApparatus}{}{\ekdl@nowittrue}
9322\NewDocumentCommand{\SetPositiveApparatus}{}{\ekdl@nowitfalse}
9323\NewDocumentCommand{\SetTEINegativeApparatus}{}{%
9324 \luadirect{ekdosis.set_negpos_apparatus("neg")}%
9325}
9326\NewDocumentCommand{\SetTEIPositiveApparatus}{}{%
9327 \luadirect{ekdosis.set_negpos_apparatus("pos")}%
9328}
9329% \end{macrocode}
9330% \end{macro}
9331% \end{macro}
9332% \end{macro}
9333% \end{macro}
9221% \begin{macrocode} 9334% \begin{macrocode}
9222\newif\iffootnoterule 9335\newif\iffootnoterule
9223\footnoteruletrue 9336\footnoteruletrue
@@ -9290,7 +9403,7 @@ Sample text with a \textcolor{red}{word} in red.
9290\newlength{\ekd@app@localheight} 9403\newlength{\ekd@app@localheight}
9291% \end{macrocode} 9404% \end{macrocode}
9292% \begin{macro}{\localappheight} 9405% \begin{macro}{\localappheight}
9293% \changes{v1.5}{2025/04/19}{changes the height of the apparatus 9406% \changes{v1.5}{2025/04/21}{changes the height of the apparatus
9294% criticus} 9407% criticus}
9295% \cs{localappheight}\marg{dimen} can be used to change locally the 9408% \cs{localappheight}\marg{dimen} can be used to change locally the
9296% length of \cs{ekd@app@height} set by the |appheight| option of 9409% length of \cs{ekd@app@height} set by the |appheight| option of
@@ -9309,7 +9422,7 @@ Sample text with a \textcolor{red}{word} in red.
9309% \end{macrocode} 9422% \end{macrocode}
9310% \end{macro} 9423% \end{macro}
9311% \begin{macro}{\addtoappheight} 9424% \begin{macro}{\addtoappheight}
9312% \changes{v1.5}{2025/04/19}{increases or decreases the height of the 9425% \changes{v1.5}{2025/04/21}{increases or decreases the height of the
9313% apparatus criticus} 9426% apparatus criticus}
9314% As the name suggests, in contrast to \cs{localappheight}, 9427% As the name suggests, in contrast to \cs{localappheight},
9315% \cs{addtoappheight}\marg{dimen} is used to increase or decrease 9428% \cs{addtoappheight}\marg{dimen} is used to increase or decrease
@@ -9598,7 +9711,7 @@ Sample text with a \textcolor{red}{word} in red.
9598% The following commands are provided to set and control the maximum 9711% The following commands are provided to set and control the maximum
9599% number of lines printed on each page. 9712% number of lines printed on each page.
9600% \begin{macro}{\setmaxlines} 9713% \begin{macro}{\setmaxlines}
9601% \changes{v1.5}{2025/04/19}{limits the number of lines per page} 9714% \changes{v1.5}{2025/04/21}{limits the number of lines per page}
9602% \cs{setmaxlines}\marg{n}, where \meta{n} is a positive integer 9715% \cs{setmaxlines}\marg{n}, where \meta{n} is a positive integer
9603% $\geq 1$, can be used either in the preamble or at any point of the 9716% $\geq 1$, can be used either in the preamble or at any point of the
9604% document to set the maximum number of lines to be printed on each 9717% document to set the maximum number of lines to be printed on each
@@ -9609,7 +9722,7 @@ Sample text with a \textcolor{red}{word} in red.
9609% \end{macrocode} 9722% \end{macrocode}
9610% \end{macro} 9723% \end{macro}
9611% \begin{macro}{\localmaxlines} 9724% \begin{macro}{\localmaxlines}
9612% \changes{v1.5}{2025/04/19}{changes the maximum number of lines 9725% \changes{v1.5}{2025/04/21}{changes the maximum number of lines
9613% locally} 9726% locally}
9614% Once a maximum number of lines per page has been set, 9727% Once a maximum number of lines per page has been set,
9615% \cs{localmaxlines}\marg{n} can be used to adjust this number on a 9728% \cs{localmaxlines}\marg{n} can be used to adjust this number on a
@@ -9622,7 +9735,7 @@ Sample text with a \textcolor{red}{word} in red.
9622% \end{macrocode} 9735% \end{macrocode}
9623% \end{macro} 9736% \end{macro}
9624% \begin{macro}{\addtomaxlines} 9737% \begin{macro}{\addtomaxlines}
9625% \changes{v1.5}{2025/04/19}{adds or subtracts lines from a given page} 9738% \changes{v1.5}{2025/04/21}{adds or subtracts lines from a given page}
9626% Unlike \cs{localmaxlines}, \cs{addtomaxlines}\meta{n} takes as 9739% Unlike \cs{localmaxlines}, \cs{addtomaxlines}\meta{n} takes as
9627% argument the number of lines one wishes to add or substract from the 9740% argument the number of lines one wishes to add or substract from the
9628% number that has been set by \cs{setmaxlines}. As a result, \meta{n} 9741% number that has been set by \cs{setmaxlines}. As a result, \meta{n}
@@ -9635,7 +9748,7 @@ Sample text with a \textcolor{red}{word} in red.
9635% \end{macrocode} 9748% \end{macrocode}
9636% \end{macro} 9749% \end{macro}
9637% \begin{macro}{\nomaxlines} 9750% \begin{macro}{\nomaxlines}
9638% \changes{v1.5}{2025/04/19}{unsets \cs{setmaxlines}} 9751% \changes{v1.5}{2025/04/21}{unsets \cs{setmaxlines}}
9639% \cs{nomaxlines} unsets any limit previously set by \cs{setmaxlines}. 9752% \cs{nomaxlines} unsets any limit previously set by \cs{setmaxlines}.
9640% \begin{macrocode} 9753% \begin{macrocode}
9641\def\nomaxlines{\luadirect{tex.sprint(ekdosis.resetlocalmaxlines())}} 9754\def\nomaxlines{\luadirect{tex.sprint(ekdosis.resetlocalmaxlines())}}
@@ -9699,7 +9812,7 @@ Sample text with a \textcolor{red}{word} in red.
9699% \end{macrocode} 9812% \end{macrocode}
9700% \end{macro} 9813% \end{macro}
9701% \begin{macro}{\App} 9814% \begin{macro}{\App}
9702% \changes{v1.5}{2025/04/19}{To be used conjointly with 9815% \changes{v1.5}{2025/04/21}{To be used conjointly with
9703% \texttt{ekdosis.el}} 9816% \texttt{ekdosis.el}}
9704% In contrast to \cs{app}, \cs{App} takes two mandatory arguments and 9817% In contrast to \cs{app}, \cs{App} takes two mandatory arguments and
9705% accepts one optional argument like so: 9818% accepts one optional argument like so:
@@ -10040,8 +10153,14 @@ Sample text with a \textcolor{red}{word} in red.
10040\newif\ifekdl@nodelim 10153\newif\ifekdl@nodelim
10041\newif\ifekdl@forcedelim 10154\newif\ifekdl@forcedelim
10042\newif\ifekdl@ilabel 10155\newif\ifekdl@ilabel
10156% \newif\ifekdl@nowit % defined above
10043\ekvdefinekeys{lem}{ 10157\ekvdefinekeys{lem}{
10044 code wit = \def\ekdlr@wit{#1}, 10158 code wit = \def\ekdlr@wit{#1},
10159 choice nowit = {true=\ekdl@nowittrue,
10160 false=\ekdl@nowitfalse},
10161 default nowit = true,
10162 unknown-choice nowit = \PackageError{ekdosis}{unknown
10163 nowit=#1}{`nowit' must be either `true' or `false'.},
10045 code source = \def\ekdlr@source{#1}, 10164 code source = \def\ekdlr@source{#1},
10046 code resp = \def\ekdlr@resp{#1}, 10165 code resp = \def\ekdlr@resp{#1},
10047 code alt = \def\ekdlr@alt{#1}, 10166 code alt = \def\ekdlr@alt{#1},
@@ -10136,6 +10255,9 @@ Sample text with a \textcolor{red}{word} in red.
10136 \ekdl@forcenumfalse 10255 \ekdl@forcenumfalse
10137 \ekdl@nonumfalse 10256 \ekdl@nonumfalse
10138 \ekdl@ilabelfalse 10257 \ekdl@ilabelfalse
10258 \ifekd@mapps
10259 \luadirect{tex.sprint(ekdosis.setapp_neg_pos(\luastringO{\ekdan@type}))}%
10260 \fi
10139 \ekvset{lem}{#1}% 10261 \ekvset{lem}{#1}%
10140 \ifekdl@ilabel 10262 \ifekdl@ilabel
10141 \luadirect{ekdosis.dolnlab(\luastringN{#2}, 10263 \luadirect{ekdosis.dolnlab(\luastringN{#2},
@@ -10145,12 +10267,12 @@ Sample text with a \textcolor{red}{word} in red.
10145 \fi 10267 \fi
10146 \null 10268 \null
10147 \ekd@test@lang 10269 \ekd@test@lang
10148 \ifekd@mapps% 10270 \ifekd@mapps
10149 \ifnum% 10271 \ifnum
10150 \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))} 10272 \luadirect{tex.sprint(ekdosis.get_bagunits(\luastringO{\ekdan@type}))}
10151 = 1 10273 = 1
10152 \boolfalse{subsq@unit@\ekdan@type}% 10274 \boolfalse{subsq@unit@\ekdan@type}%
10153 \fi% 10275 \fi
10154 \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}% 10276 \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdan@type})}%
10155 \def\ekd@munit@delim{% 10277 \def\ekd@munit@delim{%
10156 \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}% 10278 \luadirect{tex.sprint(ekdosis.getappdelim(\luastringO{\ekdan@type}))}}%
@@ -10231,7 +10353,9 @@ Sample text with a \textcolor{red}{word} in red.
10231 \ifrtl@app 10353 \ifrtl@app
10232 \ifdefined\ekdlr@postwit% 10354 \ifdefined\ekdlr@postwit%
10233 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi 10355 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi
10234 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi 10356 \unless\ifekdl@nowit
10357 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi
10358 \fi
10235 \ifdefined\ekdlr@prewit% 10359 \ifdefined\ekdlr@prewit%
10236 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi 10360 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi
10237 \ifdefined\ekdlr@resp\space\getsiglum{\ekdlr@resp}\else\fi 10361 \ifdefined\ekdlr@resp\space\getsiglum{\ekdlr@resp}\else\fi
@@ -10239,7 +10363,9 @@ Sample text with a \textcolor{red}{word} in red.
10239 \else 10363 \else
10240 \ifdefined\ekdlr@prewit% 10364 \ifdefined\ekdlr@prewit%
10241 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi 10365 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi
10242 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi 10366 \unless\ifekdl@nowit
10367 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi
10368 \fi
10243 \ifdefined\ekdlr@postwit% 10369 \ifdefined\ekdlr@postwit%
10244 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi 10370 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi
10245 \ifdefined\ekdlr@source\space\getsiglum{\ekdlr@source}\else\fi 10371 \ifdefined\ekdlr@source\space\getsiglum{\ekdlr@source}\else\fi
@@ -10290,7 +10416,9 @@ Sample text with a \textcolor{red}{word} in red.
10290 \fi 10416 \fi
10291 \ifdefined\ekdlr@prewit% 10417 \ifdefined\ekdlr@prewit%
10292 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi 10418 \space\unexpanded\expandafter{\ekdlr@prewit}\space\else\fi
10293 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi 10419 \unless\ifekdl@nowit
10420 \ifdefined\ekdlr@wit\space\getsiglum{\ekdlr@wit}\else\fi
10421 \fi
10294 \ifdefined\ekdlr@postwit% 10422 \ifdefined\ekdlr@postwit%
10295 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi 10423 \space\unexpanded\expandafter{\ekdlr@postwit}\else\fi
10296 \ifdefined\ekdlr@source\space\getsiglum{\ekdlr@source}\else\fi 10424 \ifdefined\ekdlr@source\space\getsiglum{\ekdlr@source}\else\fi
@@ -10684,7 +10812,7 @@ Sample text with a \textcolor{red}{word} in red.
10684} 10812}
10685% \end{macrocode} 10813% \end{macrocode}
10686% \begin{macro}{\SetFootnotes} 10814% \begin{macro}{\SetFootnotes}
10687% \changes{v1.5}{2025/04/19}{footnotes combined into a single 10815% \changes{v1.5}{2025/04/21}{footnotes combined into a single
10688% paragraph} \cs{SetFootnotes}\marg{options} can be used in the 10816% paragraph} \cs{SetFootnotes}\marg{options} can be used in the
10689% preamble or at any point of the document. |layout=paragraph| 10817% preamble or at any point of the document. |layout=paragraph|
10690% instructs \pkg{ekdosis} to combine all footnotes into a single 10818% instructs \pkg{ekdosis} to combine all footnotes into a single
@@ -10915,7 +11043,7 @@ Sample text with a \textcolor{red}{word} in red.
10915% \end{macro} 11043% \end{macro}
10916% \paragraph{Lacunae} 11044% \paragraph{Lacunae}
10917% \begin{macro}{\ilabel} 11045% \begin{macro}{\ilabel}
10918% \changes{v1.5}{2025/04/19}{recalls and sets the ending label of 11046% \changes{v1.5}{2025/04/21}{recalls and sets the ending label of
10919% lemmas used to mark lacunae in witnesses} When \cs{lem} has been 11047% lemmas used to mark lacunae in witnesses} When \cs{lem} has been
10920% used with the optional argument |ilabel=<label>|, 11048% used with the optional argument |ilabel=<label>|,
10921% \cs{ilabel}\marg{label} must be used to mark the point where the 11049% \cs{ilabel}\marg{label} must be used to mark the point where the
@@ -11255,7 +11383,7 @@ Sample text with a \textcolor{red}{word} in red.
11255% \end{macrocode} 11383% \end{macrocode}
11256% \end{macro} 11384% \end{macro}
11257% \begin{macro}{\ekdEOprint} 11385% \begin{macro}{\ekdEOprint}
11258% \changes{v1.5}{2025/04/19}{Sets headers and footers on 11386% \changes{v1.5}{2025/04/21}{Sets headers and footers on
11259% \enquote{paired} facing pages} 11387% \enquote{paired} facing pages}
11260% To set headers and footers on \enquote{paired} facing pages, 11388% To set headers and footers on \enquote{paired} facing pages,
11261% \cs{ekdEOprint} accepts two mandatory, self-evident arguments, like 11389% \cs{ekdEOprint} accepts two mandatory, self-evident arguments, like
@@ -11295,7 +11423,7 @@ Sample text with a \textcolor{red}{word} in red.
11295% counter to set the value of the page numbers. This counter should be 11423% counter to set the value of the page numbers. This counter should be
11296% incremented every two pages. 11424% incremented every two pages.
11297% \begin{counter}{pairedpage} 11425% \begin{counter}{pairedpage}
11298% \changes{v1.5}{2025/04/19}{A counter incremented every two pages} 11426% \changes{v1.5}{2025/04/21}{A counter incremented every two pages}
11299% |pairedpage| is first set as a global counter:--- 11427% |pairedpage| is first set as a global counter:---
11300% \begin{macrocode} 11428% \begin{macrocode}
11301\newcounter{pairedpage} 11429\newcounter{pairedpage}
@@ -11303,19 +11431,19 @@ Sample text with a \textcolor{red}{word} in red.
11303% \end{macrocode} 11431% \end{macrocode}
11304% \end{counter} 11432% \end{counter}
11305% \begin{macro}{\setpairedpagenum} 11433% \begin{macro}{\setpairedpagenum}
11306% \changes{v1.5}{2025/04/19}{sets the same page number on paired 11434% \changes{v1.5}{2025/04/21}{sets the same page number on paired
11307% pages} \cs{setpairedpagenum}\marg{number} is used just ahead of 11435% pages} \cs{setpairedpagenum}\marg{number} is used just ahead of
11308% the alignment environment to set the number of the first left-hand 11436% the alignment environment to set the number of the first left-hand
11309% paired page. 11437% paired page.
11310% \begin{macro}{\setpairedpage} 11438% \begin{macro}{\setpairedpage}
11311% \changes{v1.5}{2025/04/19}{sets the page number of the first paired 11439% \changes{v1.5}{2025/04/21}{sets the page number of the first paired
11312% page} \cs{setpairedpage} is an argument-less command meant to be 11440% page} \cs{setpairedpage} is an argument-less command meant to be
11313% issued in commands used to set headers or footers before 11441% issued in commands used to set headers or footers before
11314% \cs{thepage}. This command has the counter |pairedpage| 11442% \cs{thepage}. This command has the counter |pairedpage|
11315% incremented on right-hand pages only, and sets |page| $\leftarrow$ 11443% incremented on right-hand pages only, and sets |page| $\leftarrow$
11316% |pairedpage| on every page. 11444% |pairedpage| on every page.
11317% \begin{macro}{\resetpagenumber} 11445% \begin{macro}{\resetpagenumber}
11318% \changes{v1.5}{2025/04/19}{resets normal running page numbers} 11446% \changes{v1.5}{2025/04/21}{resets normal running page numbers}
11319% \cs{resetpagenumber} must be used right out of \enquote{mirrored} 11447% \cs{resetpagenumber} must be used right out of \enquote{mirrored}
11320% paired pages alignment environments. This argument-less command 11448% paired pages alignment environments. This argument-less command
11321% corrects any numbering error on the page following the edition 11449% corrects any numbering error on the page following the edition
@@ -12333,7 +12461,13 @@ local function app_totei(str)
12333 opt = string.sub(opt, 2, -2) 12461 opt = string.sub(opt, 2, -2)
12334 arg = string.sub(arg, 2, -2) 12462 arg = string.sub(arg, 2, -2)
12335 opt = get_attr_value(opt, "type") 12463 opt = get_attr_value(opt, "type")
12336 if opt ~= "" then opt = " type=\""..opt.."\"" else end 12464 if opt ~= ""
12465 then
12466 opti = "apptype={"..opt.."}"
12467 opt = " type=\""..opt.."\""
12468 arg = string.gsub(arg, "(\\lem%s?%[)", "%1"..opti..",")
12469 else
12470 end
12337 return app_totei(string.format("<%s%s>%s</%s>", 12471 return app_totei(string.format("<%s%s>%s</%s>",
12338 cmd, opt, arg, cmd)) 12472 cmd, opt, arg, cmd))
12339 end) 12473 end)
@@ -12365,6 +12499,201 @@ local function rdgGrp_totei(str)
12365 return str 12499 return str
12366end 12500end
12367 12501
12502-- handle multiple layers in apparatuses
12503--
12504local apparatuses = {}
12505local bagunits = {}
12506local glimit = nil
12507local gunits = 0
12508
12509function ekdosis.newapparatus(teitype,
12510 appdir,
12511 apprule,
12512 appdelim,
12513 appsep,
12514 appsubsep,
12515 appbhook,
12516 appehook,
12517 applimit,
12518 applang,
12519 appnotelang,
12520 appnegative,
12521 appTEInegative)
12522 if isintable(apparatuses, teitype)
12523 then
12524 tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
12525 ..teitype..
12526 "\" already exists.}}")
12527 else
12528 table.insert(apparatuses, {a = teitype,
12529 direction = appdir,
12530 rule = apprule,
12531 delim = appdelim,
12532 sep = appsep,
12533 subsep = appsubsep,
12534 bhook = appbhook,
12535 ehook = appehook,
12536 limit = applimit,
12537 lang = applang,
12538 notelang = appnotelang,
12539 negative = appnegative,
12540 TEInegative = appTEInegative})
12541 end
12542 bagunits[teitype] = 1
12543 return true
12544end
12545
12546function ekdosis.getapplang(teitype)
12547 i = get_a_index(teitype, apparatuses)
12548 if apparatuses[i].lang ~= ""
12549 then
12550 return apparatuses[i].lang
12551 else
12552 return "\\languagename"
12553 end
12554end
12555
12556function ekdosis.getappnotelang(teitype)
12557 i = get_a_index(teitype, apparatuses)
12558 if apparatuses[i].notelang ~= ""
12559 then
12560 return apparatuses[i].notelang
12561 else
12562 return "\\languagename"
12563 end
12564end
12565
12566function ekdosis.setapp_neg_pos(teitype)
12567 i = get_a_index(teitype, apparatuses)
12568 if apparatuses[i].negative == "yes"
12569 then
12570 return "\\csname ekdl@nowittrue\\endcsname"
12571 else
12572 return ""
12573 end
12574end
12575
12576local function getapp_TEI_neg_pos(teitype)
12577 i = get_a_index(teitype, apparatuses)
12578 if apparatuses[i].TEInegative == "yes"
12579 then
12580 return "yes"
12581 else
12582 return "no"
12583 end
12584end
12585
12586function ekdosis.getappdelim(str)
12587 for i = 1,#apparatuses
12588 do
12589 if apparatuses[i].a == str then
12590 delimfound = apparatuses[i].delim
12591 break
12592 end
12593 end
12594 return delimfound
12595end
12596
12597function ekdosis.get_bagunits(teitype)
12598 return bagunits[teitype]
12599end
12600
12601local function getapplimit(teitype)
12602 for i = 1,#apparatuses
12603 do
12604 if apparatuses[i].a == teitype then
12605 limitfound = apparatuses[i].limit
12606 break
12607 end
12608 end
12609 if tonumber(limitfound) ~= nil
12610 then
12611 if tonumber(limitfound) < 10
12612 then
12613 return 0
12614 else
12615 return limitfound
12616 end
12617 else
12618 return 0
12619 end
12620end
12621
12622function ekdosis.limit_bagunits(teitype)
12623 local limit = tonumber(getapplimit(teitype))
12624 if glimit then
12625 glimit = tonumber(glimit)
12626 gunits = tonumber(gunits)
12627 if glimit >= 10 and gunits >= glimit
12628 then
12629 bagunits[teitype] = 2
12630 gunits = 0
12631 return "\\pagebreak"
12632 else
12633 if limit >= 10 and bagunits[teitype] >= limit
12634 then
12635 bagunits[teitype] = 2
12636 gunits = 0
12637 return "\\pagebreak"
12638 else
12639 return ""
12640 end
12641 end
12642 else
12643 if limit >= 10 and bagunits[teitype] >= limit
12644 then
12645 bagunits[teitype] = 2
12646 gunits = 1
12647 return "\\pagebreak"
12648 else
12649 return ""
12650 end
12651 end
12652end
12653
12654function ekdosis.addto_bagunits(teitype, n)
12655 n = tonumber(n)
12656 if glimit then gunits = gunits - n end
12657 if tonumber(getapplimit(teitype)) ~= 0
12658 then
12659 bagunits[teitype] = bagunits[teitype] - n
12660 end
12661end
12662
12663function ekdosis.increment_bagunits(teitype)
12664 if glimit then gunits = gunits + 1 end
12665 bagunits[teitype] = (bagunits[teitype] or 0) + 1
12666end
12667
12668function ekdosis.setglimit(n)
12669 if math.tointeger(n)
12670 then
12671 glimit = math.tointeger(math.abs(n))
12672 else
12673 glimit = nil
12674 end
12675end
12676
12677local function reset_bagunits()
12678 if glimit then gunits = 0 end
12679 for i = 1,#apparatuses
12680 do
12681 bagunits[apparatuses[i].a] = 1
12682 end
12683end
12684
12685local negative_apparatus = false
12686
12687function ekdosis.set_negpos_apparatus(str)
12688 if str == "neg"
12689 then
12690 negative_apparatus = true
12691 else
12692 negative_apparatus = false
12693 end
12694 return true
12695end
12696
12368local function lem_rdg_totei(str) 12697local function lem_rdg_totei(str)
12369 str = gsub(str, 12698 str = gsub(str,
12370 spcenc^-1 * 12699 spcenc^-1 *
@@ -12379,8 +12708,20 @@ local function lem_rdg_totei(str)
12379 arg = string.sub(arg, 2, -2) 12708 arg = string.sub(arg, 2, -2)
12380 -- opt = get_attr_value(opt, "wit") 12709 -- opt = get_attr_value(opt, "wit")
12381 -- 12710 --
12382 teiwit = get_attr_value(opt, "wit") 12711 teiapptype = get_attr_value(opt, "apptype")
12383 if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end 12712 if next(apparatuses) ~= nil
12713 then
12714 if teiapptype == "" then teiapptype = "default" end
12715 if getapp_TEI_neg_pos(teiapptype) == "yes" then negative_apparatus = true end
12716 else
12717 end
12718 if negative_apparatus and cmd == "lem"
12719 then
12720 teiwit = ""
12721 else
12722 teiwit = get_attr_value(opt, "wit")
12723 if teiwit ~= "" then teiwit = " wit=\""..ekdosis.getsiglum(teiwit, "tei").."\"" else end
12724 end
12384 teisource = get_attr_value(opt, "source") 12725 teisource = get_attr_value(opt, "source")
12385 if teisource ~= "" then teisource = " source=\""..ekdosis.getsiglum(teisource, "tei").."\"" else end 12726 if teisource ~= "" then teisource = " source=\""..ekdosis.getsiglum(teisource, "tei").."\"" else end
12386 teiresp = get_attr_value(opt, "resp") 12727 teiresp = get_attr_value(opt, "resp")
@@ -13881,165 +14222,6 @@ function ekdosis.setheightandprintapparatus()
13881 end 14222 end
13882end 14223end
13883 14224
13884-- handle multiple layers in apparatuses
13885--
13886local apparatuses = {}
13887local bagunits = {}
13888local glimit = nil
13889local gunits = 0
13890
13891function ekdosis.newapparatus(teitype,
13892 appdir,
13893 apprule,
13894 appdelim,
13895 appsep,
13896 appsubsep,
13897 appbhook,
13898 appehook,
13899 applimit,
13900 applang,
13901 appnotelang)
13902 if isintable(apparatuses, teitype)
13903 then
13904 tex.print("\\unexpanded{\\PackageWarning{ekdosis}{\""
13905 ..teitype..
13906 "\" already exists.}}")
13907 else
13908 table.insert(apparatuses, {a = teitype,
13909 direction = appdir,
13910 rule = apprule,
13911 delim = appdelim,
13912 sep = appsep,
13913 subsep = appsubsep,
13914 bhook = appbhook,
13915 ehook = appehook,
13916 limit = applimit,
13917 lang = applang,
13918 notelang = appnotelang})
13919 end
13920 bagunits[teitype] = 1
13921 return true
13922end
13923
13924function ekdosis.getapplang(teitype)
13925 i = get_a_index(teitype, apparatuses)
13926 if apparatuses[i].lang ~= ""
13927 then
13928 return apparatuses[i].lang
13929 else
13930 return "\\languagename"
13931 end
13932end
13933
13934function ekdosis.getappnotelang(teitype)
13935 i = get_a_index(teitype, apparatuses)
13936 if apparatuses[i].notelang ~= ""
13937 then
13938 return apparatuses[i].notelang
13939 else
13940 return "\\languagename"
13941 end
13942end
13943
13944function ekdosis.getappdelim(str)
13945 for i = 1,#apparatuses
13946 do
13947 if apparatuses[i].a == str then
13948 delimfound = apparatuses[i].delim
13949 break
13950 end
13951 end
13952 return delimfound
13953end
13954
13955function ekdosis.get_bagunits(teitype)
13956 return bagunits[teitype]
13957end
13958
13959local function getapplimit(teitype)
13960 for i = 1,#apparatuses
13961 do
13962 if apparatuses[i].a == teitype then
13963 limitfound = apparatuses[i].limit
13964 break
13965 end
13966 end
13967 if tonumber(limitfound) ~= nil
13968 then
13969 if tonumber(limitfound) < 10
13970 then
13971 return 0
13972 else
13973 return limitfound
13974 end
13975 else
13976 return 0
13977 end
13978end
13979
13980function ekdosis.limit_bagunits(teitype)
13981 local limit = tonumber(getapplimit(teitype))
13982 if glimit then
13983 glimit = tonumber(glimit)
13984 gunits = tonumber(gunits)
13985 if glimit >= 10 and gunits >= glimit
13986 then
13987 bagunits[teitype] = 2
13988 gunits = 0
13989 return "\\pagebreak"
13990 else
13991 if limit >= 10 and bagunits[teitype] >= limit
13992 then
13993 bagunits[teitype] = 2
13994 gunits = 0
13995 return "\\pagebreak"
13996 else
13997 return ""
13998 end
13999 end
14000 else
14001 if limit >= 10 and bagunits[teitype] >= limit
14002 then
14003 bagunits[teitype] = 2
14004 gunits = 1
14005 return "\\pagebreak"
14006 else
14007 return ""
14008 end
14009 end
14010end
14011
14012function ekdosis.addto_bagunits(teitype, n)
14013 n = tonumber(n)
14014 if glimit then gunits = gunits - n end
14015 if tonumber(getapplimit(teitype)) ~= 0
14016 then
14017 bagunits[teitype] = bagunits[teitype] - n
14018 end
14019end
14020
14021function ekdosis.increment_bagunits(teitype)
14022 if glimit then gunits = gunits + 1 end
14023 bagunits[teitype] = (bagunits[teitype] or 0) + 1
14024end
14025
14026function ekdosis.setglimit(n)
14027 if math.tointeger(n)
14028 then
14029 glimit = math.tointeger(math.abs(n))
14030 else
14031 glimit = nil
14032 end
14033end
14034
14035local function reset_bagunits()
14036 if glimit then gunits = 0 end
14037 for i = 1,#apparatuses
14038 do
14039 bagunits[apparatuses[i].a] = 1
14040 end
14041end
14042
14043function ekdosis.appin(str, teitype) 14225function ekdosis.appin(str, teitype)
14044 local f = io.open(tex.jobname.."_tmp.ekd", "a+") 14226 local f = io.open(tex.jobname.."_tmp.ekd", "a+")
14045 if next(apparatuses) == nil 14227 if next(apparatuses) == nil