Detect duplicates csnames defined via \csdef

I have a large list of \csdef that is used repeatedly. In a separate tex file I am trying to detect any duplicates and running into a problem trying to print out the inital definition and the value that the duplicate is trying to set it to.

The two problem lines in the MWE are commented out and the desired output form the MWE is

macro 1: Macro 1 Value
Macro 3 Value

Number of Duplicates = 1


The error I am getting is

LaTeX Error: Missing \begin{document}.

See the LaTeX manual or LaTeX Companion for explanation. Type H for immediate help. ...

l.29 \csdef{macro 1}{Macro 3 Value}

Code:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{letltxmacro}

\newcounter{NumberOfDuplicates}

\LetLtxMacro{\OldCsdef}{\csdef}
\RenewDocumentCommand{\csdef}{%
m%    #1 = control sequence name
O{0}% #2 = number of parameters (UNUSED HERE)
m%    #3 = value
}{%
\ifcsdef{#1}{%
\typeout{ERROR: '#1' defined multiple times.}%
%        #1: \csuse{#1}%       <-- Show Old Definition
%       \par\hphantom{#1: }#3% <-- Show new definition
\stepcounter{NumberOfDuplicates}%
}{%
\OldCsdef{#1}{#3}%
}%
}%

% ------------------------------ Want to check that there are no duplicate csnames here
\csdef{macro 1}{Macro 1 Value}
\csdef{macro 2}{Macro 2 Value}
\csdef{macro 1}{Macro 3 Value}
%
\begin{document}
\medskip\par
Number of Duplicates = \arabic{NumberOfDuplicates}.
\end{document}

• I am guessing that this must be something very obvious that I am not seeing. Mar 27, 2017 at 9:44

Of course you get the “Missing \begin{document}” error: you're trying to typeset something in the preamble.

\documentclass{article}

\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{letltxmacro}

\newcounter{NumberOfDuplicates}

\LetLtxMacro{\OldCsdef}{\csdef}
\RenewDocumentCommand{\csdef}{%
m%    #1 = control sequence name
O{0}% #2 = number of parameters (UNUSED HERE)
m%    #3 = value
}{%
\ifcsdef{#1}{%
\typeout{ERROR: '#1' defined multiple times.}%
\xappto\duplicateslist{
#1: \expandafter\meaning\csname #1\endcsname % <-- Old
\noexpand\par\noexpand\leavevmode
\noexpand\hphantom{#1: }\unexpanded{#3}% <-- New
\noexpand\par
}%
\stepcounter{NumberOfDuplicates}%
}{%
\OldCsdef{#1}{#3}%
}%
}%

\AtBeginDocument{{\ttfamily\duplicateslist}}

% ------------------------------ Want to check that there are no duplicate csnames here

\csdef{macro 1}{Macro 1 Value}
\csdef{macro 2}{Macro 2 Value}
\csdef{macro 1}{Macro 3 Value}
%
\begin{document}

\medskip\par
Number of Duplicates = \arabic{NumberOfDuplicates}.
\end{document}