From 8e0a627bb31e2495bca858b5c44e63e510c3448c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 9 Feb 2023 21:13:26 +0000 Subject: optex (9feb23) git-svn-id: svn://tug.org/texlive/trunk@65766 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/optex/base/keyval.opm | 99 +++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 25 deletions(-) (limited to 'Master/texmf-dist/tex/optex/base/keyval.opm') diff --git a/Master/texmf-dist/tex/optex/base/keyval.opm b/Master/texmf-dist/tex/optex/base/keyval.opm index 7d089ce6b1f..21e6f9acf34 100644 --- a/Master/texmf-dist/tex/optex/base/keyval.opm +++ b/Master/texmf-dist/tex/optex/base/keyval.opm @@ -1,26 +1,39 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \readkv {Key-value dictionaries <2020-12-21>} % preloaded in format +\_codedecl \readkv {Key-value dictionaries <2023-01-14>} % preloaded in format \_doc ---------------------------- - {\bf Implementation.} + {\bf Implementation.}\nl The \`\readkv``` expands its parameter and does replace-strings in order to - remove spaces around equal signs and after commas. Double commas are - removed. Then \`\_kvscan` reads the parameters list finished by the double - comma and saves values to `\_kv:` macros.\nl - The \`\kv``{}` expands the `\_kv:` macro. If this macro isn't - defined then \`\_kvunknown` is processed. You can re-define it if you want. + remove spaces around equal signs and after commas. + Then \`\_kvscan` reads the parameters list finished by `,\_fin,` + and saves values to `\_kv::` macros. + The `\_kvx::` is processed (if it is defined) with parameter + after it.\nl + The \`\kvx``{}{}` defines the `\_kvx::#1` macro + and \`\nokvx``{}` defines the `\_nokvx::` macro.\nl + The \`\kv``{}` expands the `\_kv::` macro. If this macro isn't + defined then \`\_kvunknown` is processed. You can re-define it if you want.\nl + The \`\iskv``{}\iftrue` (or `\iffalse`) is the test, + if the `` is defined in current . \_cod ---------------------------- \_def\_readkv#1{\_ea\_def\_ea\_tmpb\_ea{#1}% - \_replstring\_tmpb{= }{=}\_replstring\_tmpb{ =}{=}% - \_replstring\_tmpb{, }{,}\_replstring\_tmpb{,,}{,}% - \_ea \_kvscan \_tmpb,,=,} -\_def\_kvscan #1#2=#3,{\_ifx#1,\_else \_sdef{_kv:#1#2}{#3}\_ea\_kvscan\_fi} -\_def\_kv#1{\_trycs{_kv:#1}{\_kvunknown}} + \_replstring\_tmpb{= }{=}\_replstring\_tmpb{ =}{=}\_replstring\_tmpb{, }{,}% + \_ea \_kvscan\_tmpb,\_fin,} +\_def\_kvscan#1,{\_ifx\_fin#1\_empty\_ea\_ignoreit \_else\_ea\_useit \_fi + {\_kvsd #1==\_fin \_kvscan}} +\_def\_kvsd#1=#2=#3\_fin{\_sdef{\_kvcs#1}{#2}% + \_trycs{_kvx:\_the\_kvdict:#1}% + {\_trycs{_nokvx:\_the\_kvdict}{\_ea\_ignoreit}{#1}\_ea\_ignoreit}{#2}} +\_def\_kvx#1#2{\_sdef{_kvx:\_the\_kvdict:#1}##1{#2}} +\_def\_nokvx#1{\_sdef{_nokvx:\_the\_kvdict}##1\_ea\_ignoreit\_fi##2{\_fi#1}} +\_def\_kv#1{\_trycs{\_kvcs#1}{\_kvunknown}} +\_def\_iskv#1#2{#2\_else\_ea\_unless\_fi \_ifcsname\_kvcs#1\_endcsname} +\_def\_kvcs{_kv:\_the\_kvdict:} \_def\_kvunknown{???} -\public \readkv \kv ; +\public \readkv \kvx \nokvx \kv \iskv ; \_endcode @@ -43,7 +56,7 @@ or simply `\myframe {text3}`. You can define `\myframe` as follows: \begtt \def\myframedefaults{% defaults: frame-color=\Black, % color of frame rules - text-color=\Black, % color ot text inside the frame + text-color=\Black, % color of text inside the frame rule-width=0.4pt, % width of rules used in the frame margins=2pt, % space between text inside and rules. } @@ -64,18 +77,54 @@ The last setting wins. Third: the values can be used by the expandable \^`\kv{}` macro. The \^`\kv{}` returns `???` if such key is not declared. -You can use keys without values in the parameters list too, but with -additional care. For example, suppose `draft` option without parameter. -If a user writes `\myframe [..., draft, ...]{text}` then `\myframe` should behave differently. -We have to add `DRAFTv=0,` in `\myframedefault` macro. -Moreover, `\myframe` macro must include preprocessing of `\myframedefault` using -\^`\replstring` which replaces the occurrence of `draft` by `DRAFTv=1`. +You can use keys without values in the parameters list too. +Then you can ask if the key is declared by \^`\iskv``{}\iftrue` +or the key is undeclared by \^`\iskv``{}\iffalse`. +For example, you write to your documentation of your code that +user can set the `draft` option without the value. Then you can do \begtt \optdef\myframe [] #1{... - \ea\addto\ea\myframedefaults\ea{\the\opt}% - \replstring\myframedefaults{draft}{DRAFTv=1}% - \readkv\myframedefaults - ... - \ifnum\kv{DRAFTv}=1 draft mode\else normal mode\fi + \readkv\myframedefaults \readkv{\the\opt}% + \iskv{draft}\iftrue ...draft mode... \else ...final mode... \fi + ...} +\endtt +Maybe, you want to allow not ony `draft` option but `final` option (which is +opposite to `draft`) too and you want to apply the result from the last given +option. Then `\iskv` doesn't work because you can only check if both options +are declared but you don't know what one is given as last. But you can +use \^`\kvx``{}{}` to declare which is processed +immediately when the `` is processed by `\readkv`. For example +\begtt +\newcount\mydraftmode +\kvx{draft}{\mydraftmode=1 } +\kvx{final}{\mydraftmode=0 } +\optdef\myframe [] #1{... + \readkv\myframedefaults \readkv{\the\opt}% + \ifnum\mydraftmode=1 ...draft mode... \else ...final mode... \fi ...} \endtt +The syntax of \^`\kvx` `{}{}` allows to use `#1` inside the code. +It is replaced by the actual ``. Example: `\kvx{opt}{\message{opt is #1}}`, +then `\readkv{opt=HELLO}` prints \"opt is HELLO". + +The \^`\nokvx` `{}` can declare a processed for all +undeclared by \^`\kvx`. The `#1` and `#2` can be used in the , +`#1` is , `#2` is . If `\nokvx` is unused then nothing is done +for undeclared . Example: `\nokvx{\opwarnig{Unknown option "#1"}}`. + +The default dictionary name (where key-value pairs are processed) is +empty. You can use your specific dictionary by +\^`\kvdict``={}`. Then `\redakv`, `\kv`, `\iskv`, `\kvx` and `\nokvx` +macros use this named dictionary of / pairs. +Package options can be processed when +`\kvdict={pkg:}`, example is the `\mathset` macro in +\ulink[https://petr.olsak.net/ftp/olsak/optex/math-doc.pdf]{{\tt math.opm} package}. + +Recommendation: If the value of the key-value pair includes `=` or `,` or +`]`, then use the syntax `={}`. + +\_endinput + +2023-01-13 \kvx parameter added, \nokvx introduced. +2023-01-07 \kvdict, \kvx, \iskv added. +2020-12-21 Released -- cgit v1.2.3