8

I try to get my own command to work to output a point in standard german notation.

My code (adapted version of wipet's code):

\documentclass[12pt]{article}

\def\punkt#1{\left(\punktA#1,,\right)} \def\punktA#1,{\if,#1,\else #1\vert\expandafter \punktA \fi}

\begin{document} $\punkt{\frac{1}{\pi},2,3}$ \end{document}

Two problems arose:

  1. How do I get rid of that last vertical bar after the "3"?
  2. How can I automatically scale the vertical bars to the biggest input?

3 Answers3

10

enter image description here

It's easier to use LaTeX's built-in comma list handling.

\documentclass[12pt]{article}

\ExplSyntaxOn \NewDocumentCommand\punkt{m}{ \left( \clist_use:nn{#1}{\middle|} \right)} \ExplSyntaxOff \begin{document} $\punkt{\frac{1}{\pi},2,3}$ \quad $\punkt{\frac{\frac{a}{b}}{\frac{a}{b}},2,3}$ \end{document}

As Mico notes, it would look better with some space:

enter image description here

\NewDocumentCommand\punkt{m}{
\left(\,
\clist_use:nn{#1}{\;\middle|\;}
\,\right)}
David Carlisle
  • 757,742
  • 1
    +1. Assuming the vertical bars represent some kind of relational operation, I'd be tempted to replace \middle| with \;\middle|\;, i.e., to surround the vertical bars with thickspace. And, to further tone down the cramped look, I'd suggest to the OP to replace \left( and \right) with \left(\, and \,\right), respectively. – Mico Oct 22 '22 at 13:45
  • 1
    @Mico yes true I answered more on list processing than typography:-) I'll add a note. Done. – David Carlisle Oct 22 '22 at 13:53
  • @Mico I wouldn't consider the bars as relations but rather "punctuation" . I believe them to be just coordinates of a point. (Sorry for the off-topic.) – campa Oct 22 '22 at 16:00
  • @campa - It's not off-topic. Your suggestion, that the bars might/should have status math-punct, is every bit as plausible as mine, viz., that the bars might/should have status math-rel. Either way, it's got to be an improvement over the bars' default status, which is math-ord. In fact, it would be sort of cute if a macro named \punkt generated an object with status math-punct. Let's see if the OP weighs in with some pertinent information. – Mico Oct 22 '22 at 16:03
5

The code is wrong to begin with (the original one, I mean), because it uses \if,#1, which is not a safe test for emptiness of #1. The problem is that \if expands tokens; in your case it works, because the expansion of \frac doesn't begin with a comma. But similar code might give problems if used in different contexts.

You want to first process the first item in the comma separated list and then start the recursion, where the \middle| is placed before the other items.

\documentclass[12pt]{article}

\def\punkt#1{\left(\punktA#1,,\right)} \def\punktA#1,{#1\punktB} \def\punktB#1,{% \if\relax\detokenize{#1}\relax % safe test for emptiness % do nothing in the true case \else ,\middle|,#1% delimiter and item \expandafter\punktB % restart the recursion \fi }

\begin{document}

$\punkt{}$

$\punkt{a}$

$\punkt{a,b}$

$\punkt{\frac{1}{\pi},2,3}$

\end{document}

enter image description here

You see that it also works with an empty argument.

Of course, the \clist_use:nn approach suggested by David is much simpler and requires almost no thinking.

With a more natural input syntax:

\documentclass[12pt]{article}

\ExplSyntaxOn

\NewDocumentCommand{\punkt}{m} { \left( \seq_set_split:Nnn \l_tmpa_seq { | } { #1 } \seq_use:Nn \l_tmpa_seq { ,\middle|, } \right) }

\ExplSyntaxOff

\begin{document}

$\punkt{}$

$\punkt{a}$

$\punkt{a|b}$

$\punkt{\frac{1}{\pi} | 2 | 3}$

\end{document}

The output is the same. Spaces around | are ignored.

egreg
  • 1,121,712
3

For use in practice I suggest sticking to the answer provided by David Carlisle.

But maybe—as a moot point/as an "academical thing"—you wish to know how you could implement a loop \PunktA yourself which does not append a vertical bar behind the last item of your comma-list:

You can have \punktA process two arguments instead of just one.
The first argument is undelimited/nested between {...} and denotes the tokens to prepend to the comma-list item processed in this iteration. In the first iteration it is empty. In subsequent iterations it contains \;\middle|\;.
The second argument is comma-delimited and denotes the comma-list item processed in this iteration:

\documentclass[12pt]{article}

\def\punkt#1{\left(,\punktA{}#1,,,\right)} \def\gobble#1{} \def\punktA#1#2,{\if,#2,\expandafter\gobble\else #1#2\expandafter\punktA\fi{;\middle|;}}

\begin{document} $\punkt{\frac{1}{\pi},2,3}$ \end{document}

enter image description here


Probably this does the trick, also:

\documentclass[12pt]{article}

\def\separator{;\middle|;} \def\punkt#1{\left(,\punktA\empty#1,,,\right)} \def\punktA#1,{\ifx#1\separator\else #1\expandafter\punktA\expandafter\separator\fi}

\begin{document} $\punkt{\frac{1}{\pi},2,3}$ \end{document}

enter image description here

Ulrich Diez
  • 28,770