I am interested in using non-rectangular page geometries for my flipbook idea (in fancyhdr with image and flowing text).

The page geometry that I'm after is that the text has a little rectangle missing from the bottom right (excised rectangle) on every odd page. In my previous question we figured out a way to make change the text height on every page, but not have the right geometry:




        {\global\textheight=20cm}% Next page is even
        {\global\textheight=15cm}% Next page is odd



Is there a way to make that work? I can add a picture as an example if its unclear what I mean.

  • I don't know if this is possible with LaTeX and would love to see an affirmative answer. – Gonzalo Medina Dec 2 '11 at 0:54
  • 2
    My question is the following: why do you need such a geometry. Since the other side of an odd page is an even page, a true void on the bottom right of an odd page would a true void of the bottom left of the following even page. If your aim is to avoid writing on this particular area, perhaps inserting a (void) box around which the text would flow might be the solution. Can you give us more information on the Why? of such a need? – Martigan Dec 2 '11 at 10:04
  • 1
    Have you looked into what the \parshape macro can do for you? – Mico Dec 2 '11 at 11:11
  • @Martigan: The need for this geometry is given in the link provided: fancyhdr with image and flowing text – Peter Grill Dec 2 '11 at 17:57
  • @PeterGrill: Thanks for answering this. Martigan: If you could give an example on how to do this in general on a page that would be great, maybe then we can figure out a way how to do it on odd pages. Mico: The short answer is: yes. The long answer is: I believe parshape lets you shape individual paragraphs. I do not know in advance what paragraphs are at the bottom of each page. So I believe (I don't actually know) parshape is the wrong way. – Wolfgang Kerzendorf Dec 2 '11 at 22:39

This is a very partial attempt. It doesn't really work, but could help someone find a better solution.

The idea I have is to set \parshape for every paragraph, depending on the space remaining on the page. Namely, the number of lines that should fit on the page is (\pagegoal-\pagetotal)/\baselineskip. The \parshape begins with lines of full length \hsize, then some shortened lines for the cutout, and further lines are set with full length \hsize. The number of lines with full length is (\pagegoal-\pagetotal-\l_cutout_height_dim)/\baselineskip, the number of shorter lines is the difference.

These calculations unfortunately do not account for the fact that pages can stretch or shrink. Besides, I am not sure whether I should be using \int_div_truncate:nn or \int_div_round:nn (i.e., well, truncating the result or rounding it to the nearest integer) to compute the numbers of lines.

Also, using \everypar directly is not very good idea in general, and I should perhaps use the everyhook package.

  % 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 }
                { \pagegoal - \pagetotal }
                { \baselineskip }
      \int_set:Nn \l__cutout_long_lines_int
            { \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 }
        = \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 }
            { \l__cutout_total_lines_int - \l__cutout_long_lines_int }
            { \c_zero_dim \l__cutout_hsize_dim }
          \c_zero_dim \hsize
        = \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:

EDIT: code above updated to only put the hole on odd pages. Also, in the previous version, long lines sometimes came from the next page onto the previous page, hence bleeding through the hole. Now I am using eTeX's \interlinepenalties to force a page break.

EDIT2: Use \int_eval:n instead of the long-deprecated \int_eval:w. Also bring the code up to more recent coding conventions.

  • Very cool! Will wait to see what @WolfgangKerzendorf has to say about it. Personally, I would prefer to be able to specify the width of each line (based on left indent and right indent) so that I could obtain something like this link. But, not really sure how one would spec this, and do realize that it was not part of the original specification. Specifying it vertically in terms of line numbers makes sense to me: i.e., specify that left notch is from lines 7-10, and goes in 0.5in, and that the bottom is form lines 34-39 (assuming 40 lines per page)_. – Peter Grill Dec 5 '11 at 2:04
  • 1
    This looks great. I ran it and it works mostly. Sometimes the last sentence goes into the excised area. Is it possible to do that every second page (odd pages). This is way past my latex skills, so I can't offer any suggestions. – Wolfgang Kerzendorf Dec 5 '11 at 20:32
  • It may be possible to use \interlinepenalties or another one of eTeX's advanced page-breaking parameters to force TeX to break after the last short line. I'll look into this tomorrow night. – Bruno Le Floch Dec 6 '11 at 19:36
  • 1
    @PeterGrill: in principle, what you describe should be possible, but much better done in grid typesetting (I think Joseph Wright has some experimental code for that in LaTeX3). Wolfgang: I fixed what you mentionned. I hope that it can work in your case. – Bruno Le Floch Dec 8 '11 at 12:03
  • @BrunoLeFloch: Man you did it! Thanks so much. I will try to put a template together for flipbook with your modification and post it here so it is searchable! – Wolfgang Kerzendorf Dec 9 '11 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.