非矩形页面几何形状

非矩形页面几何形状

我对使用非矩形页面几何形状来实现我的翻页书创意很感兴趣(带有图像和流动文本的 fancyhdr)。

我追求的页面几何形状是,每个奇数页的文本右下角都有一个小矩形缺失(切除的矩形)。在我之前的问题中,我们找到了一种方法来更改每个页面上的文本高度,但没有正确的几何形状:

\documentclass[twoside]{article}
\usepackage[textheight=15cm]{geometry}
\usepackage{lipsum}
\usepackage[demo]{graphicx}    
\usepackage{fancyhdr}
\usepackage{everyshi}
\usepackage{xifthen}


\newcounter{flipbookcount}
\setcounter{flipbookcount}{1}

\fancyfoot[RO]{\setlength{\unitlength}{1mm}
\begin{picture}(0,10)
\put(-24,-34){\includegraphics[width=5cm]{mypic\theflipbookcount.png}}
\end{picture}
\stepcounter{flipbookcount}
}


\EveryShipout{%
\ifthenelse{\isodd{\value{page}}}%
        {\global\textheight=20cm}% Next page is even
        {\global\textheight=15cm}% Next page is odd
        }

\begin{document}
\pagestyle{fancy}
\lipsum
\lipsum
\lipsum
\lipsum
\lipsum

\end{document}

有办法实现这个功能吗?如果我的意思不清楚,我可以添加一张图片作为示例。

答案1

这只是一次非常片面的尝试。它实际上不起作用,但可以帮助某人找到更好的解决方案。

我的想法是\parshape,根据页面上剩余的空间,为每个段落设置 。即,页面上应容纳的行数为(\pagegoal-\pagetotal)/\baselineskip\parshape以全长 的行开始\hsize,然后是一些用于剪切的缩短行,其他行设置为全长\hsize。全长的行数为(\pagegoal-\pagetotal-\l_cutout_height_dim)/\baselineskip,较短的行数为差值。

不幸的是,这些计算没有考虑到页面可以拉伸或收缩的事实。此外,我不确定是否应该使用\int_div_truncate:nn\int_div_round:nn(即,截断结果或将其四舍五入为最接近的整数)来计算行数。

此外,\everypar直接使用通常不是一个好主意,或许我应该使用包everyhook

\documentclass{article}
\usepackage{lipsum}
\usepackage{expl3,xparse}
\ExplSyntaxOn
  % This code accesses \everypar, \value{page}, \hsize, \pagegoal,
  % \pagetotal, \baselineskip, \parshape, \interlinepenalties from
  % TeX/LaTeX2e directly, as they do not have an expl3 interface.
  %
  \dim_new:N \l__cutout_height_dim
  \dim_new:N \l__cutout_width_dim
  \dim_new:N \l__cutout_hsize_dim
  \int_new:N \l__cutout_long_lines_int
  \int_new:N \l__cutout_total_lines_int
  \NewDocumentCommand { \cutoutbottomodd } { m m }
    { \__cutout_bottom_odd:nn {#1} {#2} }
  \cs_new_protected:Npn \__cutout_bottom_odd:nn #1#2
    {
      \dim_set:Nn \l__cutout_height_dim {#1}
      \dim_set:Nn \l__cutout_width_dim {#2}
      \exp_args:Nx \everypar
        {
          \exp_not:V \everypar
      \exp_not:N \__cutout_everypar_test:
        }
    }
  \cs_new_protected_nopar:Npn \__cutout_everypar_test:
    { \int_if_odd:nT { \value{page} } { \__cutout_everypar: } }
  \cs_new_protected:Npn \__cutout_everypar:
    {
      \dim_set:Nn \l__cutout_hsize_dim
        { \hsize - \l__cutout_width_dim }
      \int_set:Nn \l__cutout_total_lines_int
        {
          \int_max:nn { \c_one }
            {
              \int_div_truncate:nn
                { \pagegoal - \pagetotal }
                { \baselineskip }
            }
        }
      \int_set:Nn \l__cutout_long_lines_int
        {
          \int_div_truncate:nn
            { \pagegoal - \pagetotal - \l__cutout_height_dim }
            { \baselineskip }
        }
      \int_compare:nNnF \l__cutout_long_lines_int > \c_zero
        { \int_zero:N \l__cutout_long_lines_int }
      \parshape
        = \int_eval:n { \l__cutout_total_lines_int + \c_one } \exp_stop_f:
          \prg_replicate:nn \l__cutout_long_lines_int
            { \c_zero_dim \hsize }
          \prg_replicate:nn
            { \l__cutout_total_lines_int - \l__cutout_long_lines_int }
            { \c_zero_dim \l__cutout_hsize_dim }
          \c_zero_dim \hsize
      \interlinepenalties
        = \int_eval:n { \l__cutout_total_lines_int + \c_one } \exp_stop_f:
          \prg_replicate:nn { \l__cutout_total_lines_int - \c_one }
            { 10000 \exp_stop_f: }
          -10000 \exp_stop_f:
          10000 \exp_stop_f:
    }
\ExplSyntaxOff
\begin{document}
\cutoutbottomodd{96pt}{120pt}
\lipsum[1-10]
\large
\lipsum[11-20]
\Large
\lipsum[21-30]
\scriptsize
\lipsum[31-50]
\footnotesize
\lipsum[51-70]
\end{document}

编辑:上面的代码已更新,只在奇数页上打洞。此外,在之前的版本中,长行有时会从下一页延伸到上一页,因此会从洞中溢出。现在我使用 eTeX 来\interlinepenalties强制分页。

EDIT2:使用\int_eval:n而不是早已弃用的\int_eval:w。同时将代码更新到更新的编码约定。

相关内容