diff options
author | Karl Berry <karl@freefriends.org> | 2010-06-18 15:57:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-06-18 15:57:20 +0000 |
commit | e7c3e209e8f797c9f89a7e454e260716220ce832 (patch) | |
tree | 4bdee0039f081333dd0e0d548bb565095070b602 | |
parent | 6a610c4ffff82f7e5188bd0154b7859244e02447 (diff) |
new generic package yax (17jun10)
git-svn-id: svn://tug.org/texlive/trunk@19036 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/generic/yax/README | 25 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/yax/yax-doc.pdf | bin | 0 -> 118088 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/yax/yax-doc.tex | 894 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/yax/t-yax.tex | 24 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/yax/yax.sty | 14 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/yax/yax.tex | 535 | ||||
-rwxr-xr-x | Master/tlpkg/libexec/ctan2tds | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-genericextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/yax.tlpsrc | 0 |
9 files changed, 1494 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/generic/yax/README b/Master/texmf-dist/doc/generic/yax/README new file mode 100644 index 00000000000..21040a05a00 --- /dev/null +++ b/Master/texmf-dist/doc/generic/yax/README @@ -0,0 +1,25 @@ +This is the README file for the YaX package. +Author: Paul Isambert. +E-mail: zappathustra AT free DOT fr +Comments and suggestions are welcome. +Date: June 2010. + +The package is a format-independent key system, +with some peculiarities. +It is format-independent and based on texapi +(and thus requires e-TeX at least). +Relevant information can be found in yax-doc.pdf + +Files in this distributions: + +yax.tex => The bulk of the code. +t-yax.tex => A wrapper file for ConTeXt. +yax.sty => A wrapper file for LaTeX. +yax-doc.tex => The source of the documentation. +yax-doc.pdf => The typeset documentation. + +To process the documentation source, you need the +piTeX files (available on CTAN) on top of plain TeX +with LuaTeX at least v.0.6. Non-free fonts are used. + +Licensing of this package is covered by LPPL.
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/yax/yax-doc.pdf b/Master/texmf-dist/doc/generic/yax/yax-doc.pdf Binary files differnew file mode 100644 index 00000000000..23eef84a30c --- /dev/null +++ b/Master/texmf-dist/doc/generic/yax/yax-doc.pdf diff --git a/Master/texmf-dist/doc/generic/yax/yax-doc.tex b/Master/texmf-dist/doc/generic/yax/yax-doc.tex new file mode 100644 index 00000000000..45ce047d1ee --- /dev/null +++ b/Master/texmf-dist/doc/generic/yax/yax-doc.tex @@ -0,0 +1,894 @@ +\input pitex % which \input's YaX + +\setparameter document: + author = "Paul Isambert" + title = \yax + pdftitle = YaX + version = 1.0 + date = "\the\month/\the\day/\the\year" + display = outlines + subject = "The YaX documentation." + +\setparameter page: + left = 5cm + right = 3cm + pageheight = 26cm + +\setparameter font : + command = \mainfont + name = ChaparralPro- + roman = Regular + italic = Italic + bold = Bold + +\setparameter font : + command = \sectionfont + size = 13pt + name = ChaparralPro- + roman = Regular + italic = Italic + +\setparameter font : + command = \titlefont + size = 26pt + name = ChaparralPro- + roman = Regular + +\setparameter font: + command = \codefont + name = ltype + size = 8.1pt + type = ttf + roman = {} + bold = b + italic = o + features = "\usevalue metafont:features -trep;" + +\setparameter section: + font = \sectionfont + number = none + color = ".8 0 0" + +\def\yax{% + Y\kern-.1em \raise.15em\hbox{\sc a}\kern-.1em \lower.15em\hbox{X}% + \ifcatnext a { }{\iffnext({ }}% + } +\def\defarg#1#2{% + \def#1{\arg{#2}\kern1pt\antigobblespace}% + } +\defarg\param{parameter} \defarg\paralist{list of parameters} +\defarg\attr{attribute} \def\paramatt{\param\kern-1pt\tcode:\attr\antigobblespace} +\defarg\attrlist{list of attributes} \defarg\vallist{list of values} +\defarg\value{value} \defarg\ospace{optional space} +\defarg\andvalue{value exists} \defarg\orvalue{no value} +\defarg\true{true} \defarg\false{false} +\defarg\codarg{code} \defarg\comarg{command} +\def\describe{% + \ifnext!{\gobbleoneand{\let\COM\ecom\Describe}} + {\let\COM\com\Describe}% + } +\def\ecom#1{{\mainfont\char"E01F}\com{#1}} +\long\def\Describe#1#2.{% + \ifvmode \vskip\baselineskip \fi + \noindent\llap{\color{.8 0 0}{\COM#1}\iffemptystring{#2}{\kern1em}}#2% + \reverse\iffemptystring{#2}{\par\noindent}\ignorespaces + } + +\newblock*\syntax{\vskip\baselineskip\codefont\setcatcodes{\^^M=13}\obeylines} + {\vskip\baselineskip} +\extraboxspace=10pt + +\newbox\codebox +\newbox\processbox +\newdimen\prevcodedepth +\def\processexample{% + \setbox\codebox=\vtop{% + \let\exampleskip\relax + \parindent0pt + \hsize.75\hsize + \typesetexample + \par + \global\prevcodedepth=\prevdepth + }% + \setbox\processbox=\vtop{% + \parindent0pt + \hsize.5\hsize + \doexample + }% + \exampleskip\exampleskip + \moveleft .25\hsize\hbox{\colorbox{.9 .9 .9}{\copy\codebox\copy\processbox}}% + \exampleskip\exampleskip + \prevdepth=\prevcodedepth + } + + +\output{% + \shipout\vbox to\dimexpr(\vsize+3\baselineskip){% + \box255 + \vfil + \hbox to\hsize{\mainfont\hfil\the\pageno\hfil}% + } + \advancepageno + } + + + +\vbox to 2\baselineskip{% + \vfil + \hbox to\hsize{\hfil\titlefont \usevalue document : title } + \vfil} + +\vskip\baselineskip +\it +\hfill \usevalue document : author \par +\hfill \usevalue document : date \par +\hfill v.\usevalue document : version \par + +\rm + +\vskip2\baselineskip + + +\noindent\yax is Yet Another Key System, or \yax Ain't Keys, however you want it. +It has some peculiarities. First, keys are not keys, but attributes, +which means they depend on a parameter. You don't set key individually +in \yax (although you can do it), you define parameters, which have +attributes, which have values. Second, parameters can have definitions, +so that when you set it you can also execute a command, or execute it +later; thus, \yax is halfway between key management and macro definition. +Finally, the syntax of \yax is not traditional: there are as few braces +as possible, which you can find tremendously annoying, but it can be +changed. + +And, of course, \yax is format-independant. Files are provided for +La\TeX\ and Con\TeX t, so you can input it with \verb/\usepackage{yax}/ +or \verb/\usemodule[yax]/ respectively; anywhere else just use \verb/\input yax/. + + + + +\section{Setting parameters} + +\noindent Here's an example of how values are set: + +\example +\setparameter Zappa : + firstname = Frank + motto = "Music is the best" + hairstyle = \moustache +\example/ + +\noindent Here we have defined a \ital{parameter}, `\verb/Zappa/', which +has \ital{attributes} `\verb/firstname/', `\verb/motto/' and `\verb/hairstyle/' +with \ital{values} `\verb/Frank/', `\verb/Music is the best/' and `\verb/\moustache/' +respectively. + +\describe\setparameter. +Here's how you set parameters more precisely. This command is the only way to set values. +Its simplified syntax is as follows: + +\syntax +\noindent\com\setparameter \paralist\ : + \attr\ = \value + \attr\ = \value + ... +\noindent\com\par +\syntax/ + +\noindent First, the \com\par command that terminates the declaration: +it was not chosen simply because it echoes \ital{parameter}, but above +all because it can be implicit in a blank line, i.e. \com\setparameter +can be delimited by a blank line. That's why in the first example there +seemed to be nothing delimitating \com\setparameter: it is supposed to +be followed by a blank line. I will regularly display parameter setting in this +fashion, even though the following would be equally legitimate: + +\example +\setparameter Zappa : firstname = Frank ... \par +\example/ + +\noindent barring readibility, obviously. + +As for the detail, \paralist is a list of space-delimited parameters, +followed by a colon. Any space before the colon is removed, that's why + +\example +\setparameter Zappa Boulez: ... \par +\setparameter Zappa Boulez : ... \par +\example/ + +\noindent set the attributes of the same \verb/Zappa/ and \verb/Boulez/ parameters. +Which means, of course, that you can set the attributes of as many parameters +as you wish by doing so. + +The name of each parameter should be fully expandable. It can contain spaces, +but then it should be enclosed between braces, since space delimits parameters +in \paralist. + +Finally, you can use \com\setparameter several times on the same parameter(s), +by default it does the same thing as using one big \com\setparameter. I say +\ital{by default}, because things might occur between the two calls, e.g. the +parameter might be active and have deleted its own attributes after the first +call, which anyway is something we'll see later. + +Each \attr is made of the same thing as \param: i.e. anything expandable. +However, an \attr cannot have a name beginning with the strings \verb/e:/, +\verb/g:/ and \verb/x:/. Indeed, these prefixes are used to specify +how an attribute is to be defined, and they are similar to \com\edef, +\com\gdef and \com\xdef (with no prefix meaning \com\def), i.e.: + +\example +\setparameter foo : + one = \whatever + e: two = \whatever + g: three = \whatever + x: four = \whatever +\example/ + +\noindent defines, for the parameter \verb/foo/, the attributes \verb/one/ +and \verb/three/ as \com\whatever and the attributes \verb/two/ and \verb/four/ +as the full expansion of \com\whatever; moreover, \verb/one/ and \verb/two/ +are locally defined, whereas \verb/three/ and \verb/four/ are globally +defined. The space between the prefix and the name of the parameter is +optional. + +Finally, \value may be given in three ways. First, it can be delimited by +a space, e.g.: + +\example +\setparameter Zappa : + first name = Frank + motto = {Music is the best} + ... +\example/ + +\noindent here the space is simply the end of the line. The spaces in +\verb/Music is the best/ aren't seen, because of the braces (which will +be removed from the value). Don't forget that control sequences eats +the subsequent space, hence a control sequence can't be at the end of +a value supposedly delimited by space without braces. Actually, it can't be at +the beginning either (see below). + +Otherwise, \arg{value} can be given between double quotes: + +\example +\setparameter Zappa : + first name = "Frank" + motto = "Music is the best" + hairstyle = "\mustache" +\example/ + +\noindent which basically act as braces. The space inserted here by the +end of the line is optional and the following can be done: + +\example +\setparameter Zappa:first name="Frank"motto="Music is the best"...\par +\example/ + +\noindent Finally, there's a special rule. Control sequences gobble the +next space, but a \value can be made of one and only one control sequence, +e.g.: + +\example +\setparameter Zappa : + hairstyle = \mustache + ... +\example/ + +\noindent i.e. if \yax sees a control sequence at the beginning of a value +it will take this control sequence only as \arg{value}, which means that +anything thereafter will be considered as belonging to the next \param +name. Hence, all the following are bad ideas: + +\example +\setparameter bad values : + % the space stops the value to "bad" + one = bad space + % the control sequence is taken as the only token + two = \control sequence + % "\sequence" eats the delimitating space + three = control\sequence +... +\example/ + +\noindent but they'd all be ok with quotes or braces (which +still require a space after): + +\example +\setparameter good values : + one = "bad space" + two = "\control sequence" + three = {control\sequence} + four = \LonelyCommand + five = "\Command\Command" +... +\example/ + +\noindent Finally, they are some exceptions to this rule: first, +always put \com\par between braces, otherwise it will be seen +as the end of the parameter. Second, always put a character denotation +between either braces or quotes, even if it's the only control sequence. +If you don't know what character denotation means, never mind. Just remember +that \com\bgroup and \com\egroup are character denotations. + +Now I'm sure you ask: what is this lousy syntax? An answer is I don't +like braces. Another answer is \yax is not designed to store complicated +strings, although it can do it. Instead it aims at setting simple values +in an orderly fasion, e.g.: + +\example +\setparameter page : + pagewidth = 32cm + pageheight = 30cm + lines = 45 + whatever = \foo +... +\example/ + +\noindent in which case it is very handy, especially when you're in a hurry: + +\example +\setparameter page: pagewidth=32cm pageheight=30cm whatever=\foo...\par +\example/ + +\noindent Thus, I find commas to delimit values equally superfluous and find +the odd quote better. Anyway setting parameters is far from the whole story. + + + + + + + +\sectioncommand{section}{The meta attribute}{The \ital{meta} attribute} +\noindent You can give any attribute to any parameter (unless they're restricted, +but that's not the point for the time being). +However, there's one particular attribute which has a special meaning: \verb/meta/. +The value of \verb/meta/ should be another parameter. Then, when querying +the value of an attribute, say \verb/attr/, for a given parameter, say \verb/param/, +\yax will do the following: if \verb/param/ has \verb/attr/, it is returned. +Otherwise, if \verb/param/ has a \verb/meta/ attribute, whose value is for instance +\verb/metaparam/, then \verb/attr/ is queried for the value of \verb/metaparam/. +And if \verb/metaparam/ has no \verb/attr/ but has a \verb/meta/ attribute, +this process continues, until either a parameter is found with \verb/attr/ +or there are no new \verb/meta/. For instance: + +\example +\setparameter A : attr = value ... \par +\setparameter B : meta = A ... \par +\setparameter C : meta = B ... \par +\example/ + +\noindent If parameter \verb/C/ has no \verb/attr/, then it retrieves it +from parameter \verb/A/ via \verb/B/ (or from \verb/B/ if it has one). On +the other hand, if \verb/C/ has \verb/attr/, then its own value is returned. +You can also query the value of an attribute for a parameter and forbid the +search for \verb/meta/'s, as explained in the next section. + +Don't be afraid to create loop with \verb/meta/. The following is perfectly +legitimate: + +\example +\setparameter A : meta = C ... \par +\setparameter B : meta = A ... \par +\setparameter C : meta = B ... \par +\example/ + +\noindent and it can even be useful. \yax detects loops when searching +\verb/meta/ paths and stops in time (with no value, obviously). Finally, +you can set \verb/meta/ to a parameter that doesn't exist. It will simply +return no value. + +The use of \verb/meta/ is useful to create families +of parameters and/or to set default values, e.g.: + +\example +\setparameter mammal : + egg = no + fur = yes + ... +\setparameter cat whale : + meta = mammal + ... +\setparameter cat : \setparameter whale : + foot = clawed fur = no + tooth = fang foot = flipper + ... tooth = baleen + ... +\setparameter tiger mykitty : + meta = cat + stripped = yes + ... +\setparameter tiger : \setparameter mykitty : + foot = "very bad news" foot = "bad news" + ... ... +\example/ + +Apart from that, \verb/meta/ behaves as any other attribute, i.e. it can +be freely set and queried. + + + + + + + + +\section{Using values} + +\noindent Once attributes have been set, they can be queried by the macros +that follow. But first, one last bit of odd syntax: \paramatt means anything +up to the colon as the \param and then anything up to the next space as +the \attr. That's the reason why space in attribute names is a bad idea: +the space is the main delimitator when using attributes. It is gobbled +in the process. On the other hand, +any space surrounding the colon is removed, so that `\verb/zappa:hairstyle/ ' +and `\verb/zappa : hairstyle/ ' denote the same attribute of the same parameter. +Good news, though: if you don't like that syntax, the next section explains +how to create commands with the same meaning but a different syntax. + +In what follows, fully expandable commands are marked with \color{.8 0 0}{\char"E01F}. + +\describe!\nometa\arg{command}. +All the commands that follow can be prefixed with \com\nometa, except +\com\deleteattribute. In this case, +\yax will return the value of the attribute for the specified parameter, +as usual, or return no value, i.e. it will not search \verb/meta/ parameters. +So, in what follows, `\paramatt is defined' means two things. If \com\nometa +isn't used, it means that \param has \attr or it has a metaparameter with +\attr; on the other hand, if \com\nometa is used, it means that \param has +\attr, end of story. + +\describe!\ifattribute\paramatt\true\false. +This returns \true if \paramatt is defined, \false otherwise. Since all +commands below always check whether \paramatt is defined before trying +to do anything with the value, this command can be avoided most of the +time. + +\setparameter musician : + job = music + +\setparameter Zappa : + meta = musician + firstname = Frank + + +\Example +\setparameter musician : job = music\par +\setparameter Zappa : + meta = musician + firstname = Frank + + % See this space? +\ifattribute Zappa : job {Good, it is.}{...}\par +\nometa\ifattribute Zappa : job {...}{Too bad.} +\Example/ + + + + + +\describe!\usevalue\paramatt. +\describe!\usevalueor\paramatt\orvalue. +\describe!\usevalueand\paramatt\andvalue\orvalue. +The first macro returns the value of \paramatt if it exists, or +does nothing otherwise. Like all the \verb/-or/ and \verb/-and/ +variants below, \com\usevalueor executes \orvalue in case +\paramatt doesn't exist, while \com\usevalueand returns +the value of \paramatt immediately followed by \andvalue +(no brace added) if \paramatt exists, otherwise it executes +\orvalue. + +\Example +Zappa's job was \usevalueand Zappa : job + { (and then some!)} + {unknown} +and he played the \usevalueor Zappa : instrument + {guitar}. +\Example/ + + +\describe!\passvalue\codarg\paramatt. +\describe!\passvalueor\codarg\paramatt\orvalue. +\describe!\passvalueand\codarg\paramatt\andvalue\orvalue. +These return \codarg\barg{value} if \paramatt is defined, +with the \verb/-or/ and \verb/-and/ variants as above. + +\Example +\def\whichwas#1{(which was #1)} +Zappa's job \passvalue\whichwas Zappa : job \ took +most of his time, because it's a time-consuming +occupation \nometa\passvalueor\whichwas Zappa : job + {(you know which)}. +\Example/ + +\describe!\passvaluenobraces\codarg\paramatt. +\describe!\passvaluenobracesor\codarg\paramatt\orvalue. +\describe!\passvaluenobracesand\codarg\paramatt\andvalue\orvalue. +These are the same as \com\passvalue and variants except the +value of the attribute is concatenated to \codarg without braces +(which means that no braces are added in the process, not that +braces are removed from the value if it has any). + +\describe\settovalue\arg{dimen or count}\paramatt. +\describe\settovalueor\arg{dimen or count}\paramatt\orvalue. +\describe\settovalueand\arg{dimen or count}\paramatt\andvalue\orvalue. +This sets the first argument to the value of \paramatt if it exists. +If the first argument is more than one token (e.g. \verb/\count0/ +vs. \verb/\parindent/), it must be surrounded by braces; and actually +it can even be something like \verb/\advance\count0/. Of course +\arg{dimen or count} must be a dimension or a count, and the value +of \paramatt must be accordingly a dimension +or a number (\yax doesn't check either of them). + +\Example +\setparameter para : parskip = 2pt \par +Note that +\settovalueor\parskip para : parskip + {\parskip=1pt\relax} +(\the\parskip) is basically the same thing as +\parskip=\usevalueor para : foo {1pt\relax} +(\the\parskip). +\Example/ + +What the previous example shows is that since \com\usevalue +is thoroughly expandable one can say: + +\example +\mydimen=\usevalueor parameter : attribute {0pt} +\example/ + +\noindent and it will set \com\mydimen to the value +of \paramatt or to \verb/0pt/. The difference with \com\settovalueor +is that in the construction with \com\usevalueor the assignement +is obligatorily made (hence the \verb/-or/ variant), whereas +with \com\settovalueor the or-clause can do something else +(e.g. send an error message). And \com\settovalue insert a +prophylactic \com\relax. + + + + +\describe\storevalue\comarg\paramatt. +\describe\storevalueor\comarg\paramatt\orvalue. +\describe\storevalueand\comarg\paramatt\andvalue\orvalue. +These define \comarg as the value of \paramatt if it exists. + +\Example +\setparameter Zappa : hairstyle = \moustache\par +\storevalue\beard Zappa : hairstyle +\meaning\beard +\Example/ + + + +\describe!\ifvalue\paramatt=\value\ \true\false. +This returns \true if the value of \paramatt is \value +and \false otherwise (including unexisting \paramatt). +Note that when comparing the value of \paramatt with +\value, catcodes aren't part of the picture. +Here \value is delimited by the following space, but +there might be optional space after the `\verb/=/' sign. +Because of this, it is not possible to test for the +emptyness of a value with \com\ifvalue, i.e. + +\example +\ifvalue foo : bar = {} {true}{false} +\example/ + +\noindent won't work. Instead, either use \com\ifcasevalue below or \com\passvalue +with an emptyness-tester (e.g. \verb/texapi/'s +\com\ifemptystring, since \yax is based on \verb/texapi/ +(what, me, self-advertising?)). + +\Example +\bgroup \catcode`\Z=13 +\setparameter foo : + g: bar = Z \par +\egroup +\edef\foobar{% + \ifvalue foo : bar = Z {yes}{no}, + even though catcodes are different.} +\meaning\foobar +\Example/ + + + + +\describe!\ifcasevalue\paramatt. + \describe\val\value\ \codarg. + \describe\val\value\ \codarg. + \verb/.../ \par\noindent + \describe\elseval \codarg. + \describe\endval\relax. +This executes \codarg following \value matching +the value of \paramatt. If \paramatt doesn't exist, or +matches no \value, then \com\elseval is executed. Once again +catcodes aren't taken into account when values are compared. +The exact syntax is: \value is anything from \com\val to the +next space, and \codarg is anything that follows up to the next +\com\val, \com\elseval or \com\endval (any space on the right +is removed, so no need to stick \com\val to \codarg). +Apart from \com\endval, everything here is optional: there might +be as many \com\val-clauses as needed, including none, and the +\com\elseval-clause need not be present (in which case, if no +match occurs, nothing happens). Finally, although this is +similar to \TeX's primitive \com\ifcase, there's no need +to jump before anything with \com\expandafter to avoid +bumping into conditional structure. + +\Example +\def\doitalic#1{{\it#1}} +\setparameter type : font = italic \par +\ifcasevalue type : font + \val italic \doitalic + \val bold \dobold +\endval{Some text.} + +\edef\foo{% + \ifcasevalue type : font + \val bold This is bold + \elseval This is something else + \endval} +\meaning\foo +\Example/ + + +\describe\deleteattribute\paramatt. +This deletes \paramatt, which now responds negatively +to all previous commands, as if it was never defined. +If \paramatt doesn't exist, and if \param has \verb/meta/-parameters +with \attr, those are not deleted. Hence \com\nometa can't be +prefixed to \com\deleteattribute, because it doesn't make sense. + + + + + +\section{Using another syntax} + +\noindent If you don't like \yax's native syntax, and want for instance +good old braces to delimit \param and \attr, you might be tempted +to do something like: + +\example +\def\myusevalue#1#2{\usevalue #1:#2 } +\example/ + +\noindent On the other hand, if you don't mind \yax's syntax +but want other names for the commands, then you'll probably go: + +\example +\let\myusevalue\usevalue +\example/ + +\noindent Both are bad ideas. Indeed, in neither example will +\com\myusevalue work properly with \com\nometa. Besides, you +have to create the \verb/-or/ and \verb/-and/ variants by hand. +Not to mention that in the first example \com\myusevalue wastes +time calling \com\usevalue (and what if it is redefined?) when +it could be in direct relation with internal code. So here's how +to circumvent \yax's syntax and/or create new names. + +\describe\newsyntax\arg{syntax}\barg{prefix}. +This creates commands whose names are \verb/\/\arg{prefix}\comarg +and whose syntax for arguments is \arg{syntax}. The latter is +a parameter text which must contain \verb/#1/ and \verb/#2/ (for +\param and \attr respectively) with whatever to delimit them. +For instance: + +\example +\newsyntax#1#2{x} +\newsyntax#1 #2!{y} +\example/ + +\noindent will create among others an \com\xusevalue command whose usage is +\com\xusevalue\param\attr and a \com\yusevalue command whose +usage is \com\yusevalue\param\ \attr\tcode! and both will do the +same thing as \com\usevalue. There must be braces around \arg{prefix} +and none around \arg{syntax} (i.e. the latter is delimited by +the left brace of the former). If \arg{prefix} is empty, +you redefine the default commands, which is dangerous. + +To be precise, the commands copied are (omitting the \verb/-or/ +and \verb/-and/ variants, which are created too, if any): +\com\ifattribute, \com\usevalue, \com\passvalue, \com\passvaluenobraces, +\com\settovalue, \com\storevalue, \com\ifvalue, \com\ifcasevalue, +\com\deleteattribute and \com\restrictattribute (which you'll learn +about in the next section). + +\describe\copysyntax\arg{prefix1}\arg{prefix2}. +This defines all the commands above with \arg{prefix1} as +those same commands with \arg{prefix2}. + +\describe\letyaxcommand\arg{command1}\arg{command2}. +This at the very least \com\let \arg{command1} to \arg{command2}. +Besides, if \arg{command2} can take a \com\nometa prefix, +\arg{command1} can too. Finally, if \arg{command2} has +\verb/-or/ and \verb/-and/ variants, these are created with +\arg{command1}. E.g.: + +\example +\letyaxcommand\defval\storevalue +\example/ + +\noindent defines \com\defval, \com\defvalor and \com\defvaland +as \com\storevalue and its variants. If \arg{command2} has been +created with \com\newsyntax or \com\copysyntax, \arg{command1} +of course has the same syntax. + + +\Example +\newsyntax#1#2{x} +\letyaxcommand\uv\xusevalue +\uvand{noparameter}{noattribute}{yes}{no} +\Example/ + + +\section{Restrictions on parameters and attributes} + + +\describe\restrictparameter\paralist:\attrlist\tcode{\char`\\par}. +After this declaration, the \param's in \paralist (where they are separated +by space as in \com\setparameter) can take only those \attr's in +\attrlist (which are also separated by space). It affects \com\setparameter +only, producing an error message when an \attr not belonging to +\attrlist is given a value (and the assignment isn't made, of course). +Even if it doesn't belong to \attrlist, the \verb/meta/ attribute is +always allowed. Several \com\restrictparameter declarations on the +same parameter(s) actually accumulate the allowed attributes in \paralist, +e.g. after + +\example +\restrictparameter foo : one two three\par +\restrictparameter foo : four\par +\example/ + +\noindent one can set the attributes \verb/one/, \verb/two/, \verb/three/ +and \verb/four/ for \verb/foo/, and not only \verb/four/. The idea behind +\com\restrictparameter is not so much hiding attributes from the user +as making the use of a parameter clearer by indicating which attributes +are in use with it, especially if it can be executed (see below). + +\describe\restrictattribute\paramatt\ \vallist\tcode{\char`\\par}. +This restricts \paramatt to take only the values in \vallist (separated +by space). + +\describe\restrictallattributes\attr\ \vallist\tcode{\char`\\par}. +This restricts \attr, whatever the \param in which it appears, to +take only the values in \vallist. In this command, \attr is +found as anything before the first space, e.g.: + +\example +\restrictallattributes attribute value1 value2 value3\par +\restrictallattributes {attri bute} value1 value2 value3\par +\example/ + +\noindent (the second example if you want to have space in attribute +names). Note that if an attribute is restricted with both +\com\restrictattribute and \com\restrictallattributes, +only the former restriction holds. E.g.: + +\example +\restrictattribute foo:bar one\par +\restrictallattributes bar two three\par +\setparameter foo: + bar = two % Will produce an error message. + ... +\example/ + + + + +\section{Defining parameters} + +\describe\defparameter\paralist\barg{definition}. +Parameters aren't just a way of organizing attributes. They +can have a definition and act as commands whose arguments +are the values of their attributes. The \paralist (with +parameters once again separated by space) must be +braceless, whereas \arg{definition} must be enclosed in +braces (like a real definition). No parameter text is +allowed. However, \arg{definition} can contain `\verb/#1/', +which doesn't refer to any argument but to the parameter +being defined instead, so that one can use the commands +defined in the previous section without specifying the name +of the parameter. E.g. + +\example +\defparameter foo bar {% + \usevalue #1 : one + \passvalueor\mycomm #1 : whatever {...}% + ...} +\example/ + +\noindent defines \verb/foo/ and \verb/bar/ respectively +to + +\example +\usevalue foo : one +\passvalueor\mycomm foo : whatever {...}% +... +\usevalue bar : one +\passvalueor\mycomm bar : whatever {...}% +... +\example/ + +\describe!\executeparameter\param:. +This executes the definition of \param with the the latest values +of its attributes. If \param hasn't been defined, nothing happens. + +\Example +\defparameter foo {The value is \usevalue#1:bar } +\setparameter foo : bar = whatever\par +\executeparameter foo: +\Example/ + + +\describe\defactiveparameter\paralist\barg{definition}. +This does the same thing as \com\defparameter, i.e. define the +parameters in \paralist, but it also set them as `active,' +which means that they're automatically executed each time +their attributes are defined with \com\setparameter. You +can still use \com\executeparameter. + +\Example +\setparameter metasection : skip = 2 font = \it\par +\setparameter mysection : % not yet active + meta = metasection\par +\defactiveparameter mysection {% + \vskip \usevalueor #1 : skip 0\baselineskip + {\usevalue #1 : font \usevalue #1 : title }% + \par} + +And now we're going to have a new section. +\setparameter mysection : title = "A new section"\par +Fascinating. Once again? +\setparameter mysection : title = "Once again"\par +Cool. +\Example/ + +\vskip-2\baselineskip +\Example +\setparameter metasection : + skip = 2 + inline = false + font = \it + +\setparameter mysection mysubsection : + meta = metasection + +\setparameter mysection : + font = \sc + +\setparameter mysubsection : + skip = 1 + inline = true + +\defparameter mysection mysubsection {% + \vskip \usevalueor #1 : skip 0\baselineskip + {\usevalue #1 : font \usevalue #1 : title }% + \ifvalue #1 : inline = true {. \ignorespaces}% + \par}% + +\def\section#1{% + \setparameter mysection : title = {#1}\par + \executeparameter mysection :} + +\def\subsection#1{% + \setparameter mysubsection : title = {#1}\par + \executeparameter mysubsection :} + + +... and this is the end of our paragraph. +\section{New ideas} +Here we are going to expose bold new ideas. +\subsection{First bold new idea} +Lore, aim, hip, sum... what do you think about +it? Pig latin, you say? +\subsection{Second bold new idea} +Perhaps Do lore, aim... then, huh? +\section{New new ideas} +Etc. +\Example/ +\bye
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/yax/t-yax.tex b/Master/texmf-dist/tex/generic/yax/t-yax.tex new file mode 100644 index 00000000000..49d6af4a0b5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/yax/t-yax.tex @@ -0,0 +1,24 @@ +% This is t-yax.tex, a third-party file to load +% the YaX package in ConTeXt. Useful information +% can be found in yax-doc.pdf +% +% Author: Paul Isambert. +% E-mail: zappathustra AT free DOT fr +% Comments and suggestions are welcome. +% Date: June 2010. +% +%D \module +%D [ file=t-yax, +%D version=2010.06.17, +%D title=\CONTEXT\ User Module, +%D subtitle=YaX, +%D author=Paul Isambert, +%D date=\currentdate, +%D copyright=Paul Isambert, +%D email=zappathustra@free.fr, +%D license=LaTeX Project Public License] + +\writestatus{loading}{ConTeXt User Module / yax} +\chardef\formatnumber=3 +\input yax.tex +\endinput diff --git a/Master/texmf-dist/tex/generic/yax/yax.sty b/Master/texmf-dist/tex/generic/yax/yax.sty new file mode 100644 index 00000000000..58477727ee7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/yax/yax.sty @@ -0,0 +1,14 @@ +% This is yax.sty, a style file to load +% the YaX package in LaTeX. Useful information +% can be found in yax-doc.pdf +% +% Author: Paul Isambert. +% E-mail: zappathustra AT free DOT fr +% Comments and suggestions are welcome. +% Date: June 2010. + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{yax}[2010/06/17 v.1.0 Yet Another Key System.] +\chardef\formatnumber=4 +\input yax.tex +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/yax/yax.tex b/Master/texmf-dist/tex/generic/yax/yax.tex new file mode 100644 index 00000000000..f799557634d --- /dev/null +++ b/Master/texmf-dist/tex/generic/yax/yax.tex @@ -0,0 +1,535 @@ +% This is the YaX package. +% Relevant information can be found in yax-doc.pdf +% +% Author: Paul Isambert. +% E-mail: zappathustra AT free DOT fr +% Comments and suggestions are welcome. +% Date: June 2010. +% +\input texapi % Everything I need. It figures: I wrote it for this. + +\setcatcodes{@_=11} +\def\yax@error{\senderror{YAX}} + +% +% Retrieval of parameter and attribute. +% +\def\yax@getparameter#1#2:{% + \passtrim{#2}{#1}% + } +\def\yax@defparameter#1#2{% + \def\yax@parameter{#2}#1 + } +% #1 and #2 are thing_to_do and parameter. +\def\yax@getattribute#1#2#3 {% + \ifemptystring{#3}{\yax@getattribute{#1}{#2}} + {#1{#2}{#3}}% + } +% \yax@getall\foo +% => \foo{<parameter>}{<attribute>} +\def\yax@getall#1{% + \yax@getparameter{\yax@getattribute{#1}}% + } +% +\long\def\yax@get_topar#1#2\par{% + #1{#2}% + } +% +% +% +% +% SETTING PARAMETERS +% +% The crux of the biscuit. +% +% \setparameter <list of parameters> : +% <prefix><attribute1> = <value1> +% <prefix><attribute2> = <value2> +% ... +% <prefix><attributeN> = <valueN> +% \par +% +% A generic loop for space-delimited lists. +% The the texapi documentation for the information on the \newfor loop. +% +\newfornoempty\yax@space_loop{1}#2 {#1{#2}}% +% +\pdef\setparameter{% + \yax@getparameter\yax@setparameter_getattributes + } +\long\def\yax@setparameter_getattributes#1#2\par{% + \yax@space_loop{\yax@setparameter{#2}}{#1 }% + } +\long\def\yax@setparameter#1#2{% + \deftrim\yax@parameter{#2}% + \yax@setattributes_loop{#1 }% The space at the end delimits the last value if needed. + } +\newfor\yax@setattributes_loop#1={% + \passtrim{#1}\yax@setattributes_checkprefix + \pausefor\yax@setattributes_howgiven + }[\iffcs{yax@\yax@parameter @active} + {\usecs{yax@\yax@parameter @def}}] +\def\yax@setattributes_checkprefix#1{% + \ifprefix{e:}{#1} + {\let\yax@dodef\edefcs \removeprefixand{e:}{#1}{\deftrim\yax@attribute}} + {\ifprefix{g:}{#1} + {\let\yax@dodef\gdefcs \removeprefixand{g:}{#1}{\deftrim\yax@attribute}} + {\ifprefix{x:}{#1} + {\let\yax@dodef\xdefcs \removeprefixand{x:}{#1}{\deftrim\yax@attribute}} + {\let\yax@dodef\defcs \def\yax@attribute{#1}}}}% + } +\def\yax@setattributes_howgiven{% + \ifnextnospace" + \yax@setattributes_getquote + % No need for a new nospace: it has been removed + {\ifcatnext\foo + \yax@setattributes_do % Since one visible \cs is supposed to be the only token in value. + \yax@setattributes_getspace}% + } +\long\def\yax@setattributes_getquote"#1"{% + \yax@setattributes_do{#1}% + } +\long\def\yax@setattributes_getspace#1 {% + \yax@setattributes_do{#1}% + } +\newif\ifyax@makedef +\long\def\yax@setattributes_do#1{% + \yax@makedeftrue + \iffcs{yax@\yax@parameter @restricted}% Parameter restricted. + {\reverse\iffcs{yax@\yax@parameter:\yax@attribute @allowed}% Attribute not allowed. + {\yax@makedeffalse + \yax@error{Attribute `\unexpandedcs{yax@attribute}' + is not allowed in parameter `\yax@parameter'. + Authorized attributes are `\unexpandedcs{yax@\yax@parameter @restricted}'}}}% + \ifcs{yax@\yax@parameter:\yax@attribute @restricted}% Attribute restricted in this parameter. + {\reverse\iffcs{yax@\yax@parameter:\yax@attribute:\detokenize{#1}@allowed}% Value not allowed. + {\yax@makedeffalse + \yax@error{Value `\detokenize{#1}' + is not allowed in attribute `\yax@parameter:\yax@attribute'. + Authorized values are `\unexpandedcs{yax@\yax@parameter:\yax@attribute @restricted}'}}}% + {\iffcs{yax@attribute@\yax@attribute @restricted}% Attribute restricted in all parameters. + {\reverse\iffcs{yax@attribute@\yax@attribute:\detokenize{#1}@allowed}% Value not allowed. + {\yax@makedeffalse + \yax@error{Value `\detokenize{#1}' + is not allowed in attribute `\yax@attribute'. + Authorized values are `\unexpandedcs{yax@attribute@\yax@attribute @restricted}'}}}}% + \ifyax@makedef + \yax@dodef{yax@\yax@parameter:\yax@attribute}{#1}% + \fi + \resumefor\yax@setattributes_loop% Better not to forget this! + } +% +% +% +% +% \restrictparameter <list of parameters> : +% <attribute1> +% <attribute2> +% ... +% <attributeN> +% \par +% +\pdef\restrictparameter{% + \yax@getparameter\yax@restrictparameter_getrestrictions + }% +\long\def\yax@restrictparameter_getrestrictions#1#2\par{% + \yax@space_loop{\yax@restrictparameter{#2 meta }}{#1 }% Meta is always allowed. + } +\long\def\yax@restrictparameter#1#2{% + \def\yax@parameter{#2}% + \yax@space_loop\yax@restrictparameter_readrestrictions{#1}% + } +\long\def\yax@restrictparameter_readrestrictions#1{% + \letcs{yax@\yax@parameter :#1@allowed}\relax + \ifcs{yax@\yax@parameter @restricted} + {\addrightcs{yax@\yax@parameter @restricted}{, #1}} + {\defcs{yax@\yax@parameter @restricted}{#1}}% + } +% +% \restrictattribute <parameter>:<attribute> +% <value1> +% <value2> +% ... +% <valueN> +%\par +% +\pdef\restrictattribute{% + \yax@getall\yax@restrictattribute_getrestrictions + } +\long\def\yax@restrictattribute_getrestrictions#1#2#3\par{% + \yax@space_loop{\yax@restrictattribute_readrestrictions{#1}{#2}}{#3 }% + } +\long\def\yax@restrictattribute_readrestrictions#1#2#3{% + \letcs{yax@#1:#2:\detokenize{#3}@allowed}\relax + \ifcs{yax@#1:#2@restricted} + {\addrightcs{yax@#1:#2@restricted}{, #3}} + {\defcs{yax@#1:#2@restricted}{#3}}% + } +% +% \restrictallattributes <attribute> +% <value1> +% <value2> +% ... +% <valueN> +%\par +% +\long\pdef\restrictallattributes#1 #2\par{% + \yax@space_loop{\yax@restrictallattributes_readrestrictions{#1}}{#2 }% + } +\long\def\yax@restrictallattributes_readrestrictions#1#2{% + \letcs{yax@attribute@#1:\detokenize{#2}@allowed}\relax + \ifcs{yax@attribute@#1@restricted} + {\addrightcs{yax@attribute@#1@restricted}{, #2}} + {\defcs{yax@attribute@#1@restricted}{#2}}% + } +% +% +% +% +% \defparameter<list of parameters>{<definition>} +% \defactiveparameter<list of parameters>{<definition>} +% \executeparameter <parameter> : +% +\newif\ifyax@activeparameter +\def\defparameter#1#{% + \def\yax@parameter{#1 }% + \afterassignment\yax@defparameter_do + \def\yax@temp##1% + }% +\def\yax@defparameter_do{% + \passexpanded{\yax@space_loop\yax@defparameter_def}\yax@parameter + } + +\def\defactiveparameter{% + \yax@activeparametertrue\defparameter + }% +\long\def\yax@defparameter_def#1{% + \edefcs{yax@#1@def}{\unexpanded\expandafter{\yax@temp{#1}}}% + \ifyax@activeparameter + \yax@activeparameterfalse + \letcs{yax@#1@active}\relax + \fi + } +\def\executeparameter{% + \yax@getparameter\yax@executeparameter + } +\def\yax@executeparameter#1{% + \iffcs{yax@#1@def}{\csname yax@#1@def\endcsname}% + } +% +% +% +% +% \deleteattribute <parameter> : <attribute> +% +\def\deleteattribute{% + \yax@getall\yax@deleteattribute + } +\def\yax@deleteattribute#1#2{% + \letcs{yax@#1:#2}\yax@undefined + } +% +% +% +% +% USING VALUES +% +% These are the loops used to check whether <parameter>:<attribute> exists, +% and if not to search the meta-parameters. They are used of course in +% \usevalue and associates. +% I could use one loop only for all macros, but then I should have used more +% internal code to pass arguments here and there. +% +% #1 = list of parameters already checked (used to spot loops in meta-search) +% => becomes {#1{#3}} on each iteration. +% #2 = command executed on yax@<parameter>:<attribute> if it exists. +% => doesn't change from one iteration to the next. +% #3 = <parameter> +% => becomes \usecs{yax@<parameter>:<meta>} on each iteration, thus +% returning a new <parameter> to be searched. +% #4 = <attribute> +% => doesn't change from one iteration to the next. +% #5 = <or> if alone, <and> when #6 exists. +% #6 = <and>. +% => neither change. +% +% The loop does the following: +% If <parameter>:<attribute> exists, then execute #2 on it followed by <and> if any. +% Or, if <parameter> has a meta attribute, it calls +% the \yax@ifattribute_checkmeta subloop with <or> and <parameter> +% as passed arguments and <list of previous parameters> as the list argumen. +% This command compare each item in the list with <parameter>, and if they +% have the same meta, it means we're in a meta-loop, we break and execute <or>. +% If no match obtains, we rerun the original loop (with #3 turned to its meta). +% Or, if <parameter> had no meta in the first place, we break and execute <or>. +% +\newwhile\yax@ifattribute_noarg4{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{% + \ifcs{yax@#3:#4} + {\breakwhile{#2{yax@#3:#4}}} + {\ifcs{yax@#3:meta}% <parameter> has no <attribute>. + {\yax@ifattribute_checkmeta{}{#3}{#1}}% It has a meta, though. We do some testing (see next macro). + {\breakwhile{}}}% No meta, we break the loop, gobble <true> and release <false> + } +\newwhile\yax@ifattribute_or5{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{% + \ifcs{yax@#3:#4} + {\breakwhile{#2{yax@#3:#4}}} + {\ifcs{yax@#3:meta} + {\yax@ifattribute_checkmeta{#5}{#3}{#1}} + {\breakwhile{#5}}}% + } +\newwhile\yax@ifattribute_and6{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{#6}{% + \ifcs{yax@#3:#4} + {\breakwhile{#2{yax@#3:#4}#5}} + {\ifcs{yax@#3:meta} + {\yax@ifattribute_checkmeta{#6}{#3}{#1}} + {\breakwhile{#6}}}% + } +% The _if version pass <or> to the execution of the parameter, +% since a test is supposed to happen. +\newwhile\yax@ifattribute_if6{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{#6}{% + \ifcs{yax@#3:#4} + {\breakwhile{#2{yax@#3:#4}{#5}{#6}}} + {\ifcs{yax@#3:meta} + {\yax@ifattribute_checkmeta{#6}{#3}{#1}} + {\breakwhile{#6}}}% + } +\newfor\yax@ifattribute_checkmeta{2}#3{% + \iffxcscs{yax@#2:meta}{yax@#3:meta}% Both parameters have the same meta. So we're in a meta-loop, and we break. + {\breakfor{\breakwhile{#1}}}% + } +% +% The nometa version are definitely simpler. +% +\long\def\yax@ifattributenometa_and#1#2#3#4#5{% + \ifcs{yax@#2:#3}{#1{yax@#2:#3}#4}{#5}% + } +\long\def\yax@ifattributenometa_or#1#2#3#4{% + \ifcs{yax@#2:#3}{#1{yax@#2:#3}}{#4}% + } +\def\yax@ifattributenometa_noarg#1#2#3{% + \iffcs{yax@#2:#3}{#1{yax@#2:#3}}% + } +% +% +% +% +% \nometa +% +\def\nometa#1{% + \ifcs{yax@\commandtoname#1_nometa} + {\usecs{yax@\commandtoname#1_nometa}} + {\yax@error{You can't use \noexpand\nometa before \string#1}}% + } +% +% +% +% Defining \<com>, \<com>or and \<com>and at once, +% with the \nometa-variant. +% +\def\yax@def_noarg#1#2{% + \def#1{\yax@getall{\yax@ifattribute_noarg{}{#2}}}% + \defcs{\commandtoname#1or}{\yax@getall{\yax@ifattribute_or{}{#2}}}% + \defcs{\commandtoname#1and}{\yax@getall{\yax@ifattribute_and{}{#2}}}% +% + \defcs{yax@\commandtoname#1_nometa}{\yax@getall{\yax@ifattributenometa_noarg{#2}}}% + \defcs{yax@\commandtoname#1or_nometa}{\yax@getall{\yax@ifattributenometa_or{#2}}}% + \defcs{yax@\commandtoname#1and_nometa}{\yax@getall{\yax@ifattributenometa_and{#2}}}% + } +\def\yax@def_onearg#1#2{% + \def#1##1{\yax@getall{\yax@ifattribute_noarg{}{#2{##1}}}}% + \defcs{\commandtoname#1or}##1{\yax@getall{\yax@ifattribute_or{}{#2{##1}}}}% + \defcs{\commandtoname#1and}##1{\yax@getall{\yax@ifattribute_and{}{#2{##1}}}}% +% + \defcs{yax@\commandtoname#1_nometa}##1{\yax@getall{\yax@ifattributenometa_noarg{#2{##1}}}}% + \defcs{yax@\commandtoname#1or_nometa}##1{\yax@getall{\yax@ifattributenometa_or{#2{##1}}}}% + \defcs{yax@\commandtoname#1and_nometa}##1{\yax@getall{\yax@ifattributenometa_and{#2{##1}}}}% + } +% +% +% +% +% \ifattribute +% +\def\ifattribute{% + \yax@getall{\yax@ifattribute_and{}\gobbleone}% + }% +\def\yax@ifattribute_nometa{% + \yax@getall{\yax@ifattributenometa_and\gobbleone}% + } +% +% +% +% +% \passvalue +% +\yax@def_onearg\passvalue\yax@passvalue +\def\yax@passvalue#1#2{% + \passexpandedcs{#1}{#2}% + } +\yax@def_onearg\passvaluenobraces\yax@passvalue_nobrace +\def\yax@passvalue_nobrace#1#2{% + \passexpandedcs\swapargs{#2}{#1}% + } +% +% +% +% +% \usevalue +% +\yax@def_noarg\usevalue\usecs +% +% +% +% +% \settovalue (not expandable, obviously, +% although it leaves nothing in the input but +% the assignment. +% +\yax@def_onearg\settovalue\yax@settovalue +\def\yax@settovalue#1#2{% + #1 \usecs{#2}\relax + } +% +% +% +% +% \storevalue (like \settovalue, basically). +% +\yax@def_onearg\storevalue\yax@storevalue +\def\yax@storevalue#1#2{% + \lettocs#1{#2}% + }% +% +% +% +% +% \ifvalue +% +\def\ifvalue{% + \yax@getall{\yax@ifvalue_removesign\yax@ifvalue_getvalue}% + }% + +\def\yax@ifvalue_nometa{% + \yax@getall{\yax@ifvalue_removesign\yax@ifvaluenometa_getvalue}% + }% +\def\yax@ifvalue_removesign#1#2#3#4={#1{#2}{#3}}% +\long\def\yax@ifvalue_getvalue#1#2#3 {% + \ifemptystring{#3} + {\yax@ifvalue_getvalue{#1}{#2}} + {\yax@ifattribute_if{}{\passexpandedcs{\ifstring{#3}}}{#1}{#2}}% + } +\def\yax@ifvaluenometa_getvalue#1#2#3 {% + \ifemptystring{#3} + {\yax@ifvaluenometa_getvalue{#1}{#2}} + {\ifcs{yax@#1:#2}{\passexpandedcs{\ifstring{#3}}{yax@#1:#2}}\secondoftwo}% + } +% +% +% +% +% \ifcasevalue +% +\let\yax@ifcasevalue_passvalueor\passvalueor % just in case \passvalue is redefined by a \newsyntax. +\let\yax@yax@ifcasevalue_passvalueor_nometa\yax@passvalueor_nometa +\letcstocs{yax@yax@ifcasevalue_passvalueor_nometa}{yax@passvalueor_nometa} + +\def\ifcasevalue{% + \yax@getall\yax@ifcasevalue_getvalue + } +\def\yax@ifcasevalue_nometa{% + \yax@getall{\expandafter\nometa\yax@ifcasevalue_getvalue}% + } +\def\yax@ifcasevalue_getvalue#1#2{% + \yax@ifcasevalue_passvalueor\yax@ifcasevalue_scan#1:#2 \yax@ifcasevalue_novalue + } +\newstring\val \newstring\elseval +\long\def\yax@ifcasevalue_novalue#1\endval{% + \iffcontains{\elseval}{#1}{\splitstring{\elseval}{#1}\yax@ifcasevalue_doelse}% + } +\def\yax@ifcasevalue_doelse#1#2{\trim{#2}} +\def\yax@ifcasevalue_scan#1#2\endval{% + \ifcontains{\elseval}{#2} + {\splitstring{\elseval}{#2}\yax@ifcasevalue_dotest{#1}} + {\yax@ifcasevalue_dotest{#2}{}{#1}}% + } +\def\yax@ifcasevalue_dotest#1#2#3{% + \yax@ifcasevalue_loop{#3}{#2}{{yax@dummy_value} #1\val}% + } +\newfor\yax@ifcasevalue_loop{2}#3 #4\val{% + \iffstring{#1}{#3}{\passtrim{#4}\breakfor}% + }[\passtrim{#2}\unbrace] +% +% +% +% +% \newsyntax +% +\long\def\yax@newsyntax_noarg#1#2#3{% + \defcs{#1}#2{\yax@ifattribute_noarg{}{#3}{##1}{##2}}% + \defcs{#1or}#2{\yax@ifattribute_or{}{#3}{##1}{##2}}% + \defcs{#1and}#2{\yax@ifattribute_and{}{#3}{##1}{##2}}% +% + \defcs{yax@#1_nometa}#2{\yax@ifattributenometa_noarg{#3}{##1}{##2}}% + \defcs{yax@#1or_nometa}#2{\yax@ifattributenometa_or{#3}{##1}{##2}}% + \defcs{yax@#1and_nometa}#2{\yax@ifattributenometa_and{#3}{##1}{##2}}% + } +\long\def\yax@newsyntax_onearg#1#2#3{% + \defcs{#1}##1#2{\yax@ifattribute_noarg{}{#3{##1}}{##2}{##3}}% + \defcs{#1or}##1#2{\yax@ifattribute_or{}{#3{##1}}{##2}{##3}}% + \defcs{#1and}##1#2{\yax@ifattribute_and{}{#3{##1}}{##2}{##3}}% +% + \defcs{yax@#1_nometa}##1#2{\yax@ifattributenometa_noarg{#3{##1}}{##2}{##3}}% + \defcs{yax@#1or_nometa}##1#2{\yax@ifattributenometa_or{#3{##1}}{##2}{##3}}% + \defcs{yax@#1and_nometa}##1#2{\yax@ifattributenometa_and{#3{##1}}{##2}{##3}}% + } +\long\def\newsyntax#1#{% + \yax@newsyntax{#1}% + } +\long\def\yax@newsyntax#1#2{% + \defcs{#2restrictattribute}#1{\yax@restrictattribute_getrestrictions{##1}{##2}}% + \defcs{#2deleteattribute}#1{\letcs{yax@##1:##2}\yax@undefined}% + \defcs{#2ifattribute}#1{\yax@ifattribute_and{}\gobbleone{##1}{##2}}% + \defcs{yax@#2ifattribute_nometa}#1{\yax@ifattributenometa_and\gobbleone{##1}{##2}}% + \yax@newsyntax_noarg{#2usevalue}{#1}\usecs + \def\yax@temp##1##2{#1}% + \passexpanded{\yax@newsyntax_onearg{#2passvalue}}{\yax@temp{##2}{##3}}\yax@passvalue + \passexpanded{\yax@newsyntax_onearg{#2passvaluenobraces}}{\yax@temp{##2}{##3}}\yax@passvalue_nobrace + \passexpanded{\yax@newsyntax_onearg{#2settovalue}}{\yax@temp{##2}{##3}}\yax@settovalue + \passexpanded{\yax@newsyntax_onearg{#2storevalue}}{\yax@temp{##2}{##3}}\yax@storevalue + \defcs{#2ifvalue}#1{\yax@ifvalue_removesign\yax@ifvalue_getvalue{##1}{##2}}% + \defcs{yax@#2ifvalue_nometa}#1{\yax@ifvalue_removesign\yax@ifvaluenometa_getvalue{##1}{##2}}% + \defcs{#2ifcasevalue}#1{\yax@ifcasevalue_getvalue{##1}{##2}}% + \defcs{yax@#2ifcasevalue_nometa}#1{\expandafter\nometa\yax@ifcasevalue_getvalue{##1}{##2}}% + } + +\def\yax@let#1#2#3{% + \letcstocs{#2#1}{#3#1}% + \letcstocs{yax@#2#1_nometa}{yax@#3#1_nometa}% + } +\def\yax@let_all#1#2#3{% + \yax@let{#1}{#2}{#3}\yax@let{#1or}{#2}{#3}\yax@let{#1and}{#2}{#3}% + } +\def\copysyntax#1#2{% + \letcstocs{#1restrictattribute}{#2restrictattribute}% + \letcstocs{#1deleteattribute}{#2deleteattribute}% + \yax@let{ifattribute}{#1}{#2}% + \yax@let_all{usevalue}{#1}{#2}\yax@let_all{passvalue}{#1}{#2}\yax@let_all{passvaluenobraces}{#1}{#2}% + \yax@let_all{settovalue}{#1}{#2}\yax@let_all{storevalue}{#1}{#2}% + \yax@let{ifvalue}{#1}{#2}% + \yax@let{ifcasevalue}{#1}{#2}% + } + +\def\letyaxcommand#1#2{% + \let#1#2% Base \let. + \ifcs{yax@\commandtoname#2and_nometa} % #2 is a YaX command with -and -or variants. + {\letcstocs{\commandtoname#1or}{\commandtoname#2or}% + \letcstocs{\commandtoname#1and}{\commandtoname#2and}% + \letcstocs{yax@\commandtoname#1_nometa}{yax@\commandtoname#2_nometa}% + \letcstocs{yax@\commandtoname#1or_nometa}{yax@\commandtoname#2or_nometa}% + \letcstocs{yax@\commandtoname#1and_nometa}{yax@\commandtoname#2and_nometa}}% + {\iffcs{yax@\commandtoname#2_nometa}% #2 is a YaX command without variants but with \nometa (i.e. the \if...). + {\letcstocs{yax@\commandtoname#1_nometa}{yax@\commandtoname#2_nometa}}}% + } + +\restorecatcodes +\endinput
\ No newline at end of file diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 12900331313..dbc1a32f352 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -1016,6 +1016,7 @@ $standardtex='\.(.bx|cfg|sty|clo|ldf|cls|def|fd|cmap|4ht)$'; 'xwatermark', '\.sty', # no .cfg 'xlop', 'xlop\.(tex|sty)', # no manual.sty 'xstring', 'xstring\.tex|' . $standardtex, + 'yax', '(t-)?yax\.(sty|tex)|' . $standardtex, 'zefonts', '\.sty|\.fd', ); diff --git a/Master/tlpkg/tlpsrc/collection-genericextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-genericextra.tlpsrc index a9e350d80b0..9caaf9ed728 100644 --- a/Master/tlpkg/tlpsrc/collection-genericextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-genericextra.tlpsrc @@ -30,4 +30,5 @@ depend texapi depend vrb depend vtex depend xlop +depend yax depend collection-basic diff --git a/Master/tlpkg/tlpsrc/yax.tlpsrc b/Master/tlpkg/tlpsrc/yax.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/yax.tlpsrc |