8

Inspired by LINQ's query method, such as

deck.Take(randomCount)
    .Where (card => card.Suit == "Hearts")
    .Skip(2)
    .Take(5)
    .OrderBy (card => card.FaceValue);

The deck which is an object of a class that inherits IEnumerable will have the LINQ's query methods.

I want to apply this to LaTeX macros, for example, \includegraphics as follows.

\documentclass[preview,border=12pt]{standalone}
\usepackage{graphicx}
\begin{document}
\includegraphics[viewport={10cm 10cm 10cm 10cm},clip,width=3cm]{example-image-a}
\includegraphics
    .viewport{10cm 10cm 10cm 10cm}
    .clip{}
    .width{3cm}
    .file{example-image-a}
\end{document}

Questions

  1. How to create a macro that behaves as follows?

    \includegraphics
        .viewport{10cm 10cm 10cm 10cm}
        .clip{}
        .width{3cm}
        .file{example-image-a}
    

    Remember that we can omit some of the keys if not needed. For example,

    \includegraphics
        .width{3cm}
        .file{example-image-a}
    

    can be invoked.

    And the order is not important, for example,

    \includegraphics
        .file{example-image-a}
        .width{3cm}
    

    can be invoked as well. But at least one is mandatory, in this case, file.

  2. What is the disadvantage of implementing this style of coding?

  • 1
    For TeX, it is disaster if there is no clear end of the parameter list (i.e. a character which always occurs at the end, like ]). If you add that, then your syntax is just a minimal variation of the usual key-value syntax. – Stephan Lehmke Nov 29 '13 at 7:03
  • if you have an ending ; and use parentheses ( and ) rather than braces, as in your initial model, then as Stephan Lehmke says, this is a rather easily equivalent variant of the [key1=value, key2=value, ...] syntax. – user4686 Nov 29 '13 at 7:18
  • @jfbu braces are better because they can be nested. To have parentheses in an argument, one would have to write ({...}). – Stephan Lehmke Nov 29 '13 at 7:22
  • 2
    @jfbu what about #{ syntax? – Stephan Lehmke Nov 29 '13 at 7:55
  • 1
    There seem to be only disadvantages and no advantages to doing this. It's like asking to use a German grammatical construct in the middle of an English sentence. It's not that either German or English are bad on their own but randomly mixing the two grammars is confusing for humans even if you can get it to work technically. – David Carlisle Nov 29 '13 at 11:12
5

I wrote several similar systems, none of them for LaTeX though, probably for the good reason raised by David Carlisle, that using such macro interfaces in LaTeX would confuse users and cancel any benefits you could have from such an interface.

Let me review one of these systems, it is carefully described so that you can easily adapt these techniques to your case or other similar situations.

hbox-like interfaces in plain TeX with getoptk

One such system is the getoptk package which you may find in tex/plain/contrib/getoptk.tex and that were described in TUGboat 32-2, it defines new macros in plain TeX which enable the user to define commands mimicing the interface of hbox, hfill etc.

getoptk in action!

Using these macros, you could define a version of \includegraphics which you could use like this:

\includegraphics
  viewport{10cm 10cm 10cm 10cm}
  clip
  width=3cm
  {example-image-a}

As you see, we crucially need a non optional argument to mark the list of our options. Preparing the definition of that revolted teen \includegraphics requires the definition of an option dictionary:

\newgetoptkdictionary{includegraphics}
\defgetoptktoks{viewport}{\def\includegraphics@viewport{#1}}
\defgetoptkflag{clip}{\cliptrue}
\defgetoptkdimen{width}{\imagewidth=#1}

The defgetoptk* calls define new optional arguments and behaviours. The replacement texts of these behaviours are saved as the macros

\getoptk@behaviour@includegraphics@viewport
\getoptk@behaviour@includegraphics@clip
\getoptk@behaviour@includegraphics@width

We now need to define the \includegraphics macro itself, it looks like

\def\includegraphics{%
   \setgetoptkdictionary{includegraphics}%
   \getoptk\includegraphics@M
}

and the previous call to our \includegraphics would be replaced by

\includegraphics@M{%
  \getoptk@behaviour@includegraphics@viewport{10cm 10cm 10cm 10cm}
  \getoptk@behaviour@includegraphics@clip
  \getoptk@behaviour@includegraphics@width{3cm}%
}{example-image-a}

Neat, isn'it? The package is a bit long and uses some mid-level programming techniques in TeX (edef, futurelet and registers, essentially).

Other similar macros

I am the author of a hobby TeX format, branded Bhrìd TeX — I am looking for a new, funnier, name, by the way — which I started in 1999 after reading David Solomon's advanced TeX book — I decided to move to the non-advanced one a year later. But enough archeology!

If you enjoy reading french, please open the programmer's manual you should go the the section 2.6 and look for the family of macros \getoptspec. They are similar to getoptkbut work with macros instead of keywords, which is of course easier to write! If you feel evil minded enough to play with the catcodes of . ( and ) and a few others you may even let TeX understand that statement

deck.Take(randomCount)
    .Where (card => card.Suit == "Hearts")
    .Skip(2)
    .Take(5)
    .OrderBy (card => card.FaceValue);

But doing such tricks is not the LaTeX way.

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.