2

In LyX, is it possible to change the order of required and option arguments of a macro?

I want to make the option argument come after the required argument in this macro.

If it's possible, how can I do it?

Screenshot of the macro

  • It is possible in LaTeX of course. LyX is only a editor that hides (too much, in my opinion) of LaTeX – user31729 Apr 14 '17 at 15:40
  • 1
    I'm looking for a solution in LyX, if that's possible, to avoid writing code. – Gal Grünfeld Apr 15 '17 at 9:50
  • 2
    This way you learn nothing and will be a slave of TeX.SE ;-) – user31729 Apr 15 '17 at 9:51
  • 1
    Haha. I've no problem with writing code and learning relevant LaTeX/TeX code - I just want to automate as much as possible to decrease time needed to do things. And that's something that LyX is quite good at doing. Also, I want to have as least code as possible in my LyX document due to elegance (I render things automatically in LyX). – Gal Grünfeld Apr 15 '17 at 9:54
1

I don't recommend doing this because it'll be confusing to anyone else who reads your document. It will also not work for all macros, particularly ones that play around with category codes prior to reading their arguments. That said it is possible.

Here's some LaTeX code that defines a macro \flip that will flip the required and optional arguments of a macro that's defined to have exactly one required argument and one optional argument.

\usepackage{etoolbox}

\makeatletter
\newcommand*\flip[1]{%
    \cslet{flip@\string#1}#1%
    \long\def#1##1{%
        \@ifnextchar[{\@flip{#1}{##1}}{\csuse{flip@\string#1}{##1}}%
    }%
}
\long\def\@flip#1#2[#3]{%
    \csuse{flip@\string#1}[#3]{#2}%
}
\makeatother

For example, given the macro

\newcommand\foo[2][none]{%
    \par
    Required argument: #2\\
    Optional argument: #1%
}

you can write \flip\foo one time and it'll redefine \foo to take a required argument followed by an optional argument. Here's a complete document illustrating this.

\documentclass{article}
\usepackage{parskip}
\usepackage{etoolbox}

\makeatletter
\newcommand*\flip[1]{%
    \cslet{flip@\string#1}#1%
    \long\def#1##1{%
        \@ifnextchar[{\@flip{#1}{##1}}{\csuse{flip@\string#1}{##1}}%
    }%
}
\long\def\@flip#1#2[#3]{%
    \csuse{flip@\string#1}[#3]{#2}%
}
\makeatother

\newcommand\foo[2][none]{%
    \par
    Required argument: #2\\
    Optional argument: #1%
}


\begin{document}

Normal use:
\foo{blah}
\foo[option]{asdf}

Now we can flip the arguments:
\flip\foo
\foo{blah}
\foo{asdf}[option]
\end{document}

enter image description here

I've never used LyX before now, but I was able to insert my code into the preamble and achieve the same effect.

Note that \flip doesn't respect the lack of \long on a macro (i.e., macros defined via the \def family without \long or defined via \newcommand*). This is likely to lead to confusing errors in some cases. It's possible to deal with this similar to how etoolbox patches macros, but it didn't seem worth it to do so for this answer.

It would also be possible to define \flip such that it didn't redefine its argument but instead such that \flip\foo{required}[optional] expanded to \foo[optional]{required}. Something like (untested)

\long\def\flip#1#2[#3]{#1[#3]{#2}}

which would turn the optional argument into a required one, but if you don't have the optional argument, there's no reason to use the \flip.

In conclusion, it's possible to do, but you probably shouldn't do it.

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.