I've cobbled together the \basis macro which sets and gets a hidden/internal length \b@sis. It is meant to work as follows :
- Calling
\basisreturns the value of\b@sis - Calling
\basis{}sets\b@sisto the default value (The current font size\f@size) and - Calling
\basis{1ex}sets the\b@sisto the specified length.
2 and 3 work but 1 does not always return the value as expected. I can't use \basis within TikZ as a length for instance nor can I show it's value using \the\basis or \showthe\basis. I also tried prefixing \expandafterto the previous two "the" commands with no effect. Below is the code I have so far
\documentclass{standalone}
\usepackage{luatex85}
\usepackage{xparse}
\usepackage{ifthen}
\usepackage{xifthen}
\usepackage{tikz}
\usepackage{booktabs}
\makeatletter
\newlength{\b@sis}
\newlength{\length}
\setlength{\length}{2pt}
\setlength{\b@sis}{2pt}
\ProvideDocumentCommand{\basis}{g}{%
\IfNoValueTF{#1}{%
\b@sis}{%
\ifthenelse{\isempty{#1}}%
{\setlength{\b@sis}{\f@size pt}%
\setlength{\length}{\f@size pt}}%
{\setlength{\b@sis}{#1}%
\setlength{\length}{#1}}}}%
\newcommand{\showbasis}{\the\b@sis}
\makeatother
\begin{document}
\begin{tabular}{|l|r|c|c|} % The following calls fail
\toprule
No response & \basis \showbasis & \tikz \draw circle(0.5*\length); \\%& \tikz \draw circle(0.5*\basis); \\
\midrule
Sets default & \basis{} \showbasis & \basis{}\tikz \draw circle(0.5*\length); \\%& \tikz \draw circle(0.5*\basis); \\
\midrule
Sets Value & \basis{1ex} \showbasis & \basis{1ex}\tikz \draw circle(0.5*\length); \\%& \tikz \draw circle(0.5*\basis); \\
\bottomrule
\end{tabular}
\end{document}
its output looks as follows
My belief is that the \IfNoValueTF is not being expanded when there is no argument and that the expected length not returned. Is there some means of expanding it to return the internal length or is there perhaps a better means fordoing this.
I see \ProvideDocumentCommand allows for an l argument, perhaps I should be using this within my definition ? e.g. is there a change \basis is reading ahead to the first non-whitespace character, the xparse manual implies this might be the case.
Update
Egreg clearly has the better solution but I only saw it after David Carlisle responded and I had messed about with it some more. The interface I got to used \basis and \basis[VALUE] to set the value and \basis* to retrieve it. This is really bad practice though and is certainly not what star is for.
\ProvideDocumentCommand{\basis}{s o}{%
\IfBooleanTF{#1}
{\the\b@sis}
{\IfNoValueTF{#2}{%
\setlength{\b@sis}{\f@size pt}%
\setlength{\length}{\f@size pt}}
{\setlength{\b@sis}{#2}%
\setlength{\length}{#2}}}
}%



\IfNoValueTF{\the#1}{...}{...}or\IfNoValueTF{#1}{\the\b@sis}{...}? I just tried both, uncommenting the\tikz ... circle(\b@sis);parts and compiling the file. The first dies withmissing number treated as zero. The latter withMissing \endcsname insertedand a hint,\l__xpars_processor_int, it fails in xparse. – Carel May 18 '17 at 14:56{}should be mandatory arguments, no standard latex command sometimes takes{}and sometimes not ('g' is something of an aberration intended for experimenting with interfaces not matching latex2e) , also it is rather strange to use the same command to both set and retrieve the length. Why not have\setbasisthat takes an argument and\basisto retrieve the current value that does not take an argument? – David Carlisle May 18 '17 at 16:10\setbasisand\basisinterface, but I am curious as to how\basismight substitute for\length. I'm starting to get a grip on writing my own macros, for quite some time they've largely been an enigma to me, I think it's due to a lack of understanding of the TeX primitives. – Carel May 18 '17 at 16:38