Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
no, that is not possible –  Herbert Jul 12 '11 at 8:08
1  
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
add comment

2 Answers

up vote 15 down vote accepted

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

If you are able to detect it once your picture is to 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 color 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 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 on it. However, the basic idea is sound and works.)

\documentclass{article}

\usepackage{tikz}
\usepackage{adjustbox}

\newsavebox{\mysavebox}
\newlength{\myrest}
\begin{document}

\begin{lrbox}{\mysavebox}%
\begin{tikzpicture}[red,thick]
 \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);
\end{tikzpicture}%
\end{lrbox}%
%
\ifdim\ht\mysavebox>\textheight
    \setlength{\myrest}{\ht\mysavebox}%
    \loop\ifdim\myrest>\textheight
        \newpage\par\noindent
        \clipbox{0 {\myrest-\textheight} 0 {\ht\mysavebox-\myrest}}{\usebox{\mysavebox}}%
        \addtolength{\myrest}{-\textheight}%
    \repeat
    \newpage\par\noindent
    \clipbox{0 0 0 {\ht\mysavebox-\myrest}}{\usebox{\mysavebox}}%
\else
    \usebox{\mysavebox}%
\fi

\end{document}

Result

share|improve this answer
1  
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
1  
@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 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 at 19:33
add comment

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.

Picture

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
        else:
            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

Picture


Picture


Picture

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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