随机页码

随机页码

我需要一些帮助来实现一个疯狂的想法。对于一本书,我希望页码是随机排列的。例如,如果这本书有 5 页,我想要 (4,1,2,5,3) 这样的页码。理想情况下,目录和参考资料会起作用。我对 TeX 了解不够,无法自己做。我已经对如何进行的一些指导感到满意了。

我使用书中的 LaTeX 课程和 XeLatex。

谢谢你!

答案1

这将使用范围内的指定排列,如果您拥有的页面多于该值,它将恢复正常,因此一旦您知道有多少页,您就可以随时在最后修改定义

在此处输入图片描述

\documentclass{book}

\renewcommand\thepage{%
\ifcase\value{page}%
0\or
4\or
1\or
2\or
5\or
6\or
3\else
\arabic{page}%
\fi}

\begin{document}

\tableofcontents

\chapter{Intro}
\section{Zzzz}aaaa
\section{Zzzzz}aaaa \clearpage bbbb
\section{Zzzzz}aaaa


\chapter{Something}
\section{Zzzz zzz}aaaa
\section{Zzzzzz zzz}aaaa \clearpage bbbb
\section{Zzzzzzz zzz}aaaa


\end{document}

答案2

只是为了好玩,这个实现不需要外部程序,只需要运行两次 LaTeX。但是,每次后续运行时页面都会发生变化。

\documentclass{article}
\usepackage{xparse}
\usepackage{zref-user,zref-abspage,atveryend}
\usepackage{kantlipsum}

% Coerce zref into not adding the last page number in the .aux file
% which would always issue the warning that labels have changed
\makeatletter
\zref@newlist{lastabs}
\zref@addprop{lastabs}{abspage}
\AfterLastShipout{%
  \if@filesw
    \begingroup
      \advance\c@page\m@ne
      \toks@\expandafter{\Z@L@lastabs}%
      \expandafter\zref@wrapper@immediate\expandafter{%
        \expandafter\ZREF@label\expandafter{\the\toks@}{LastAbsPage}%
      }%
    \endgroup
  \fi
}
\makeatother

\ExplSyntaxOn

\cs_set_eq:Nc \zref_extract:nn { zref@extract }

% a variant of the Knuth shuffle algorithm as implemented
% in https://tex.stackexchange.com/a/224559/4427

\cs_new:Nn \knuthshuffle_get_random:Nnn
 {
  \int_set:Nn #1 { \fp_eval:n { randint(#2,#3) } }
 }

\tl_new:N \l_knuthshuffle_tempa_tl
\tl_new:N \l_knuthshuffle_tempb_tl
\int_new:N \l_knuthshuffle_random_int
\prop_new:N \l_knuthshuffle_newperm_prop
\prop_new:N \g_knuthshuffle_identity_prop % the identity
\seq_new:N \g_knuthshuffle_permutation_seq

\cs_new_protected:Nn \knuthshuffle_generate:n
 {
  \prop_set_eq:NN \l_knuthshuffle_newperm_prop \g_knuthshuffle_identity_prop
  \int_step_inline:nnnn { #1 } { -1 } { 2 }
   {
    \knuthshuffle_get_random:Nnn \l_knuthshuffle_random_int { 1 } { ##1 }
    \prop_get:NnN \l_knuthshuffle_newperm_prop { ##1 } \l_knuthshuffle_tempa_tl 
    \prop_get:NVN \l_knuthshuffle_newperm_prop \l_knuthshuffle_random_int \l_knuthshuffle_tempb_tl 
    \prop_put:NnV \l_knuthshuffle_newperm_prop { ##1 } \l_knuthshuffle_tempb_tl
    \prop_put:NVV \l_knuthshuffle_newperm_prop \l_knuthshuffle_random_int \l_knuthshuffle_tempa_tl
   }
  \seq_clear:N \g_knuthshuffle_permutation_seq
  \int_step_inline:nnnn { 1 } { 1 } { #1 }
   {
    \seq_gput_right:Nx \g_knuthshuffle_permutation_seq
     {
      \prop_item:Nn \l_knuthshuffle_newperm_prop { ##1 }
     }
   }
  %\seq_show:N \g_knuthshuffle_permutation_seq % for debugging
 }
\cs_generate_variant:Nn \knuthshuffle_generate:n { x }

\AtBeginDocument
 {
  \int_compare:nT { \zref_extract:nn {LastAbsPage}{abspage} > 0 }
   {
    \int_step_inline:nnnn { 1 } { 1 } { \zref_extract:nn {LastAbsPage}{abspage} }
     {
      \prop_gput:Nnn \g_knuthshuffle_identity_prop { #1 } { #1 }
     }
    \knuthshuffle_generate:n { \zref_extract:nn {LastAbsPage}{abspage} }
    \renewcommand{\thepage}{\randomarabic{page}}
   }
 }

\NewExpandableDocumentCommand{\randomarabic}{m}
 {
  \seq_item:Nn \g_knuthshuffle_permutation_seq { \value{#1} }
 }

\ExplSyntaxOff

\begin{document}

\kant[1-102]

\ExplSyntaxOn
% for showing the used page numbers
\seq_use:Nn \g_knuthshuffle_permutation_seq { ,~ }
\ExplSyntaxOff

\end{document}

最后,以示例的方式添加了所用页码的序列。

这是最后一页的底部。

在此处输入图片描述

更复杂的策略也可以处理目录。现在,只有当页数自上次运行 LaTeX 以来发生变化时,才会计算随机序列,否则将使用之前的序列。

\documentclass{article}
\usepackage{xparse}
\usepackage{zref-abspage,atveryend}
\usepackage{kantlipsum}

\makeatletter
\zref@newlist{lastabs}
\zref@addprop{lastabs}{abspage}
\AfterLastShipout{%
  \if@filesw
    \begingroup
      \advance\c@page\m@ne
      \toks@\expandafter{\Z@L@lastabs}%
      \expandafter\zref@wrapper@immediate\expandafter{%
        \expandafter\ZREF@label\expandafter{\the\toks@}{LastAbsPage}%
      }%
    \endgroup
  \fi
}
\makeatother

\ExplSyntaxOn

\cs_set_eq:Nc \zref_extract:nn { zref@extract }

\cs_new:Nn \knuthshuffle_get_random:Nnn
 {
  \int_set:Nn #1 { \fp_eval:n { randint(#2,#3) } }
 }

\tl_new:N \l_knuthshuffle_tempa_tl
\tl_new:N \l_knuthshuffle_tempb_tl
\int_new:N \l_knuthshuffle_random_int
\prop_new:N \l_knuthshuffle_newperm_prop
\prop_new:N \g_knuthshuffle_identity_prop % the identity
\seq_new:N \g_knuthshuffle_permutation_seq

\cs_new_protected:Nn \knuthshuffle_generate:n
 {
  \prop_set_eq:NN \l_knuthshuffle_newperm_prop \g_knuthshuffle_identity_prop
  \int_step_inline:nnnn { #1 } { -1 } { 2 }
   {
    \knuthshuffle_get_random:Nnn \l_knuthshuffle_random_int { 1 } { ##1 }
    \prop_get:NnN \l_knuthshuffle_newperm_prop { ##1 } \l_knuthshuffle_tempa_tl 
    \prop_get:NVN \l_knuthshuffle_newperm_prop \l_knuthshuffle_random_int \l_knuthshuffle_tempb_tl 
    \prop_put:NnV \l_knuthshuffle_newperm_prop { ##1 } \l_knuthshuffle_tempb_tl
    \prop_put:NVV \l_knuthshuffle_newperm_prop \l_knuthshuffle_random_int \l_knuthshuffle_tempa_tl
   }
  \seq_clear:N \g_knuthshuffle_permutation_seq
  \int_step_inline:nnnn { 1 } { 1 } { #1 }
   {
    \seq_gput_right:Nx \g_knuthshuffle_permutation_seq
     {
      \prop_item:Nn \l_knuthshuffle_newperm_prop { ##1 }
     }
   }
  %\seq_show:N \g_knuthshuffle_permutation_seq % for debugging
 }
\cs_generate_variant:Nn \knuthshuffle_generate:n { x }

\AtBeginDocument
 {
  \seq_if_empty:NT \g_knuthshuffle_permutation_seq
   {
    \int_compare:nT { \zref_extract:nn {LastAbsPage}{abspage} > 0 }
     {
      \int_step_inline:nnnn { 1 } { 1 } { \zref_extract:nn {LastAbsPage}{abspage} }
       {
        \prop_gput:Nnn \g_knuthshuffle_identity_prop { #1 } { #1 }
       }
      \knuthshuffle_generate:n { \zref_extract:nn {LastAbsPage}{abspage} }
     }
   }
  \renewcommand{\thepage}{\randomarabic{page}}
 }

\AfterLastShipout
 {
  \int_compare:nT { \value{abspage} = \zref_extract:nn {LastAbsPage}{abspage} }
   {
    \iow_now:cx { @auxout }
     {
      \randompagesequence
       { \zref_extract:nn {LastAbsPage}{abspage} }
       { \seq_use:Nn \g_knuthshuffle_permutation_seq { , } }
     }
   }
 }

\cs_new_protected:Npn \randompagesequence #1 #2
 {
  \int_compare:nT { #1 = \zref_extract:nn {LastAbsPage}{abspage} }
   {
    \seq_gset_from_clist:Nn \g_knuthshuffle_permutation_seq { #2 }
   }
 }
\NewExpandableDocumentCommand{\randomarabic}{m}
 {
  \seq_item:Nn \g_knuthshuffle_permutation_seq { \value{#1} }
 }

\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn
\seq_show:N \g_knuthshuffle_permutation_seq
\ExplSyntaxOff

\tableofcontents

\section{One}
\kant[1-20]
\section{Two}
\kant[21-30]
\section{Three}
\kant[31-53]

\ExplSyntaxOn
% for showing the used page numbers
\seq_use:Nn \g_knuthshuffle_permutation_seq { ,~ }
\ExplSyntaxOff

\end{document}

在此处输入图片描述

答案3

好吧,只是尝试一下:一个解决方案,expl3唯一的缺点是它不会检查具有该编号的现有页面。最大页码可以在中设置\l__blob_int

随机的

\documentclass{book}

\usepackage{expl3}
\ExplSyntaxOn
\clist_new:N \l__quack_clist
\int_new:N \l__blub_int
\int_gset:Nn \l__blub_int {0}
\int_new:N \l__blob_int
\int_gset:Nn \l__blob_int {10}
\int_do_while:nn {\l__blub_int < \l__blob_int}
    {
        \clist_put_right:NV \l__quack_clist \l__blub_int
        \int_incr:N \l__blub_int
    }
\renewcommand\thepage{%
    \clist_item:Nn \l__quack_clist {\fp_eval:n {randint(\clist_count:N\l__quack_clist)}}
}
\ExplSyntaxOff

\begin{document}

\tableofcontents

\chapter{Intro}
\section{Zzzz}aaaa
\section{Zzzzz}aaaa \clearpage bbbb
\section{Zzzzz}aaaa


\chapter{Something}
\section{Zzzz zzz}aaaa
\section{Zzzzzz zzz}aaaa \clearpage bbbb
\section{Zzzzzzz zzz}aaaa


\end{document}

相关内容