I am a relative TeX newbie trying to write a new package to generate timelines that can span multiple pages (the existing timeline solutions are not suitable for me, and I would like to write something superior to share with the community as way of 'giving back').

Anyway, at present I have successfully been able to mock up a very nice timeline using only the \begin{picture}...\end{picture} functionality (no tikz).

The problem is spanning pages - is it possible to have TeX automatically break a figure at certain points in order to support horizontal or vertical spanning of multiple pages?

  • no, that is not possible – user2478 Jul 12 '11 at 8:08
  • 3
    I don't have a complete answer, but here is another idea: how about having a single pdf document with your picture as one single huge page, then crop and split the pdf as needed with an external tool, and finally import back the pieces in your final document with plain \includegraphic’s? – Juan A. Navarro Jul 12 '11 at 10:05
  • @Juan: Wouldn't that be exactly what I have in my answer, but just going over an external image? Note that gincltex lets you include .tex files like images using \includegraphics. It's code is very similar to adjustbox which allows direct clipping of TeX material. – Martin Scharrer Jul 12 '11 at 10:29

Unfortunately this doesn't work. Picture environments (picture, tikzpicture, ...) are (horizontal) boxes on their own and LaTeX doesn't break these. You would need to do this by yourself.

If you are able to detect it once your picture is too long (longer than max. \textheight or calculate the rest of the current page) you could insert some code like <global save settings>\end{picture}\begin{picture}<restore settings> to close the current picture and open a new one. I do similar things with TikZ's \path in tikz-timing where I have to start a new path to change the colour and style but want to keep certain settings and the position. It's, however, a little tricky, especially for whole pictures, I guess.

Another possibility would be to draw the whole picture as long it turns out to be, but inside a savebox, i.e. you store it first but don't typeset it directly. Then you can measure its height (\ht\yourboxmacro) and if it is too high you can clip it using my adjustbox package. The idea would be to insert it twice: once clipped to the size of the first page and then again on the next page with the first part clipped. Using a loop you could, of course, support more than two pages.

Here some example code. I used tikzpicture here because I know its syntax but not the one of picture very well. It will work with that as well of course. (Note that there is a bug in the current version of adjustbox. I fixed it for the example image below, but the top is still clipped incorrectly. I have to have a closer look at it. However, the basic idea is sound and works.)




 \draw (0,0) rectangle (-.9\textwidth,-2.8\textheight);
 \draw (0,0) -- (-.9\textwidth,-2.8\textheight);
 \draw (-.9\textwidth,0) -- (0,-2.8\textheight);
 \path (-1mm,-1mm);
 \path (current bounding box.north east) +(1mm,1mm);
        \clipbox{0 {\myrest-\textheight} 0 {\ht\mysavebox-\myrest}}{\usebox{\mysavebox}}%
    \clipbox{0 0 0 {\ht\mysavebox-\myrest}}{\usebox{\mysavebox}}%



| improve this answer | |
  • 2
    agreed that (with currently available software) it's not possible to produce a picture that breaks across page boundaries. however, if the picture were put in a box, bits of it could surely be snipped off and put on different pages. (i think this was proposed, long ago, as a means of doing multi-page tables before supertabular and longtable, etc., came along; since the proposal would presumably have appeared in the '80s, i'm not particularly surprised i didn't remember the details...) – wasteofspace Jul 12 '11 at 10:10
  • Thanks everyone. Actually I discovered and tested this approach on my own after posting, by modifying some code I found in a recent post on comp.text.tex (groups.google.com/forum/#!topic/comp.text.tex/se8qapxOdew). However, I hadn't yet discovered that it's possible to include raw TeX code instead of an image, nor discovered the loop syntax. Thanks Martin. Also thanks for the history insight Anon ... I do appreciate history, being that I'm attempting to write a timeline package for a history book and all! – Dr. Voltaire Jul 12 '11 at 11:00
  • 2
    @Dr.Voltaire: If clipping is new for you see the grfguide (manual of graphics/x) for more information. My adjustbox package is based on that and extends it to TeX code. – Martin Scharrer Jul 12 '11 at 11:18
  • @MartinScharrer What could you propose if the picture spanned both horisontally and vertically? With your above method, a picture spanning 2 pages vertically and many pages horisontally produces just 2 pages. – ajeh Jun 18 '14 at 16:09
  • @ajeh I think you can just include further \newpage and \clipbox commands, clipping the appropriate parts of the pictures appropriately. Take a look at the documentation for the command and compare it with the answer. Then try to adapt it to add the two pages for the top/bottom of the picture after/before the bottom/top of the picture. – cfr Jul 6 '14 at 19:33

I know this is a place for TeX, but I ran into the problem and wrote a bit of Python to solve it for me. It requires Python and PIL (the Python Imaging Library)

Say you have a really long picture like this, and you want to slice it up into smaller bits, because it is so long.


Here is a Python script that will do that.

from __future__ import division
import Image
import math
import os

def long_slice(image_path, out_name, outdir, slice_size):
    """slice an image into parts slice_size tall"""
    img = Image.open(image_path)
    width, height = img.size
    upper = 0
    left = 0
    slices = int(math.ceil(height/slice_size))

    count = 1
    for slice in range(slices):
        #if we are at the end, set the lower bound to be the bottom of the image
        if count == slices:
            lower = height
            lower = int(count * slice_size)  

        bbox = (left, upper, width, lower)
        working_slice = img.crop(bbox)
        upper += slice_size
        #save the slice
        working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
        count +=1

if __name__ == '__main__':

    long_slice("longcat.jpg", #image filename 
               "longcat", #slice names
                os.getcwd(), #output dir
                300 #height in px

This is is the output




| improve this answer | |
  • I like your suggestion, but can you explain how the py script will link to the TeX files – MadyYuvi Aug 16 '19 at 5:54
  • You would feed a large image into this script, it would then emit the image sliced into smaller chunks (in this case chunks up to 300px tall). You then can take these chunks and insert them into your LaTeX. – Gourneau Aug 19 '19 at 7:43
  • Thanks for your great explanation...it helps me a lot... – MadyYuvi Aug 19 '19 at 8:44

I really liked Martin Scharrer's answer (from July 12, 2011) and his example works. However, when I tried modifying Martin's answer to use for my purposes I found the code clipped \mysavebox in a strange way (Perhaps it was because I needed to use a minipage). It took me 2 months of experimenting and searching online to find the reason why. The total vertical length of \mysavebox includes not only the height, but also the depth (i.e., \ht\mysavebox + \dp\mysavebox). Now the clipping for each page works great. If you are finding similar difficulties, maybe the following solution will help you. I use the new variable I create, \mytotallen, like Martin uses \ht\mysavebox.




    \begin{footnotesize} %change font size
        Lots and lots and lots of text... (3 pages worth)

\newlength{\mytotallen} %create a new length variable \mytotallen
\setlength{\mytotallen}{\ht\mysavebox + \dp\mysavebox} %add together the height (\ht) and depth (\dp) of \mysavebox
    \setlength{\myrest}{\mytotallen} %initialize \myrest
        \clipbox{0 {\myrest-\textheight} 0 {\mytotallen-\myrest}}{\usebox{\mysavebox}}
        \addtolength{\myrest}{-\textheight}%subtract one page's length each loop from \myrest
    \clipbox{0 0 0 {\mytotallen-\myrest}}{\usebox{\mysavebox}}
| improve this answer | |
  • @Zarko: I'll do so then too – user31729 Dec 20 '15 at 9:13

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.