Tables – How to Place a Caption at the Foot of Long Tables Using Longtable Package

captionslongtabletables

I would like to ask a question about longtable package. I've already posted it in other forums.

I have a long table (a several-pages-long one) using longtable package and I would like to add a table caption at the bottom of every piece of table, but a different one in the FIRST page.

longtable package allows a different "header" in the first page of the table (\endfirsthead) and/or a different "footer" in the LAST page of the table (\endlastfoot). What I would like to do is a different foot caption in the FIRST page of the table.

My example would be something like this:

First page table foot caption: "Table 1.2: Table description and so, and so…".

Following page table foot captions: "Table 1.2 (contd.): Table description and so, and so…".

It is similar to the example available at the documentation of longtable package about the usage of \endfirsthead, but I want to put it at the bottom of the tables because captions for all figures and tables in my document are at the foot, not at the head.

Is it so strange what I want to do?? How can I do it with longtable?

I would be very grateful if you could give me any hint or tip.

Thank you in advance for your answers! 🙂

Best Answer

You can try the following example. That adds \endfirstfoot.

\documentclass{article}
\usepackage[a6paper,showframe]{geometry}

\usepackage{longtable}
\makeatletter
\newbox\LT@firstfoot
\def\endfirstfoot{\LT@end@hd@ft\LT@firstfoot}
\newdimen\LT@footdiff
\def\LT@start{%
  \let\LT@start\endgraf
  \endgraf\penalty\z@
  \vskip\LTpre\endgraf
  \LT@footdiff-\ht\LT@foot
  \advance\LT@footdiff\ht\LT@firstfoot
  \dimen@\pagetotal
  \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi
  \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi
  \advance\dimen@ \ht\ifvoid\LT@firstfoot\LT@foot\else\LT@firstfoot\fi
  \dimen@ii\vfuzz
  \vfuzz\maxdimen
  \setbox\tw@\copy\z@
  \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox
  \setbox\tw@\vbox{\unvbox\tw@}%
  \vfuzz\dimen@ii
  \advance\dimen@ \ht
      \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi
  \advance\dimen@\dp
      \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi
  \advance\dimen@ -\pagegoal
  \ifdim \dimen@>\z@\vfil\break\fi
  \global\@colroom\@colht
  \ifvoid\LT@firstfoot
    \ifvoid\LT@foot
    \else
      \advance\vsize-\ht\LT@foot
      \global\advance\@colroom-\ht\LT@foot
      \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@
      \maxdepth\z@
    \fi
  \else
    \advance\vsize-\ht\LT@firstfoot
    \global\advance\@colroom-\ht\LT@firstfoot
    \dimen@\pagegoal\advance\dimen@-\ht\LT@firstfoot\pagegoal\dimen@
    \maxdepth\z@
  \fi
  \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak
  \output{\LT@output}%
}
\def\LT@output{%
  \ifnum\outputpenalty <-\@Mi
    \ifnum\outputpenalty > -\LT@end@pen
      \LT@err{floats and marginpars not allowed in a longtable}\@ehc
    \else
      \setbox\z@\vbox{\unvbox\@cclv}%
      \ifdim \ht\LT@lastfoot>\ht\LT@foot
        \dimen@\pagegoal
        \advance\dimen@-\ht\LT@lastfoot
        \ifdim\dimen@<\ht\z@
          \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}%
          \@makecol
          \@outputpage
          \setbox\z@\vbox{\box\LT@head}%
        \fi
      \fi  
      \global\@colroom\@colht
      \global\vsize\@colht   
      \vbox
        {\unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi}%
    \fi
  \else
    \ifvoid\LT@firstfoot
      \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}%
      \@makecol
      \@outputpage
      \global\vsize\@colroom
    \else
      \setbox\@cclv\vbox{\unvbox\@cclv\box\LT@firstfoot\vss}%
      \@makecol
      \@outputpage
      \global\advance\@colroom\LT@footdiff
      \global\vsize\@colroom
    \fi
    \copy\LT@head\nobreak
  \fi
}
\makeatother

\begin{document}
\begin{longtable}{l}
\hline first head\\\hline\endfirsthead
\hline head\\\hline\endhead
\hline first foot\\\hline\endfirstfoot
\hline (continued)\\foot\\\hline\endfoot
\hline last foot\\\hline\endlastfoot
A\\B\\C\\D\\E\\F\\G\\H\\I\\J\\K\\L\\M\\N\\O\\P\\Q\\R\\S\\T\\U\\V\\W\\X\\Y\\Z\\
a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u\\v\\w\\x\\y\\z\\
0\\1\\2\\3\\4\\5\\6\\7\\8\\9\\
\end{longtable}
\end{document} 

Result


Addendum by Skillmon:

The above approach will use the normal foot instead of the firstfoot if the longtable will only take a single page and lastfoot wasn't used. The following is almost identical to the above code, but it will use the firstfoot on a single page longtable.

The precedence for the footer on a single page longtable will be:

  1. lastfoot, and if that's empty

  2. firstfoot, and if that's empty

  3. foot.

Code:

\documentclass{article}
\usepackage[a6paper,showframe]{geometry}

\usepackage{longtable}
\makeatletter
\newbox\LT@firstfoot
\def\endfirstfoot{\LT@end@hd@ft\LT@firstfoot}
\newdimen\LT@footdiff
\def\LT@start{%
  \let\LT@start\endgraf
  \endgraf\penalty\z@
  \vskip\LTpre\endgraf
  \LT@footdiff-\ht\LT@foot
  \advance\LT@footdiff\ht\LT@firstfoot
  \dimen@\pagetotal
  \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi
  \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi
  \advance\dimen@ \ht\ifvoid\LT@firstfoot\LT@foot\else\LT@firstfoot\fi
  \dimen@ii\vfuzz
  \vfuzz\maxdimen
  \setbox\tw@\copy\z@
  \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox
  \setbox\tw@\vbox{\unvbox\tw@}%
  \vfuzz\dimen@ii
  \advance\dimen@ \ht
      \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi
  \advance\dimen@\dp
      \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi
  \advance\dimen@ -\pagegoal
  \ifdim \dimen@>\z@\vfil\break\fi
  \global\@colroom\@colht
  \ifvoid\LT@firstfoot
    \ifvoid\LT@foot
    \else
      \advance\vsize-\ht\LT@foot
      \global\advance\@colroom-\ht\LT@foot
      \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@
      \maxdepth\z@
    \fi
  \else
    \advance\vsize-\ht\LT@firstfoot
    \global\advance\@colroom-\ht\LT@firstfoot
    \dimen@\pagegoal\advance\dimen@-\ht\LT@firstfoot\pagegoal\dimen@
    \maxdepth\z@
  \fi
  \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak
  \output{\LT@output}%
}
\def\LT@output{%
  \ifnum\outputpenalty <-\@Mi
    \ifnum\outputpenalty > -\LT@end@pen
      \LT@err{floats and marginpars not allowed in a longtable}\@ehc
    \else
      \setbox\z@\vbox{\unvbox\@cclv}%
      \ifdim \ht\LT@lastfoot>\ht\LT@foot
        \dimen@\pagegoal
        \advance\dimen@-\ht\LT@lastfoot
        \ifdim\dimen@<\ht\z@
          \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}%
          \@makecol
          \@outputpage
          \setbox\z@\vbox{\box\LT@head}%
        \fi
      \fi  
      \global\@colroom\@colht
      \global\vsize\@colht   
      \vbox
        {%
          \unvbox\z@
          \box
            \ifvoid\LT@lastfoot
              \ifvoid\LT@firstfoot
                \LT@foot
              \else
                \LT@firstfoot
              \fi
            \else
              \LT@lastfoot
            \fi
        }%
    \fi
  \else
    \ifvoid\LT@firstfoot
      \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}%
      \@makecol
      \@outputpage
      \global\vsize\@colroom
    \else
      \setbox\@cclv\vbox{\unvbox\@cclv\box\LT@firstfoot\vss}%
      \@makecol
      \@outputpage
      \global\advance\@colroom\LT@footdiff
      \global\vsize\@colroom
    \fi
    \copy\LT@head\nobreak
  \fi
}
\makeatother

\begin{document}
\begin{longtable}{l}
\hline first head\\\hline\endfirsthead
\hline head\\\hline\endhead
\hline first foot\\\hline\endfirstfoot
\hline (continued)\\foot\\\hline\endfoot
\hline last foot\\\hline\endlastfoot
A\\B\\C\\D\\E\\F\\G\\H\\I\\J\\K\\L\\M\\N\\O\\P\\Q\\R\\S\\T\\U\\V\\W\\X\\Y\\Z\\
a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u\\v\\w\\x\\y\\z\\
0\\1\\2\\3\\4\\5\\6\\7\\8\\9\\
\end{longtable}
\end{document} 
Related Question