Here's a first starter (to be improved later on, with more time)
The idea is to write the data for \fl@from
and \fl@to
as 'label' information to the .aux
file (which is read again at the next compilation run) with zref
- facilities and extract the stored information again with \zref@extract
.
In speech of zref
from
and to
are properties.
\documentclass{article}
\usepackage{etoolbox}
\usepackage{zref}
\makeatletter
%% floruit handlers:
\newcommand\fl@from{10000}
\newcommand\fl@to{0}
\newcommand\fl@years{}
\newcommand\fl@handler[1]{
\ifnumcomp{#1}{<}{\fl@from}{\renewcommand\fl@from{#1}}{}
\ifnumcomp{#1}{>}{\fl@to}{\renewcommand\fl@to{#1}}{}
}
\newcommand{\fl@output}[1]{%
\renewcommand\fl@from{10000}
\renewcommand\fl@to{0}
\forlistloop{\fl@handler}{\fl@years}
\zref@ifrefundefined{#1}{}{%
\ifnum\zref@extract{#1}{from}=\fl@from
\else
\ifnum\zref@extract{#1}{from}=\zref@extract{#1}{to}
\textit{\zref@extract{#1}{to}}%
\else
\textit{fl.~\zref@extract{#1}{from}--\zref@extract{#1}{to}}%
\fi
\fi
}
}
\newbool{fl_called}
\newcommand\floruit[1]{#1\booltrue{fl_called}\listadd\fl@years{#1}}
\zref@newprop{from}[-1]{\fl@from}
\zref@newprop{to}[-1]{\fl@to}
\newcommand{\florlabel}[1]{%
\zref@labelbyprops{#1}{from,to}%
}
%% person environment:
\newcounter{person}
\newenvironment{person}[1]{
\refstepcounter{person}%
\edef\@oldcurrentlabel{\@currentlabel}
\renewcommand\fl@years{}
\textbf{\theperson:~#1} \fl@output{flordata:\number\value{person}}\par
}{%
\ifbool{fl_called}{\par\fl@output{flordata:\number\value{person}}}{}\par
%Restore the label data in case we have some \refstepcounter after \refstepcounter{person}
\edef\@currentlabel{\@oldcurrentlabel}
\florlabel{flordata:\number\value{person}}%
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{person}{Old MacDonald}
Old MacDonald had a farm in \floruit{1923}, but appears to have sold it by \floruit{1940}.
\end{person}
\begin{person}{Gary Cooper}
Gary Cooper starred in High Noon (\floruit{1952})...
\end{person}
\begin{person}{John Doe}
Blah blah (\floruit{1912}), more blah (\floruit{1930}) \& finally blah (\floruit{1931}).
\end{person}
\begin{person}{Jane Doe}
No floruit here...
\end{person}
The floruit should be with the name like so:
\textbf{3: John Doe} \textit{fl. 1912--1931}\par
Blah blah (1912), more blah (1930) \& finally blah (1931).\par
\end{document}
I will try to improve the list-handling. The etoolbox
boolean values are tricky, in my point of view.
**Some update with expl3
features for a 'cleaner' code
\documentclass{article}
\usepackage{xparse}
\usepackage{zref}
\makeatletter
\ExplSyntaxOn
\cs_generate_variant:Nn \prop_put:Nnn {Nxx}
\cs_generate_variant:Nn \int_set:Nn {Nx}
% Storage containers
\seq_new:N \l_meide_flordata_seq
\prop_new:N \l_meide_flordata_prop
% Clear the list
\NewDocumentCommand{\ClearFlordata}{}{%
\seq_clear:N \l_meide_flordata_seq
}
\NewDocumentCommand{\floruit}{m}{%
\seq_put_right:Nn \l_meide_flordata_seq {#1}
\DisplayInlineFlorData{#1}%
}
\DeclareExpandableDocumentCommand{\ExtractListProp}{m}{%
\prop_item:Nn \l_meide_flordata_prop {#1}%
}
\int_new:N \l_meide_from_int
\int_new:N \l_meide_to_int
\NewDocumentCommand{\ProcessFlorData}{}{%
% Checking first whether there's something in the list at all
\seq_if_empty:NTF \l_meide_flordata_seq {%
\prop_put:Nnx \l_meide_flordata_prop {from} { 0 }
\prop_put:Nnx \l_meide_flordata_prop {to} { 0 }
}{%
\prop_put:Nnx\l_meide_flordata_prop {from} { \seq_item:Nn \l_meide_flordata_seq {1} }
\prop_put:Nnx\l_meide_flordata_prop {to} { \seq_item:Nn \l_meide_flordata_seq {2} }
\int_compare:nNnTF {\seq_count:N \l_meide_flordata_seq } > {1} {%
\prop_put:Nnx \l_meide_flordata_prop {to} {\seq_item:Nn \l_meide_flordata_seq {2}}
}{
\prop_put:Nnx \l_meide_flordata_prop {to} {\seq_item:Nn \l_meide_flordata_seq {1}}
}
}
% Determine the min and max of the list and store it to the from or to properties
\seq_map_inline:Nn \l_meide_flordata_seq {
\int_set:Nx \l_tmpa_int {\prop_item:Nn \l_meide_flordata_prop {from} }
\int_set:Nx \l_tmpb_int {\int_min:nn {##1} {\l_tmpa_int }}
\prop_put:NnV \l_meide_flordata_prop { from } { \l_tmpb_int }
\int_set:Nx \l_tmpa_int {\prop_item:Nn \l_meide_flordata_prop {to} }
\int_set:Nx \l_tmpb_int {\int_max:nn {##1} {\l_tmpa_int }}
\prop_put:NnV \l_meide_flordata_prop { to } { \l_tmpb_int }
}
\edef\@currentlabel{\@oldcurrentlabel}
% Do not write a label if there's nothing to write, i.e. the sequence is empty!
\seq_if_empty:NF \l_meide_flordata_seq {
\florlabel{flordata:\number\value{person}}%
}
}
\ExplSyntaxOff
% Defines the format for the numbers
\NewDocumentCommand{\FormatFlorData}{om}{%
\IfValueTF{#1}{%
\textit{fl.~#1 -- #2}%
}{%
\textit{#2}%
}%
}
% A simple wrapper for the display of the inline data given with \floruit
\NewDocumentCommand{\DisplayInlineFlorData}{+m}{%
(#1)%
}
% Display the numbers
\NewDocumentCommand{\DisplayFlorData}{m}{%
% Check first if the reference is defined
\zref@ifrefundefined{#1}{}{%
\ifnum\zref@extract{#1}{from}=\zref@extract{#1}{to}
\FormatFlorData{\zref@extract{#1}{from}}%
\else
\FormatFlorData[\zref@extract{#1}{from}]{\zref@extract{#1}{to}}%%
\fi
}
}
% zref - related code
% Define zref - properties and fill them with the `\prop` - key - value of the same name
% This could be done in a loop using expl3 - loops etc.
\zref@newprop{from}[-1]{\ExtractListProp{from}}
\zref@newprop{to}[-1]{\ExtractListProp{to}}
\newcommand{\florlabel}[1]{%
\zref@labelbyprops{#1}{from,to}%
}
% Basic Environment and counter definition
\newcounter{person}
\NewDocumentEnvironment{person}{+m}{%
\ClearFlordata%
\refstepcounter{person}
% Store the last label for future purposes
\edef\@oldcurrentlabel{\@currentlabel}
\textbf{\theperson:~#1} \DisplayFlorData{flordata:\number\value{person}}\par
}{%
% Now evaluate the data given in the environment and write the label accordingly.
\ProcessFlorData%
}
\makeatother
\begin{document}
\begin{person}{Old MacDonald}
Old MacDonald had a farm in \floruit{1923}, but appears to have sold it by \floruit{1940}.
\end{person}
\begin{person}{Gary Cooper}
Gary Cooper starred in High Noon \floruit{1952}...
\end{person}
\begin{person}{John Doe}
Blah blah \floruit{1912}, more blah \floruit{1930} \& finally blah \floruit{1931}.
\end{person}
\begin{person}{Mr. Gumby}
Was active in \floruit{1900}, \floruit{1855}, \floruit{2017}, \floruit{1066}.
\end{person}
\begin{person}{Jane Doe}
No floruit here...
\end{person}
\end{document}
label
strategy, by writing labels to the.aux
file which are evaluated during the 2nd run of the code (which is necessary in most cases)