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

4
  • It is possible in LaTeX of course. LyX is only a editor that hides (too much, in my opinion) of LaTeX
    – user31729
    Commented Apr 14, 2017 at 15:40
  • 1
    I'm looking for a solution in LyX, if that's possible, to avoid writing code. Commented Apr 15, 2017 at 9:50
  • 2
    This way you learn nothing and will be a slave of TeX.SE ;-)
    – user31729
    Commented Apr 15, 2017 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). Commented Apr 15, 2017 at 9:54

1 Answer 1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .