1

I'm trying to make a class following my school's standard for thesis and I got a problem when I tried to implement a list of acronyms, because this list should be alphabetically sorted and the packages that I found were incompatible with my implemented class. So I decide to make my own implementation using arrays.

I can create arrays as \foo#1 (in which each element of array receive as new index in #1, using \csname foo#1 \endcsname), but to sort this array I need to insert an element in a specific position of the array.

An example of my code at now is:

\documentclass[]{report}

\newcounter{countArrayTest}
\setcounter{countArrayTest}{0}

\newcommand{\appendElement}[1]{%
    \expandafter\newcommand\csname arraytest\the\value{countArrayTest} \endcsname{#1}
    \stepcounter{countArrayTest}
}

\newcommand{\getIndexElement}[1]{
    \csname arraytest#1 \endcsname
}

\newcommand{\testInsert}{%
    \expandafter\renewcommand\csname arraytest1 \endcsname{\getIndexElement{0}}
    \expandafter\renewcommand\csname arraytest0 \endcsname{Test1}
}

\newcounter{CountTempAux}

\newcommand{\showAll}{%
    \setcounter{CountTempAux}{0}
    \loop\ifnum\value{CountTempAux}<\value{countArrayTest}
        \csname arraytest\the\value{CountTempAux} \endcsname
        \stepcounter{CountTempAux}
    \repeat
}

\begin{document}


\appendElement{Element1}
\appendElement{Element2}


\testInsert

\showAll

\end{document}

The problem is, I expected the answer "Test1 Element1", but I got "Test1 Test1".

Any suggestion to solve this problem?

Caio
  • 277

2 Answers2

2

I agree with Alan Munn's comment that it is probably easier if you show'd us the problems you're having with the acronym packages you tried (acronym? glossaries?).

To your question at hand: the problem you're having lies in

\newcommand{\testInsert}{%
    \expandafter\renewcommand\csname arraytest1 \endcsname{\getIndexElement{0}}
    \expandafter\renewcommand\csname arraytest0 \endcsname{Test1}
}

\arraytest1 is not defined to be \arraytest0 but to \getIndexElement{0}. Later when you call it inside \showall \arraytest0 has already been redefined to Test1.

In order to store the contents of \arraytest0 you'd need to expand \getIndexEntry{0}

\newcommand{\testInsert}{%
    \expandafter\edef\csname arraytest1 \endcsname{\getIndexElement{0}}%
    \expandafter\renewcommand\csname arraytest0 \endcsname{Test1}%
}

Now

\appendElement{Element1}\appendElement{Element2}
\testInsert
\showAll

will give

Test1 Element1

This won't work if \arraytest0 contains unexpandable stuff, though:

\appendElement{\textbf{Element1}}\appendElement{Element2}
\testInsert
\showAll

In this case you can use \protected@edef

\makeatletter
\newcommand{\testInsert}{%
    \expandafter\protected@edef\csname arraytest1 \endcsname{\getIndexElement{0}}%
    \expandafter\renewcommand\csname arraytest0 \endcsname{Test1}%
}
\makeatother
\appendElement{\textbf{Element1}}\appendElement{Element2}
\testInsert
\showAll

Test1 Element1

You could also use etoolbox's \csletcs (*):

\usepackage{etoolbox}
\newcommand{\testInsert}{%
    \csletcs{arraytest1}{arraytest0}%
    \expandafter\renewcommand\csname arraytest0\endcsname{Test1}%
}

(*) your current definition of showall produces lots of spaces between the elements. In order to avoid that you should comment out all lines not ending with a command:

\newcommand{\showAll}{%
    \setcounter{CountTempAux}{0}%
    \loop\ifnum\value{CountTempAux}<\value{countArrayTest}%
        \csname arraytest\the\value{CountTempAux} \endcsname
        \stepcounter{CountTempAux}%
    \repeat
}

The same holds for every other command you're defining. For example

\newcommand{\appendElement}[1]{%
    \expandafter\newcommand\csname arraytest\the\value{countArrayTest} \endcsname{#1}
    \stepcounter{countArrayTest}
}

defines \arraytest0 (including a space after the 0! unless you change that the \csletcs code from me won't work yet) and produces two additional spaces when called. Better:

\newcommand{\appendElement}[1]{%
    \expandafter\newcommand\csname arraytest\the\value{countArrayTest}\endcsname{#1}%
    \stepcounter{countArrayTest}%
}

You might want to use \@namedef or etoolbox's \csdef, anyway:

\newcommand{\appendElement}[1]{%
    \@namedef{arraytest\the\value{countArrayTest}}{#1}%
    \stepcounter{countArrayTest}%
}
cgnieder
  • 66,645
0

If you are willing to put in this much work, it may be worth trying the tocloft package. Here's a quick-start article on the tocloft package. It drops a file in the compilation directory that you can run through sort(1) or another utility as part of the build process.