Using the code from How to check if a datatool db has an existing member with the same problem (build a datatool
DB with unique strings) it works well as long if there is not an additional level (here via \DeclareDocumentCommand
) with the same functionality. Now the solution dosen't recognize the ABC string and add it again to the DB. The definition \tmp
should be fully expanded (xstring
User’s manual). The result should be only one string ABC
in the duplicates
DB.
The strings I need to bring in are assigned to various definitions several times before ending in a DB (a simplified MWE below).
\documentclass{article}
\usepackage{datatool}
\usepackage{xparse,xstring}
\makeatletter
% Patch \DTLgetlocation to gobble the error
\let\ErrorFreeDTLgetlocation\DTLgetlocation
\patchcmd{\ErrorFreeDTLgetlocation}% <cmd>
{\PackageError}% <search>
{\@gobbletwo}% <replace>
{}{}% <success><failure>
\def\@@dtlnovalue{\@dtlnovalue}
\newcommand*{\DBKey}{Value}
\newcommand*{\AddMemberToDB}[2]{%
% #1 = name of DB
% #2 = member to be added to DB
\DTLnewrow{#1}%
\DTLnewdbentry{#1}{\DBKey}{#2}%
}
\newcommand*{\IfIsInDB}[4]{% %New definition!
% #1 = name to be used for this duplicate's DB
% #2 = member to check if in DB (gets added if not)
% #3 = code to execute if member is in DB
% #4 = code to execute if member is not in DB
\ErrorFreeDTLgetlocation{\RowIndex}{\ColIndex}{#1}{#2}%
\ifx\RowIndex\@@dtlnovalue
#4%
\AddMemberToDB{#1}{#2}%
\else
#3
\fi
}
\makeatother
\DeclareDocumentCommand{\AddEntrytoDB}{m m}{
\def\tmp{}
\StrDel{#2}{ }[\tmp]% delete the spaces
\IfIsInDB{#1}{\tmp}
{CMD: \tmp is a duplicate}
{CMD: \tmp\, added DB}
}
\begin{document}
\def\ABC{A B C} % ABC string with spaces
\def\varABC{}
\StrDel{\ABC}{ }[\varABC]% delete the spaces
\DTLnewdb{duplicates} % create new DB
\AddMemberToDB{duplicates}{\varABC} % add ABC string w/o spaces to DB
Current DB:\par % display the DB
\DTLdisplaydb{duplicates}
\medskip
\IfIsInDB{duplicates}{\varABC} % check another ABC string w/o spaces
{ABC is a duplicate}% Yes: is in
{ABC added DB}% No: is not in, add it
\par
\AddEntrytoDB{duplicates}{\ABC} % add another ABC string via Command
\medskip
Current DB:\par % display the DB
\DTLdisplaydb{duplicates}
\end{document}
\dtlexpandnewvalue
to the\AddMemberToDB
. I thought the code formatting looked familiar. :-) – Peter Grill Oct 22 '19 at 6:15\IfIsInDB
to include the line\edef\@ExpandedTarget{#2}
and then use\@ExpandedTarget
instead of#2
and replace the call toAddMemberToDB
with\AddEntrytoDB
, things work as desired. – Peter Grill Oct 22 '19 at 19:33\def\efg{efg}
and add\AddEntrytoDB{duplicates}{\efg}
to the document. The DB should now contain 2 entries, but every additional entry is a duplicate and only the last definition is in the DB. It looks that the DB stores the definition of '\@ExpandedTarget' and not it's value. – Luis Potter Oct 23 '19 at 10:42\@dtlnovalue
, not\@@dtlnovalue
. – Peter Grill Oct 24 '19 at 6:03