summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expkv-cs
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-05-25 20:46:32 +0000
committerKarl Berry <karl@freefriends.org>2021-05-25 20:46:32 +0000
commitc9c5327330cc47c3c0b99ae3956c5ae4af7e52e7 (patch)
treed6534d550770cb0dab4eb3d59af392cba7501155 /Master/texmf-dist/source/latex/expkv-cs
parent881a80a648cf13fd0b856493d5320d3ab6a74250 (diff)
expkv-cs (25may21)
git-svn-id: svn://tug.org/texlive/trunk@59340 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/expkv-cs')
-rw-r--r--Master/texmf-dist/source/latex/expkv-cs/expkv-cs.dtx290
1 files changed, 243 insertions, 47 deletions
diff --git a/Master/texmf-dist/source/latex/expkv-cs/expkv-cs.dtx b/Master/texmf-dist/source/latex/expkv-cs/expkv-cs.dtx
index 5847a4980be..38a70349d74 100644
--- a/Master/texmf-dist/source/latex/expkv-cs/expkv-cs.dtx
+++ b/Master/texmf-dist/source/latex/expkv-cs/expkv-cs.dtx
@@ -64,6 +64,19 @@ and the derived files expkv-cs.pdf
\RequirePackage[oldstylenums,nott]{kpfonts}
\input{glyphtounicode}
\pdfgentounicode=1
+\RequirePackage{tcolorbox}
+\newtcolorbox{exresult}[2][]
+ {colback=expkvgrey!10!white,colframe=expkvgrey,fontupper=\small,width={#2},#1}
+\newtcbox\exres[1][]
+ {
+ colback=expkvgrey!10!white
+ ,colframe=expkvgrey
+ ,size=small
+ ,nobeforeafter
+ ,tcbox raise base
+ ,fontupper=\small
+ ,#1
+ }
\RequirePackage{listings}
\RequirePackage{booktabs}
\RequirePackage{array}
@@ -73,26 +86,127 @@ and the derived files expkv-cs.pdf
\RequirePackage{caption}
\RequirePackage{microtype}
\RequirePackage{accsupp}
+\lstdefinelanguage{expkvd}[primitive]{TeX}
+ {
+ ,moretexcs=[4]^^A e-TeX
+ {
+ expanded,
+ numexpr,
+ protected,
+ }
+ ,moretexcs=[5]^^A plain/LaTeX
+ {
+ approx,
+ begin,
+ empty,
+ item,
+ LaTeX,
+ makeatletter,makeatother,multicolumn,
+ newcommand,newdimen,
+ RequirePackage,
+ rule,
+ TeX,
+ textit,texttt,
+ usepackage,
+ }
+ ,moretexcs=[6]^^A used packages
+ {
+ ^^A xfp
+ fpeval,
+ ^^A keyval
+ setkeys,
+ ^^A yax
+ defactiveparameter,storevalue,setparameterlist
+ }
+ ,moretexcs=[2]^^A expkv-cs macros
+ {
+ ekvcSplit,ekvcSplitAndForward,ekvcSplitAndUse,
+ ekvcHash,ekvcHashAndForward,ekvcHashAndUse,
+ ekvcValue,ekvcValueFast,ekvcValueSplit,ekvcValueSplitFast,
+ ekvcSecondaryKeys,
+ ekvcFlagNew,
+ ekvcFlagHeight,
+ ekvcFlagRaise,
+ ekvcFlagSetTrue,ekvcFlagSetFalse,
+ ekvcFlagIf,ekvcFlagIfRaised,
+ ekvcFlagReset,
+ ekvcFlagGetHeight,ekvcFlagGetHeights
+ }
+ ,moretexcs=[3]^^A expkv-pkg macros
+ {
+ ^^A expkv
+ ekvdef,ekvdefNoVal,^^A
+ ekvlet,ekvletNoVal,ekvletkv,ekvletkvNoVal,^^A
+ ekvdefunknown,ekvdefunknownNoVal,^^A
+ ekvredirectunknown,ekvredirectunknownNoVal,^^A
+ ekvset,ekvsetSneaked,^^A
+ ekvsetdef,ekvsetSneakeddef,ekvsetdefSneaked,^^A
+ ekvparse,^^A
+ ekvVersion,ekvDate,^^A
+ ekvifdefined,ekvifdefinedNoVal,ekvifdefinedset,^^A
+ ekvbreak,ekvbreakPreSneak,ekvbreakPostSneak,^^A
+ ekvsneak,ekvsneakPre,^^A
+ ekvchangeset,^^A
+ ekvoptarg,ekvoptargTF,^^A
+ ekverr,
+ ^^A expkv-def
+ ekvdefinekeys
+ }
+ }
+\colorlet{codeparam}{cyan!65!black}
+\def\mylstwd{.55em}
\lstset
{
+ ,language=expkvd
,flexiblecolumns=false
- ,basewidth=.53em
+ ,basewidth=\mylstwd
,gobble=2
,basicstyle=\fontfamily{jkp}\itshape
- ,morekeywords=^^A
- {^^A
- \ekvcSplit,\ekvcSplitAndForward,\ekvcSplitAndUse
- \ekvcHash,\ekvcHashAndForward,\ekvcHashAndUse
- \ekvcValue,\ekvcValueFast,
- \ekvcSecondaryKeys
- }
- ,morecomment=[l]\%
+ ,texcsstyle=*[1]{\bfseries\color{expkvgrey}} ^^A primitives
+ ,texcsstyle=*[2]{\bfseries\color{expkvred}} ^^A expkv
+ ,texcsstyle=*[3]{\color{expkvred}} ^^A expkv-pkg
+ ,texcsstyle=*[4]{\bfseries\color{expkvgrey}} ^^A e-TeX
+ ,texcsstyle=*[5]{\bfseries\color{expkvgrey}} ^^A plain/LaTeX macros
+ ,texcsstyle=*[6]{} ^^A macros of other packages
,commentstyle=\color[gray]{0.4}
- ,literate={\{}{{\CodeSymbol\{}}{1}
- {\}}{{\CodeSymbol\}}}{1}
+ ,literate=
+ {\{} {{\CodeUpBf\{}}{1}
+ {\}} {{\CodeUpBf\}}}{1}
+ {$} {{\CodeUpBf\$}}{1}
+ {[} {{\CodeUp[}}{1}
+ {]} {{\CodeUp]}}{1}
+ {(} {{\CodeUp(}}{1}
+ {)} {{\CodeUp)}}{1}
+ {*} {{$*$}}{1}
+ {1} {{\CodeUp{1}}}{1}
+ {2} {{\CodeUp{2}}}{1}
+ {3} {{\CodeUp{3}}}{1}
+ {4} {{\CodeUp{4}}}{1}
+ {5} {{\CodeUp{5}}}{1}
+ {6} {{\CodeUp{6}}}{1}
+ {7} {{\CodeUp{7}}}{1}
+ {8} {{\CodeUp{8}}}{1}
+ {9} {{\CodeUp{9}}}{1}
+ {0} {{\CodeUp{0}}}{1}
+ {##} {{\CodeColored{codeparam}{1}{\#}}}{1}
+ {##1}{{\CodeColored{codeparam}{2}{\#1}}}{2}
+ {##2}{{\CodeColored{codeparam}{2}{\#2}}}{2}
+ {##3}{{\CodeColored{codeparam}{2}{\#3}}}{2}
+ {##4}{{\CodeColored{codeparam}{2}{\#4}}}{2}
+ {##5}{{\CodeColored{codeparam}{2}{\#5}}}{2}
+ {##6}{{\CodeColored{codeparam}{2}{\#6}}}{2}
+ {##7}{{\CodeColored{codeparam}{2}{\#7}}}{2}
+ {##8}{{\CodeColored{codeparam}{2}{\#8}}}{2}
+ {##9}{{\CodeColored{codeparam}{2}{\#9}}}{2}
+ {<key>}{{$\langle$}key{$\rangle$}}{5}
+ {<set>}{{$\langle$}set{$\rangle$}}{5}
+ {<set1>}{{$\langle$}set1{$\rangle$}}{6}
+ {<set2>}{{$\langle$}set2{$\rangle$}}{6}
^^A,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
}
-\newcommand*\CodeSymbol[1]{\kern-1pt\textbf{#1}\kern1pt}
+\newcommand*\CodeColored[3]{\textcolor{#1}{\makebox[\dimexpr\mylstwd*#2]{#3}}}
+\newcommand*\CodeUpBf[1]{\makebox[\mylstwd]{\textup{\textbf{#1}}}}
+\newcommand*\CodeUp[1]{\makebox[\mylstwd]{\textup{#1}}}
\RequirePackage{randtext}
\let\metaORIG\meta
\protected\def\meta #1{\texttt{\metaORIG{#1}}}
@@ -705,7 +819,7 @@ and the derived files expkv-cs.pdf
% alias pos = possessive,
% nmeta me =
% {
-% name=Jonathan P. Spratte,
+% name=Jonathan,
% age=a young,
% nationality=Germany,
% hobby=\TeX\ coding,
@@ -738,15 +852,54 @@ and the derived files expkv-cs.pdf
% As one might see, the |lady| key could actually have been an |nmeta| key as
% well, as all that is done with the argument is using it as a \kv\ list.
%
-% Using \pkg{xparse} and forwarding arguments one can easily define \kv\ macros
-% with actual optional and mandatory arguments as well. A small nonsense example
-% (which should perhaps use |\ekvcSplitAndForward| instead of
-% |\ekvcHashAndForward| since it only uses four keys and one other argument --
-% and isn't expandable since it uses a \env{tabular} environment):
+% The result of all the first two usages would be:
+% \begin{exresult}{\linewidth}
+% \ekvcSplit\character
+% {
+% name=John Doe,
+% age=any,
+% nationality=the Universe,
+% hobby=to exist,
+% type=Mister,
+% pronoun=He,
+% possessive=his,
+% }
+% {#1 is a #5 from #3. #6 is of #2 age and #7 hobby is #4.\par}
+% \ekvcSecondaryKeys\character
+% {
+% alias pro = pronoun,
+% alias pos = possessive,
+% nmeta me =
+% {
+% name=Jonathan,
+% age=a young,
+% nationality=Germany,
+% hobby=\TeX\ coding,
+% },
+% meta lady =
+% {type=Lady, pronoun=She, possessive=her, name=Jane Doe, #1},
+% nmeta paulo =
+% {
+% name=Paulo,
+% type=duck,
+% age=a young,
+% nationality=Brazil,
+% hobby=to quack,
+% }
+% }
+% \character{}
+% \character{me}
+% \end{exresult}
+%
+% Using \pkg{xparse} or \expkv's \cs{ekvoptarg} or \cs{ekvoptargTF} and
+% forwarding arguments one can easily define \kv\ macros with actual optional
+% and mandatory arguments as well. A small nonsense example (which should
+% perhaps use |\ekvcSplitAndForward| instead of |\ekvcHashAndForward| since it
+% only uses four keys and one other argument -- and isn't expandable since it
+% uses a \env{tabular} environment):
% \begin{lstlisting}
-% \usepackage{xparse}
% \makeatletter
-% \NewExpandableDocumentCommand\nonsense{O{} m}{\nonsense@a{#1}{#2}}
+% \newcommand*\nonsense{\ekvoptarg\nonsense@a{}}
% \ekvcHashAndForward\nonsense@a\nonsense@b
% {
% keyA = A,
@@ -762,17 +915,44 @@ and the derived files expkv-cs.pdf
% & C & \ekvcValue{keyC}{#1} \\
% & D & \ekvcValue{keyD}{#1} \\
% \multicolumn{2}{l}{mandatory} & #2 \\
-% \end{tabular}\par
+% \end{tabular}%
% }
% \makeatother
% \end{lstlisting}
-% And then we would be able to do some nonsense:
+% And then we would be able to do some nonsense
% \begin{lstlisting}
% \nonsense{}
% \nonsense[keyA=hihi]{haha}
% \nonsense[keyA=hihi, keyB=A]{hehe}
% \nonsense[keyC=huhu, keyA=hihi, keyB=A]{haha}
% \end{lstlisting}
+% resulting in
+% \begin{exresult}{\linewidth}
+% \makeatletter
+% \newcommand*\nonsense{\ekvoptarg\nonsense@a{}}
+% \ekvcHashAndForward\nonsense@a\nonsense@b
+% {
+% keyA = A,
+% keyB = B,
+% keyC = c,
+% keyD = d,
+% }
+% \newcommand*\nonsense@b[2]
+% {%
+% \begin{tabular}{lll}
+% key & A & \ekvcValue{keyA}{#1} \\
+% & B & \ekvcValue{keyB}{#1} \\
+% & C & \ekvcValue{keyC}{#1} \\
+% & D & \ekvcValue{keyD}{#1} \\
+% \multicolumn{2}{l}{mandatory} & #2 \\
+% \end{tabular}%
+% }
+% \makeatother
+% \nonsense{}
+% \nonsense[keyA=hihi]{haha}
+% \nonsense[keyA=hihi, keyB=A]{hehe}
+% \nonsense[keyC=huhu, keyA=hihi, keyB=A]{haha}
+% \end{exresult}
%
%
% \subsection{Speed Considerations}\label{sec:speed}
@@ -945,8 +1125,8 @@ and the derived files expkv-cs.pdf
% \begin{macro}{\ekvcVersion,\ekvcDate}
% We're on our first input, so lets store the version and date in a macro.
% \begin{macrocode}
-\def\ekvcVersion{0.8}
-\def\ekvcDate{2021-04-12}
+\def\ekvcVersion{0.9}
+\def\ekvcDate{2021-05-24}
% \end{macrocode}
% \end{macro}
%
@@ -993,8 +1173,26 @@ and the derived files expkv-cs.pdf
% Some macros will have to be defined long. These two will be let to |\long|
% when this should be the case.
% \begin{macrocode}
-\def\ekvc@long{}
-\def\ekvc@any@long{}
+\let\ekvc@long\ekv@empty
+\let\ekvc@any@long\ekv@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekvc@ifdefined}
+% We want to test whether a macro is already defined. This test checks for a
+% defined macro that isn't |\relax|.
+% \begin{macrocode}
+\long\def\ekvc@ifdefined#1%
+ {%
+ \ifdefined#1%
+ \ifx\relax#1%
+ \ekv@fi@gobble
+ \fi
+ \@firstofone
+ \ekv@fi@firstoftwo
+ \fi
+ \@secondoftwo
+ }
% \end{macrocode}
% \end{macro}
%
@@ -1009,7 +1207,8 @@ and the derived files expkv-cs.pdf
% a little magic trick to get the macro parameter |#1| for the macro
% definition this is used in, even though we're calling |\unexpanded|. We do
% that by splitting the expanded |\ekvset| at some marks and place |##1| in
-% between.
+% between. At this spot we also add |\ekv@alignsafe| and |\ekv@endalignsafe|
+% to ensure that macros created with \expkvc\ are alignment safe.
% \begin{macrocode}
\def\ekvc@ekvset@pre@expander#1%
{%
@@ -1021,7 +1220,9 @@ and the derived files expkv-cs.pdf
}
\def\ekvc@ekvset@pre@expander@b#1\ekvc@stop#2\ekvc@stop
{%
+ \unexpanded\expandafter{\ekv@alignsafe}%
\unexpanded{#1}##1\unexpanded{#2}%
+ \unexpanded\expandafter{\ekv@endalignsafe}%
}
% \end{macrocode}
% \end{macro}
@@ -1035,7 +1236,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcSplitAndUse#1#2%
{%
\let\ekvc@helpers@needed\@firstoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{\ekvcSplitAndUse@#1{}{#2}}%
}
@@ -1083,7 +1284,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcSplitAndForward#1#2#3%
{%
\let\ekvc@helpers@needed\@firstoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{\ekvcSplitAndUse@#1{{#2}}{#3}}%
}
@@ -1098,7 +1299,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcSplit#1#2#3%
{%
\let\ekvc@helpers@needed\@secondoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{%
\expandafter
@@ -1154,8 +1355,8 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvc@SetupSplitKeys
{%
\ekvc@keycount=0
- \def\ekvc@any@long{}%
- \def\ekvc@initials{}%
+ \let\ekvc@any@long\ekv@empty
+ \let\ekvc@initials\ekv@empty
\ekvparse\ekvc@err@value@required\ekvc@SetupSplitKeys@a
}
% \end{macrocode}
@@ -1165,7 +1366,7 @@ and the derived files expkv-cs.pdf
\protected\def\ekvc@SetupSplitKeys@a#1%
{%
\advance\ekvc@keycount1
- \def\ekvc@long{}%
+ \let\ekvc@long\ekv@empty
\ekvc@ifspace{#1}%
{\ekvc@SetupSplitKeys@b#1\ekvc@stop}%
{\ekvc@SetupSplitKeys@c{#1}}%
@@ -1355,7 +1556,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcHashAndUse#1#2%
{%
\let\ekvc@helpers@needed\@firstoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{\ekvcHashAndUse@#1{}{#2}}%
}
@@ -1398,7 +1599,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcHashAndForward#1#2#3%
{%
\let\ekvc@helpers@needed\@firstoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{\ekvcHashAndUse@#1{{#2}}{#3}}%
}
@@ -1413,7 +1614,7 @@ and the derived files expkv-cs.pdf
\protected\long\def\ekvcHash#1#2#3%
{%
\let\ekvc@helpers@needed\@secondoftwo
- \ekv@ifdefined{\expandafter\@gobble\string#1}%
+ \ekvc@ifdefined#1%
{\ekvc@err@already@defined#1}%
{%
\expandafter
@@ -1441,13 +1642,13 @@ and the derived files expkv-cs.pdf
% \begin{macrocode}
\protected\long\def\ekvc@SetupHashKeys#1%
{%
- \def\ekvc@any@long{}%
- \def\ekvc@initials{}%
+ \let\ekvc@any@long\ekv@empty
+ \let\ekvc@initials\ekv@empty
\ekvparse\ekvc@err@value@required\ekvc@SetupHashKeys@a{#1}%
}
\protected\def\ekvc@SetupHashKeys@a#1%
{%
- \def\ekvc@long{}%
+ \let\ekvc@long\ekv@empty
\ekvc@ifspace{#1}%
{\ekvc@SetupHashKeys@b#1\ekvc@stop}%
{\ekvc@SetupHashKeys@c{#1}}%
@@ -1687,7 +1888,7 @@ and the derived files expkv-cs.pdf
}
\protected\def\ekvcSecondaryKeys@a#1%
{%
- \def\ekvc@long{}%
+ \let\ekvc@long\ekv@empty
\ekvc@ifspace{#1}%
{\ekvcSecondaryKeys@b#1\ekvc@stop}%
{\ekvc@err@missing@type{#1}\@gobble}%
@@ -2137,15 +2338,10 @@ and the derived files expkv-cs.pdf
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\ekvc@err,\ekvc@err@}
+% \begin{macro}[internal]{\ekvc@err}
% We need a way to throw error messages expandably in some contexts.
% \begin{macrocode}
-\def\ekvc@err#1%
- {%
- \long\def\ekvc@err##1{\expandafter\ekv@err@\@firstofone{#1##1.}\ekv@stop}%
- }
-\begingroup\expandafter\endgroup
-\expandafter\ekvc@err\csname ! expkv-cs Error:\endcsname
+\ekv@exparg{\long\def\ekvc@err#1}{\ekverr{expkv-cs}{#1}}
% \end{macrocode}
% \end{macro}
%