Comment renvoyer à une page choisie au hasard dans le document courant ?#

Il est possible de créer un lien « page au hasard » en utilisant Bien sûr, en cliquant plusieurs fois sur le même lien, on sera toujours dirigé vers la même page, mais cette page sera attribuée au lien de manière aléatoire durant la compilation.

Pour cela, on peut utiliser Lua pour générer au hasard le numéro d’une page (entre 1 et le nombre total de pages du documents), puis créer un lien avec hyperref renvoyant vers la page correspondante. Il existe plusieurs moyens d’obtenir le nombre total de pages du document courant ; la technique retenue fonctionne avec n’importe quelle classe de document à condition d’avoir une version de suffisamment récente. Comme le programme doit connaître le nombre total de pages du document, il faut compiler celui-ci au moins deux fois.

%!TEX engine=lualatex
\documentclass[a5paper, latin]{memoir}
\usepackage{babel, lipsum, luacode, hyperref}

\newcommand{\versPageAleatoire}{%
  % folioAleatoire() est une fonction définie infra en Lua.
  \hyperlink{page.\directlua{tex.print(folioAleatoire())}}
            {Vers une page au hasard}%
}

\makepagestyle{headings}
% en-tête (fausse page): {gauche}{centre}{droite}
\makeevenhead{headings}{\thepage}{}{}
% en-tête (belle page): {gauche}{centre}{droite}
\makeoddhead{headings}{}{}{\thepage}
% pied de page (fausse page): {gauche}{centre}{droite}
\makeevenfoot{headings}{}{\versPageAleatoire}{}
% pied de page (belle page): {gauche}{centre}{droite}
\makeoddfoot{headings}{}{\versPageAleatoire}{}

\begin{luacode}
  -- Initialiser le générateur de nombres aléatoires    
  math.randomseed(math.random(1,10000), math.random(1,10000))
  
  local function nbTotalPages()
    -- Le compteur totalPages est défini infra après begin{document}
    local counter = tex.getcount("totalPages")
    if counter < 2 then return 2 else return counter end
  end
  
  function folioAleatoire()
  -- Générer un nombre entier aléatoire
  -- compris entre 1 et et le numéro du dernier folio du présent document.
    local folio = math.random(1, nbTotalPages())
    -- On évite de renvoyer à la page sur laquelle se trouve le lien.
    if folio == tex.getcount("c@page") then
      return folioAleatoire()
    else
      return folio
    end
  end
\end{luacode}

\begin{document}

% Il faut stocker dans un compteur le nombre total de pages
% écrit dans le fichier auxiliaire lors de la précédente compilation,
% de manière à pouvoir récupérer cette valeur avec tex.getcount dans Lua.
% On pourrait utiliser le compteur dédié spécifique à la classe memoir
% ou une extension, mais la solution indiquée ici devrait fonctionner
% avec n'importe quelle installation LaTeX récente.
% Ce code doit toujours se trouver après \begin{document}.
\makeatletter
\newcount\totalPages
\totalPages=\@abspage@last
\makeatother

\lipsum[1-20]

\end{document}

Sources

Basé sur une solution proposée par Thomas Savary sur la liste gut@ens.fr.