diff options
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/genealogy-profiles/README.md | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.pdf | bin | 132492 -> 175095 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.preamble.sty | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.tex | 387 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/genealogy-profiles/genealogy-profiles.sty | 463 |
5 files changed, 617 insertions, 241 deletions
diff --git a/Master/texmf-dist/doc/latex/genealogy-profiles/README.md b/Master/texmf-dist/doc/latex/genealogy-profiles/README.md index eb4dd087efd..00563b2841c 100644 --- a/Master/texmf-dist/doc/latex/genealogy-profiles/README.md +++ b/Master/texmf-dist/doc/latex/genealogy-profiles/README.md @@ -5,9 +5,9 @@ Macros and environments for presenting genealogical profiles. See [genealogy-profiles.pdf](docs/genealogy-profiles.pdf) for the documentation. -Contents last updated 2024-01-24. +Contents last updated 2024-12-05. -<!-- Package available via CTAN at https://www.ctan.org/pkg/genealogy-profiles --> +Package available via CTAN at https://www.ctan.org/pkg/genealogy-profiles License: CC-BY-SA 4.0 Author: Mikkel Eide Eriksen <mikkel.eriksen@gmail.com> diff --git a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.pdf b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.pdf Binary files differindex bf030bf3646..44f69829e89 100644 --- a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.pdf +++ b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.pdf diff --git a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.preamble.sty b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.preamble.sty index a2dda4a26d5..4c1657a641b 100644 --- a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.preamble.sty +++ b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.preamble.sty @@ -82,6 +82,10 @@ patronymic index = gpr-surnames, surname index = gpr-surnames, byname index = gpr-surnames, + patronymic style=\itshape, + byname style=\scshape, + surname style=\scshape, + use styles in index } diff --git a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.tex b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.tex index e65b90aa9a5..2f40ade7b29 100644 --- a/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.tex +++ b/Master/texmf-dist/doc/latex/genealogy-profiles/genealogy-profiles.tex @@ -15,25 +15,33 @@ \maketitle -\section{Preface} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section*{Preface} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This package enables the presenstation of individual \emph{profiles}, which may be useful for genealogical or local history treatises. -Each profile is typeset using key/value-configurable environments, and a number of macros are provided to enable references and name formatting. +Each profile is typeset using key/value-configurable environments, and a number of macros are provided to enable formatting, references, and floruit (lifespan) calculations. + +In order to provide an ergonomic interface for document authors, extra care has been taken to enable automatic and configurable parsing of names. Issues can be reported at\\\null\hfill\url{https://github.com/mikkelee/latex-genprofile/issues} +%\begin{multicols}{2} +%\begingroup +%\hypersetup{pdfborder=0 0 0} +%\makeatletter +%\renewcommand{\tableofcontents}{\@starttoc{toc}} % no "Contents" heading +%\makeatother +%\tableofcontents +%\endgroup +%\end{multicols} + \begin{figure} \begingroup \gprKeys{ name type = given and surname, surname style = \scshape, - begin profile = { - \begin{tcolorbox}[title = \gprHeader] - }, + layout preset = tcolorbox, begin life events = \small, - end life events = \tcblower, - end profile = \end{tcolorbox}, } \begin{gprProfile}{Wolfgang_Amadeus Mozart}[ birth = {1756-01-27}{Getreidegasse 9, Salzburg}, @@ -59,7 +67,7 @@ The package is configured in the following manner: {usepackage} {\brackets{genealogy-profiles}} - Loads the package and sets some sensible defaults as further described below. + Loads the package and sets some sensible defaults as further described in \cref{sec:genconf,sec:profopts}. \end{docCommand} @@ -73,17 +81,20 @@ The package is configured in the following manner: \section{Usage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Environments} %--------------------------------------------------------------- + + \begin{docEnvironment} {gprProfile} - {\oarg{profile options}\marg{name}\oarg{life events}} + {\oarg{profile options}\marg{full name}\oarg{life events}} Typesets its contents according to the configured layout (see \cref{sec:structure}). For possible profile options, see \cref{sec:profopts}. - The name will be parsed according to the current \refKey{name part order} (see \cref{sec:nameparsing} for discussion) and styled according to \refKey{givenname style} etc. + The \meta{full name} will be parsed according to the current \refKey{name part order} (see \cref{sec:nameparsing} for discussion) and styled according to \refKey{nameparts:style} etc. - Each profile must have an ID, either supplied by the author via the \refKey{id} profile option key or automatically generated via the general \refKey{auto id} key. + Each profile must have an \refAux{id}, either supplied by the author via the \refKey{id} profile option key or automatically generated via the general \refKey{auto id} key (the latter being the default). - The \refKey{life events} will be parsed as a database by the \href{https://ctan.org/pkg/genealogytree}{genealogytree} package. + The \refKey{life events} will be parsed as a database by the \refPkg{genealogytree} package. \end{docEnvironment} @@ -91,10 +102,12 @@ The package is configured in the following manner: {gprProfile*} {\marg{profile options}\oarg{life events}} - The \refEnv*{gprProfile*} environment provides more control at the expense of convenience, by requiring the name part(s) be set explicitly as profile options. See \refKey{givenname} etc. + The \refEnv*{gprProfile*} environment provides more control at the expense of convenience, by requiring the name part(s) be set explicitly as profile options. See \refKey{given name} etc. \end{docEnvironment} +\clearpage +\subsection{Commands} %------------------------------------------------------------------- \begin{docCommands}[ doc name = {gprName} @@ -104,9 +117,9 @@ The package is configured in the following manner: { doc parameter = {\sarg\marg{name}}}, } - Typesets a name, styled according to \refKey{givenname style} etc. + Typesets a name, styled according to configured name styles (see \refKey{nameparts:style}), without attempting to link to a profile. - The regular version adds the name to any indices, the starred veresion does not. + The regular version adds the name to any configured indices, the starred version does not. \end{docCommands} @@ -119,13 +132,13 @@ The package is configured in the following manner: { doc parameter = {\sarg\oarg{id}\marg{name}}}, } - Typesets a reference to a profile. + Typesets a reference to a profile according to \refKey{reference style}. - The ID is optional, in case they are not known or available at the time of writing. However, if the name is unique to the document, the reference should automatically be recognized. + The \meta{id} is optional, in case it is not known or available at the time of writing. However, if the name is unique to the document, the reference should automatically be recognized. - If it is not possible for the package to identify the intended reference, either via ID or unique name, warnings will be emitted in the log as well as in the document (the latter can be configured via the \refKey{unknown reference style}). + If it is not possible for the package to identify the intended reference, either via \meta{id} or unique name, warnings will be emitted in the log as well as in the document (the latter can be configured via \refKey{unknown reference style}). - When using an ID, the name parameter can be left empty, or alternately be used to override the displayed name, eg. to change case to genitive, etc. + When using an \meta{id}, the name parameter can be left empty, or alternatively be used to override the by-default displayed full name, eg. to change case to genitive, etc. The regular version adds the reference to configured indices, the starred version does not. @@ -133,85 +146,78 @@ The package is configured in the following manner: \end{docCommands} -\begin{docCommands}[ - doc name = {gprYear} - ] - { - { doc parameter = {\marg{year}}}, - { doc parameter = {\sarg\marg{year}}}, - } - - All tagged years in a profile will be gathered and inserted as a range into a \docValue*{floruit} life event, which will by default only be displayed if there is no defined lifespan (ie. birth or baptism \emph{and} death or burial). - - The starred version does not typeset anything, and can thus be used to add \enquote{hidden} years to the floruit event. - - These commands require two runs. -\end{docCommands} - - -\begin{docCommands}[ - doc name = {gprYears} - ] - { - { doc parameter = {\marg{year range}}}, - { doc parameter = {\sarg\marg{year range}}}, - } - - Adds two years to the \docValue*{floruit} event, by splitting at one or more hyphens. - - Values such as \docValue*{1750--1755} or \docValue*{1750--55} will both be parsed as the two years \docValue*{1750} and \docValue*{1755} and typesets as the expected 1750--1755 or 1750--55, respectively. - - Like \refCom{gprYear}, the starred version produces no output, and two runs are required. -\end{docCommands} - - -\clearpage -\section{Profile Layout} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Layout} %--------------------------------------------------------------------- \label{sec:structure} The typeset profiles are laid out according to the following structure. -\begin{enumerate} +\begin{enumerate}[noitemsep] \item The contents of \refKey{begin profile} \item If \refKey{auto header} is \docValue*{true}: - \begin{enumerate} + \begin{enumerate}[noitemsep] \item The contents of \refKey{begin header} \item The contents of \refKey{header format} \item The contents of \refKey{end header} \end{enumerate} \item If \refKey{life events} and/or \refCom{gprYear}(s) were used: - \begin{enumerate} + \begin{enumerate}[noitemsep] \item The contents of \refKey{begin life events}. - \item The events formatted according to the database format configured via the \href{https://ctan.org/pkg/genealogytree}{genealogytree} package. The provided default simply lists life events separated by commas. + \item The events formatted according to the database format configured via the \refPkg{genealogytree} package. \item The contents of \refKey{end life events} \end{enumerate} +\item The contents of \refKey{begin content} \item The content provided to the environment by the author. +\item The contents of \refKey{end content} \item The contents of \refKey{end profile} \end{enumerate} -\section{Name Parsing} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Names} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:nameparsing} -Names are parsed according to the configured \refKey{name part order} (some presets are provided with \refKey{name type}), in a left-to-right evaluation. +Names are parsed according to the configured \refKey{name part order} (some presets are provided via \refKey{name type}), in a left-to-right evaluation. In order for single name parts to include multiple separate tokens (eg. multiple given names), underscores can be used to combine them. For example, \docValue*{Wolfgang\_Amadeus Mozart} will, with the default \docValue{given and surname} name type, be parsed as the given name(s) \docValue*{Wolfgang Amadeus} and the surname \docValue*{Mozart}. If the \refKey{name part order} has more parts than the supplied value, the right-most parts will be empty. If this is not desired, one may mark empty name parts with a single underscore; for example, using the \docValue{nordic historical} name type, \docValue*{Jens _ Smed} will parse as the given name \docValue*{Jens}, no patronymic, and the byname \docValue*{Smed} (ie. blacksmith). -Inside a profile environment, a number of shortcuts are provided to access the available name parts, as well as the ID and a full name styled according to the name style keys. +Inside a profile environment, a number of shortcuts are provided to access the available name parts, as well as the \refAux{id} and a full name styled according to the individual name part style keys (see \cref{sec:promac}). + +\subsection{Creating and Using Name Parts} %---------------------------------------------- + +\begin{docCommand} + {gprCreateNamePart} + {\marg{name part}\oarg{macro name}} + + If the supplied default name part types are not sufficient, new types can be created. They must be included in the \refKey{name part order} to be properly recognized during name parsing and indexing. + + Creating a \meta{name part} results in: + \begin{itemize} + \item \refKey{nameparts:key} key in profile options for manually setting the name part in profiles. + \item \refKey{nameparts:style} key in general options for styling the name part. + \item \refKey{nameparts:index} key in general options for which index to use for the name part. + \item \refCom{nameparts:macro} macro for typesetting the styled name part within a profile. + \item \refCom{nameparts:macrostar} macro for typesetting the unstyled name part within a profile. + \item \refCom{nameparts:macrostyle} macro for typesetting arbitrary text in the configured name part style. + \end{itemize} + + By default, the generated commands will be CamelCased (eg. \docAuxKey*{given name} results in \docAuxCommand*{gprGivenName...}), but this can be overridden by supplying your own base name as the optional argument. + + The name parts \docAuxKey*{given name}, \docAuxKey*{patronymic}, \docAuxKey*{surname}, and \docAuxKey*{byname} have been pregenerated, along with their associated style/index keys and commands (see \cref{sec:promac,key:given name}). + +\end{docCommand} -\clearpage \section{Profile Macros} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\label{sec:promac} -A number of extra macros are available inside profiles to allow accessing some key values. +A number of extra macros are available inside profiles to allow accessing some key values, as well as gather years for floruit calculations. \begin{docCommand} {gprHeader} @@ -228,25 +234,101 @@ A number of extra macros are available inside profiles to allow accessing some k doc parameter = {\brackets{}} ] { - { doc name = gprID}, - { doc name = gprStyledName}, - { doc name = gprFullName}, - { doc name = gprGivenName}, - { doc name = gprPatronymic}, - { doc name = gprSurname}, - { doc name = gprByname}, + { doc name = gprID }, + { doc name = gprID* }, + { doc name = gprFullName }, + { doc name = gprFullName* } } - Typesets the ID and name parts accordig to configured styles. + Typesets the \refAux{id} and full name according to configured styles (see \refKey{id style} and \refKey{nameparts:style}). The starred versions of the commands are unstyled. + +\end{docCommands} + + +\begin{docCommands}[ + doc parameter = {\brackets{}} + ] + { + { doc name = gprGivenName }, + { doc name = gprGivenName* }, + { doc name = gprPatronymic }, + { doc name = gprPatronymic* }, + { doc name = gprSurname }, + { doc name = gprSurname* }, + { doc name = gprByname }, + { doc name = gprByname* }, + { + doc name = gpr\meta{NamePart}, + doc label = nameparts:macro, + } , + { + doc name = gpr\meta{NamePart}*, + doc label = nameparts:macrostar, + } + } + + Typesets individual name parts according to configured styles (see \refKey{nameparts:style}). The starred versions of the commands are unstyled. + + More can be created using \refCom{gprCreateNamePart}. +\end{docCommands} + + +\begin{docCommands}[ + doc parameter = {\marg{text}} + ] + { + { doc name = gprIDStyle }, + { doc name = gprGivenNameStyle }, + { doc name = gprPatronymicStyle }, + { doc name = gprSurnameStyle }, + { doc name = gprBynameStyle }, + { + doc name = gpr\meta{NamePart}Style, + doc label = nameparts:macrostyle, + }, + } + + Styles given text according to the configured name style (see \refKey{nameparts:style}). + + More can be created using \refCom{gprCreateNamePart}. +\end{docCommands} + - The styled name is formatted according to the style keys, see \refKey{givenname style} etc. +\begin{docCommands}[ + doc name = {gprYear} + ] + { + { doc parameter = {\marg{year}}}, + { doc parameter = {\sarg\marg{year}}}, + } + + All tagged years in a profile will be gathered and inserted as a \docValue*{floruit} range under \refKey{life events}, which will by default only be displayed if there is no defined lifespan (ie. birth or baptism \emph{and} death or burial). + The starred version does not typeset anything, and can thus be used to add \enquote{hidden} years to the floruit event. + + These commands require two runs. \end{docCommands} -\subsection{Option Keys} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{docCommands}[ + doc name = {gprYears} + ] + { + { doc parameter = {\marg{year range}}}, + { doc parameter = {\sarg\marg{year range}}}, + } -\subsubsection{General Options} %--------------------------------------------------------- + Adds two years to the \docValue*{floruit} event, by splitting at one or more hyphens. + + Values such as \docValue*{1750--1755} or \docValue*{1750--55} will both be parsed as the two years \docValue*{1750} and \docValue*{1755} and typeset as the expected 1750--1755 or 1750--55, respectively. + + Like \refCom{gprYear}, the starred version produces no output, and two runs are required. +\end{docCommands} + +\clearpage +\section{Option Keys} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{General Options} %------------------------------------------------------------ \label{sec:genconf} These are used with the \refCom{gprKeys} command, either globally in the preamble or locally in a group. @@ -264,9 +346,9 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl {=\meta{true/false}} {initially \docValue*{true}} - Generates an ID for each profile if no \refKey{id} is supplied. The format is the name part initials combined with a number to ensure uniqueness. + Automatically generates an \refAux{id} for each profile if no \refKey{id} is supplied. They are built from the initials of each the name part (empty parts replaced by a dash) combined with a number to ensure uniqueness. - If no ID is set either automatically or manually, an error is emitted. + If a profile has no \refAux{id} set, whether automatically or manually, an error is emitted. \end{docKey} \begin{docKey} @@ -274,7 +356,7 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl {=\meta{...}} {initially not set} - Prefixes auto-generated IDs with a string, which may be useful for works containing multiple sections. + Prefixes auto-generated \refAux{id}s with a string, which may be useful for works containing multiple sections. \end{docKey} \begin{docKeys} @@ -299,6 +381,12 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl doc name = end life events, }, { + doc name = begin content, + }, + { + doc name = end content, + }, + { doc name = end profile, }, } @@ -310,9 +398,9 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl \begin{docKey} {header format} {=\meta{...}} - {initially \brackets{\docValue*{\cs{gprStyledName}\brackets{}\cs{hfill}\cs{gprID}\brackets{}}}} + {initially \brackets{\docValue*{\cs{gprFullName}\brackets{}\cs{hfill}\cs{gprID}\brackets{}}}} - Formats a profile header. See \refCom{gprID} etc. for available macros. + Formats a profile header, which will be available as \refCom{gprHeader}, and is automatically inserted if \refKey{auto header} is \docValue*{true}. See \refCom{gprID} etc. for available macros. \end{docKey} \begin{docKeys} @@ -321,22 +409,22 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl ] { { - doc name = name type, - doc description = {initially \docValue{given and surname}} + doc name = name part order, + doc description = {initially \brackets{\docValue*{given name, surname}}} }, { - doc name = name part order, - doc description = {initially \brackets{\docValue*{givenname, surname}}} + doc name = name type, + doc description = {initially \docValue{given and surname}} }, } - The \refKey*{name part order} is used for splitting a \refKey{fullname} to its constituent parts for formatting, index entries, and (if configured) IDs. + The \refKey*{name part order} is used for splitting a \refKey{full name} to its constituent parts for the configured styling, indexing, and autogenerated \refAux{id}s. Using the \refKey*{name type} key provides access to a number of preconfigured \refKey*{name part order}s: \begin{itemize} - \item \docValue{given and surname} will set the \refKey*{name part order} key to \brackets{\docValue*{givenname, surname}} (the default). - \item \docValue{nordic historical} will set the \refKey*{name part order} key to \brackets{\docValue*{givenname, patronymic, byname}}, commonly used in Scandinavia and the rest of the nordic countries. + \item \docValue{given and surname} will set the \refKey*{name part order} key to \brackets{\docValue*{given name, surname}} (the default). + \item \docValue{nordic historical} will set the \refKey*{name part order} key to \brackets{\docValue*{given name, patronymic, byname}}, which was traditionally used in Scandinavia and the rest of the nordic countries. \end{itemize} If no preset \refKey*{name type} exists for the intended use case, the \refKey*{name part order} can be set directly (suggestions are welcome). @@ -349,7 +437,10 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl ] { { - doc name = givenname style, + doc name = id style, + }, + { + doc name = given name style, }, { doc name = patronymic style, @@ -360,12 +451,18 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl { doc name = byname style, }, + { + doc name = \meta{name part} style, + doc label = nameparts:style, + }, } - These keys set the styling for each name part, which will be available as the \refCom{gprStyledName}. + These keys set the styling for the \refAux{id} and name parts. The styled name parts will together be available as the \refCom{gprFullName}. + More can be created using \refCom{gprCreateNamePart}. \end{docKeys} +\clearpage \begin{docKeys} [ doc parameter = {=\meta{...}}, @@ -376,10 +473,10 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl doc name = id index, }, { - doc name = fullname index, + doc name = full name index, }, { - doc name = givenname index, + doc name = given name index, }, { doc name = patronymic index, @@ -390,14 +487,19 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl { doc name = byname index, }, + { + doc name = \meta{name part} index, + doc label = nameparts:index, + }, } - Setting these keys will cause \refEnv{gprProfile} and \refCom{gprRef} to emit index data to the named index. The index must be created with eg. \texttt{imakeidx} before using. + Setting these keys will cause \refEnv{gprProfile}, \refCom{gprName}, and \refCom{gprRef} to emit index data to the named index. The index must be created with eg. \texttt{imakeidx} before using. - They can point to the same index (eg. one may wish to use one index for patronymics, surnames, and/or bynames). In fact, that has been set for this document (see final page). + They can point to the same index. For example, you can use the same index for patronymics, surnames, and/or bynames --- which has in fact been configured for this document (see final page). At the end of the document, \docAuxCommand*{printindex} can then be used for each index as normal. + More can be created using \refCom{gprCreateNamePart}. \end{docKeys} \begin{docKey} @@ -405,7 +507,7 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl {=\meta{true/false}} {initially not set} - Causes index entries to include the IDs in parentheses. + Causes index entries to include the \refAux{id} in parentheses, which is especially useful in documents with many identically named profiles. \end{docKey} \begin{docKeys} @@ -422,16 +524,45 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl }, } - Causes the indexes to include references to persons with unknown IDs or ambiguous names, which can be used for correcting drafts. + Causes the indexes to include references to persons with unknown \refAux{id}s or ambiguous names, which can be used for correcting drafts. \end{docKeys} \begin{docKey} + {layout preset} + {=\meta{...}} + {initially not set} + + Sets a preconfigured layout style. Currently, two options are available: + + \begin{itemize} + \item \docValue{clear} will blank out all the layout keys (see \refKey{begin profile} etc). + + \item \docValue{tcolorbox} sets the following keys: + + \begin{tcblisting}{listing only} + \gprKeys{ + auto header = false, + begin profile = {\begin{tcolorbox}[title=\gprHeader]}, + end life events = {\tcblower}, + end profile = {\end{tcolorbox}} + } + \end{tcblisting} + + The box can be further configured via \docAuxCommand*{tcbset} as per the \refPkg{tcolorbox} documentation. + + \end{itemize} + + Suggestions for more presets are welcome. + +\end{docKey} + +\begin{docKey} {main index entry style} {=\meta{...}} {initially not set} - Adds formatting to the main index entry page numbers (ie. the ones pointing to the profile), leaving the ones reference with \refCom{gprRef} untouched; for example \docValue*{textbf} will bold the main entry. + Adds formatting to the main index entry page numbers (ie. the ones pointing to the profile), leaving the ones referenced with \refCom{gprRef} untouched; for example \docValue*{textbf} will bold the main entry. \end{docKey} \begin{docKey} @@ -443,11 +574,21 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl \end{docKey} \begin{docKey} + {page reference style} + {=\meta{...}} + {initially \docValue*{p.\cs{nobreakspace}\#1}} + + Formats page references. The value is expanded with the argument \docValue*{\#1} being the page number. +\end{docKey} + +\begin{docKey} {reference style} {=\meta{...}} {see below} - Formats references. The value is expanded with the arguments \docValue*{\#1} being the name, \docValue*{\#2} being the ID, and \docValue*{\#2} being the page reference. The default is to present these as the name followed by combined super- and subscripts (see also \cref{sec:examples} for another style). + Formats references to known profiles. The value is expanded with the arguments \docValue*{\#1} being the name, \docValue*{\#2} being the \refAux{id}, and \docValue*{\#3} being the formatted page reference. The default is to present these as the name followed by combined super- and subscripts (see also \cref{sec:examples} for another style). + + The result is wrapped in a \refPkg{hyperref} link to the referenced profile. \end{docKey} \begin{docKey} @@ -455,35 +596,45 @@ These are used with the \refCom{gprKeys} command, either globally in the preambl {=\meta{...}} {see below} - Formats unknown references. The value is expanded with the arguments \docValue*{\#1} being the name supplied by \refCom{gprRef} and \docValue*{\#2} being a short description of the reason. The default is to present the name as red text with the reason (unknown/ambiguous) following in parentheses. + Formats references to unknown profiles. The value is expanded with the arguments \docValue*{\#1} being the supplied name, and \docValue*{\#2} being a short description of the reason. The default is to present the name as red text with the reason (unknown/ambiguous) following in parentheses. \end{docKey} +\begin{docKey} + {use styles in index} + {=\meta{true/false}} + {initially not set} + + Causes index entries to be styled according to the various \refKey{nameparts:style} keys. +\end{docKey} -\subsubsection{Profile Options} %--------------------------------------------------------- + +\subsection{Profile Options} %------------------------------------------------------------ \label{sec:profopts} -These are used with the \refEnv{gprProfile} and \refEnv{gprProfile*} environments. +These are used in the first argument of the \refEnv{gprProfile} and \refEnv{gprProfile*} environments. \begin{docKey} {id} {=\meta{...}} {initially not set} - Sets an ID for the profile. If none is specified and \refKey{auto id} is \docValue*{true}, one will be generated from name initials combined with a number to ensure uniqueness. + Sets an \meta{id} for the profile. If none is specified and \refKey{auto id} is \docValue*{true}, one will be generated from name initials combined with a number to ensure uniqueness. - If an already used ID is specified, an error will be emitted. + Not specifying an \meta{id} while \refKey{auto id} is \docValue*{false} will cause an error. - Likewise, not specifying an ID while \refKey{auto id} is \docValue*{false} will cause an error. + Likewise, if an already used \meta{id} is specified, an error will be emitted. \end{docKey} \begin{docKey} - {fullname} + {full name} {=\marg{...}} {initially not set} Sets the full name of the person. If it is specified, the configured \refKey{name part order} will be used to set the individual name parts. If it is not specified, one will be generated by combining the given name parts according to the configured \refKey{name part order}, using the below keys. See \cref{sec:nameparsing} for further details. + + This key is set by the mandatory argument of \refEnv{gprProfile}. \end{docKey} \begin{docKeys} @@ -493,7 +644,7 @@ These are used with the \refEnv{gprProfile} and \refEnv{gprProfile*} environment ] { { - doc name = givenname, + doc name = given name, }, { doc name = patronymic, @@ -504,10 +655,15 @@ These are used with the \refEnv{gprProfile} and \refEnv{gprProfile*} environment { doc name = byname, }, + { + doc name = \meta{name part}, + doc label = nameparts:key, + }, } - Sets individual name parts. + Sets individual name parts, to be used with \refEnv{gprProfile*}. + More can be created using \refCom{gprCreateNamePart}. \end{docKeys} \begin{docKey} @@ -515,7 +671,7 @@ These are used with the \refEnv{gprProfile} and \refEnv{gprProfile*} environment {=\meta{...}} {initially not set} - Populates a \href{https://ctan.org/pkg/genealogytree}{genealogytree} database, which will be typeset according to the settings of that package; refer to its documenation for configuration. Simple display defaults have been provided. + Populates a \refPkg{genealogytree} database, which will be typeset according to the settings of that package; refer to its documentation for configuration. The provided default simply lists life events separated by commas, skipping \docValue*{floruit} if there is a defined lifespan (ie. birth or baptism \emph{and} death or burial). For convenience, this key can be set with the final optional argument of the \refEnv{gprProfile} and \refEnv{gprProfile*} environments. \end{docKey} @@ -533,7 +689,7 @@ These are used with the \refEnv{gprProfile} and \refEnv{gprProfile*} environment \label{sec:examples} -\subsection{Using \texttt{tcolorbox} \& \docValue*{nordic historical}} +\subsection{Using \docValue*{tcolorbox} \& \docValue*{nordic historical}} A simple example to show name parsing and use of \refCom{gprRef} and \refCom{gprYear}. \begin{dispExample} @@ -541,16 +697,15 @@ A simple example to show name parsing and use of \refCom{gprRef} and \refCom{gpr name type = nordic historical, patronymic style = \itshape, byname style = \scshape, - begin profile = {\begin{tcolorbox}[title = \gprHeader]}, - end life events = \tcblower, - end profile = \end{tcolorbox}, + layout preset = tcolorbox, } \begin{gprProfile}{Jens Hansen}[ birth = {1790}{Denmark} ] Wife: \gprRef{Anne_Marie Olsdatter}. Let's also tag some years: - \gprYear{1830}, \gprYear{1835}, and \gprYear{1840}. + \gprName{Jens} is mentioned in the censuses of + \gprYear{1801}, \gprYear{1834}, and \gprYear{1840}. \end{gprProfile} \begin{gprProfile}{Anne_Marie Olsdatter}[ birth = {1795}{Denmark} ] @@ -564,7 +719,7 @@ A simple example to show name parsing and use of \refCom{gprRef} and \refCom{gpr \end{dispExample} \clearpage -\subsection{Using \texttt{hrule} \& \docValue*{given and surname}} +\subsection{Using Custom Layout \& \docValue*{given and surname}} A simple example to show different layout and reference styles. @@ -576,8 +731,8 @@ A simple example to show different layout and reference styles. auto header, begin profile = \spacedrule, end life events = \spacedrule, - end profile = \spacedrule, - reference style = {#1\footnote{#2, #3}} + end profile = {\spacedrule\vspace*{\baselineskip}}, + reference style = {#1\footnote{#2,~#3}} } \begin{gprProfile}{George Washington}[ @@ -588,6 +743,9 @@ A simple example to show different layout and reference styles. in America in \gprYear{1784}. \end{gprProfile} +This sentence demonstrates that references work even outside +profiles: \gprRef[GW1]{_ Washington} was the first president +of the United States. \end{dispExample} \clearpage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -595,7 +753,8 @@ A simple example to show different layout and reference styles. \small % because index format=off \printindex -\indexprologue{This index was created by setting the keys \refKey*{patronymic index}, \refKey*{surname index}, and \refKey*{byname index} all to the same index.} +\gprKeys{name type=nordic historical} +\indexprologue{This index was created by setting the keys \docAuxKey*{patronymic index}, \docAuxKey*{surname index}, and \docAuxKey*{byname index} all to the same index. Notice that \gprName{Jens Hansen Smed} is listed both under his patronymic \gprPatronymicStyle{Hansen} and his byname \gprBynameStyle{Smed}.} \printindex[gpr-surnames] \end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/genealogy-profiles/genealogy-profiles.sty b/Master/texmf-dist/tex/latex/genealogy-profiles/genealogy-profiles.sty index 69f1cf00d70..d956f1bcc03 100644 --- a/Master/texmf-dist/tex/latex/genealogy-profiles/genealogy-profiles.sty +++ b/Master/texmf-dist/tex/latex/genealogy-profiles/genealogy-profiles.sty @@ -1,5 +1,5 @@ \RequirePackage{expl3}[2023-10-10] -\ProvidesExplPackage{genealogy-profiles}{2024/01/24}{0.1}{Macros for creating genealogical profiles} +\ProvidesExplPackage{genealogy-profiles}{2024/12/05}{0.1}{Macros for creating genealogical profiles} % License: CC-BY-SA 4.0 % Author: Mikkel Eide Eriksen <mikkel.eriksen@gmail.com> @@ -14,7 +14,12 @@ \keys_define:nn { genealogy-profiles } { name~part~order .code:n = { - \seq_gset_from_clist:Nn \g__gpr_name_part_order_seq {#1} + \seq_gset_from_clist:Nn \g__gpr_name_part_order_seq { #1 } + \seq_map_inline:Nn \g__gpr_name_part_order_seq { + \tl_if_exist:cF { l__gpr_#1_tl } { + \gpr_error:nn { name-part-missing } { #1 } + } + } } , name~type .choices:nn = { given~and~surname , @@ -23,11 +28,11 @@ \int_case:nn { \l_keys_choice_int } { {1} { \seq_gset_from_clist:Nn \g__gpr_name_part_order_seq - { givenname, surname } + { given~name, surname } } {2} { \seq_gset_from_clist:Nn \g__gpr_name_part_order_seq - { givenname, patronymic, byname } + { given~name, patronymic, byname } } } @@ -45,26 +50,48 @@ end~header .tl_set:N = \l__gpr_end_header_tl , begin~life~events .tl_set:N = \l__gpr_begin_life_events_tl , end~life~events .tl_set:N = \l__gpr_end_life_events_tl , + begin~content .tl_set:N = \l__gpr_begin_content_tl , + end~content .tl_set:N = \l__gpr_end_content_tl , + + layout~preset .choices:nn = { + clear , + tcolorbox + } { + \int_case:nn { \l_keys_choice_int } { + {1} { + \tl_clear:N \l__gpr_begin_profile_tl + \tl_clear:N \l__gpr_end_profile_tl + \tl_clear:N \l__gpr_begin_header_tl + \tl_clear:N \l__gpr_end_header_tl + \tl_clear:N \l__gpr_begin_life_events_tl + \tl_clear:N \l__gpr_end_life_events_tl + \tl_clear:N \l__gpr_begin_content_tl + \tl_clear:N \l__gpr_end_content_tl + } + {2} { + \bool_set_false:N \l__gpr_auto_header_bool + \tl_set:Nn \l__gpr_begin_profile_tl { + \begin{tcolorbox}[title = \gprHeader] + } + \tl_set:Nn \l__gpr_end_life_events_tl { + \tcblower + } + \tl_set:Nn \l__gpr_end_profile_tl { + \end{tcolorbox} + } + } + } + } , reference~style .cs_set:Np = \gpr__reference_style_handler:nnn #1#2#3 , unknown~reference~style .cs_set:Np = \gpr__unknown_reference_handler:nn #1#2 , page~number~style .cs_set:Np = \gpr__page_number_handler:n #1 , - % name part styling - givenname~style .tl_set:N = \l__gpr_givenname_style_tl , - patronymic~style .tl_set:N = \l__gpr_patronymic_style_tl , - surname~style .tl_set:N = \l__gpr_surname_style_tl , - byname~style .tl_set:N = \l__gpr_byname_style_tl , - header~format .tl_set:N = \l__gpr_header_format_tl , auto~header .bool_set:N = \l__gpr_auto_header_bool , % indexes - id~index .tl_set:N = \l__gpr_id_index_tl , - fullname~index .tl_set:N = \l__gpr_fullname_index_tl , - patronymic~index .tl_set:N = \l__gpr_patronymic_index_tl , - surname~index .tl_set:N = \l__gpr_surname_index_tl , - byname~index .tl_set:N = \l__gpr_byname_index_tl , + full~name~index .tl_set:N = \l__gpr_full_name_index_tl , nest~index~entries .bool_set:N = \l__gpr_nest_index_entries_bool , id~in~index~entries .bool_set:N = \l__gpr_id_in_index_entries_bool , @@ -73,18 +100,14 @@ include~unknown~in~index .default:n = { true } , include~ambiguous~in~index .bool_set:N = \l__gpr_include_ambiguous_in_index_bool , include~ambiguous~in~index .default:n = { true } , + use~styles~in~index .bool_set:N = \l__gpr_use_styles_in_index_bool , debug~log .bool_set:N = \l__gpr_debug_log_bool } \keys_define:nn { genealogy-profiles / profile } { - id .tl_set:N = \l__gpr_id_tl , - fullname .tl_set:N = \l__gpr_fullname_tl , - givenname .tl_set:N = \l__gpr_givenname_tl , - patronymic .tl_set:N = \l__gpr_patronymic_tl , - surname .tl_set:N = \l__gpr_surname_tl , - byname .tl_set:N = \l__gpr_byname_tl , + full~name .tl_set:N = \l__gpr_full_name_tl , life~events .tl_set:N = \l__gpr_life_events_tl , @@ -95,13 +118,53 @@ \keys_set:nn { genealogy-profiles } { #1 } } +\cs_new_protected:Nn \gpr_create_style_keys:nn +{ + \keys_define:nn { genealogy-profiles } { + #1~style .tl_set:c = { l__gpr_#1_style_tl } , + #1~index .tl_set:c = { l__gpr_#1_index_tl } , + } + \keys_define:nn { genealogy-profiles / profile } { + #1 .tl_set:c = { l__gpr_#1_tl } , + } + + \tl_set:cn { l__gpr_#1_cmd_tl } { #2 } + \exp_args:Nc \NewDocumentCommand { #2 Style } { m } { + \gpr_name_part_style:nn { #1 } { ##1 } + } +} +\cs_generate_variant:Nn \gpr_create_style_keys:nn { + nV +} + +\NewDocumentCommand { \gprCreateNamePart } { m o } { + \IfValueTF { #2 } { + \tl_set:Nn \l_tmpa_tl { #2 } + } { + \tl_set:Nn \l_tmpa_tl { gpr } + \seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 } + \seq_map_inline:Nn \l_tmpa_seq { + \tl_put_right:Nn \l_tmpa_tl { \text_titlecase_first:n { ##1 } } + } + } + \gpr_create_style_keys:nV { #1 } \l_tmpa_tl + \seq_new:c { l__gpr_#1_index_before_seq } + \seq_new:c { l__gpr_#1_index_after_seq } +} + +\gprCreateNamePart { given~name } +\gprCreateNamePart { patronymic } +\gprCreateNamePart { surname } +\gprCreateNamePart { byname } +\gpr_create_style_keys:nn { id } { gprID } + % set some defaults \keys_set:nn { genealogy-profiles } { auto~id , include~unknown~in~index , include~ambiguous~in~index , name~type = { given~and~surname } , - header~format = { \gprStyledName \hfill \gprID } , + header~format = { \gprFullName \hfill \gprID } , reference~style = { #1 \gpr_super_subscript:nn {#2} {#3} } , @@ -163,6 +226,19 @@ { Multiple ~ profiles ~ with ~ the ~ name ~ '#1', ~ you ~ will ~ need ~ to ~ use ~ IDs ~ to ~ reference ~ them } +\msg_new:nnn +{ genealogy-profiles } { profile-count } +{ There ~ are ~ #1 ~ profiles ~ in ~ this ~ document. } + +\msg_new:nnnn +{ genealogy-profiles } { name-part-missing } +{ Use ~ of ~ unknown ~ name ~ part ~ "#1" ~ on ~ input ~ line ~ #2 } +{ Create ~ it ~ with ~ gprCreateNamePart ~ first. } + +\msg_new:nnn +{ genealogy-profiles } { outside-profile } +{ The ~ #1 ~ macro ~ should ~ only ~ be ~ used ~ inside ~ profiles, ~ on ~ input ~ line ~ #2 } + \cs_new_protected:Nn \gpr_warning:nn { \msg_warning:nnee { genealogy-profiles } { #1 } { #2 } { \the\inputlineno } @@ -182,9 +258,6 @@ % Extensions to expl3 library % -\prg_generate_conditional_variant:Nnn \tl_if_blank:n - { v, V } { F } - \prg_generate_conditional_variant:Nnn \property_if_recorded:nn { en } { T, TF } @@ -197,9 +270,9 @@ \seq_use:Nn \l__gpr_floruit_years_seq {,} } -\tl_clear_new:N \l__gpr_fullname_raw_tl +\tl_clear_new:N \l__gpr_full_name_raw_tl \property_new:nnnn { raw-name } { now } { \c_novalue_tl } { - \tl_use:N \l__gpr_fullname_raw_tl + \tl_use:N \l__gpr_full_name_raw_tl } \prop_clear_new:N \g__gpr_name_to_id_prop % saved at end, loaded into _active at start @@ -212,17 +285,15 @@ % Names % -\tl_const:Ne \c_gpr_underscore_tl { \char_generate:nn { `_ } { 8 } } - \cs_new_protected:Nn \gpr_name_handler:n { - \tl_set:Nn \l__gpr_fullname_tl {#1} - \tl_replace_all:NVn \l__gpr_fullname_tl \c_gpr_underscore_tl { ~ } + \tl_set:Nn \l__gpr_full_name_tl {#1} + \regex_replace_all:nnN { \s*_\s* } { \ } \l__gpr_full_name_tl \seq_set_split:Nnn \l_tmpa_seq {~} {#1} \seq_map_indexed_inline:Nn \g__gpr_name_part_order_seq { \tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_tmpa_seq {##1} } - \tl_replace_all:NVn \l_tmpa_tl \c_gpr_underscore_tl { ~ } + \regex_replace_all:nnN { \s*_\s* } { \ } \l_tmpa_tl \tl_if_blank:VTF \l_tmpa_tl { \tl_clear:c { l__gpr_##2_tl } } { @@ -244,19 +315,19 @@ \cs_new_protected:Nn \gpr_map_name_to_id:Nnn { % check if name already has an associated id - \prop_get:NVNTF #1 \l__gpr_fullname_raw_tl \l_tmpb_tl + \prop_get:NVNTF #1 \l__gpr_full_name_raw_tl \l_tmpb_tl { % mark name ambiguous if already reserved \tl_if_eq:NNF \l__gpr_id_tl \l_tmpb_tl { \msg_note:nne { genealogy-profiles } { ambiguous-rawname } - { \tl_use:N \l__gpr_fullname_raw_tl } - \prop_gput:NVn #1 \l__gpr_fullname_raw_tl {_AMBIGUOUS_} + { \tl_use:N \l__gpr_full_name_raw_tl } + \prop_gput:NVn #1 \l__gpr_full_name_raw_tl {_AMBIGUOUS_} } } { % otherwise save raw name -> id - \prop_gput:NVV #1 \l__gpr_fullname_raw_tl \l__gpr_id_tl + \prop_gput:NVV #1 \l__gpr_full_name_raw_tl \l__gpr_id_tl } } \cs_generate_variant:Nn \gpr_map_name_to_id:Nnn { @@ -371,6 +442,8 @@ \prop_map_inline:Nn \g__gpr_references_prop { \gpr_check_backrefs:nn {##1} {##2} } + \msg_note:nne { genealogy-profiles } { profile-count } + { \seq_count:N \g__gpr_used_profile_ids_seq } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -385,29 +458,99 @@ } } \cs_generate_variant:Nn \gpr_add_to_named_index:nnN { - VVN, VeN + VVN, VeN, vVN } -\cs_new:Nn \gpr_build_index_entry:Nnnn { - \seq_clear:N \l_tmpa_seq - \clist_map_inline:nn {#2} { - \tl_if_blank:vF { l__gpr_##1_tl } { - \seq_put_right:Nv \l_tmpa_seq { l__gpr_##1_tl } +\cs_new_protected:Nn \gpr_get_name_parts:NNN +{ + \seq_clear:N #1 + \seq_map_inline:Nn #2 { + \tl_if_empty:cF { l__gpr_##1_tl } { + \bool_if:NTF #3 { + \seq_put_right:Ne #1 { + \use:c + { \tl_use:c { l__gpr_##1_cmd_tl } Style } + { \tl_use:c { l__gpr_##1_tl } } + } + } { + \seq_put_right:Nv #1 { l__gpr_##1_tl } + } } } +} +\cs_generate_variant:Nn \gpr_get_name_parts:NNN { + NcN +} + + +\cs_new:Nn \gpr_build_index_entry:nnN { + \tl_if_empty:cF { l__gpr_#1_tl } { + % build before/after seqs if not defined + \seq_if_empty:cT { l__gpr_#1_index_before_seq } { + \tl_set:Nn \l_tmpa_tl { l__gpr_#1_index_after_seq } + \seq_map_inline:Nn \g__gpr_name_part_order_seq { + \tl_if_eq:nnT { #1 } { ##1 } { + \tl_set:Nn \l_tmpa_tl { l__gpr_#1_index_before_seq } + } + \seq_put_right:cn { \tl_use:N \l_tmpa_tl } { ##1 } + } + } - \seq_clear:N \l_tmpb_seq - \clist_map_inline:nn {#3} { - \tl_if_blank:vF { l__gpr_##1_tl } { - \seq_put_right:Nv \l_tmpb_seq { l__gpr_##1_tl } + \gpr_get_name_parts:NcN \l_tmpa_seq { l__gpr_#1_index_before_seq } \c_false_bool + \tl_set:Ne \l_tmpa_tl { + \seq_use:Nn \l_tmpa_seq {~} + } + \bool_if:NTF \l__gpr_nest_index_entries_bool { + % nested entries + \bool_if:NT \l__gpr_use_styles_in_index_bool { + \gpr_get_name_parts:NcN \l_tmpb_seq { l__gpr_#1_index_before_seq } \c_true_bool + \tl_put_right:Ne \l_tmpa_tl { @ \seq_use:Nn \l_tmpb_seq {~} } + } + + \gpr_get_name_parts:NcN \l_tmpa_seq { l__gpr_#1_index_after_seq } \c_false_bool + \tl_put_right:Ne \l_tmpa_tl { + ! + \seq_use:Nn \l_tmpa_seq {~} + \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (#2) } + } + \bool_if:NT \l__gpr_use_styles_in_index_bool { + \gpr_get_name_parts:NcN \l_tmpb_seq { l__gpr_#1_index_after_seq } \c_true_bool + \tl_put_right:Ne \l_tmpa_tl { + @ + \seq_use:Nn \l_tmpb_seq {~} + \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (\gprIDStyle{#2}) } + } + } + } { + % un-nested entries + + % we only use a comma if there is an after seq + \int_compare:nNnTF { \seq_count:c { l__gpr_#1_index_after_seq } } = { 0 } { + \tl_set:Nn \l_tmpb_tl { } + } { + \tl_set:Nn \l_tmpb_tl { ,~ } + } + + \gpr_get_name_parts:NcN \l_tmpb_seq { l__gpr_#1_index_after_seq } \c_false_bool + \tl_put_right:Ne \l_tmpa_tl { + \tl_use:N \l_tmpb_tl + \seq_use:Nn \l_tmpb_seq {~} + \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (#2) } + } + \bool_if:NT \l__gpr_use_styles_in_index_bool { + \gpr_get_name_parts:NcN \l_tmpa_seq { l__gpr_#1_index_before_seq } \c_true_bool + \gpr_get_name_parts:NcN \l_tmpb_seq { l__gpr_#1_index_after_seq } \c_true_bool + \tl_put_right:Ne \l_tmpa_tl { + @ + \seq_use:Nn \l_tmpa_seq {~} + \tl_use:N \l_tmpb_tl + \seq_use:Nn \l_tmpb_seq {~} + \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (\gprIDStyle{#2}) } + } + } } - } - \tl_set:Ne #1 { - \seq_use:Nn \l_tmpa_seq {~} - \bool_if:NTF \l__gpr_nest_index_entries_bool { ! } { ,~ } - \seq_use:Nn \l_tmpb_seq {~} - \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (#4) } + \gpr_add_to_named_index:vVN { l__gpr_#1_index_tl } \l_tmpa_tl #3 } } @@ -416,49 +559,33 @@ \tl_if_blank:VF \l__gpr_id_index_tl { \tl_if_novalue:nF {#1} { \gpr_add_to_named_index:VeN \l__gpr_id_index_tl - { #1 ~ \tl_use:N \l__gpr_fullname_tl } + { + #1 ~ \tl_use:N \l__gpr_full_name_tl + \bool_if:NT \l__gpr_use_styles_in_index_bool { + @ \gprIDStyle{#1} ~ \tl_use:N \l__gpr_styled_name_tl + } + } #2 } } - \tl_if_blank:VF \l__gpr_fullname_index_tl { - \gpr_add_to_named_index:VVN - \l__gpr_fullname_index_tl + \tl_if_blank:VF \l__gpr_full_name_index_tl { + \gpr_add_to_named_index:VeN + \l__gpr_full_name_index_tl { - \tl_use:N \l__gpr_fullname_tl - \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (\tl_use:N #1) } + \bool_if:NTF \l__gpr_use_styles_in_index_bool { + \tl_use:N \l__gpr_styled_name_tl + } { + \tl_use:N \l__gpr_full_name_tl + } + \bool_if:NT \l__gpr_id_in_index_entries_bool { ~ (\gprIDStyle{\tl_use:N #1}) } } #2 } - \tl_if_blank:VF \l__gpr_patronymic_index_tl { - \tl_if_blank:VF \l__gpr_patronymic_tl { - \gpr_build_index_entry:Nnnn \l_tmpa_tl - { patronymic, surname, byname } - { givenname } - { #1 } - - \gpr_add_to_named_index:VVN \l__gpr_patronymic_index_tl \l_tmpa_tl #2 - } - } - \tl_if_blank:VF \l__gpr_surname_index_tl { - \tl_if_blank:VF \l__gpr_surname_tl { - \gpr_build_index_entry:Nnnn \l_tmpa_tl - { surname, byname } - { givenname, patronymic } - { #1 } - - \gpr_add_to_named_index:VVN \l__gpr_surname_index_tl \l_tmpa_tl #2 - } - } - \tl_if_blank:VF \l__gpr_byname_index_tl { - \tl_if_blank:VF \l__gpr_byname_tl { - \gpr_build_index_entry:Nnnn \l_tmpa_tl - { byname } - { givenname, patronymic, surname } - { #1 } - - \gpr_add_to_named_index:VVN \l__gpr_byname_index_tl \l_tmpa_tl #2 + \seq_map_inline:Nn \g__gpr_name_part_order_seq { + \tl_if_empty:cF { l__gpr_##1_index_tl } { + \gpr_build_index_entry:nnN { ##1 } { #1 } #2 } } } @@ -475,12 +602,11 @@ \seq_clear_new:N \l__gpr_styled_name_seq \seq_map_inline:Nn \g__gpr_name_part_order_seq { - \tl_if_blank:vF { l__gpr_##1_tl } { - \seq_put_right:Nn \l__gpr_styled_name_seq { - \group_begin: - \tl_use:c { l__gpr_##1_style_tl } - \tl_use:c { l__gpr_##1_tl } - \group_end: + \tl_if_empty:cF { l__gpr_##1_tl } { + \seq_put_right:Ne \l__gpr_styled_name_seq { + \use:c + { \tl_use:c { l__gpr_##1_cmd_tl } Style } + { \tl_use:c { l__gpr_##1_tl } } } } } @@ -488,6 +614,17 @@ \tl_set:Nn #1 { \seq_use:Nn \l__gpr_styled_name_seq {~} } } +\cs_new_protected:Nn \gpr_name_part_style:nn +{ + \group_begin: + \tl_use:c { l__gpr_#1_style_tl } + #2 + \group_end: +} +\cs_generate_variant:Nn \gpr_name_part_style:nn { + nv, nV +} + \cs_new_protected:Nn \gpr_format_floruit:N { \int_compare:nNnTF { \seq_count:N \l__gpr_floruit_years_seq } = {1} @@ -530,8 +667,8 @@ { \hyperlink{ \property_ref:nn { gpr/#1/target } { target } } { \gpr__reference_style_handler:nnn { + % render styled #3 only if present, otherwise use #2 \tl_if_blank:nTF { #3 } { #2 } { - % render styled #3 if present \group_begin: \gpr_name_handler:n {#3} \tl_use:N \l__gpr_styled_name_tl @@ -547,13 +684,16 @@ } } } + \bool_if:NF #4 { + \gpr_add_to_indexes:nN { #1 } \c_false_bool + } } { \gpr_warning:nn { unknown-reference-id } { #1 } - \gpr__unknown_reference_handler:nn {#2} { unknown~id: ~ #1 } - } - \bool_if:NF #4 { - \gpr_add_to_indexes:nN { #1 } \c_false_bool + \gpr__unknown_reference_handler:nn { #2 } { unknown~id: ~ #1 } + \bool_if:NF #4 { + \gpr_add_to_indexes:nN { unknown~id: ~ #1 } \c_false_bool + } } \gpr_save_reference:Vn \l__gpr_id_tl { #1 } } @@ -565,14 +705,24 @@ % genealogytree package integration % -\cs_new_protected:Nn \gpr_set_genealogytree_keys:n +\cs_new_protected:Nn \gpr_set_gtr_keys:n +{ + \gtrset{ #1 } +} + +\cs_new_protected:Nn \gpr_set_gtr_database_keys:n { - \gtrset{ database/.cd, #1 } + \gpr_set_gtr_keys:n{ database/.cd, #1 } } -\cs_generate_variant:Nn \gpr_set_genealogytree_keys:n { +\cs_generate_variant:Nn \gpr_set_gtr_database_keys:n { V } +\cs_new_protected:Nn \gpr_print_gtr_database: +{ + \gtrPrintDatabase +} + \prg_new_protected_conditional:Nnn \gpr_if_lifespan_defined: {T,F,TF} { \bool_if:nTF { @@ -600,12 +750,23 @@ \end{gtrprintlist}% \gtr@print@infolist% } -\gtrset{database~format=gtr_db_format} +\gpr_set_gtr_keys:n { database~format = gtr_db_format } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% User commands +% Environments % +\cs_new_protected:Nn \gpr_create_profile_macro:nnn +{ + \exp_args:Nc \DeclareDocumentCommand { #1 } { s } + { + \IfBooleanTF { ##1 } { #2 } { #3 } + } +} +\cs_generate_variant:Nn \gpr_create_profile_macro:nnn { + vvn +} + \NewDocumentEnvironment { gprProfile* } { m O{} } { \bool_if:NT \l__gpr_debug_log_bool { \tl_log:e {\the\inputlineno} @@ -614,22 +775,22 @@ \group_begin: \keys_set:nn { genealogy-profiles / profile } { #1, life~events={#2} } - \tl_if_empty:NTF \l__gpr_fullname_tl { + \tl_if_empty:NTF \l__gpr_full_name_tl { % if no full name supplied, build one from given parts \seq_clear:N \l_tmpa_seq \seq_map_inline:Nn \g__gpr_name_part_order_seq { - \tl_if_blank:vF { l__gpr_##1_tl } { + \tl_if_empty:cF { l__gpr_##1_tl } { \seq_put_right:Nv \l_tmpa_seq { l__gpr_##1_tl } } } - \tl_set:Ne \l__gpr_fullname_tl { \seq_use:Nn \l_tmpa_seq {~} } - \tl_set_eq:NN \l__gpr_fullname_raw_tl \l__gpr_fullname_tl + \tl_set:Ne \l__gpr_full_name_tl { \seq_use:Nn \l_tmpa_seq {~} } + \tl_set_eq:NN \l__gpr_full_name_raw_tl \l__gpr_full_name_tl \tl_clear_new:N \l__gpr_styled_name_tl \gpr_style_name:N \l__gpr_styled_name_tl } { % otherwise use full name to split into parts - \tl_set_eq:NN \l__gpr_fullname_raw_tl \l__gpr_fullname_tl - \gpr_name_handler:V \l__gpr_fullname_tl + \tl_set_eq:NN \l__gpr_full_name_raw_tl \l__gpr_full_name_tl + \gpr_name_handler:V \l__gpr_full_name_tl } % ensure unique id @@ -637,7 +798,7 @@ \bool_if:NTF \l__gpr_autoid_bool { \gpr_generate_unique_id: } { - \gpr_error:nn { missing-id } { \l__gpr_fullname_tl } + \gpr_error:nn { missing-id } { \l__gpr_full_name_tl } } } { \seq_if_in:NVT \g__gpr_used_profile_ids_seq \l__gpr_id_tl { @@ -645,8 +806,8 @@ } \seq_gput_right:NV \g__gpr_used_profile_ids_seq \l__gpr_id_tl } - \gpr_map_name_to_id:NVV \g__gpr_name_to_id_prop \l__gpr_fullname_raw_tl \l__gpr_id_tl - \gpr_map_name_to_id:NVV \g__gpr_name_to_id_active_prop \l__gpr_fullname_raw_tl \l__gpr_id_tl + \gpr_map_name_to_id:NVV \g__gpr_name_to_id_prop \l__gpr_full_name_raw_tl \l__gpr_id_tl + \gpr_map_name_to_id:NVV \g__gpr_name_to_id_active_prop \l__gpr_full_name_raw_tl \l__gpr_id_tl % store raw name in aux \property_record:ee { gpr/\tl_use:N \l__gpr_id_tl/name } { raw-name } @@ -668,14 +829,25 @@ \seq_clear_new:N \l__gpr_floruit_years_seq % placeholders for id and names - \cs_set:Npe \gprID { \tl_use:N \l__gpr_id_tl } - \cs_set:Npe \gprStyledName { \tl_use:N \l__gpr_styled_name_tl } - \cs_set:Npe \gprFullName { \tl_use:N \l__gpr_fullname_tl } - \cs_set:Npe \gprGivenName { \tl_use:N \l__gpr_givenname_tl } - \cs_set:Npe \gprPatronymic { \tl_use:N \l__gpr_patronymic_tl } - \cs_set:Npe \gprSurname { \tl_use:N \l__gpr_surname_tl } - \cs_set:Npe \gprByname { \tl_use:N \l__gpr_byname_tl } - \cs_set:Npe \gprHeader { \tl_use:N \l__gpr_header_format_tl } + \cs_set:Npn \gprHeader { \tl_use:N \l__gpr_header_format_tl } + \gpr_create_profile_macro:nnn { gprID } { + \tl_use:N \l__gpr_id_tl + } { + \gpr_name_part_style:nV { id } \l__gpr_id_tl + } + \gpr_create_profile_macro:nnn { gprFullName } { + \tl_use:N \l__gpr_full_name_tl + } { + \tl_use:N \l__gpr_styled_name_tl + } + % name parts + \seq_map_inline:Nn \g__gpr_name_part_order_seq { + \gpr_create_profile_macro:vvn { l__gpr_##1_cmd_tl } + { l__gpr_##1_tl } + { + \gpr_name_part_style:nv { ##1 } { l__gpr_##1_tl } + } + } % set hyperref target just before typesetting \MakeLinkTarget*{ gpr/\tl_use:N \l__gpr_id_tl/target } @@ -701,12 +873,18 @@ \tl_if_empty:NF \l__gpr_life_events_tl { \tl_use:N \l__gpr_begin_life_events_tl - \gpr_set_genealogytree_keys:V \l__gpr_life_events_tl - \gtrPrintDatabase + \gpr_set_gtr_database_keys:V \l__gpr_life_events_tl + \gpr_print_gtr_database: \tl_use:N \l__gpr_end_life_events_tl } + + % begin content + \tl_use:N \l__gpr_begin_content_tl }{ + % end content + \tl_use:N \l__gpr_end_content_tl + % end typesetting \tl_use:N \l__gpr_end_profile_tl @@ -722,11 +900,15 @@ } \NewDocumentEnvironment { gprProfile } { O{} m O{} } { - \begin{gprProfile*}{fullname={#2}, #1}[#3] + \begin{gprProfile*}{full~name={#2}, #1}[#3] }{ \end{gprProfile*} } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Reference and name macros +% + \cs_new_protected:Nn \gpr_cmd_ref:Nnn { \group_begin: @@ -738,11 +920,11 @@ { \str_if_eq:VnTF \l_tmpa_tl {_AMBIGUOUS_} { - \gpr_warning:nn { ambiguous-reference } { \l__gpr_fullname_tl } + \gpr_warning:nn { ambiguous-reference } { \l__gpr_full_name_tl } \gpr__unknown_reference_handler:Vn \l__gpr_styled_name_tl { ambiguous } \bool_if:NT \l__gpr_include_ambiguous_in_index_bool { - \gpr_add_to_indexes:nN { ambiguous } \c_false_bool + \gpr_add_to_indexes:nN { ambiguous~name } \c_false_bool } } { @@ -753,7 +935,7 @@ \gpr_warning:nn { unknown-reference-name } { #3 } \gpr__unknown_reference_handler:Vn \l__gpr_styled_name_tl { unknown~name } \bool_if:NT \l__gpr_include_unknown_in_index_bool { - \gpr_add_to_indexes:nN { unknown } \c_false_bool + \gpr_add_to_indexes:nN { unknown~name } \c_false_bool } } } @@ -790,6 +972,9 @@ \group_end: } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Floruit macros +% \cs_new_protected:Nn \gpr_cmd_year:n { @@ -802,6 +987,10 @@ e } \NewDocumentCommand { \gprYear } { s m } { + \tl_if_empty:NT \l__gpr_id_tl { + \gpr_error:nn { outside-profile } { gprYear } + } + \gpr_cmd_year:e {#2} \bool_if:NF { #1 } { #2 } } @@ -832,10 +1021,34 @@ e } \NewDocumentCommand { \gprYears } { s m } { + \tl_if_empty:NT \l__gpr_id_tl ( + \gpr_error:nn { outside-profile } { gprYears } + ) + \gpr_cmd_years:e {#2} \bool_if:NF { #1 } { #2 } } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Deprecations +% + +\cs_new:Npn \gprStyledName { \gprFullName } + +\keys_define:nn { genealogy-profiles } +{ + givenname~style .tl_set:c = { l__gpr_given~name_style_tl } , + givenname~index .tl_set:c = { l__gpr_given~name_index_tl } , + fullname~index .tl_set:N = \l__gpr_full_name_index_tl , +} +\keys_define:nn { genealogy-profiles / profile } { + givenname .tl_set:c = { l__gpr_given~name_tl } , + fullname .tl_set:N = \l__gpr_full_name_tl , +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Experimental! +% \NewDocumentCommand { \gprSpouse } { s o m o } { \gtrsymMarried{} ~ |