Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to define an environment which takes coordinate like arguments (1,2). I think about two different calling schemes:

  1. \begin{myenv}(mandatory coordinate)[optional](optional coordinate)

  2. \begin{myenv}[optional](mandatory coordinate)(optional coordinate)

I need suggestion how to implement them. I am using TikZso for the optional arguments I would like use pgfkeys, but I don't have a clue about how to specify arguments with parentheses.

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

This is rather easy with xparse.

\usepackage{xparse}
\NewDocumentEnvironment{myenv}{ o r() d() }
 {<begin code>}
 {<end code>}

You can test whether the first optional argument is expressed with

\IfValueTF{#1}
 {<code with optional argument expressed>}
 {<code with optional argument not expressed>}%

or with the two branches exchanged if you use \IfNoValueTF{#1}. Similarly for #3 (a coordinate pair delimited by parentheses).

With this sequence of arguments, you have an optional argument (to be enclosed in brackets), a mandatory coordinate argument and an optional coordinate argument. It's easier this way, probably.

If you want to supply defaults for the case the optional arguments are not expressed, use something like

\NewDocumentEnvironment{myenv}{ O{default} r() D(){0,0} }

where the uppercase letter means that a default (specified in the following braced list) is used. In this case you won't use \IfValueTF or \IfNoValueTF.

share|improve this answer
    
It is working fine to parse the argument but I couldn't manage to store each component of the coordinates in a macro. I tried \SplitArgument{1}{,}r() but couldn't write a proper macro to handle this. –  zunbeltz Apr 26 '13 at 13:09
add comment

Not sure if this is what you want

\documentclass{article}
\parindent 0in\parskip 1em
\usepackage{readarray}
\begin{document}
\newenvironment{myenv}[1]{%
\getargsC{#1}%
\def\coordone{\argi}%
\if2\narg\def\coordtwo{\argii}\else\def\coordtwo{Undefined}\fi%
First: \coordone\\
Second: \coordtwo}{}

\begin{myenv}{(1,2)}\end{myenv}

\begin{myenv}{(1,2) (5,7)}\end{myenv}
\end{document}

enter image description here

share|improve this answer
add comment

enter image description here

\documentclass{article}
\makeatletter

\protected\def\myenva{\@ifnextchar[\myenva@A{\myenva@A[]}}
\def\myenva@A[#1]#2{\@ifnextchar({\myenva@B[{#1}]{#2}}{\myenva@B[{#1}]{#2}(0,0)}}
\def\myenva@B[#1]#2(#3,#4){%
  \par myenva[#1]\{#2\}(#3,#4)\par}

\protected\def\myenvb#1{\@ifnextchar[{\myenvb@A{#1}}{\myenvb@A{#1}[]}}
\def\myenvb@A#1[#2]{\@ifnextchar({\myenvb@B{#1}[{#2}]}{\myenvb@B{#1}[{#2}](0,0)}}
\def\myenvb@B#1[#2](#3,#4){%
  \par myenvb\{#1\}[#2](#3,#4)\par}


\makeatother

\begin{document}

\begin{myenva}{one}
\end{myenva}

\begin{myenva}[opt]{one}
\end{myenva}


\begin{myenva}{one}(9,9)
\end{myenva}

\begin{myenva}[opt]{one}(9,9)
\end{myenva}

\begin{myenvb}{one}
\end{myenvb}

\begin{myenvb}{one}[opt]
\end{myenvb}


\begin{myenvb}{one}(9,9)
\end{myenvb}

\begin{myenvb}{one}[opt](9,9)
\end{myenvb}

\end{document}

Note that in both cases this is using the same base function with defaults supplied [] in the optional case and (0,0) in the coordinate case. However that is not forced if you want the function to do something completely different of no [] is supplied, just replace {\myenva@A[]} by \myenva@C and define that command to do whatever you want rather than omitting the argument being equivalent to supplying [].

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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