I would like to create a "yearbook-style" layout of photos in LaTeX. Each photo would have a caption and the objective would be to automatically layout the differently sized rectangular photos to minimize the whitespace on the page (with a mandatory margin around each photo and caption). If I could do this with a browser as well that would also be helpful, but that is a question for a different forum. I would have expected this problem to be solved problematically with some kind of open sourced package but I have found none.
[Tex/LaTex] Create a “yearbook-style” multi-page layout of photos
automationboxesgraphicsmarginspositioning
Related Solutions
Why not use the geometry
package?
\documentclass[11pt,a4paper]{book}
\usepackage[
textwidth=16.5cm,
outer=1.5cm,
textheight=45\baselineskip,
headheight=\baselineskip,
includehead=false,% Default
heightrounded,
]{geometry}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead{}
\fancyhead[LO]{\leftmark}
\fancyhead[RE]{\rightmark}
\usepackage{lipsum}
\begin{document}
\chapter{foo}
\section{foobar}
\lipsum[1-12]
\end{document}
In the model that TeX uses there is no way to achieve your goal other than manually or in very very restricted contexts. As TeX is first generating paragraphs and only at the end of a paragraph checking whether or not to cut a page you will always end up on the second page with some part of the paragraph already been typeset (and thus to the width of the previous page).
You can achieve your goal by manually splitting the paragraph yourself (and effectively restarting a new one (with different settings afterwards)). I.e., if you know what the last word on the first page is you can put special command at this point, say, \EndOfFirstPage
. The define this command in the preamble or in your class file as follows:
\newcommand\EndOfFirstPage{%
\setlength\parfillskip{0pt}% line should end at the right
\par % finish paragraph for now
\setlength\parfillskip{0pt plus 1fil}% default again
\pagebreak
... % <--- change your geometry settings here
\noindent % new paragraph on the new page that claims to be
% a continuation
}
Of course, whenever you later change the text of the first page you may need to move the split point around. Or you could combine the above with your approach using the atbegshi
package for setting the geometry and the \EndOfFirstPage
only to produce the split. This has the advantage that the geometry would be nearly correct even if the command is not there to indicate the split (only the par at the page break wrong) and you could delay adding \EndOfFirstPage
to a time when you are mostly done with the editing.
Automatic methods would involve keeping track of where you are on the page (how many more lines would fit) somehow capturing each paragraph untypeset, trial typesetting it to find out how long it would be, then if necessary generating a complex \parshape
so that the lines of the last paragraph on the page change width on the page boundary.
Bottom line, such thing doesn't exist and it is not something that is in any way easy or even possible to be worked out reliably (non of the experts in the last 20 years overcame that limitation). We now think that we do have code for it in the LaTeX3 project but so far only an idea (and one that wouldn't work with current 2e's output routine, so this isn't going to help easily).
Best Answer
This is not complete answer to this question, it's rather showcase of idea I had about generative layouts and
luatex
. I don't think that any of following examples is useful as is, but maybe in can serve as basis for more interesting solutions in the future, maybe something like this.My idea is following: we have LaTeX command that stores it's content in a box ant then add list id and dimensions to the list.
Next we have environment
genlayout
that selects layout algorithm and run it on list of boxes:This package can be used like this:
Now the lua library
generativelayout.lua
Every generator is added as object with methods run and init, which are called form
genlayout
environment. Generator can be selected with optional parameter ofgenlayout
, if empty,default
is selected. The output is following:We can sort the boxes:
You can use functions from other generators, as
generators.default.run(self,boxes)
More funny example of putting boxes on random places on the page:
Here we use trick with
picture
environment to place things on exact place on the pageAnd finally, my port of http://codeincomplete.com/posts/2011/5/7/bin_packing/ to lua:
I don't think the result is really nice and I think there is some error in placing boxes on their exact place, but maybe someone will like it: