我需要一些帮助来实现一个疯狂的想法。对于一本书,我希望页码是随机排列的。例如,如果这本书有 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}