summaryrefslogtreecommitdiff
path: root/macros/optex/base/keyval.opm
blob: b0462296b3727f63fffcc4b8cceed68f2a75feaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \readkv {Key-value dictionaries <2020-12-21>} % preloaded in format

   \_doc ----------------------------
   {\bf Implementation.}
   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:<key>` macros.\nl
   The \`\kv``{<key>}` expands the `\_kv:<key>` macro. If this macro isn't
   defined then \`\_kvunknown` is processed. You can re-define it if you want.
   \_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}}
\_def\_kvunknown{???}

\public \readkv \kv ;

\_endcode

Users or macro programmers can define macros with options in key=value format.
It means a comma-separated list of equations key=value. First, we give an
example.

Suppose that you want to define a macro `\myframe` with options: color of
rules, color of text inside the frame, rule-width, space between text and
rules. You want to use this macro as:

\begtt
\myframe [margins=5pt,rule-width=2pt,frame-color=\Red,text-color=\Blue] {text1}
or
\myframe [frame-color=\Blue] {text2} % other parameters are default
\endtt
%
You can define `\myframe` as follows:

\begtt
\def\myframedefaults{%    defaults:
   frame-color=\Black, % color of frame rules
   text-color=\Black,  % color ot text nside the frame
   rule-width=0.4pt,   % width of rules used in the frame
   margins=2pt,        % space between text inside and rules.
}
\optdef\myframe [] #1{\bgroup
   \ea\addto\ea\myframedefaults\ea{\ea,\the\opt}%
   \readkv\myframedefaults
   \rulewidth=\kv{rule-width}
   \hhkern=\kv{margins}\vvkern=\kv{margins}\relax
   \kv{frame-color}\frame{\kv{text-color}\strut #1}%
   \egroup}
\endtt
%
We recommend using \^`\optdef` for defining macros with optional parameters
written in `[]`. Then the optional parameters are saved in the \^`\opt` tokens
register. First: we append the \^`\opt` (actual optional parameters) to
`\myframedefault` by \^`\addto` macro.
Second: we read the parameters by
\^`\readkv{<pramaters list>}` macro.
Third: the values can be used by expandable \^`\kv{<key>}` macro.
The \^`\kv{<key>}` 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`.
\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
   ...}
\endtt