From 90cf4bb17e7fa6363050630b74668722dd857fbe Mon Sep 17 00:00:00 2001
From: Robert Alessi <alessi@robertalessi.net>
Date: Thu, 22 Jun 2023 18:54:08 +0200
Subject: new functions for combining footnotes into a single paragraph

---
 ekdosis.dtx | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 164 insertions(+), 30 deletions(-)

(limited to 'ekdosis.dtx')

diff --git a/ekdosis.dtx b/ekdosis.dtx
index 203415b..8230ead 100644
--- a/ekdosis.dtx
+++ b/ekdosis.dtx
@@ -59,7 +59,7 @@ Alessi <alessi@robertalessi.net>
 %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
 %<package>\ProvidesPackage{ekdosis}
 %<*package>
-    [2023/06/17 v1.5-dev Typesetting TEI xml-compliant critical editions]
+    [2023/06/22 v1.5-dev Typesetting TEI xml-compliant critical editions]
 %</package>
 %<*driver>
 \begin{filecontents}[noheader,overwrite]{bibdata.xml}
@@ -372,6 +372,15 @@ Alessi <alessi@robertalessi.net>
   version =	 {1.0}
 }
 
+@Software{footmisc,
+  title =	 {The Footmisc package},
+  titleaddon =	 {A range of footnote options},
+  author =	 {Mittelbach, Frank and Fairbairns, Robin},
+  url =		 {https://ctan.org/pkg/footmisc},
+  date =	 {2022-05-26},
+  version =	 {6.0e},
+}
+
 @Software{keyfloat,
   title =	 {The Keyfloat package},
   titleaddon =	 {Provides a key/value interface for generating
@@ -3618,6 +3627,13 @@ texts=latin[xml:lang="la"]+\textcolor{red}{;}+
 % just loading the \pkg{fnpos} package in the
 % preamble.\footcite{fnpos}
 %
+% \danger The \pkg{footmisc} package\footcite{footmisc} is not
+% compatible with \pkg{ekdosis}. More precisely, \pkg{footmisc} is
+% incompatible with the way the \cs{footnote} command is defined
+% inside the |alignment| environment. Therefore, \pkg{footmisc} can
+% only be used on the condition that no regular \cs{footnote} be
+% inserted in the |alignment| environment.
+% 
 % \section{Laying Out the Apparatus Criticus}
 % \label{sec:apparatus-layout}
 %
@@ -4392,6 +4408,9 @@ argument of the
 % element (ll.~5--7). Otherwise, the \texttt{TEI} output would not be
 % valid.
 %
+% \subsection{Footnotes Combined Into a Single Paragraph}
+% \label{sec:footnotes}
+%
 % \needspace{4\baselineskip}
 % \section{Poetry}
 % \label{sec:poetry}
@@ -8225,7 +8244,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \paragraph{\textsf{ekdosis} Symbol}
 % \begin{macro}{\eKd}
-% \changes{v1.5}{2023/06/17}{Prints \textsf{ekdosis} indentifying
+% \changes{v1.5}{2023/06/22}{Prints \textsf{ekdosis} indentifying
 % symbol} As of v1.5, \pkg{ekdosis} has its own identifying
 % symbol. It is produced by \cs{eKd} and best printed with the Old
 % Standard Greek font.
@@ -8488,7 +8507,7 @@ Sample text with a \textcolor{red}{word} in red.
 % \begin{macro}{\teidirectE}
 % \changes{v1.3}{2021/08/18}{direct insertion of elements in the
 % \texttt{TEI xml} file}
-% \changes{v1.5}{2023/06/17}{direct insertion of empty elements in the
+% \changes{v1.5}{2023/06/22}{direct insertion of empty elements in the
 % \texttt{TEI xml} file}
 % \cs{teidirect}\oarg{xml attributes}\marg{xml element}\marg{code}
 % does nothing in \LaTeX. It is only used to insert elements in the
@@ -8503,7 +8522,7 @@ Sample text with a \textcolor{red}{word} in red.
 % \end{macro}
 % \end{macro}
 % \begin{macro}{\getTEIxmlid}
-% \changes{v1.5}{2023/06/17}{returns \texttt{TEI xml:ids} from a
+% \changes{v1.5}{2023/06/22}{returns \texttt{TEI xml:ids} from a
 % csv-list of ids} This command returns from a csv-list of unique
 % identifiers declared in commands such as \cs{DeclareWitness} and the
 % like a space-separated list of their corresponding |xml:id|s, each
@@ -8979,7 +8998,7 @@ Sample text with a \textcolor{red}{word} in red.
 \newlength{\ekd@app@localheight}
 %    \end{macrocode}
 % \begin{macro}{\localappheight}
-% \changes{v1.5}{2023/06/17}{changes the height of the apparatus
+% \changes{v1.5}{2023/06/22}{changes the height of the apparatus
 % criticus}
 % \cs{localappheight}\marg{dimen} can be used to change locally the
 % length of \cs{ekd@app@height} set by the |appheight| option of
@@ -8998,7 +9017,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\addtoappheight}
-% \changes{v1.5}{2023/06/17}{increases or decreases the height of the
+% \changes{v1.5}{2023/06/22}{increases or decreases the height of the
 % apparatus criticus}
 % As the name suggests, in contrast to \cs{localappheight},
 % \cs{addtoappheight}\marg{dimen} is used to increase or decrease
@@ -9285,7 +9304,7 @@ Sample text with a \textcolor{red}{word} in red.
 % The following commands are provided to set and control the maximum
 % number of lines printed on each page.
 % \begin{macro}{\setmaxlines}
-% \changes{v1.5}{2023/06/17}{limits the number of lines per page}
+% \changes{v1.5}{2023/06/22}{limits the number of lines per page}
 % \cs{setmaxlines}\marg{n}, where \meta{n} is a positive integer
 % $\geq 1$, can be used either in the preamble or at any point of the
 % document to set the maximum number of lines to be printed on each
@@ -9296,7 +9315,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\localmaxlines}
-% \changes{v1.5}{2023/06/17}{changes the maximum number of lines
+% \changes{v1.5}{2023/06/22}{changes the maximum number of lines
 % locally}
 % Once a maximum number of lines per page has been set,
 % \cs{localmaxlines}\marg{n} can be used to adjust this number on a
@@ -9309,7 +9328,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\addtomaxlines}
-% \changes{v1.5}{2023/06/17}{adds or subtracts lines from a given page}
+% \changes{v1.5}{2023/06/22}{adds or subtracts lines from a given page}
 % Unlike \cs{localmaxlines}, \cs{addtomaxlines}\meta{n} takes as
 % argument the number of lines one wishes to add or substract from the
 % number that has been set by \cs{setmaxlines}. As a result, \meta{n}
@@ -9322,7 +9341,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\nomaxlines}
-% \changes{v1.5}{2023/06/17}{unsets \cs{setmaxlines}}
+% \changes{v1.5}{2023/06/22}{unsets \cs{setmaxlines}}
 % \cs{nomaxlines} unsets any limit previously set by \cs{setmaxlines}.
 %    \begin{macrocode}
 \def\nomaxlines{\luadirect{tex.sprint(ekdosis.resetlocalmaxlines())}}
@@ -9386,7 +9405,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\App}
-% \changes{v1.5}{2023/06/17}{To be used conjointly with
+% \changes{v1.5}{2023/06/22}{To be used conjointly with
 % \texttt{ekdosis.el}}
 % In contrast to \cs{app}, \cs{App} takes two mandatory arguments and
 % accepts one optional argument like so:
@@ -9950,13 +9969,13 @@ Sample text with a \textcolor{red}{word} in red.
     }%
   }%
   \ifekd@mapps
-      \append@app[\ekdan@type]{\rdg@app}%
+    \append@app[\ekdan@type]{\rdg@app}%
   \else
-  \append@app{\rdg@app}%
+    \append@app{\rdg@app}%
   \fi
-  \fi
-  \egroup
-  \ekd@subsq@rdgtrue
+\fi
+\egroup
+\ekd@subsq@rdgtrue
 }
 %    \end{macrocode}
 % \end{macro}
@@ -10059,11 +10078,11 @@ Sample text with a \textcolor{red}{word} in red.
           \ifbool{ekd@lang@pkg}%
           {{\noexpand\selectlanguage{\app@note@lang}\unexpanded{#2}}}{%
             {\unexpanded{#2}}}}}%
-  \ifekd@mapps%
-  \unconditional@appin[\ekdan@type]{\note@contents}%
-  \else%
-  \unconditional@appin{\note@contents}%
-  \fi%
+  \ifekd@mapps
+    \unconditional@appin[\ekdan@type]{\note@contents}%
+  \else
+    \unconditional@appin{\note@contents}%
+  \fi
     \luadirect{ekdosis.setprevnotelab(\luastringO{\ekdn@labelb})}%
   \egroup
   \subsq@unittrue
@@ -10158,6 +10177,92 @@ Sample text with a \textcolor{red}{word} in red.
 }
 %    \end{macrocode}
 % \end{macro}
+% \paragraph{Combining Footnotes Into a Single Paragraph}
+% Footnotes combined as one paragraph are inserted with the standard
+% \cs{footnote} command which is redirected to
+% \cs{unconditional@appin} when |ekd@parafootnotes| is set to
+% |true|:---
+%    \begin{macrocode}
+\newif\ifekd@parafootnotes
+%    \end{macrocode}
+% The keys to be used by \cs{SetFootnotes} are defined below:---
+%    \begin{macrocode}
+\ekvdefinekeys{ekd@footnotes}{
+  choice layout = {
+    default = \relax,
+    paragraph = \ekd@parafootnotestrue
+  },
+  initial layout = default,
+  unknown-choice layout = \PackageError{ekdosis}{unknown
+    layout=#1}{`layout' must be either `default' or `paragraph'.},
+  store type = \ekdfn@type,
+  initial type = default,
+  code textfnmark = \protected\def\ekd@around@fnmark##1{#1},
+  initial textfnmark = \textsuperscript{#1},
+  code appfnmark = \protected\def\ekdappfnmark##1{#1},
+  initial appfnmark = \textsuperscript{#1}
+}
+\newif\ifekd@fnmark
+\ekvdefinekeys{ekd@infootnotes}{
+  store type = \ekdfn@type,
+  initial type = default,
+  code mark = \ekd@fnmarktrue
+              \protected\def\ekd@fnmark@value{#1}
+}
+%    \end{macrocode}
+% \begin{macro}{\SetFootnotes}
+%   \changes{v1.5}{2023/06/22}{footnotes combined into a single
+%   paragraph} \cs{SetFootnotes}\marg{options} can be used in the
+%   preamble or at any point of the document. |layout=paragraph|
+%   instructs \pkg{ekdosis} to combine all footnotes into a single
+%   paragraph. Then the other |key-value| options that are defined
+%   just above allow to format the marks and specify the layer where
+%   the notes are to be printed.
+%    \begin{macrocode}
+\ekvsetdef\SetFootnotes{ekd@footnotes}
+%    \end{macrocode}
+% \end{macro} 
+% \begin{macro}{\ekd@parafootnote}
+%   \cs{ekd@parafootnote}\oarg{layer}\marg{contents} holds the new
+%   definition of \cs{footnote}. This command accepts an optional
+%   argument that can be used to specify the layer in which the
+%   contents of the footnote is to be printed.
+%    \begin{macrocode}
+\NewDocumentCommand{\ekd@parafootnote}{O{} m}{%
+  \ifekd@state
+    \bgroup
+    \ekvset{ekd@infootnotes}{#1}%
+    \ifekd@fnmark
+      \edef\ekd@parafn@mark{%
+        \LRnum{\unexpanded\expandafter{\ekd@fnmark@value}}}%
+      \edef\ekd@inparafn@mark{%
+        \ekdappfnmark{\LRnum{\unexpanded\expandafter{\ekd@fnmark@value}}}}%
+    \else
+      \refstepcounter{footnote}%
+      \edef\ekd@parafn@mark{\LRnum{\thefootnote}}%
+      \edef\ekd@inparafn@mark{\ekdappfnmark{\LRnum{\thefootnote}}}%
+    \fi
+    \leavevmode
+    \stepcounter{ekd@lab}%
+    \zlabel{ekd:\theekd@lab}%
+    \luadirect{ekdosis.storeabspg(
+      \luastring{\zref@extract{ekd:\theekd@lab}{abspage}})}%
+    \add@apparatus
+    \luadirect{ekdosis.increment_bagunits(\luastringO{\ekdfn@type})}%
+    \luadirect{tex.sprint(ekdosis.limit_bagunits(\luastringO{\ekdan@type}))}%
+    \ekd@around@fnmark{\ekd@parafn@mark}%
+    \ifekd@mapps
+      \unconditional@appin[\ekdfn@type]{\ekd@inparafn@mark #2}%
+    \else
+      \unconditional@appin{\ekd@inparafn@mark #2}%
+    \fi
+    \egroup
+  \else
+    \footnote{#2}%
+  \fi
+}
+%    \end{macrocode}
+% \end{macro}
 % \paragraph{Emendations and Conjectures}
 % Here follows the |key-value| options to be used by
 % \cs{SetCritSymbols} below:---
@@ -10270,7 +10375,7 @@ Sample text with a \textcolor{red}{word} in red.
 % \end{macro}
 % \paragraph{Lacunae}
 % \begin{macro}{\ilabel}
-% \changes{v1.5}{2023/06/17}{recalls and sets the ending label of
+% \changes{v1.5}{2023/06/22}{recalls and sets the ending label of
 % lemmas used to mark lacunae in witnesses} When \cs{lem} has been
 % used with the optional argument |ilabel=<label>|,
 % \cs{ilabel}\marg{label} must be used to mark the point where the
@@ -10313,7 +10418,11 @@ Sample text with a \textcolor{red}{word} in red.
 % Start and stop |ekdosis|:
 %    \begin{macrocode}
 \NewDocumentCommand{\EkdosisOn}{}{%
-  \ekd@statetrue}
+  \ekd@statetrue
+  \ifekd@parafootnotes
+    \RenewCommandCopy\footnote\ekd@parafootnote
+  \fi
+}
 \NewDocumentCommand{\EkdosisOff}{}{%
   \ekd@statefalse%
 }
@@ -10413,6 +10522,9 @@ Sample text with a \textcolor{red}{word} in red.
   \ifekd@hidelinenumbers
     \def\thelinenumber{}%
   \fi
+  \ifekd@parafootnotes
+    \RenewCommandCopy\footnote\ekd@parafootnote
+  \fi
 }
 \NewDocumentCommand{\EkdosisColStop}{}{%
   \stepcounter{ekd@lab}%
@@ -10592,7 +10704,7 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\ekdEOprint}
-% \changes{v1.5}{2023/06/17}{Sets headers and footers on
+% \changes{v1.5}{2023/06/22}{Sets headers and footers on
 % \enquote{paired} facing pages}
 % To set headers and footers on \enquote{paired} facing pages,
 % \cs{ekdEOprint} accepts two mandatory, self-evident arguments, like
@@ -10632,7 +10744,7 @@ Sample text with a \textcolor{red}{word} in red.
 % counter to set the value of the page numbers. This counter should be
 % incremented every two pages.
 % \begin{counter}{pairedpage}
-% \changes{v1.5}{2023/06/17}{A counter incremented every two pages}
+% \changes{v1.5}{2023/06/22}{A counter incremented every two pages}
 % |pairedpage| is first set as a global counter:---
 %    \begin{macrocode}
 \newcounter{pairedpage}
@@ -10640,19 +10752,19 @@ Sample text with a \textcolor{red}{word} in red.
 %    \end{macrocode}
 % \end{counter}
 % \begin{macro}{\setpairedpagenum}
-%   \changes{v1.5}{2023/06/17}{sets the same page number on paired
+%   \changes{v1.5}{2023/06/22}{sets the same page number on paired
 %   pages} \cs{setpairedpagenum}\marg{number} is used just ahead of
 %   the alignment environment to set the number of the first left-hand
 %   paired page.
 % \begin{macro}{\setpairedpage}
-%   \changes{v1.5}{2023/06/17}{sets the page number of the first paired
+%   \changes{v1.5}{2023/06/22}{sets the page number of the first paired
 %   page} \cs{setpairedpage} is an argument-less command meant to be
 %   issued in commands used to set headers or footers before
 %   \cs{thepage}. This command has the counter |pairedpage|
 %   incremented on right-hand pages only, and sets |page| $\leftarrow$
 %   |pairedpage| on every page.
 % \begin{macro}{\resetpagenumber}
-%   \changes{v1.5}{2023/06/17}{resets normal running page numbers}
+%   \changes{v1.5}{2023/06/22}{resets normal running page numbers}
 %   \cs{resetpagenumber} must be used right out of \enquote{mirrored}
 %   paired pages alignment environments. This argument-less command
 %   corrects any numbering error on the page following the edition
@@ -11031,7 +11143,8 @@ 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 footnote = lpeg.Cs(lpeg.P("footnote"))
+local note = lpeg.Cs(lpeg.P("note"))
 local inlem = lpeg.Cs{ "<lem" * ((1 - (lpeg.P"<lem" + lpeg.P"</lem>")) + lpeg.V(1))^0 * "</lem>" }
 local inanchor = lpeg.Cs{ "<anchor" * ((1 - (lpeg.P"<" + lpeg.P">")) + lpeg.V(1))^0 * ">" }
 local inopeningnote = lpeg.Cs{ "<note" * ((1 - (lpeg.P"<" + lpeg.P">")) + lpeg.V(1))^0 * ">" }
@@ -11403,7 +11516,7 @@ local cmdtotags = {
    {a="RLfootnote", b="note", c=" place=\"bottom\""},
    {a="enquote *", b="quote", c=""},
    {a="marginpar", b="note", c=" place=\"margin\""},
-   {a="footnote", b="note", c=" place=\"bottom\""},
+   -- {a="footnote", b="note", c=" place=\"bottom\""},
    {a="enquote", b="quote", c=""},
    {a="prname *", b="span",
     c=" xml:lang=\"ar-Latn\" type=\"transliterated\""},
@@ -11578,6 +11691,26 @@ local function xml_entities(str)
    return str
 end
 
+local function footnote_totei(str)
+   str = gsub(str, dblbkslash * footnote * spce^-1 * bcbraces, "%1%2%3[]%4")
+   str = gsub(str,
+	      dblbkslash *
+		 footnote *
+		 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")
+		 cmd = "note"
+		 if teitype ~= "" then teitype = " type=\""..teitype.."\"" else end
+		 return string.format("<%s%s place=\"bottom\">%s</%s>", cmd, teitype, arg, cmd)
+   end)
+   return str
+end
+
 local function note_totei(str)
    str = gsub(str,
 	      dblbkslash *
@@ -12509,6 +12642,7 @@ end
 local function textotei(str)
    str = xml_entities(str)
    str = texpatttotei(str)
+   str = footnote_totei(str)
    str = note_totei(str)
    str = remove_extra_anchors(str)
    str = app_totei(str)
-- 
cgit v1.2.3

