# Obtain snapshot of .idx file before end of document

For some trickery concerning cross-references between index and glossary, I would like to obtain a snapshot of the .idx file at a certain point of large document (book) - after the main body, but before the glossary, to be precise. There are several possible solutions I have tried, all of them unsuccessfully.

1. open a second .idx file (say, \jobname.idx2) and patch \@wrindex to write to both files. I tried that with xpatch's \pretocmd, but it complains:

-

analyzing '\@wrindex'
++ control sequence is defined
++ control sequence is a macro
++ control sequence is a macro with parameters
-- nested patching command and parameters in patch
-> the patching command seems to be nested in the
argument to some other command
-> the patch text seems to contain # characters
-> either avoid nesting or use # characters with
category code 12 in the patch text
-> simply doubling the # characters will not work


Update: Here is a MWE

\documentclass{book}

\usepackage{lipsum,makeidx,xpatch,hyperref}

\makeatletter
\newwrite\@dblindexfile
\immediate\openout\@dblindexfile=\jobname.dbx

\newcommand{\writedbx}[1]{\protected@write\@dblindexfile{}{\string\indexentry{#1}}}

\tracingpatches
\AtBeginDocument{\xpretocmd{\@wrindex}{\protected@write\@dblindexfile{}{\string\indexentry{#1}}}{}{}}
%\xpretocmd{\@wrindex}{\protected@write\@dblindexfile{}{\string\indexentry{#1}}}{}{}

\makeatother

\begin{document}

\chapter{Were the moon landings faked?}

\lipsum[1]

\end{document}


I turns out though that if I do the xpretocmd outside the \AtBeginDocument, it does work:

[debug] tracing \pretocmd on input line 13
[debug] analyzing '\@wrindex'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ control sequence is a macro with parameters
[debug] ++ macro can be retokenized cleanly
[debug] == retokenizing macro now


And the file does indeed get written, so the patched macro seems to work. I had used the \AtBeginDocument to make sure that the patch would be applied to the macro as redefined by hyperref, but of course I can make sure of that manually.

So, thanks for the suggestion to make an MWE.

• MWE please – Henri Menke Dec 6 '16 at 19:28
• MWE for what, exactly? – Michael Palmer Dec 6 '16 at 19:37
• at least a document that produces the error message that you show would be good. – David Carlisle Dec 6 '16 at 19:51

Make # temporarily of category code 12 as suggested:

\documentclass{book}

\usepackage{lipsum,makeidx,xpatch,hyperref}
\makeindex
\makeatletter
\newwrite\@dblindexfile
\immediate\openout\@dblindexfile=\jobname.dbx

\tracingpatches
\catcode#=12
\AtBeginDocument{\xpretocmd{\@wrindex}{\protected@write\@dblindexfile{}{\string\indexentry{#1}}}{}{}}
\catcode#=6
%\xpretocmd{\@wrindex}{\protected@write\@dblindexfile{}{\string\indexentry{#1}}}{}{}

\makeatother

\begin{document}

\chapter{Were the moon landings faked?}

\lipsum[1]

\index{aaa}

\end{document}

• Yes, that works, thank you. The effect is the same though as that of just omitting the \AtBeginDocument. In both cases, the modifications made by hyperref (insertion of |hyperpage) are not captured in the patched command. This is not a problem for my purposes. (I was assuming that hyperref would throw away my patched command entirely, but it seems that it wraps it instead.) But good to know that one can patch inside \AtBeginDocument if necessary. – Michael Palmer Dec 6 '16 at 20:47