0

I'm making a reference card for lamination. It consists of a bunch of tables that between them have no particular order.

How do I lay these out to have a high density reference card?

What I'm thinking now is that I'll render to some image, and do the final layout manually in photoshop or something, but it'd be nice if there were some automatic way.

The tables are of different width, so I don't think a layout like this would be the best use of space.

I've also looked at other reference card designs like this, but I suspect they may not allow for an dense of a collection of tables as I prefer.

2
  • 1
    I doubt there's an automated way in (La)TeX to perform an optimal (bin) packing (of non-uniform objects) on a page. You're best off to follow your route by exporting each table to a PDF/image and then arranging them to suit your needs in another application.
    – Werner
    Dec 24 '20 at 23:54
  • You can also use saveboxes, which will also give you all the (height+depth)s and widths. Dec 25 '20 at 16:33
1

It's a fitting job for xcoffins. It is a package created to facilitate the layout of stuff on the page: text, tables, images, graphics, etc., in a very simple way. Handy to construct cover and title pages, and cheat sheets...

It works like a graphic design program (almost, no GUI, you have to compile to see the changes) in the sense that it uses the relative positions of the objects, rather than absolute coordinates.

You put the material in special boxes that have several handles (in the corners, in the middle of the sides, in the center and others) that allow you to join the handle of one box with a handle of another box. For example, the lower left corner of the first with the upper left corner of the second.

On top of that, you can add vertical and horizontal offsets to position the content exactly where you want it.

I collected several tables, a list, a figure and a text (the title) and assembled all them (9 objects) using a large box the size of the text area, like a frame (called \Framex) to collect the others. I took several tables from the reference you gave from Michael Goerz refcards.

All the material will go on top of the frame. After the nine joins are completed, the frame is composed on a single page.

I included a table with the dimensions of the boxes (using the tools provided by xcoffins plus a macro to convert pt to cm), before the assembly process. It might be helpful to build a mockup model with paper rectangles to find the best arrangement.

I recommend doing one merge at a time and compiling, to see how the box fits together and if offsets are needed. The process is very fast once you understand the name of the basic identifiers of the handles using the letters l, r, t, b, vc, hc.

I also recommend reading the manual on the package, replicating the example for a quick learning curve.

https://ctan.org/pkg/xcoffins?lang=en

I do not claim to have achieved a nice design.

xx

mm

This is the code. Many packages are needed only for the tables.

\documentclass[10pt,a4paper,landscape]{article}

\usepackage[left=1.00cm, right=1.00cm, top=1.00cm, bottom=1.00cm]{geometry}
\usepackage{xcoffins}
\usepackage{nopageno}
\usepackage{graphicx}
\usepackage{xparse}

% Just for tables
\usepackage[table]{xcolor}
\usepackage{booktabs,multirow}
\usepackage{rotating}
\usepackage{calc}
\usepackage{tabularx}
\usepackage{upgreek}

%https://tex.stackexchange.com/questions/99550/how-do-i-convert-pt-in-cm-mm-to-em-ex-as-they-are-defined-at-a-given-point-in-th
\ExplSyntaxOn
\NewDocumentCommand{\convertto}{mm}
% #1 = em or ex (or any other unit)
% #2 = dimen to convert
{
    \texttt{#2~=~\fp_to_decimal:n { round ( (#2)/(1#1), 5 ) }#1}
}
\DeclareExpandableDocumentCommand{\thelength}{ O{mm} m }
{
    \fp_to_decimal:n { round ( #2/1#1, 1 ) } #1
}
\ExplSyntaxOff


\setlength{\parindent}{0pt}
\newlength{\Hoffset}
\newlength{\Voffset}
\setlength{\Hoffset}{10pt}
\setlength{\Voffset}{10pt}


\NewCoffin\Framex
\NewCoffin\Ri
\NewCoffin\Rii
\NewCoffin\Riii
\NewCoffin\Riv
\NewCoffin\Rv
\NewCoffin\Rvi
\NewCoffin\Rvii
\NewCoffin\Rviii
\NewCoffin\Rxiv

\begin{document}

%%  Filling *************************

\setlength{\fboxsep}{0pt}
%\SetHorizontalCoffin\Framex{\fbox{\color{gray!10}\rule{\textwidth}{\textheight-1pt}}} % Frame

\SetVerticalCoffin\Framex{\textheight}{\fbox{\color{gray!10}\rule{\textwidth}{\textheight-1pt}}} % Frame


\SetVerticalCoffin\Ri{80pt}{%   % ascii
\texttt{
    \begin{tabular*}{\textwidth}{|ccc|} 
        \cline{1-3}
        048\textit{d} & 30\textit{h} & 0 \\
        049\textit{d} & 31\textit{h} & 1 \\
        050\textit{d} & 32\textit{h} & 2 \\
        051\textit{d} & 33\textit{h} & 3 \\
        052\textit{d} & 34\textit{h} & 4 \\
        053\textit{d} & 35\textit{h} & 5 \\
        054\textit{d} & 36\textit{h} & 6 \\
        055\textit{d} & 37\textit{h} & 7 \\
        056\textit{d} & 38\textit{h} & 8 \\
        057\textit{d} & 39\textit{h} & 9 \\
        058\textit{d} & 3A\textit{h} & : \\
        059\textit{d} & 3B\textit{h} & ; \\
        060\textit{d} & 3C\textit{h} & < \\
        061\textit{d} & 3D\textit{h} & = \\
        062\textit{d} & 3E\textit{h} & > \\
        063\textit{d} & 3F\textit{h} & ? \\ 
            \cline{1-3}
    \end{tabular*}
}}

\SetVerticalCoffin\Rii{250pt}{% #fortan Computation Functions
    \small
 \begin{tabular}{l l}
    \tt ceiling(a),~floor(a)                        & to next higher/lower int \\
    \tt conjg(z)                                    & complex conjugate \\
    \tt dim(x,y)                                    & max(x-y, 0) \\
    \tt max(a1,a2,..),~min(a1,..)              & maximum/minimum \\
    \tt dprod(a,b)                                  & dp product of  sp a, b \\
    \tt mod(a,p)                                    & a mod p \\
    \tt modulo(a,p)                                 & modulo with sign of a/p \\
    \tt sign(a,b)                                   & make sign of a = sign of b \\
    \tt matmul(m1,m2)                              & matrix multiplication \\
    \tt dot\_product(a,b)                           & dot product of vectors\\  
\end{tabular}

\textbf{more:} \texttt{ sin, cos, tan, acos, asin, atan, atan2, 
    sinh, cosh, tanh, exp, log, log10, sqrt}
}

\SetVerticalCoffin\Riii{30em}{% #perl Escape Sequences:
    \begin{tabular}{p{2em}p{12em}p{2em}p{12em}}
        \textbackslash{}a & alarm (beep) & \textbackslash{}e & escape \\
        \textbackslash{}f & formfeed & \textbackslash{}n & newline \\
        \textbackslash{}r & carriage return & \textbackslash{}t & tab \\
        \multicolumn{1}{l}{\textbackslash{}cx} & control-x & \textbackslash{}l & lowercase next char \\
        \textbackslash{}L & lowercase until \textbackslash{}E & \textbackslash{}U & uppercase until \textbackslash{}E \\
        \textbackslash{}Q & diable metachars until \textbackslash{}E & \textbackslash{}E & end case modifications \\
    \end{tabular}%
}

\SetVerticalCoffin\Riv{200pt}{% Powers of Ten
    \renewcommand{\arraystretch}{1.5}
        \footnotesize   
    \begin{tabular}{|c|c|c|c|c|c|c|c|}
        \multicolumn{8}{c}{\large \textbf{Powers of Ten}}\\
        \hline
        Exa (E)   &   Peta (P)   &  Tera (T)   &     Giga (G)     &  Mega (M)  &    Kilo (k)  &   Hekto (h)  &   Deka (da)  \\
        $10^{18}$ &  $10^{15}$   &  $10^{12}$  &     $10^{9}$     &  $10^{6}$  &    $10^{3}$  &   $10^{2}$   &   $10^{1}$  \rule[-3ex]{0cm}{1ex} \\
        \hline
        Deci (d)  &   Centi (c)  &  Milli (m)  &  Micro ($\upmu$) &  Nano (n)  &    Pico (p)  &   Femto (f)  &   Atto (a)   \\
        $10^{-1}$ &  $10^{-2}$   &  $10^{-3}$  &    $10^{-6}$     & $10^{-9}$  &  $10^{-12}$  &  $10^{-15}$  &  $10^{-18}$  \rule[-3ex]{0cm}{1ex} \\
        \hline
    \end{tabular}
}

\SetVerticalCoffin\Rv{100pt}{% a figure
\includegraphics[height=100pt,width=100pt]{example-grid-100x100pt}  
}


\SetVerticalCoffin\Rvi{400pt}{% phyton  Standard Library
    \footnotesize
\begin{description}
    \item[String Services:] string, re, struct, difflib, StringIO, cStringIO, textwrap, codecs, unicodedata, stringprep, fpformat
    \item[File/Directory Access:] os.path, fileinput, stat, statvfs, filecmp, tempfile, glob, fnmatch, linecache, shutil, dircache
    \item[Generic OS services:] os, time, optparse, getopt, logging, getpass, curses, platform, errno, ctypes
    \item[Optional OS services:] select, thread, threading, dummy thread, dummy threading, mmap, readline, rlcompleter
    \item[Data Types:] datetime, calendar, collections, heapq, bisect, array, sets, sched, mutex, Queue, weakref, UserDict, UserList, UserString, types, new, copy, pprint, repr
    \item[Numeric and Math Modules:] math, cmath, decimal, random, itertools, functools, operator
    \item[Internet Data Handling:] email, mailcap, mailbox, mhlib, mimetools, mimetypes, MimeWriter, mimify, multifile, rfc822, base64, binhex, binascii, quopri, uu
    \item[Structured Markup Processing Tools:] HTMLParser, sgmllib, htmllib, htmlentitydefs, xml parsers expat, xml.dom.*, xml.sax.*, xml.etree.ElementTree
    \item[File Formats:] csv, ConfigParser, robotparser, netrc, xdrlib
    \item [Services:] hashlib, hmac, md5, sha
    \item[Compression:] zlib, gzip, bz2, zipfile, tarfile
    \item[Persistence:] pickle, cPickle, copy reg, shelve, marshal, anydbm, whichdb, dbm, gdbm, dbhash, bsddb, dumbdbm, sqlite3
    \item[Unix specific:] posix, pwd, spwd, grp, crypt, dl, termios, tty, pty, fcntl, posixfile, resource, nis, syslog, commands
    \item[IPC/Networking:] subprocess, socket, signal, popen2, asyncore, asynchat
\end{description}   
}


\SetVerticalCoffin\Rvii{0.45\textwidth}{%
\begin{tabularx}{0.45\textwidth}{@{}XX@{}}
    
    Phasellus orci quam, vehicula a, pulvinar sit amet, laoreet eget,
    massa. Cum sociis natoque penatibus et magnis dis parturient montes,
    nascetur ridiculus mus. Fusce adipiscing porttitor risus. Curabitur
    lacinia orci at ligula consequat pretium. Ut egestas. Lorem ipsum
    dolor sit amet, consectetuer elit. &
    
    Phasellus orci quam, vehicula a, pulvinar sit amet, laoreet eget,
    massa. Cum sociis natoque penatibus et magnis dis parturient montes,
    nascetur ridiculus mus. Fusce adipiscing porttitor risus. Curabitur
    lacinia orci at ligula consequat pretium. Ut egestas. Lorem ipsum
    dolor sit amet, consectetuer elit. \\
    
    Aliquam nonummy urna malesuada tellus. Nulla aliquam convallis
    quam. Aliquam auctor quam sed sapien. Vivamus auctor. Sed quam
    augue, adipiscing non, dictum id, elementum sed, turpis. Nam euismod
    faucibus nulla. Vivamus quam augue, adipiscing sed, mattis eu,
    imperdiet et, sem. Etiam malesuada elementum tellus. &
    
    Aliquam nonummy urna malesuada tellus. Nulla aliquam convallis
    quam. Aliquam auctor quam sed sapien. Vivamus auctor. Sed quam
    augue, adipiscing non, dictum id, elementum sed, turpis. Nam euismod
    faucibus nulla. Vivamus quam augue, adipiscing sed, mattis eu,
    imperdiet et, sem. Etiam malesuada elementum tellus. \\
    
        Aliquam nonummy urna malesuada tellus. Nulla aliquam convallis
    quam. Aliquam auctor quam sed sapien. Vivamus auctor. Sed quam
    augue, adipiscing non, dictum id, elementum sed, turpis. Nam euismod
    faucibus nulla. Vivamus quam augue, adipiscing sed, mattis eu,
    imperdiet et, sem. Etiam malesuada elementum tellus. &
    
    Aliquam nonummy urna malesuada tellus. Nulla aliquam convallis
    quam. Aliquam auctor quam sed sapien. Vivamus auctor. Sed quam
    augue, adipiscing non, dictum id, elementum sed, turpis. Nam euismod
    faucibus nulla. Vivamus quam augue, adipiscing sed, mattis eu,
    imperdiet et, sem. Etiam malesuada elementum tellus.
    
\end{tabularx}%
}

\SetVerticalCoffin\Rviii{100pt}{%
\begin{tabular}{clr}
    \toprule
    Alg.  & Dataset & Result \\
    \midrule
    \multirow{4}[2]{*}{\begin{sideways}BFS\end{sideways}} & soc-ork  & 1.61 \\
    & soc-lj & \cellcolor{red!10}2.95 \\
    & h09   & 1.60 \\
    & i04 & \cellcolor{blue!20}14.72 \\
    \bottomrule
\end{tabular}%
}

\SetVerticalCoffin\Rxiv{370pt}{\bfseries \Huge  Reference Card for Lamination}  % title

    %%  Assembly] *************************
\JoinCoffins\Framex[l,t]\Rii[l,t](\Hoffset,-\Voffset)           % fortran
\JoinCoffins\Framex[\Rii-r,\Rii-t]\Ri[l,t](0pt,0pt)             % ascii
\JoinCoffins\Framex[\Ri-r,\Ri-t]\Rxiv[l,t](7\Hoffset,0pt)       % title 
\JoinCoffins\Framex[\Rxiv-hc,\Rxiv-b]\Riii[hc,t](\Hoffset,-\Voffset)    % perl
\JoinCoffins\Framex[\Rii-l,\Rii-b]\Rv[l,t](0pt,-\Voffset)       % grid 100x100
\JoinCoffins\Framex[\Riii-l,\Riii-b]\Riv[l,t](-5\Hoffset,-\Voffset) % Powers of Ten
\JoinCoffins\Framex[\Rv-l,\Rv-b]\Rvi[l,t](0pt,-\Voffset)    %phyton  Standard Library
\JoinCoffins\Framex[\Rvi-r,\Rvi-t]\Rvii[l,t](\Hoffset,4\Voffset)    % tabularx
\JoinCoffins\Framex[\Rv-r,\Rv-vc]\Rviii[l,vc](2\Hoffset,0pt)    % sideways table

%%%********************************************************************

\section*{Heights and widths}
\begin{tabular}{lrr}
    \toprule    
    ID & height & width \\
    \midrule
    Ri &\thelength[mm]{\CoffinTotalHeight\Ri} & \thelength[mm]{\CoffinWidth\Ri} \\  
    Rii & \thelength[mm]{\CoffinTotalHeight\Rii} & \thelength[mm]{\CoffinWidth\Rii} \\  
    Riii & \thelength[mm]{\CoffinTotalHeight\Riii} & \thelength[mm]{\CoffinWidth\Riii} \\   
    Rvi & \thelength[mm]{\CoffinTotalHeight\Rvi} & \thelength[mm]{\CoffinWidth\Rvi} \\  
    Rv & \thelength[mm]{\CoffinTotalHeight\Rv} & \thelength[mm]{\CoffinWidth\Rv} \\ 
    Rvi & \thelength[mm]{\CoffinTotalHeight\Rvi} & \thelength[mm]{\CoffinWidth\Rvi} \\  
    Rvii & \thelength[mm]{\CoffinTotalHeight\Rvii} & \thelength[mm]{\CoffinWidth\Rvii} \\   
    Rviii & \thelength[mm]{\CoffinTotalHeight\Rviii} & \thelength[mm]{\CoffinWidth\Rviii} \\
    Rxiv & \thelength[mm]{\CoffinTotalHeight\Rxiv} & \thelength[mm]{\CoffinWidth\Rxiv} \\  % title
    \bottomrule 
\end{tabular}

\clearpage

% Typeset the assembly      
\noindent\TypesetCoffin\Framex  
    
\end{document}

Final note. I think that the problem of optimal bin packing does not apply to a reference sheet were the material should follow some logical order.

From https://en.wikipedia.org/wiki/Bin_packing_problem

Despite the fact that the bin packing problem has an NP-hard computational complexity, optimal solutions to very large instances of the problem can be produced with sophisticated algorithms. In addition, many heuristics have been developed: for example, the first fit algorithm provides a fast but often non-optimal solution, involving placing each item into the first bin in which it will fit. It requires Θ(n log n) time, where n is the number of items to be packed. The algorithm can be made much more effective by first sorting the list of items into decreasing order (sometimes known as the first-fit decreasing algorithm), although this still does not guarantee an optimal solution, and for longer lists may increase the running time of the algorithm.

The xcoffins package could be used to implement any heuristics algorithm, like the next-fit decreasing height algorithm, as is shown here

nfdh

1

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.