summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/semantex/semantex.tex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/semantex/semantex.tex')
-rw-r--r--macros/latex/contrib/semantex/semantex.tex504
1 files changed, 288 insertions, 216 deletions
diff --git a/macros/latex/contrib/semantex/semantex.tex b/macros/latex/contrib/semantex/semantex.tex
index 2a3bee0153..f4cf279f0e 100644
--- a/macros/latex/contrib/semantex/semantex.tex
+++ b/macros/latex/contrib/semantex/semantex.tex
@@ -34,7 +34,7 @@
\usepackage[nameinlink]{cleveref}
-\title{Seman\!\TeX: Semantic mathematics (v$0.201\alpha$)}
+\title{Seman\!\TeX: Semantic mathematics (v$0.3\alpha$)}
\date{\today}
\author{Sebastian Ørsted (\href{mailto:sorsted@gmail.com}{sorsted@gmail.com})}
@@ -293,6 +293,7 @@ $ \vh[inverseimage]{\sheafF}[spar,stalk=\vp]
\NewObject\MyVar\vn{n}
\NewObject\MyVar\vp{p}
\NewObject\MyVar\vU{U}
+\NewObject\MyVar\vx{x}
\NewObject\MyVar\sheafF{\mathcal{F}}
% Now we set up the class \MyVar:
@@ -318,7 +319,7 @@ $ \vh[inverseimage]{\sheafF}[spar,stalk=\vp]
$ \vf[conj,der=\vn] $
-$ \vg[inv,res=\vU]{x} $
+$ \vg[inv,res=\vU]{\vx} $
$ \vh[inverseimage]{\sheafF}[spar,stalk=\vp]
= \sheafF[stalk=\vh{\vp}] $
@@ -335,7 +336,7 @@ with
\usepackage{semantex}
\end{lstlisting}
The \semantex system is object-oriented; all entities are objects of some class. When you load the package, there
-is only one class by default, which is simply called \lstinline!\SemantexVariable!.
+is only one class by default, which is simply called \lstinline!\SemantexBaseObject!.
You should think of this as a low-level class, the parent of all other classes. Therefore, I highly advice against using it directly or modifying it.
Instead, we create a new, more high-level variable class.
We choose to call it \lstinline!\MyVar!.
@@ -771,19 +772,19 @@ Adding support for free algebras, power series, and Laurent series is almost as
},
{freealg}{
par,
- leftpar=\noexpand\langle,
- rightpar=\noexpand\rangle,
+ leftpar=\langle,
+ rightpar=\rangle,
},
{powerseries}{
par,
- leftpar=\noexpand\llbracket,
- rightpar=\noexpand\rrbracket,
+ leftpar=\llbracket,
+ rightpar=\rrbracket,
},
{laurent}{
par,
leftpar=(, rightpar=),
- prearg={\!\!\noexpand\SemantexDelimiterSize(},
- postarg={\noexpand\SemantexDelimiterSize)\!\!},
+ prearg={\!\!\SemantexDelimiterSize(},
+ postarg={\SemantexDelimiterSize)\!\!},
% These are printed before and after the argument.
% The command "\SemantexDelimiterSize" is substituted
% by \big, \Big, ..., or whatever size the
@@ -796,19 +797,19 @@ Adding support for free algebras, power series, and Laurent series is almost as
singlekeys={
{freealg}{
par,
- leftpar=\noexpand\langle,
- rightpar=\noexpand\rangle,
+ leftpar=\langle,
+ rightpar=\rangle,
},
{powerseries}{
par,
- leftpar=\noexpand\llbracket,
- rightpar=\noexpand\rrbracket,
+ leftpar=\llbracket,
+ rightpar=\rrbracket,
},
{laurent}{
par,
leftpar=(, rightpar=),
- prearg={\!\!\noexpand\SemantexDelimiterSize(},
- postarg={\noexpand\SemantexDelimiterSize)\!\!},
+ prearg={\!\!\SemantexDelimiterSize(},
+ postarg={\SemantexDelimiterSize)\!\!},
% These are printed before and after the argument.
% The command "\SemantexDelimiterSize" is substituted
% by \big, \Big, ..., or whatever size the
@@ -816,10 +817,7 @@ Adding support for free algebras, power series, and Laurent series is almost as
},
},
}
-For expansion reasons (which I am not completely sure of),
-we need \lstinline!\noexpand! before these commands.
-In general, whenever something fails, try throwing in \lstinline!\noexpand!'s in front of suspicious-looking commands,
-and things will usually work out just fine. See for yourself:
+See for yourself:
\begin{LTXexample}
$\vk[freealg]{\vx}$,
$\vk[powerseries]{\vy}$,
@@ -831,7 +829,7 @@ Let us look at some other algebraic operations that we can control via \semantex
\begin{lstlisting}
\SetupClass\MyVar{
singlekeys={
- {op}{upper={\noexpand\mathrm{op}}},
+ {op}{upper={\mathrm{op}}},
% opposite groups, rings, categories, etc.
{algclosure}{overline},
% algebraic closure
@@ -863,7 +861,7 @@ Let us look at some other algebraic operations that we can control via \semantex
\end{lstlisting}
\SetupClass\MyVar{
singlekeys={
- {op}{upper={\noexpand\mathrm{op}}},
+ {op}{upper={\mathrm{op}}},
% opposite groups, rings, categories, etc.
{algclosure}{overline},
% algebraic closure
@@ -1015,26 +1013,26 @@ In fact, you could have defined the \lstinline!overline! yourself as follows:
\begin{lstlisting}
\SetupClass\MyVar{
singlekeys={
- {overline}{command=\noexpand\overline},
+ {overline}{command=\overline},
},
}
\end{lstlisting}
\SetupClass\MyVar{
singlekeys={
- {overline}{command=\noexpand\overline},
+ {overline}{command=\overline},
},
}
-This is how the key \lstinline!overline! is defined internally, except it is defined on the level of the superclass \lstinline!\SemantexVariable! instead. We need the key \lstinline!\noexpand! in order for everything to expand properly. This is only necessary for some commands, and to tell the truth, I haven't quite figured out the system of which commands need it and which ones do not. However, as usual, if something does not work, try throwing in some \lstinline!\noexpand!'s and see if it solves the problem.
+This is how the key \lstinline!overline! is defined internally, except it is defined on the level of the superclass \lstinline!\SemantexBaseObject! instead.
Here are some more examples of predefined keys that use the command key:
\begin{lstlisting}
\SetupClass\MyVar{ % do not add these -- they are already predefined!
novalueskeys={
- {smash}{command=\noexpand\smash},
- {tilde}{command=\noexpand\tilde},
+ {smash}{command=\smash},
+ {tilde}{command=\tilde},
{widetilde}{command=\widetilde},
- {bar}{command=\noexpand\bar},
- {bold}{command=\noexpand\mathbf},
- {roman}{command=\noexpand\mathrm},
+ {bar}{command=\bar},
+ {bold}{command=\mathbf},
+ {roman}{command=\mathrm},
},
}
\end{lstlisting}
@@ -1339,16 +1337,16 @@ and hypercohomology. This is quite easy with the \lstinline!command! key:
\SetupClass\MyVar{
singlekeys={
{reduced}{command=\widetilde},
- {cech}{command=\noexpand\check},
- {hyper{command=\noexpand\mathbb},
+ {cech}{command=\check},
+ {hyper{command=\mathbb},
},
}
\end{lstlisting}
\SetupClass\MyVar{
singlekeys={
{reduced}{command=\widetilde},
- {cech}{command=\noexpand\check},
- {hyper}{command=\noexpand\mathbb},
+ {cech}{command=\check},
+ {hyper}{command=\mathbb},
},
}
@@ -1380,21 +1378,21 @@ This can be done the following way:
valuekeys={
{Lder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{L}^{#1},
+ symbolputleft=\mathbb{L}^{#1},
},
{Rder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{R}^{#1},
+ symbolputleft=\mathbb{R}^{#1},
},
},
singlekeys={
{Lder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{L},
+ symbolputleft=\mathbb{L},
},
{Rder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{R},
+ symbolputleft=\mathbb{R},
},
},
}
@@ -1403,21 +1401,21 @@ This can be done the following way:
valuekeys={
{Lder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{L}^{#1},
+ symbolputleft=\mathbb{L}^{#1},
},
{Rder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{R}^{#1},
+ symbolputleft=\mathbb{R}^{#1},
},
},
singlekeys={
{Lder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{L},
+ symbolputleft=\mathbb{L},
},
{Rder} {
innerreturn,leftreturn,
- symbolputleft=\noexpand\mathbb{R},
+ symbolputleft=\mathbb{R},
},
},
}
@@ -1470,27 +1468,19 @@ In order to customize this, there are two extra keys:
These work exactly like \lstinline!singlekeys! and~\lstinline!valuekeys!.
\begin{lstlisting}
\SetupClass\MyVar{
+ argkeyval=true, % this turns keyval syntax in arguments on
argvaluekeys={
{coef}{ othersep={;}{#1} },
},
}
\end{lstlisting}
-(But it will not quite work yet -- stay tuned for a moment!)
The key \lstinline!othersep! is a key that controls the separator
between the current argument and the previous argument (it will only be printed if there was a previous argument). By default, this separator is a comma. So in the syntax~\lstinline!\co{*}{\vX,coef=\vR}!,
there are two arguments, \lstinline!\vX! and~\lstinline!\vR!, and the separator is a semicolon.
-However, even with the above setup, the notation \lstinline!\co{*}{\vX,coef=\vR}! will not work
-just yet. For the keys you define using \lstinline!argvaluekeys!
-are turned off by default. To turn them on for the object~\lstinline!\co!, run the following code:
-\begin{lstlisting}
-\SetupObject\co{
- valuekeys={
- {arg}{argwithkeyval={#1}},
- },
-}
-\end{lstlisting}
-The reason the keys are turned off by default is that keys in arguments that support values are only used in very rare cases, like cohomology with coefficients. If such keys were turned on in general, it would mess up
+As you see above, we had to turn keyval syntax on in order for it to work.
+By default, only singlekeys are turned on in the argument, not valuekeys.
+The reason is that valuekeys in arguments are only useful in very rare cases, like cohomology with coefficients. If such keys were turned on in general, it would mess up
every occurrence of an equality sign in arguments, and the following
would not work:
\begin{LTXexample}
@@ -1500,9 +1490,12 @@ $\Hom[\sheafreg[\vU]]{
}$
\end{LTXexample}
+The key~\lstinline!argkeyval! can take four arguments: \lstinline!true! (as above),
+\lstinline!false! (no singlekeys or valuekeys allowed), \lstinline!singlekeys! (the default behaviour where only singlekeys are turned on), and \lstinline!onesinglekey! (only allows one singlekey).
+
It should be noted that there are several predefined
-keys (of type \mbox{\lstinline!singlekey!)} which are defined on the level
-of the class \lstinline!\SemantexVariable!. The full list is:\fxfatal{Finish this}
+singlekeys which are defined on the level
+of the class \lstinline!\SemantexBaseObject!. The full list is:\fxfatal{Finish this}
\begin{itemize}
\item slot, \ldots
@@ -1677,6 +1670,9 @@ class types:
Let me add that \semantex uses a very clear separation between the input syntax and the underlying machinery. Because of this, if the user needs a different kind of class type, it is not very hard to create one. You must simply open the source code of \semantex, find the class you want to modify, and then copy the definition of the command~\lstinline!\New⟨Class type⟩Class! and modify it in whatever way you want.
+There is another class type, called the \lstinline!plain! class type, which is the class
+type of the class~\lstinline!\SemantexBaseObject!. This class is pretty useless as all it does is print its symbol, without allowing any keyval syntax, so don't use it.
+
\chapter{The \texorpdfstring{\texttt{Delimiter}}{Delimiter} class type}
\NewDelimiterClass\MyDelim[parent=\MyVar]
@@ -1824,7 +1820,7 @@ $\int \vf \wedgeD{\vx[1],
\chapter{The \texttt{parse} routine}
-As you can see above, \semantex has a ``waterfall-like'' behaviour. It runs keys in the order it receives them. This works fine most of the time, but for some more complicated constructions, it is useful to be able to provide a data set in any order and have them printed in a fixed order. For this purpose, we have the \lstinline!parse! routine.
+As you can see above, \semantex has a \enquote{waterfall-like} behaviour. It runs keys in the order it receives them. This works fine most of the time, but for some more complicated constructions, it is useful to be able to provide a data set in any order and have them printed in a fixed order. For this purpose, we have the \lstinline!parse! routine.
@@ -1834,98 +1830,130 @@ Suppose we want to be able to write the set of \( \vn \times \vm \)-matrices wit
\operatorname{Mat}}
$ \Mat[\vn\times\vm]{\vk} $.
\end{LTXexample}\endgroup%
-\noindent However, this is not quite as systematic and semantic as we might have wanted. Indeed, what if later you would like to change the notation to~\( \MyVar{\operatorname{Mat}}[\vn,\vm]{\vk} \)?
-Therefore, we do something like the following instead (we explain the notation below):
-\begin{lstlisting}
\NewObject\MyVar\Mat{\operatorname{Mat}}[
- execute={
- \SemantexDataProvide{rows}
- \SemantexDataProvide{columns}
- % provides data sets for number of rows and columns
- % for this object
- },
+ % We provide data sets "rows" and "columns" to
+ % be set up by the user later
+ dataprovide={rows},
+ dataprovide={columns},
valuekeys={
- {rows}{
- execute={
- \SemantexDataSet{rows}{#1}
+ {rows}{ dataset={rows}{#1} }, % set the rows data set
+ {columns}{ dataset={columns}{#1} }, % set the columns data set
+ },
+ parseoptions={ % Here we add code to the parse routine
+ % We check whether columns = rows. If so, we only write
+ % the number once
+ ifeqTF={\SemantexDataGetExpNot{columns}}{\SemantexDataGetExpNot{rows}}
+ {
+ % We use a very weird key called "setkeysx" -- this
+ % fully executes the content of the keys before
+ % setting them
+ setkeysx={
+ lower={\SemantexDataGetExpNot{columns}},
},
- },
- {columns}{
- execute={
- \SemantexDataSet{columns}{#1}
+ }
+ {
+ setkeysx={
+ lower={
+ \SemantexDataGetExpNot{rows}
+ \times
+ \SemantexDataGetExpNot{columns}
+ },
},
},
},
- parseoptions={
- execute={
- \SemantexStrIfEqTF{\SemantexDataGetExpNot{columns}}
- {\SemantexDataGetExpNot{rows}}
- % tests if rows = columns
- {
- \SemantexKeysSetx{
- lower={
- \SemantexDataGetExpNot{columns}
- }
- }
- }
- {
- \SemantexKeysSetx{
- lower={
- \SemantexDataGetExpNot{rows}
- \times
- \SemantexDataGetExpNot{columns}
- }
- }
- }
- },
- },
-]
-\end{lstlisting}%
+]%
+\noindent However, this is not quite as systematic and semantic as we might have wanted. Indeed, what if later you would like to change the notation to~\( \MyVar{\operatorname{Mat}}[\vn,\vm]{\vk} \)? (In this case, you could use multi-value keys, though.)
+In this chapter, we show how to eanble a syntax like the following instead:
+\begin{LTXexample}
+$ \Mat[rows=\vn,columns=\vm]{\vk} $, $ \Mat[rows=\vn,columns=\vn]{\vk} $
+\end{LTXexample}
+
+The important ingredient here is the \lstinline!parse! routine. This routine is executed right before the function is being rendered, and you can add code to it via the
+key~\lstinline!parseoptions!. However, we need a bit more programming keys to make it work. Let us see it in action and explain the syntax below:
+\begin{lstlisting}
\NewObject\MyVar\Mat{\operatorname{Mat}}[
- execute={
- \SemantexDataProvide{rows}
- \SemantexDataProvide{columns}
- },
+ % We provide data sets "rows" and "columns" to
+ % be set up by the user later
+ dataprovide={rows},
+ dataprovide={columns},
valuekeys={
- {rows}{
- execute={
- \SemantexDataSet{rows}{#1}
+ {rows}{ dataset={rows}{#1} }, % set the rows data set
+ {columns}{ dataset={columns}{#1} }, % set the columns data set
+ },
+ parseoptions={ % Here we add code to the parse routine
+ % We check whether columns = rows. If so, we only write
+ % the number once
+ ifeqTF={\SemantexDataGetExpNot{columns}}
+ {\SemantexDataGetExpNot{rows}}
+ {
+ % We use a very weird key called "setkeysx" -- this
+ % fully executes the content of the keys before
+ % setting them
+ setkeysx={
+ lower={\SemantexDataGetExpNot{columns}},
},
- },
- {columns}{
- execute={
- \SemantexDataSet{columns}{#1}
+ }
+ {
+ setkeysx={
+ lower={
+ \SemantexDataGetExpNot{rows}
+ \times
+ \SemantexDataGetExpNot{columns}
+ },
},
},
},
- parseoptions={
- execute={
- \SemantexStrIfEqTF{\SemantexDataGetExpNot{columns}}{\SemantexDataGetExpNot{rows}}
- {
- \SemantexKeysSetx{
- lower={
- \SemantexDataGetExpNot{columns}
- }
- }
- }
- {
- \SemantexKeysSetx{
- lower={
- \SemantexDataGetExpNot{rows}
- \times
- \SemantexDataGetExpNot{columns}
- }
- }
- }
- },
- },
-]%
-Now we can do the following:
-\begin{LTXexample}
-$ \Mat[rows=\vn,columns=\vm]{\vk} $, $ \Mat[rows=\vn,columns=\vn]{\vk} $
-\end{LTXexample}
+]
+\end{lstlisting}
+
+Here we used a lot of programmking keys. Let us see the full list of them.
+(An important notice: For some of these keys, such as \lstinline!boolifTF!, you currently cannot use spaces in the \lstinline!⟨bool⟩! argument, so e.g. \lstinline!boolifTF{ mybool } { ... } { ... }! will not work; you have to write \lstinline!boolifTF{mybool}!. I am trying to solve this problem, but have not yet been able to do so.)
+
+\begin{lstlisting}
+dataprovide={⟨data⟩}, % provides data
+dataset={⟨data⟩}{⟨value⟩}, % sets data
+datasetx={⟨data⟩}{⟨value⟩}, % sets data after expanding it
+dataputright={⟨data⟩}{⟨value⟩}, % adds to the right of data
+dataputrightx={⟨data⟩}{⟨value⟩}, % adds to the right of data after expanding it
+dataputleft={⟨data⟩}{⟨value⟩}, % adds to the left of data
+dataputleftx={⟨data⟩}{⟨value⟩}, % adds to the left of data after expanding it
+dataclear={⟨data⟩,} % clears a piece of data
+setkeys={⟨keys⟩}, % sets the keys in question, which is rather useless since you could have just written those keys directly instead
+keysset={⟨keys⟩}, % equivalent to setkeys
+setkeysx={⟨keys⟩}, % executes the keys in question after expanding them
+keysset={⟨keys⟩}, % equivalent to setkeysx
+ifeqTF={⟨str1⟩}{⟨str2⟩}{⟨if true⟩}{⟨if false⟩}, % checks if strings are equal
+ifeqT={⟨str1⟩}{⟨str2⟩}{⟨if true⟩},
+ifeqF={⟨str1⟩}{⟨str2⟩}{⟨if false⟩},
+ifblankTF={⟨str⟩}{⟨if true⟩}{⟨if false⟩}, % checks if string is blank
+ifblankT={⟨str⟩}{⟨if true⟩},
+ifblankF={⟨str⟩}{⟨if false⟩},
+boolprovide={⟨bool⟩}, % provides a boolean
+boolsettrue={⟨bool⟩}, % sets the boolean to true
+boolsetfalse={⟨bool⟩}, % sets the boolean to false
+boolifTF={⟨bool⟩}{⟨if true⟩}{⟨if false⟩}, % checks if boolean is true
+boolifT={⟨bool⟩}{⟨if true⟩},
+boolifF={⟨bool⟩}{⟨if false⟩,
+intprovide={⟨int⟩}, % provides an integer
+intclear={⟨int⟩}, % sets the integer to 0
+intincr={⟨int⟩}, % adds 1 to the integer
+intset={⟨int⟩}{⟨value⟩}, % sts the integer
+intifgreaterthanTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks which number of greater
+intifgreaterthanT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intifgreaterthanF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+intifequalTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks if the numbers are equal
+intifequalT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intifequalF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+intiflessthanTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks which number of less
+intiflessthanT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intiflessthanF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+ERRORkeyvaluenotfound={⟨key⟩}{⟨value⟩}, % throws an error saying that the key has been set to an unkonwn value
+ERROR={⟨error text⟩}, % throws a general error with the provided error test
+execute={⟨error text⟩}, % executes the code in question
+\end{lstlisting}
+
+When using these keys (including inside the key~\lstinline!execute!), you can use a number of commands that provide and manipulate data. Most of them are just command versions of the keys above, and for now, I leave it to the reader to guess what they do based on the above picture:
-The key~\lstinline!execute! is a key that basically just executes code. You can in principle write any \TeX\ code there, and it will be applied right at the spot. However, inside the \lstinline!execute!~key, you can also use the following locally defined commands. These can be used to handle the data that is associated with the object in question. I don't have time to document them right now, so you'll have to guess what they do from the name for now, or you can find their definition in the source code of the package.
\begin{lstlisting}
\SemantexDataProvide
\SemantexDataSet
@@ -1956,88 +1984,110 @@ The key~\lstinline!execute! is a key that basically just executes code. You can
\SemantexIntClear
\SemantexIntIncr
\SemantexIntSet
-\SemantexIntIfPositiveTF
-\SemantexIntIfPositiveT
-\SemantexIntIfPositiveF
-\SemantexIntIfGreaterThanOneTF
-\SemantexIntIfGreaterThanOneT
-\SemantexIntIfGreaterThanOneF
-\SemantexExpNot
+\SemantexIntIfGreaterThanTF
+\SemantexIntIfGreaterThanT
+\SemantexIntIfGreaterThanF
+\SemantexIntIfEqualTF
+\SemantexIntIfEqualT
+\SemantexIntIfEqualF
+\SemantexIntIfLessThanTF
+\SemantexIntIfLessThanT
+\SemantexIntIfLessThanF
+\SemantexExpNot##1
+\SemantexERRORKeyValueNotFound
+\SemantexERROR
\end{lstlisting}
-The key~\lstinline!parseoptions! is a key that is executed right before rendering the object. This is where you write whatever the system is supposed to \emph{do} with the data sets you provide. You can also force it to be applied at any point by using the \lstinline!parse!~key.
-
Let us look at a more complicated example: Let us create a command for partial derivatives:
\NewObject\MyVar\partialdif[
nopar,
- execute={
- \SemantexBoolProvide{raisedfunction}
- \SemantexBoolSetTrue{raisedfunction}
- },
+ boolprovide={raisefunction},
+ boolsettrue={raisefunction},
setidots=\cdots,
setisep=\,,
valuekeys={
{default}{
si={\partial #1},
},
- },
- singlekeys={
- {raisedfunction}{
- execute={
- \SemantexBoolSetTrue{raisedfunction}
- },
- },
- {noraisedfunction}{
- execute={
- \SemantexBoolSetFalse{raisedfunction}
+ {raise}{
+ ifeqTF={#1}{true}
+ {
+ boolsettrue={raisefunction},
+ }
+ {
+ ifeqTF={#1}{false}
+ {
+ boolsetfalse={raisefunction},
+ }
+ {
+ ERRORkeyvaluenotfound={raise}{#1},
+ },
},
},
},
parseoptions={
- execute={
- \SemantexIfBlankTF{ \SemantexDataGet{upper} }
+ ifblankTF={ \SemantexDataGet{upper} }
+ {
+ intifgreaterthanTF={ \SemantexIntGet{numberoflowerindices} } { 1 }
{
- \SemantexKeysSetx{
+ setkeysx={
symbol={
\frac
{
\partial ^ { \SemantexIntGet{numberoflowerindices} }
- \SemantexBoolIfT{raisedfunction}
+ \SemantexBoolIfT{raisefunction}
{
- \SemantexDataGetExpNot{arg}
+ \SemantexDataGet{arg}
}
}
{
- \SemantexDataGetExpNot{lower}
+ \SemantexDataGet{lower}
}
},
- }
+ },
}
{
- \SemantexKeysSetx{
+ setkeysx={
symbol={
\frac
{
- \partial ^ { \SemantexDataGet{upper} }
- \SemantexBoolIfT{raisedfunction}
+ \partial
+ \SemantexBoolIfT{raisefunction}
{
- \SemantexDataGetExpNot{arg}
+ \SemantexDataGet{arg}
}
}
{
- \SemantexDataGetExpNot{lower}
+ \SemantexDataGet{lower}
}
},
}
- }
- \SemantexDataClear{lower}
- \SemantexDataClear{upper}
- \SemantexBoolIfT{raisedfunction}
- {
- \SemantexDataClear{arg}
- \SemantexIntClear{numberofarguments}
- }
+ },
+ }
+ {
+ setkeysx={
+ symbol={
+ \frac
+ {
+ \partial ^ { \SemantexDataGet{upper} }
+ \SemantexBoolIfT{raisefunction}
+ {
+ \SemantexDataGet{arg}
+ }
+ }
+ {
+ \SemantexDataGet{lower}
+ }
+ },
+ },
+ },
+ dataclear={lower},
+ dataclear={upper},
+ boolifT={raisefunction}
+ {
+ dataclear={arg},
+ dataclear={numberofarguments},
},
},
]
@@ -2045,73 +2095,92 @@ Let us look at a more complicated example: Let us create a command for partial d
\begin{lstlisting}
\NewObject\MyVar\partialdif[
nopar,
- execute={
- \SemantexBoolProvide{raisedfunction}
- \SemantexBoolSetTrue{raisedfunction}
- },
+ boolprovide={raisefunction},
+ boolsettrue={raisefunction},
setidots=\cdots,
setisep=\,,
valuekeys={
{default}{
si={\partial #1},
},
- },
- singlekeys={
- {raisedfunction}{
- execute={
- \SemantexBoolSetTrue{raisedfunction}
- },
- },
- {noraisedfunction}{
- execute={
- \SemantexBoolSetFalse{raisedfunction}
+ {raise}{
+ ifeqTF={#1}{true}
+ {
+ boolsettrue={raisefunction},
+ }
+ {
+ ifeqTF={#1}{false}
+ {
+ boolsetfalse={raisefunction},
+ }
+ {
+ ERRORkeyvaluenotfound={raise}{#1},
+ },
},
},
},
parseoptions={
- execute={
- \SemantexIfBlankTF{ \SemantexDataGet{upper} }
+ ifblankTF={ \SemantexDataGet{upper} }
+ {
+ intifgreaterthanTF={ \SemantexIntGet{numberoflowerindices} } { 1 }
{
- \SemantexKeysSetx{
+ setkeysx={
symbol={
\frac
{
\partial ^ { \SemantexIntGet{numberoflowerindices} }
- \SemantexBoolIfT{raisedfunction}
+ \SemantexBoolIfT{raisefunction}
{
- \SemantexDataGetExpNot{arg}
+ \SemantexDataGet{arg}
}
}
{
- \SemantexDataGetExpNot{lower}
+ \SemantexDataGet{lower}
}
},
- }
+ },
}
{
- \SemantexKeysSetx{
+ setkeysx={
symbol={
\frac
{
- \partial ^ { \SemantexDataGet{upper} }
- \SemantexBoolIfT{raisedfunction}
+ \partial
+ \SemantexBoolIfT{raisefunction}
{
- \SemantexDataGetExpNot{arg}
+ \SemantexDataGet{arg}
}
}
{
- \SemantexDataGetExpNot{lower}
+ \SemantexDataGet{lower}
}
},
}
- }
- \SemantexDataClear{lower}
- \SemantexDataClear{upper}
- \SemantexBoolIfT{raisedfunction}
- {
- \SemantexDataClear{arg}
- \SemantexIntClear{numberofarguments}
- }
+ },
+ }
+ {
+ setkeysx={
+ symbol={
+ \frac
+ {
+ \partial ^ { \SemantexDataGet{upper} }
+ \SemantexBoolIfT{raisefunction}
+ {
+ \SemantexDataGet{arg}
+ }
+ }
+ {
+ \SemantexDataGet{lower}
+ }
+ },
+ },
+ },
+ dataclear={lower},
+ dataclear={upper},
+ boolifT={raisefunction}
+ {
+ dataclear={arg},
+ dataclear={numberofarguments},
},
},
]
@@ -2128,13 +2197,13 @@ Let us see it in action:
d=\vn]{ \vf }
\]
\[
- \partialdif[\vx,\vy,\vz,noraisedfunction]{ \vf } ,
+ \partialdif[\vx,\vy,\vz,raise=false]{ \vf } ,
\partialdif[\vu^2,\vv^2,
- d=4,noraisedfunction]{
+ d=4,raise=false]{
\vf },
\partialdif[\vx[1],
\vx[2],...,\vx[\vn],
- d=\vn,noraisedfunction]{
+ d=\vn,raise=false]{
\vf }
\]
\end{LTXexample}
@@ -2151,7 +2220,10 @@ As you see, we use the \lstinline!d!~key to tell the command what superscript it
\chapter{Bugs}
-Lots of things can be improved in the system, including the order in which things are being expanded internally. I am not going to explain this is detail for now, but hope to correct this in the future. For now, the system seems to work fine as long as you do \enquote{normal} things and insert~\lstinline!\noexpand!'s whenever something goes wrong. The only real bug that I currently know of occurs if you use the key~\lstinline!Otherspar! in a heading. Then it all dies painfully.
+The biggest unsolved problem I know of is how to correctly strip spaces in programming keys such as \lstinline!boolifTF!. Similarly, I would also like to allow keys to be defined using the
+syntax~\lstinline!{ inv } { upper=-1 }! rather than~\lstinline!{inv}{ upper=-1 }!. This will hopefully be solved soon.
+
+For now, the system seems to work fine as long as you do \enquote{normal} things. The only real bug that I currently know of occurs if you use the key~\lstinline!Otherspar! in a heading. Then it all dies painfully.
Then again, why the heck would you do that in the first place? Who scales parentheses in headings?
%\input{testground}