\documentclass[paper=A5, DIV=12, fontsize=12pt]{scrartcl}
\usepackage{polyglossia}
\setmainlanguage[autospacing=false, autospaceguillemets=false]{french}
\setmainfont{Theano Didot}
\setsansfont{IBM Plex Sans}
\setmonofont{IBM Plex Mono}
\usepackage{bxtexlogo}
\def\OpTeX{Op\kern-.1em\TeX}

\def\labelitemi{—}
\def\labelitemii{–}
\def\labelitemiii{-}

\usepackage{codehigh}
\CodeHigh{language=latex/latex2}

\def\bdtitre#1{
  \begin{center}
    {\large #1}
  \end{center}
  \medskip
}

\let\tt\texttt

\usepackage{reledmac}
\lineation{page}

% TODO : voir si n'a pas des fonctionnalités auxquelles je n'ai pas pensées
% (p. ex. version capitalisée)
\usepackage{zref-clever}
\zcRefTypeSetup{line}{name-pl=lignes,}
\makeatletter
\zref@newprop{line}[0]{\the\line@num}
\zref@addprop{main}{line}
\makeatother

\def\bdlabel#1{\zlabel{#1}\edlabel{#1}}

%%%%%%%%%%%%%%%%% 

\usepackage{nameref}
\usepackage{crossrefenum}
\let\crfnmPages\crfnmPage
\let\crfnmEdpages\crfnmEdpage
\let\crfnmEdlines\crfnmEdline
\def\crfnmDefaultBeforeLastInEnum{ et }
\let\crfnmDefaultBeforeLastInSecond\crfnmDefaultBeforeLastInEnum
\def\crfnmDefaultRangeSep{-}
\def\crfnmDefaultBeforeLastInSecond{, } % TODO : erreur dans le manuel

%%%%%%%%%%%%%%%%%%

\begin{document}

\bdtitre{Le petit Chaperon rouge}

% https://fr.wikisource.org/wiki/Contes_de_Perrault_(éd._1902)/Le_petit_Chaperon_rouge

\beginnumbering\autopar

Il était une fois une petite fille de village, la plus éveillée qu’on eût su voir :
sa mère\bdlabel{mr-1} en était folle, et sa mère\bdlabel{mr-2}-grand plus folle encore.
Cette bonne femme lui fit faire un petit chaperon rouge
qui lui seyait si bien, que partout on l’appelait le petit Chaperon rouge.

Un jour, sa mère\bdlabel{mr-3} ayant cuit et fait des galettes, lui dit :
« Va voir comment se porte ta mère\bdlabel{mr-4}-grand, car on m’a dit qu’elle était malade.
Porte-lui une galette et ce petit pot de beurre. »

Le petit Chaperon rouge partit aussitôt pour aller chez sa mère\bdlabel{mr-5}-grand, qui demeurait dans un autre village.
En passant dans un bois, elle rencontra compère le Loup\bdlabel{lp-1}, qui eut bien envie de la manger ;
mais il n’osa, à cause de quelques bûcherons qui étaient dans la forêt.
Il lui demanda où elle allait. La pauvre enfant, qui ne savait pas
qu’il était dangereux de s’arrêter à écouter un loup\bdlabel{lp-2}, lui dit :
« Je vais voir ma mère\bdlabel{mr-6}-grand, et lui porter une galette, avec un petit pot de beurre, que ma mère\bdlabel{mr-7} lui envoie.

— Demeure-t-elle bien loin ? lui dit le loup\bdlabel{lp-3}.

— Oh ! oui, dit le petit Chaperon rouge ; c’est par delà le moulin que vous voyez tout là-bas, à la première maison du village.

— Eh bien ! dit le Loup\bdlabel{lp-4}, je veux l’aller voir aussi :
je m’y en vais par ce chemin-ci, et toi par ce chemin-là ; et nous verrons à qui plus tôt y sera. »

Le Loup\bdlabel{lp-5} se mit à courir de toute sa force par le chemin qui était le plus court,
et la petite fille s’en alla par le chemin le plus long,
s’amusant à cueillir des noisettes, à courir après des papillons,
et à faire des bouquets des petites fleurs qu’elle rencontrait.

Le Loup\bdlabel{lp-6} ne fut pas longtemps à arriver à la maison de la mère\bdlabel{mr-8}-grand ; il heurte : toc, toc.

« Qui est là ?

— C’est votre fille, le petit Chaperon rouge, dit le Loup\bdlabel{lp-7} en contrefaisant sa voix,
qui vous apporte une galette et un petit pot de beurre, que ma mère\bdlabel{mr-9} vous envoie. »

La bonne mère\bdlabel{mr-10}-grand, qui était dans son lit, à cause qu’elle se trouvait un peu mal, lui cria :
« Tire la chevillette, la bobinette cherra. »

Le Loup\bdlabel{lp-8} tira la chevillette, et la porte s’ouvrit.
Il se jeta sur la bonne femme, et la dévora en moins de rien,
car il y avait plus de trois jours qu’il n’avait mangé.

Ensuite il ferma la porte, et s’alla coucher dans le lit de la mère\bdlabel{mr-11}-grand,
en attendant le petit Chaperon rouge, qui, quelque temps après,
vint heurter à la porte : toc, toc.

« Qui est là ? »

Le petit Chaperon rouge, qui entendit la grosse voix du Loup\bdlabel{lp-9}, eut peur d’abord,
mais, croyant que sa mère\bdlabel{mr-12}-grand était enrhumée, répondit :
« C’est votre fille, le petit Chaperon rouge, qui vous apporte une galette et un petit pot
de beurre, que ma mère\bdlabel{mr-13} vous envoie. »

Le Loup\bdlabel{lp-10} lui cria en adoucissant un peu sa voix : « Tire la chevillette, la bobinette cherra. »
Le petit Chaperon rouge tira la chevillette, et la porte s’ouvrit.

Le Loup\bdlabel{lp-11}, la voyant entrer, lui dit en se cachant dans le lit, sous la couverture :
« Mets la galette et le petit pot de beurre sur la huche, et viens te coucher avec moi. »
Le petit Chaperon rouge se déshabille, et va se mettre dans le lit,
où elle fut bien étonnée de voir comment sa mère\bdlabel{mr-14}-grand était faite en son déshabillé.
Elle lui dit : « Ma mère\bdlabel{mr-15}-grand, que vous avez de grands bras !

— C’est pour mieux t’embrasser, ma fille !

— Ma mère\bdlabel{mr-16}-grand, que vous avez de grandes jambes !

— C’est pour mieux courir, mon enfant !

— Ma mère\bdlabel{mr-17}-grand, que vous avez de grandes oreilles !

— C’est pour mieux écouter, mon enfant !

— Ma mère\bdlabel{mr-18}-grand, que vous avez de grands yeux !

— C’est pour mieux te voir, mon enfant !

— Ma mère\bdlabel{mr-19}-grand, que vous avez de grandes dents !

— C’est pour te manger ! »

Et, en disant ces mots, ce méchant Loup\bdlabel{lp-12} se jeta sur le petit Chaperon
rouge, et la mangea.

\endnumbering

\newpage

\sffamily
\setkomafont{pagenumber}{\sffamily}
\parskip=1ex
\parindent=0pt
\raggedright

Extrait du préambule de ce fichier :

\begin{codehigh}
\usepackage{reledmac}
\lineation{page}

% Fournit \zpageref et \zref
\usepackage{zref}
\def\bdlabel#1{\zlabel{#1}\edlabel{#1}}
\makeatletter
\zref@newprop{line}[0]{\the\line@num}
\zref@addprop{main}{line}
\makeatother

% Fournit \zcref
\usepackage{zref-clever}
\zcRefTypeSetup{line}{name-pl=lignes,}

\end{codehigh}

\newpage

\zlabel{ex-0}

Voici la liste des occurrences du mot « loup » :

\begin{codehigh}
Pages
\zpageref{lp-1}, \zpageref{lp-2},
\zpageref{lp-3}, \zpageref{lp-4},
\zpageref{lp-5}, \zpageref{lp-6},
\zpageref{lp-7}, \zpageref{lp-8},
\zpageref{lp-9}, \zpageref{lp-10},
\zpageref{lp-11}, \zpageref{lp-12}
\end{codehigh}

Pages \zpageref{lp-1}, \zpageref{lp-2}, \zpageref{lp-3}, \zpageref{lp-4}, \zpageref{lp-5}, \zpageref{lp-6}, \zpageref{lp-7}, \zpageref{lp-8}, \zpageref{lp-9}, \zpageref{lp-10}, \zpageref{lp-11}, \zpageref{lp-12}

\newpage

\zlabel{ex-1}

\begin{codehigh}
\zcpageref{lp-1, lp-2, lp-3, lp-4,
lp-5, lp-6, lp-7, lp-8, lp-9, lp-10,
lp-11, lp-12}
\end{codehigh}

\zcpageref{lp-1, lp-2, lp-3, lp-4, lp-5, lp-6, lp-7, lp-8, lp-9, lp-10, lp-11, lp-12}

\newpage

\zlabel{ex-2}

\begin{codehigh}
Lignes \zcref[ref=line, noname]{lp-1,
lp-2, lp-3, lp-4, lp-5, lp-6, lp-7, lp-8,
lp-9, lp-10, lp-11, lp-12}
\end{codehigh}

Lignes \zcref[ref=line, noname]{lp-1, lp-2, lp-3, lp-4, lp-5, lp-6, lp-7, lp-8, lp-9, lp-10, lp-11, lp-12}

% \bdexemple{\zcref[ref=line, noname]{mr-1, mr-2, mr-3, mr-4, mr-5, mr-6, mr-7, mr-8, mr-9, mr-10, mr-11, mr-12, mr-13, mr-14, mr-15, mr-16, mr-17, mr-18, mr-19}}

\newpage

\zlabel{ex-3}

\begin{codehigh}
\crossrefenum[edpage]{{lp-1}{lp-2}
{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}
{lp-9}{lp-10}{lp-11}{lp-12}}
\end{codehigh}

\crossrefenum[edpage]{{lp-1}{lp-2}{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}{lp-9}{lp-10}{lp-11}{lp-12}}

\newpage

\zlabel{ex-4}

\begin{codehigh}
\crossrefenum[edline]{{lp-1}{lp-2}
{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}
{lp-9}{lp-10}{lp-11}{lp-12}}
\end{codehigh}

\crossrefenum[edline]{{lp-1}{lp-2}{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}{lp-9}{lp-10}{lp-11}{lp-12}}

\newpage

\zlabel{ex-5}

\begin{codehigh}
\crossrefenum[edpageline]{{lp-1}{lp-2}
{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}
{lp-9}{lp-10}{lp-11}{lp-12}}
\end{codehigh}

\crossrefenum[edpageline]{{lp-1}{lp-2}{lp-3}{lp-4}{lp-5}{lp-6}{lp-7}{lp-8}{lp-9}{lp-10}{lp-11}{lp-12}}

\newpage

\zlabel{ex-6}

Voici la liste des occurences du mot « mère » :

\begin{codehigh}
\crossrefenum[edpageline]{{mr-1}{mr-2}
{mr-3}{mr-4}{mr-5}{mr-6}{mr-7}{mr-8}
{mr-9}{mr-10}{mr-11}{mr-12}{mr-13}{mr-14}
{mr-15}{mr-16}{mr-17}{mr-18}{mr-19}}
\end{codehigh}

\crossrefenum[edpageline]{{mr-1}{mr-2}{mr-3}{mr-4}{mr-5}{mr-6}{mr-7}{mr-8}{mr-9}{mr-10}{mr-11}{mr-12}{mr-13}{mr-14}{mr-15}{mr-16}{mr-17}{mr-18}{mr-19}}

\newpage

\zlabel{ex-7}

\begin{codehigh}
\def\crfnmEdpagelineBeforeLastInEnum{\,; et }
\def\crfnmEdpagelineEnumDelim{\,; }
\def\crfnmEdlineFormatInSecond#1{%
  {\footnotesize #1}%
}

\crossrefenum[edpageline]{{mr-1}{mr-2}
{mr-3}{mr-4}{mr-5}{mr-6}{mr-7}{mr-8}
{mr-9}{mr-10}{mr-11}{mr-12}{mr-13}{mr-14}
{mr-15}{mr-16}{mr-17}{mr-18}{mr-19}}
\end{codehigh}

\def\crfnmEdpagelineBeforeLastInEnum{ ; et }
\def\crfnmEdpagelineEnumDelim{ ; }
\def\crfnmEdlineFormatInSecond#1{{\footnotesize #1}}
\crossrefenum[edpageline]{{mr-1}{mr-2}{mr-3}{mr-4}{mr-5}{mr-6}{mr-7}{mr-8}{mr-9}{mr-10}{mr-11}{mr-12}{mr-13}{mr-14}{mr-15}{mr-16}{mr-17}{mr-18}{mr-19}}

\newpage

Dis-moi \tt{crossrefenum}, où puis-je trouver les exemples dans ce fichier ?

\newpage

\zlabel{ex-8}

\begin{codehigh}
Les exemples se trouvent
\crossrefenum[zpage]{{ex-1}{ex-2}{ex-3}
{ex-4}{ex-5}{ex-6}{ex-7}{ex-8}}.
\end{codehigh}

\begin{verbatim}
! crossrefenum: Unsupported type zpage for
format LaTeX2e{}..
\end{verbatim}

\newpage

\bdtitre{Principes de \tt{crossrefenum}}

Objectifs communs avec \tt{zref-clever} :

\begin{itemize}
\item Supprimer les redondances dans les énumérations de références ;
\item Mise en forme flexible et personnalisable (p. ex. préfixes) ;
\item Références ponctuelles et intervalles.
\item[→] Favoriser l'utilisation systématique de références internes précises.
\end{itemize}

Fonctionnalité spécifique à \tt{zref-clever} :

\begin{itemize}
\item Tri des références ;
\item Différents types références dans une même invocation.
\end{itemize}

Objectifs spécifiques à \tt{crossrefenum} :

\begin{itemize}
\item Références combinant deux indicateurs (page et note, page et ligne) ;
\item Indépendant du programme qui détermine les valeurs associées aux références 
  (p. ex. noyau de \LaTeX, \tt{zref},\ldots) ;
\item Indépendant du format (fonctionne actuellement avec \LaTeX{} et \ConTeXt) et du moteur.
\end{itemize}

Pour une présentation détaillée des cas traités et des fonctionnalités, se référer au manuel et au fichier de test.

\newpage

Choix d'implémentation pour atteindre ces objectifs :

\begin{itemize}
\item Noyau :
  \begin{itemize}
  \item Écrit en pur \TeX, n'utilise aucune macro fournie par un format ou d'autres extensions ;
  \item Récupère les valeurs brutes 
    → Compare les valeurs pour exclure celles qui sont redondantes et créer les intervalles
    → Met en forme l'énumération de références en appelant les macros personnalisables.
  \end{itemize}
\item Interfaces :
  \begin{itemize}
  \item Les calculs sont opérés sans effet de bord, donc les macros
    qui fournissent les valeurs brutes doivent être purement développables
    (≠ \tt{lineno}) ;
  \item Les macros de mise en forme ont des valeurs par défaut
    (valables pour tous les types d'indicateurs)
    qui peuvent être modifiées pour certains types.
  \item[→] Possibilité d'étendre :
    \begin{itemize}
    \item À de nouveaux types : en fournissant les macros
      nécessaires à la récupération des valeurs brutes et à la mise en forme) ;
    \item À de nouveaux formats : en implémentant le support des types
      fournis par ce format et en indiquant les macros standards utilisées
      pour avertir l'utilisateur et écrire dans le fichier auxiliaire.
    \end{itemize}
  \end{itemize}
\item Suite de tests détaillée.
\end{itemize}

\newpage

\zlabel{ex-9}

\begin{codehigh}
\makeatletter

\def\crfnm@zpage{Zpage}
\crfnm@newListFrom[\crfnm@simpleRefTypes]
  [\crfnm@zpage] -> \crfnm@simpleRefTypes
\crfnm@newListFrom[\crfnm@supportedTypes]
  [\crfnm@zpage] -> \crfnm@supportedTypes

\def\crfnm@ZpageRef#1{\zpageref{#1}}

\def\crfnm@getZpageNumber#1{%
  \zref@extract{#1}{page}%
}

\def\crfnmZpage{p.~}
\let\crfnmZpages\crfnmZpage

\makeatother

Les exemples se trouvent
\crossrefenum[zpage]{{ex-1}{ex-2}{ex-3}
{ex-4}{ex-5}{ex-6}{ex-7}{ex-8}{ex-9}}.
\end{codehigh}

\makeatletter

\def\crfnm@zpage{Zpage}
% TODO : ajouter \crfnm@addToList et \crfnm@declareType[<simple/double>]{<type>}
\crfnm@newListFrom[\crfnm@simpleRefTypes][\crfnm@zpage] -> \crfnm@simpleRefTypes
\crfnm@newListFrom[\crfnm@supportedTypes][\crfnm@zpage] -> \crfnm@supportedTypes

% TODO : message d'erreur si les deux suivantes ne sont pas définies
\def\crfnm@ZpageRef#1{\zpageref{#1}}
% TODO : préciser dans le manuel que doit être purement développable
\def\crfnm@getZpageNumber#1{\zref@extract{#1}{page}}

\def\crfnmZpage{p.~}
\let\crfnmZpages\crfnmZpage

\makeatother

Les exemples se trouvent \crossrefenum[zpage]{{ex-1}{ex-2}{ex-3}{ex-4}{ex-5}{ex-6}{ex-7}{ex-8}{ex-9}}.

\newpage

\bdtitre{\tt{crossrefenum} aujourd'hui et demain}

Tous les objectifs ont été atteints.

Nombre d'utilisateurs connus : 2.

Améliorations envisagées, classées par ordre décroissant de priorité :

\begin{itemize}
\item Corriger quelques erreurs dans la documentation
  et ajouter quelques petites fonctionnalités manquantes.
\item Rendre l'interface plus sympathique :
  \begin{itemize}
  \item Liste d'étiquettes séparées par des virgules
    (comme avec \tt{zref-clever}) plutôt que groupes successifs :
  \item Interfaces clé-valeur pour la déclaration des options de mise en forme.
  \end{itemize}
\item Supporter \OpTeX.
\end{itemize}

\newpage

\bdtitre{Développer indépendamment des formats de \TeX : bilan et perspectives}

Atouts et difficultés de la programmation en pur \TeX :

\begin{itemize}
\item Documentation de qualité sur \TeX{} comme langage de programmation :
  \emph{The \TeX book} de Donald Knuth, \emph{\TeX{} by Topic} de Victor Eijkhout,
  et surtout \emph{Apprendre à programmer en \TeX} de Christian Tellechea ;
\item Outils de débogage archaïques quoique sous-estimés ;
\item Langage à macros comprenant essentiellement les composants de base :
  \begin{itemize}
  \item Grande liberté, mais demande de réinventer la roue ;
  \item Mécanismes d'expansion parfois difficiles à comprendre et à simuler mentalement ;
  \item Macros ≠ fonctions : pas de distinction entre valeur de retour et effet de bord
    → contrainte forte sur l'écriture de macros devant produire une valeur utilisée par une autre macro ;
  \item Rend complexes des tâches qui sont simples dans la plupart des autres langages
    (p. ex. manipulation de chaînes de caractères).
  \end{itemize}
\item Mais aurait pu être facilité si j'avais étudié et repris des macros de programmation
  écrites en pur \TeX{} par d'autres.
\end{itemize}

\newpage

Faut-il renoncer à écrire des extensions utilisables avec tous les moteurs et formats ?
Le cloisonnement interne de l'écosystème \TeX{} est-il nécessaire ?

\begin{itemize}
\item Domination de l'écosystème par des grands massifs monolithiques
  → les outils existants sur lesquels on peut s'appuyer dépendent souvent
  eux-mêmes d'un format ;
\item Cloisonnement sans doute inévitable quand on touche à la composition des pages entières ;
\item Mais possibilité d'avoir une approche plus modulaire de certains composants :
  \begin{itemize}
  \item Gestion des fontes ;
  \item Composition de petites unités ;
  \item Extensions de programmation spécialisées (p. ex. \tt{xstring}, \tt{texapi}, \tt{expkv-bundle}).
  \item[→] Travail de recension à mener (notamment dans \tt{tex/generic} et \tt{tex/plain}).
  \end{itemize}
\end{itemize}

\end{document}
