# Create plain CSV list of pages with/without figures

I'm wondering if there's an easy way to have LaTeX output two lists:

1. of pages containing and
2. of pages not containing figures and/or other color objects.

I'd like to print color pages on a color printer (expensive) and print the rest of the pages on B&W. I'd like to be able to have one PDF and two txt files with CSV lists I can just dump into a print dialog.

If this can't easily be done, then is there is way to modify the list of figures format so it just lists the pages with comma separation? That way I could compile a temporary version of the PDF with that LOF, and copy them to a text file. Don't know how I'd get the complement of that set of page numbers then though.

I saw this post which recommended doing it manually or using PDFpages, but it seemed a little inconclusive.

Update

Andrey has provided a nice solution below to output a CSV list. I now realize that for my thesis, the list is long enough that it won't fit in a print dialog, and my printing place says they prefer two separate PDF docs anyway.

So, I wonder is it possible to integrate the pdfpages method demonstrated here so that it takes in the CSV lists produced by Andrey's method and uses them to create two additional PDF files, one with color pages, and one B&W. That method is as follows, where inputPDFfilename is the full PDF:

\documentclass{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages={3-6, 17, 28, 29-31}]{inputPDFfilename}
\end{document}


One tricky aspect is that pdfpages takes absolute page numbers. I'm not familiar enough with the packages and syntax in Andrey's method to modify it myself at present. It would be cool if this could be fully integrated into the same LaTeX project that creates my thesis.

-
Are you only printing one-sided? Otherwise, you may need to print both sides of sheets with figures on the color printer. –  Bruno Le Floch Aug 25 '11 at 11:34
For now, just one-sided. It's for a thesis. Thanks –  SSilk Aug 25 '11 at 13:24

This solution hacks into the figure environment to output a list of color pages. You can also use \MarkColorPage to mark other places with color content. The data is input back on the next LaTeX pass and is used to construct the black-white list as well. The lists (with absolute page numbers) are then written to files <jobname>.bwlist and <jobname>.colorlist. I had to add \clearpage in the end, otherwise the last page number was off by one.

The reason that two passes are needed is that a correct page number can only be obtained (?) at page shipout time, which \write and \iow_shipout_x:Nn do. If there was a way to similarly defer code for execution on shipout, correct lists could have been obtained in one pass.

(This is my very first attempt at programming with LaTeX3. Comments are highly appreciated!)

\documentclass{article}

\usepackage{expl3,xparse}
\usepackage{atbegshi}

\ExplSyntaxOn
\clist_new:N \g_lp_bw_clist
\clist_new:N \g_lp_color_clist
\int_new:N   \g_lp_page_int

\clist_gput_right:Nx \g_lp_bw_clist {#1}
}
\clist_gput_right:Nx \g_lp_color_clist {#1}
}
\cs_new:Nn \lp_test_page: {
\int_gincr:N \g_lp_page_int
\exp_args:NNx \clist_if_in:NnF \g_lp_color_clist { \int_use:N \g_lp_page_int } {
}
}
\cs_new:Nn \lp_write_list:Nn {
\iow_open:Nn \g_lp_stream { \tl_use:N \c_job_name_tl .#2 }
\iow_now:Nx  \g_lp_stream { \clist_use:N #1 }
\iow_close:N \g_lp_stream
}
\cs_new:Nn \lp_write_lists: {
\clist_gremove_duplicates:N \g_lp_color_clist
\lp_write_list:Nn \g_lp_bw_clist    { bwlist }
\lp_write_list:Nn \g_lp_color_clist { colorlist }
}
\cs_new:Nn \lp_mark_color_page: {
\iow_shipout_x:Nn \g_lp_stream {
\exp_not:N \lp_add_color_page:n { \int_use:N \g_lp_page_int }
}
}

\AtBeginDocument{
\ExplSyntaxNamesOn
\file_input:n { \tl_use:N \c_job_name_tl .clp }
\ExplSyntaxNamesOff
\iow_open:Nn \g_lp_stream { \tl_use:N \c_job_name_tl .clp }
}
\AtBeginShipout{
\lp_test_page:
}
\AtEndDocument{
\clearpage
\iow_close:N \g_lp_stream
\lp_write_lists:
}
\cs_set_eq:NN \MarkColorPage \lp_mark_color_page:

\char_set_catcode_letter:N @
\RenewDocumentEnvironment { figure } { o } {
\IfNoValueTF {#1} {
\@float { figure }
}{
\@float { figure } [#1]
}
\lp_mark_color_page:
}{
\end@float
}
\char_set_catcode_other:N @
\ExplSyntaxOff

\begin{document}

\listoffigures

\clearpage
\begin{figure}
\caption{Test}
\end{figure}

\clearpage
\begin{figure}[!htbp]
\caption{Test}
\end{figure}

\clearpage
Hello World

\end{document}


To create separate PDFs, use this document code after the page lists have been produced:

\documentclass{article}

\usepackage{pdfpages}

\openin\pagein=thesis.\listtype
\closein\pagein

\begin{document}

\edef\optarg{[pages={\pages}]}
\expandafter\includepdf\optarg{thesis.pdf}

\end{document}


\listtype should be either bwlist or colorlist. You can either create two copies of the document and replace \listtype with appropriate name in each one, or define it on command line (see this question for details):

pdflatex '\def\liststype{bwlist} \input{something.tex}'
-
Rather than the \bool_while_do construct with \tmp_counter you can use \prg_stepwise_inline:nnnn {#1} {1} {#2-1} { \clist_gput_right:Nx \bwlist {##1} }. The convention for variables is to start with the scope (l, g or c), then the package name if any, then the name of the variable itself, and finally the type. For instance, \g_fig_color_clist, \g_fig_bw_clist, \g_fig_last_page_int, \g_fig_stream, and \l_fig_tmpa_int if you had needed that counter. –  Bruno Le Floch Aug 25 '11 at 10:38
@Bruno Le Floch: Thanks. I completely forgot about naming conventions. –  Andrey Vihrov Aug 25 '11 at 11:49
@Andrey: Thanks for the response! Unfortunately, this doesn't work very well for me. I just tried it with my thesis, and it sort of seems to do what it's supposed to, except the color pages list only picks up probably 50% of the pages with figures, and it occasionally picks up a page that doesn't have a figure or any color stuff on it. Any thoughts? My thesis is too big to post an example, obviously. Thanks. –  SSilk Aug 26 '11 at 2:31
@SSilk: The method I used to obtain page numbers was not reliable. I now took a different approach. It's a bit slower and is not so extensible, but all pages are considered, including roman-numbered ones etc. –  Andrey Vihrov Aug 26 '11 at 10:45
@SSilk: I hope I fixed the bug now. The warning is still there, but it should not cause issues. Let's see if I can get this working any time soon :-) –  Andrey Vihrov Sep 1 '11 at 18:59

You could do this on the PDF directly without involving LaTeX. See e.g. Split a PDF into separate files containing colour and B&W pages.

-
+1, while not LaTeX, it certainly looks useful. I'll have to keep this in mind. –  rcollyer Sep 1 '11 at 19:07