3

I'm a newbie and have jumped in at the deep by trying to get this MWE to work. I'm using Lyx 2.1.1.

I've left out the first line from the MWE

\documentclass{article}

Lines 2 - 28 I've inserted into the LaTex Preamble under Document Settings, i.e. the following code:

\usepackage{graphicx}
\usepackage{caption}
\usepackage{xcolor}
\usepackage{multicol, lettrine}
\makeatletter
% \begin{macrocode}
\def\csn#1{\csname#1\endcsname}%
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%
\def\setproperty#1#2#3{\ece\edef{#1@p#2}{#3}}%
\def\setpropertyglobal#1#2#3{\ece\xdef{#1@p#2}{#3}}%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}

% \begin{macro}{\getproperty}
% Used as |\getproperty|\marg{property}\marg{atom}
% \begin{macrocode}
\def\getproperty#1#2{%
  \expandafter\ifx\csname#1@p#2\endcsname\relax
% then \empty
  \else \csname#1@p#2\endcsname
  \fi
}%
% \end{macrocode}
% \end{macro}

I've omitted the next line (line 29)

\begin{document}

And finally added from line 31 to 78 into the document itself using the Insert TeX Code option:

\def\alist{fig167,fig168,fig169,fig176,%
fig180,fig181,fig182,fig183,fig185,fig186,fig187,fig188}
%% create a macro to create new lists
\def\newDB#1{%
\expandafter\gdef\csname#1\endcsname{}
}
%% add an image to the DB, use the LaTeX macro
%% \g@addto@macro to store them at the DB location
\def\addtoDB#1#2{%
\ifx\@empty#1
\g@addto@macro{#1}{#2}
\else
\g@addto@macro#1{,#2}
\fi
}
%% internal macro, saves the image to the DB
%% #1 is the image database
%% #2 is the image file name
%% #3 is the image long caption.
\def\DB{alist}
\long\def\addimageDB#1#2#3#4{%
%\def\captionname{caption}
% adds to DB #1, the image name #2
\expandafter\addtoDB\expandafter{\csname#1\endcsname}{#2}   
%% set the caption property, set us imagename.caption.data
\setproperty{#2}{caption}{#3}
%% set the date
\setproperty{#2}{date}{#4}
%% makes a label property for use later on fig:name
\setproperty{#2}{label}{fig:#2}
}
%% get the caption of the image
%% #1 database name (not macro)
%% #2 image file
%% sugar for DB terminology
\def\getfield#1#2{%
\getproperty{#1}{#2}
}
% Example code
\addimageDB{alist}{fig145}{This is the caption for image fig145. Testing a paragraph.}{1920}

When I try to create a pdf document I get the following error:

Undefined control sequence

 ...dimageDB{alist}{fig145}{caption145}{1920}

The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

I can't figure out what is wrong since addimage is defined at line 56.

darthbith
  • 7,384

1 Answers1

2

LyX sometimes parses the log-file wrongly, or at least it shows the error in a way that can only be interpreted wrong. If you click View complete log and do a bit of scrolling, you'll find that the error message is something like

! Undefined control sequence.
\addtoDB ...ty#1 \g @addto@macro{#1}{#2} \else \g 
                                                  @addto@macro#1{,#2} \fi 

The last control sequence before the line break, in this case \g, is the one that is undefined. That control sequence is really \g@addto@macro though, the reason it stops after the g is that @ in this case is not seen as a normal letter, and can therefore not be a part of the name of a control sequence. To fix this, add \makeatletter at the start of the code block, and \makeatother at the end. See What do \makeatletter and \makeatother do? (and probably some of the linked questions) for more about this. Basically, whenever you use a macro with a @ in its name, you need \makeatletter before the use, and \makeatother after.

Personally I think I would add most of the definitions to the preamble instead, though it's not required. \makeatletter/\makeatother is still needed, but as LyX adds these to the LaTeX source it generates anyway, you don't actually have to add them yourself.

For example, you could add the following to the preamble:

\usepackage{graphicx}
\usepackage{caption}
\usepackage{xcolor}
\usepackage{multicol, lettrine}

\def\csn#1{\csname#1\endcsname}%
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%
\def\setproperty#1#2#3{\ece\edef{#1@p#2}{#3}}%
\def\setpropertyglobal#1#2#3{\ece\xdef{#1@p#2}{#3}}%
\def\getproperty#1#2{%
  \expandafter\ifx\csname#1@p#2\endcsname\relax
% then \empty
  \else \csname#1@p#2\endcsname
  \fi
}%

\def\alist{fig167,fig168,fig169,fig176,%
fig180,fig181,fig182,fig183,fig185,fig186,fig187,fig188}
%% create a macro to create new lists
\def\newDB#1{%
\expandafter\gdef\csname#1\endcsname{}
}
%% add an image to the DB, use the LaTeX macro
%% \g@addto@macro to store them at the DB location
\def\addtoDB#1#2{%
\ifx\@empty#1
\g@addto@macro{#1}{#2}
\else
\g@addto@macro#1{,#2}
\fi
}
%% internal macro, saves the image to the DB
%% #1 is the image database
%% #2 is the image file name
%% #3 is the image long caption.
\def\DB{alist}
\long\def\addimageDB#1#2#3#4{%
%\def\captionname{caption}
% adds to DB #1, the image name #2
\expandafter\addtoDB\expandafter{\csname#1\endcsname}{#2}   
%% set the caption property, set us imagename.caption.data
\setproperty{#2}{caption}{#3}
%% set the date
\setproperty{#2}{date}{#4}
%% makes a label property for use later on fig:name
\setproperty{#2}{label}{fig:#2}
}
%% get the caption of the image
%% #1 database name (not macro)
%% #2 image file
%% sugar for DB terminology
\def\getfield#1#2{%
\getproperty{#1}{#2}
}

and add an ERT with the following in the document:

\addimageDB{alist}{fig145}{This is the caption for image fig145. Testing a paragraph.}{1920}

\getfield{fig145}{caption}

then I get this:

enter image description here

Torbjørn T.
  • 206,688