8

I have two files math.sty and matlab.sty. I want to define for example the power operation in the two with the same name (it is important that they have exactly the same name for the use that I have to give the files later) and invoke them in the same document. But when it's called, it raises an error. For example:

maths.sty contains:

\newcommand\power{ Power is a mathematical operation that is
 represented with a superscript: $5^3$.}

and matlab.sty contains

\newcommand\power{ In matlab the power is written with the symbol $
 \^{} $}

Is there any alternative to newcommand?

UPDATE: The files math.sty and matlab.sty have many definitions. Also, I have to add the files mathUSER.sty and matlabUSER.sty. I want to have all the definitions available for use in a template. And these new commands have to be written in a simple way so that children can use them without problem and create their own commands.

I have written all definitions in dictionary.sty. I would like to separate these definitions in matlab.sty, maths.sty, matlabuser.sty and mathsuser.sty.

\newcommand\dictionary[2]{
  \IfEqCase{#1}{
            {matlab}{\matlab{#2}}
            {maths}{\maths{#2}}         
            {matlabuser}{\matlabuser{#2}}
            {mathsuser}{\mathsuser{#2}}       
  }       
}

\newcommand\matlab[1]{
\IfEqCase{#1}{
    {abs}{The absolute the absolute value in programming...}
    {addition}{The addition ...}
   }
}

\newcommand\maths[1]{
\IfEqCase{#1}{
    {addition}{The addition in maths...}
    ...
   }
}

\newcommand\matlabuser[1]{ \IfEqCase{#1}{
     ...
   } 
}

\newcommand\mathsuser[1]{ \IfEqCase{#1}{
    ...
   } 
}

Invoke: \dictionary{matlab}{abs} I do not want to have matlababs, matlababsuser, mathsabs and mathsabsuser only abs. That is too complex for a child. Any idea to simplify code?

Template example:

\documentclass[10pt,a4paper]{report}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{makeidx}
\usepackage{graphicx}
\usepackage{dictionary}
\begin{document}
This is my text book and handbook.
Today, I have learned \dictionary{matlab}{abs} and \dictionary{maths}{abs}  ...
\end{document}
8
  • 1
    welcome to tex.sx. you can't have both defined with \newcommand. you could define both with \providecommand; then whichever one is encountered first will be the one that is in effect. but that doesn't satisfy you're requirement that you want both of them to be available. presumably it's possible to specify an environment in which each should be active. in that case, you can redefine the command within each specific environment, or define \power with a built-in \if to determine which version to use in which context. Oct 4, 2017 at 19:19
  • 1
    Well, if you load both .sty files each having a macro named \power, how should LaTeX know which version it should apply? Same names are possible, but not this way.
    – user31729
    Oct 4, 2017 at 19:19
  • That's the problem. I want to know if I can indicate from which file should read at any time. For example something like matlab / power.
    – Marina
    Oct 4, 2017 at 19:31
  • 4
    Not before you give some more details in your question.
    – egreg
    Oct 4, 2017 at 21:05
  • 1
    You can't load using \usepackage a foo.sty package multiple times (fontenc is an exception), i.e. LaTeX has a mechanism to recognize you already loaded it and will not load it a second time. Besides, you can only do this from the preamble, so you files are loaded once and the macros they define are defined once.
    – user4686
    Oct 5, 2017 at 20:29

4 Answers 4

3

Here is a solution to your question after the update.

The idea is to store the text in an internal macro for each combination of term and dictionary and later call this macro to get the text, but of course, without having to use the internal macro itself. For this, two macros are needed, \dictionary{<dictionary>}{<term>} to get the text and \DefineDictionaryEntry{<dictionary>}{<trem>}{<text>} to define the text. For example, after

\DefineDictionaryEntry{matlab}{power}{The function power ...}

the line

\dictionary{matlab}{power}

will give out

The function power ...

The core for these macros looks like this:

\newcommand*{\DefineDictionaryEntry}[3]{%
    \expandafter\def\csname dict@#1@#2\endcsname{#3}%
}
\newcommand*{\dictionary}[2]{
    \csname dict@#1@#2\endcsname
}

In the example above the first line will define a macro \dict@matlab@power, which is then called with \dictionary. Now, this is barely usable, because in case of typos it will lead to odd error messages and/or results. It would be nice to check, if the dictionary and the term exists and give out an understanable error message if necessary.

In order to check, if a dictionary exists, the macro \NewDictionary{<dictionary>} defines an internal macro, which is later used for checking. The core for this looks like this:

\newcommand*{\NewDictionary}[1]{%
    \expandafter\def\csname dict@#1\endcsname{y}%
}

Here too, some checking should be done.

From the LaTeX core the command \@ifundefined{<macro name>}{<code for macro undefined>}{<code for macro defined>} can be used to check, if a macro does exist. And \PackageError{<package name>}{<error message>}{<help text>} is used for error messages.

Additionally, packages normaly start with \ProvidesPackage{<package name>}[<date> <version> <short description>] and in packages other packages are loaded with \RequirePackage{<package name>}.

All this can be put in a package dictionary, which is then used by the other packages (matlab, maths, etc.) to define the terms.

% dictionary.sty
\ProvidesPackage{dictionary}[2017/10/07 v1.00 Simple dictionary package.]
\newcommand*{\dictionary}[2]{
    \@ifundefined{dict@#1}{%
        % error message, dictionary does not exist
        \PackageError{dictionary}{%
            The dictionary #1 does not exist or is not loaded.\MessageBreak
            Nothing will be printed.%
        }{%
            You may have a spelling error in your call or you forgot\MessageBreak
            to load the package. Please check and correct this.
        }%
    }{%
        \@ifundefined{dict@#1@#2}{%
            % error message, dictionary entry does not exist
            \PackageError{dictionary}{%
                The term #2 does not exist in dictionary #1.\MessageBreak
                Nothing will be printed.%
            }{%
                You may have a spelling error in your call or the term\MessageBreak
                is not defined yet. Please check and correct this.
            }%
        }{%
            % the core, for e.g. \dictionary{math}{power} the internal
            % command \dict@math@power is called
            \csname dict@#1@#2\endcsname
        }%
    }%
}
\newcommand*{\DefineDictionaryEntry}[3]{%
    \@ifundefined{dict@#1}{%
        % error message, dictionary does not exist
        \PackageError{dictionary}{%
            The dictionary #1 does not exist or is not loaded.\MessageBreak
            The new term #2 will not be defined.
        }{%
            You may have a spelling error in your call or you forgot\MessageBreak
            to load the package. Please check and correct this.
        }%
    }{%
        \@ifundefined{dict@#1@#2}{%
            % the core, for e.g. \DefineDictionaryEntry{math}{abs}{The abs ...} the internal
            % command \dict@math@abs is defined with the meaning 'The abs ...'
            \expandafter\def\csname dict@#1@#2\endcsname{#3}%
        }{%
            % error message, term already defined
            \PackageError{dictionary}{%
                The term #2 is already defined in dictionary #1.\MessageBreak
                You can not redefine it.
            }{%
                You may have a spelling error or you just copied the line\MessageBreak
                and forgot to change the term. Please check and correct this.
            }%
        }%
    }%
}
\newcommand*{\NewDictionary}[1]{%
    \@ifundefined{dict@#1}{%
        % the core, for e.g. \NewDictionary{mathuser} the internal
        % command \dict@mathuser is defined. With this, It's possible
        % to check, if the dictionary exists
        \expandafter\def\csname dict@#1\endcsname{y}%
    }{%
        % error message, dictionary already exists
        \PackageError{dictionary}{%
            The dictionary #1 already exist.\MessageBreak
            You can not define it again.
        }{%
            You may have a spelling error or you just copied the line\MessageBreak
            and forgot to change the dictionary name.\MessageBreak
            Please check and correct this.
        }%
    }%
}

Now the other packages are simple:

matlab.sty:

% matlab.sty
\ProvidesPackage{matlab}[2017/10/07 v1.00 Dictionary for matlab.]
\RequirePackage{dictionary}
\NewDictionary{matlab}
\DefineDictionaryEntry{matlab}{power}{The function power ...}
\DefineDictionaryEntry{matlab}{abs}{The function abs ...}
% more definitions here

maths.sty

% maths.sty
\ProvidesPackage{maths}[2017/10/07 v1.00 Dictionary for math.]
\RequirePackage{dictionary}
\NewDictionary{math}
\DefineDictionaryEntry{math}{power}{The power ...}
\DefineDictionaryEntry{math}{abs}{The absolute ...}
% more definitions here

Please note that for \ProvidesPackage the <package name> must be the file name without .sty.

Other packages can be written the same way:

% mathuser.sty
\ProvidesPackage{mathuser}[2017/10/07 v1.00 Dictionary for math by User.]
\RequirePackage{dictionary}
\NewDictionary{mathuser}
\DefineDictionaryEntry{mathuser}{test}{This is a test entry, written by User.}

With all this, in the document you need to load all the dictionaries you want to use:

\documentclass[10pt,a4paper]{article}
\usepackage{matlab}
\usepackage{maths}
\usepackage{mathuser}

% dictionaries and their entries can also be defined in the preamble
\NewDictionary{mydict}
\DefineDictionaryEntry{mydict}{addition}{Additionally, we learned about addition}

\begin{document}

Test the terms:

\dictionary{matlab}{power}

\dictionary{math}{power}

\dictionary{matlab}{abs}

\dictionary{math}{abs}

\dictionary{mathuser}{test}

\dictionary{mydict}{addition}

\end{document}
17

In the preamble use

\usepackage{math}
\let\mathpower\power
\let\power\undefined
\usepackage{matlab}
\let\matlabpower\power
\let\power\undefined

Then both packages are loaded and \power is not defined.

in parts of the document where you want the math version use

 \let\power\mathpower ........ \power

in parts of the document where you want the matlab version use

 \let\power\matlabpower ........ \power
0
7

It seems like you want to use one macro with two possible outputs. The best way to achive that is to use an optional paramater to specify which behaviour is desired:

enter image description here

Notes:

  • If this macro needs to be defined in two separate files, which may both be included, then repleace \newcommand* with \providecommand*.

Code:

\documentclass{article}
\usepackage{xstring}

\newcommand*{\power}[1][]{%
    \IfStrEq{#1}{matlab}{%
        In matlab the power is written with the symbol \textasciicircum.%
    }{%
        Power is a mathematical operation that is represented with a superscript: $5^3$.%
    }%
}

\begin{document}

\power

\power[matlab]

\end{document}
7

Here is another way to solve this.

Under the assumption, that there may be more then one command with the same name in both .sty files, this is a way to switch between them all.

In the .sty file define the commands as (in matlab.sty)

\newcommand\matlabpower{In Matlab ...}
\newcommand\matlabsquareroot{In Matlab ...}

or (in math.sty)

\newcommand\mathpower{Power is ...}
\newcommand\mathsquareroot{Squareroot is ...}

Then, after the definition of all of these commands, add (in matlab.sty)

\newcommand\switchtomatlab{%
    \let\power\matlabpower
    \let\squareroot\matlabsquareroot
}

or (in math.sty)

\newcommand\switchtomath{%
    \let\power\mathpower
    \let\squareroot\mathsquareroot
}

At the end add (in matlab.sty)

\switchtomatlab

or (in math.sty)

\switchtomath

After loading, the marcos of the last .sty file loaded are active. Inside the document you can change the meaning of \power and \squareroot by calling \switchtomatlab or \switchtomath.

The effect is limited to the current group. So writing, for example

\switchtomatlab
\power
\begin{someenvirontment}
\switchtomath
\power
\end{someenvironment}
\power

will lead to

In Matlab ...

Power is ...

In Matlab ...

You could also define an environment to locally switch to one meaning

\newenvironment{termsmatlab}{\begingroup\swtichtomatlab}{\endgroup}

Caution: an environment math already exists!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.