summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/conv-xkv
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/conv-xkv
Initial commit
Diffstat (limited to 'macros/latex/contrib/conv-xkv')
-rw-r--r--macros/latex/contrib/conv-xkv/README.md26
-rw-r--r--macros/latex/contrib/conv-xkv/conv-xkv.dtx385
-rw-r--r--macros/latex/contrib/conv-xkv/conv-xkv.ins63
-rw-r--r--macros/latex/contrib/conv-xkv/doc/conv-xkv.pdfbin0 -> 86415 bytes
-rw-r--r--macros/latex/contrib/conv-xkv/examples/convert2xkeyval.tex119
5 files changed, 593 insertions, 0 deletions
diff --git a/macros/latex/contrib/conv-xkv/README.md b/macros/latex/contrib/conv-xkv/README.md
new file mode 100644
index 0000000000..398e0e02e5
--- /dev/null
+++ b/macros/latex/contrib/conv-xkv/README.md
@@ -0,0 +1,26 @@
+The conv-xkv Package
+Author: D. P. Story
+Dated: 2017-02-17
+
+This small package supports key-value syntax other than the standard latex
+syntax of <key>=<value>. Using this package, create key-values of the form
+<key>:<value> or <key>-><value>, for example. The package converts the new
+notation to xkeyval notation and passes it on to xkeyval.
+
+What's new: (2017/01/03) The delimiters for the optional first argument
+of \cxkvsetkeys is changed from the standard `[]' to `()'. Also, if no key-value
+of the special type (such as <key>:<value> or <key>-><value>) is detected, the
+whole argument is passed to \setkeys. This means that either the new key-value
+pairing or the standard pairing may be used; \cxkvsetkeys{lname:Story} or
+\cxkvsetkey{lname=Story} both work.
+
+Please test and give feedback.
+
+Enjoy.
+
+D. P. Story
+www.acrotex.net
+dpstory@uakron.edu
+dpstory@acrotex.net
+
+
diff --git a/macros/latex/contrib/conv-xkv/conv-xkv.dtx b/macros/latex/contrib/conv-xkv/conv-xkv.dtx
new file mode 100644
index 0000000000..2815654df2
--- /dev/null
+++ b/macros/latex/contrib/conv-xkv/conv-xkv.dtx
@@ -0,0 +1,385 @@
+% \iffalse
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% conv-xkv package %%
+%% Copyright (C) 2016--2017 D. P. Story %%
+%% dpstory@uakron.edu %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1.2 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{conv-xkv}
+%<package> [2017/02/17 v1.1c convert xkeyval format (dps)]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{web}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{web}{aebdocfmt.def cannot be found}}
+\begin{document}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\darg#1{{\ttfamily\char123\relax#1\char125\relax}}
+\def\CMD#1{\textbackslash#1}
+\let\pkg\textsf
+\let\opt\texttt
+ \GetFileInfo{conv-xkv.sty}
+ \title{\textsf{conv-xkv}: Convert \textsf{xkeyval} format style}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@uakron.edu}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \DocInput{conv-xkv.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
+ \texttt{makeindex -s gind.ist -o conv-xkv.ind conv-xkv.idx} on the command line and recompile
+ \texttt{conv-xkv.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
+ \texttt{makeindex -s gglo.ist -o conv-xkv.gls conv-xkv.glo} on the command line and recompile
+ \texttt{conv-xkv.dtx}.}
+\end{document}
+%</driver>
+% \fi
+%
+% \MakeShortVerb{|}
+% \DoNotIndex{\w,\x,\y,\z}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+% {\PackageInfo{web}{cannot find aebdonotindex.def}}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \section{Introduction}
+% This is a intellectual exercise for creating \emph{alternate key-value} notation. The standard {\LaTeX}
+% notation is \texttt{\ameta{key}=\ameta{value}}. To change to the JavaScript object style of
+% key-values (\texttt{\ameta{key}:\ameta{value}}), use \cs{cxkvsetkeys} as you would \cs{setkeys}:
+%\begin{quote}
+% \cs{cxkvsetkeys}\darg{\ameta{family}}\darg{\ameta{KV-pairs}}
+%\end{quote}
+% to convert \texttt{\ameta{key}:\ameta{value}} to \texttt{\ameta{key}=\ameta{value}} and \pkg{xkeyval} processes the keys as it
+% normally does. The comma (,) separates sets of key-value pairs and must not, therefore, be used as the delimiter
+% that separates the \ameta{key} from the \ameta{value}.
+%
+% The package is more general than what is described above. You can define several key-value delimiters, for whatever reason,
+% in your document or package. Declare a \textit{named} delimiter:
+%\begin{quote}\ttfamily
+%\cs{DeclareDelimiter}\darg{\ameta{name}}\darg{\ameta{delimiter}}
+%\end{quote}
+%Use the newly declared delimited as follows:
+%\begin{quote}
+%\cs{cxkvsetkeys(\ameta{name})}\darg{\ameta{family}}\darg{\ameta{KV-pairs}}
+%\end{quote}
+%The case of using a colon (:) for the delimiter is already defined, its name is `\texttt{colon}' and need not be declared.
+%
+%\paragraph*{Important change in syntax} With version dated 2017/01/03 or later, the optional argument \ameta{name} is now delimited
+%by \textbf{parentheses}, rather than the standard brackets. This is to be able to detect \ameta{name} when the full syntax
+%of \cs{setkeys} is used:
+%\changes{v1.1a}{2017/01/03}{Change in syntax, use parentheses rather than brackets}
+%\begin{quote}
+% \cs{setkeys*[\ameta{prefix}]\darg{\ameta{families}}[\ameta{na}]\darg{\ameta{keys}}}
+%\end{quote}
+%The syntax for \cs{cxkvsetkeys} shall be
+%\begin{quote}
+% \cs{cxkvsetkeys(\ameta{name})*[\ameta{prefix}]\darg{\ameta{families}}[\ameta{na}]\darg{\ameta{keys}}}
+%\end{quote}
+% The \pkg{conv-xkv} package does nothing with \pkg{xkeyval} arguments \texttt{*[\ameta{prefix}]} and
+% \texttt{[\ameta{na}]} other than to collect them and pass them on to \cs{setkeys} at the appropriate time.
+% The \pkg{conv-xkv} is concerned only with converting a new notation \texttt{\ameta{key}\ameta{delim}\ameta{value}}
+% to \texttt{\ameta{key}=\ameta{value}}.
+%
+% If the key-values do not contain the designated delimiter, \pkg{conv-xkv} simply passes everything on to \cs{setkeys}.
+% What this means is that, for example, both \cs{cxkvsetkeys\darg{myfam}\darg{fname:Don,lname:Story}} works as does
+% \cs{cxkvsetkeys\darg{myfam}\darg{fname=Don,lname=Story}}. One then has the option of using the standard notation
+% or an alternate notation.
+%
+%
+% \paragraph*{Demo file} The example file is \texttt{convert2xkeyval.tex}, use it to explore the possibilities and is found
+% in the \texttt{examples} folder of this distribution.
+%
+% \section{Preliminaries}
+% We require the \pkg{xkeyval} package.
+% \changes{v1.0}{2016/12/20}{Date of first upload to CTAN}
+% \begin{macrocode}
+\RequirePackage{xkeyval}
+% \end{macrocode}
+% The code below is taken from \pkg{hyperref}, and set and restore commands are renamed. This hopefully makes
+% a number of special characters available to act as a delimiter.
+% \begin{macrocode}
+\begingroup
+ \@makeother\`%
+ \@makeother\=%
+ \edef\x{%
+ \edef\noexpand\x{%
+ \endgroup
+ \noexpand\toks@{%
+ \catcode 96=\noexpand\the\catcode`\noexpand\`\relax
+ \catcode 61=\noexpand\the\catcode`\noexpand\=\relax
+ }%
+ }%
+ \noexpand\x
+ }%
+\x
+\@makeother\`
+\@makeother\=
+\def\ckv@SetCatcodes{%
+ \@makeother\`%
+ \@makeother\=%
+ \@makeother\~%
+ \catcode`\$=3 %
+ \catcode`\&=4 %
+ \catcode`\^=7 %
+ \catcode`\_=8 %
+ \@makeother\|%
+ \@makeother\:%
+ \@makeother\(%
+ \@makeother\)%
+ \@makeother\[%
+ \@makeother\]%
+ \@makeother\/%
+ \@makeother\!%
+ \@makeother\<%
+ \@makeother\>%
+ \@makeother\.%
+ \@makeother\;%
+ \@makeother\+%
+ \@makeother\-%
+ \@makeother\"%
+ \@makeother\'%
+}
+\begingroup
+ \def\x#1{\catcode`\noexpand#1=\the\catcode`#1\relax}%
+ \xdef\ckv@RestoreCatcodes{%
+ \the\toks@
+ \x\~%
+ \x\$%
+ \x\&%
+ \x\^%
+ \x\_%
+ \x\|%
+ \x\:%
+ \x\(%
+ \x\)%
+ \x\[%
+ \x\]%
+ \x\/%
+ \x\!%
+ \x\<%
+ \x\>%
+ \x\.%
+ \x\;%
+ \x\+%
+ \x\-%
+ \x\"%
+ \x\'%
+ }%
+\endgroup
+\ckv@SetCatcodes
+% \end{macrocode}
+% \section{Core commands for this package}
+% The default delimiter is the colon (:).
+% \begin{macrocode}
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\csarg\def{kvdelim-colon}{:}
+% \end{macrocode}
+% Use \DescribeMacro{\usekvdelim}\cs{usekvdelim} to display delimiter, as associated with
+% the argument \texttt{\#1}.
+% \begin{macrocode}
+\def\usekvdelim#1{\@nameuse{kvdelim-#1}}
+% \end{macrocode}
+% \begin{macro}{\DeclareDelimiter}
+% In the preamble, we declare the delimiter to be used. The command takes one argument, which
+% is the delimiter to be used, for example `\texttt{:}' or `\texttt{->}'. If this declaration
+% does not appear in the preamble, the delimiter is taken to be `\texttt{:}'.
+% \begin{macrocode}
+\def\DeclareDelimiter{\ckv@SetCatcodes\DeclareDelimiter@i}
+\def\DeclareDelimiter@i#1#2{\@ifundefined{kvdelim-#1}
+ {\csarg\def{kvdelim-#1}{#2}\ckv@RestoreCatcodes\cxkvSetup{#1}}
+ {\ckv@RestoreCatcodes}}
+\@onlypreamble\DeclareDelimiter
+% \end{macrocode}
+% \end{macro}
+% \cs{cxkv@tmptoks} is used to hold the converted key-values, the contents of
+% this token register is passed to \cs{setkeys} in \cs{cxkv@cnvrtDelimniiEquali}
+% \begin{macrocode}
+\newtoks\cxkv@tmptoks \cxkv@tmptoks={}
+\def\cxkv@dummy{dummy}
+\def\cxkv@dummyc{dummy,}
+\bgroup
+ \catcode`\#=12\relax\gdef\cxkvarg{#}
+ \obeyspaces\gdef\cxkv@TAB{ }
+\egroup
+% \end{macrocode}
+% \begin{macro}{\cxkvsetkeys}
+% This is the default definition, setup for using the colon (:) as the key-value
+% delimiter. But these next two commands are redefined by the
+% \cs{DeclareDelimiter} command in the preamble. The syntax is
+%\begin{quote}
+%\cs{cxkvsetkeys[\ameta{name}]}\darg{\ameta{family}}\darg{\ameta{KV-pairs}}
+%\end{quote}
+%where \ameta{KV-pairs} are the key-value pairs using the declared delimiter.
+%\begin{quote}\ttfamily
+%\cs{cxkvsetkeys}\darg{myfam}\{fname:\,Fred,lname:\,Flintstone\}
+%\end{quote}
+%The family \texttt{myfam} and keys \texttt{fname} and \texttt{lname} must have been defined
+%earlier: If the optional argument is not specified, then it is assumed the \ameta{name} argument
+%is \texttt{colon}, a reserved word for this package for this argument.
+%\begin{verbatim}
+% \define@key{myfam}{\def\fname{#1}}
+% \define@key{myfam}{\def\lname{#1}}
+%\end{verbatim}
+% \begin{macrocode}
+\def\cxkv@colon{colon}
+% \end{macrocode}
+% The general form for \cs{setkeys} is
+%\begin{quote}
+% \cs{setkeys*[\ameta{prefix}]\darg{\ameta{families}}[\ameta{na}]\darg{\ameta{keys}}}
+%\end{quote}
+% \begin{macro}{\cxkvsetkeys}
+%The syntax for \cs{cxkvsetkeys} shall be
+%\begin{quote}
+% \cs{cxkvsetkeys(\ameta{name})*[\ameta{prefix}]\darg{\ameta{families}}[\ameta{na}]\darg{\ameta{keys}}}
+%\end{quote}
+%The process to pick up the full parameter set of \cs{setkeys} is lengthy.
+% \begin{macrocode}
+\newcommand\cxkvsetkeys{%
+ \@ifnextchar({\cxkvsetkeys@i}{\cxkvsetkeys@i(colon)}}
+\def\cxkvsetkeys@i(#1){\cxkvsetkeys@ii{#1}}
+\def\cxkvsetkeys@ii#1{\def\cxkv@delimname{#1}\@ifstar
+ {\def\cxkv@skOpts{*}\cxkvsetkeys@iii}
+ {\def\cxkv@skOpts{}\cxkvsetkeys@iii}}
+\newcommand\cxkvsetkeys@iii[2][]{\def\@rgi{#1}\ifx\@rgi\@empty
+ \expandafter\def\expandafter\cxkv@skOpts
+ \expandafter{\cxkv@skOpts{#2}}\else
+ \expandafter\def\expandafter
+ \cxkv@skOpts\expandafter{\cxkv@skOpts[#1]{#2}}\fi
+ \def\thisxkvF@mily{#2}\cxkvsetkeys@iv}
+\newcommand\cxkvsetkeys@iv[2][]{\def\@rgi{#1}\ifx\@rgi\@empty\else
+ \expandafter\def\expandafter\cxkv@skOpts
+ \expandafter{\cxkv@skOpts[#1]}\fi
+ \expandafter\cxkvsetkeys@v\expandafter{\thisxkvF@mily}{#2}}
+\def\cxkvsetkeys@v#1#2{\cxkv@skipfalse
+ \ifx\cxkv@delimname\cxkv@colon\else
+ \InputIfFileExists{xkv-\cxkv@delimname.cut}
+ {\PackageInfo{conv-xkv}{Inputting xkv-\cxkv@delimname.cut}}
+ {\PackageInfo{conv-xkv}{Cannot find xkv-\cxkv@delimname.cut}}\fi
+ \@nameuse{cxkvsetkeys-\cxkv@delimname}{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\csarg\def{cxkvsetkeys-colon}#1#2{%
+ \def\thisxkvF@mily{#1}\def\thisxkvV@lues{#2}\def\cxkv@scratch{}%
+ \cxkv@tmptoks={}%
+ \@nameuse{cxkv@cnvrtDelimniiEqual-colon}#2,dummy:dummy,\@nil}
+\csarg\def{cxkv@cnvrtDelimniiEqual-colon}#1:#2,#3\@nil{%
+ \cxkv@cnvrtDelimniiEquali{colon}{#1}{#2}{#3}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\cxkvSetup}
+% Write the definitions of \cs{cxkvsetkeys} and \cs{cxkv@cnvrtDelimniiEqual} to
+% the file \texttt{conv-xkv.cut} then input this file back in.
+% \begin{macrocode}
+\def\cxkvSetup#1{\bgroup
+\IfFileExists{xkv-#1.cut}{\PackageInfo{conv-xkv}{xkv-#1.cut
+ already exists,\MessageBreak will not create another one}}{%
+ \PackageInfo{conv-xkv}{Creating the file xkv-#1.cut
+ containing\MessageBreak required definitions}%
+ \newwrite \cxkv@write
+ \uccode`c=`\%
+ \def\w{#1}\def\x{cxkvsetkeys-#1}%
+ \def\y{cxkv@cnvrtDelimniiEqual-#1}%
+ \def\z{kvdelim-#1}%
+ \immediate\openout \cxkv@write xkv-#1.cut
+ \immediate\write\cxkv@write{\string\makeatletter}%
+ \uppercase{\immediate\write\cxkv@write{\string
+ \csarg\string\def{\y}\cxkvarg1\@nameuse{\z}%
+ \cxkvarg2,\cxkvarg3\string\@nil{c^^J\cxkv@TAB
+ \string\cxkv@cnvrtDelimniiEquali{\w}{\cxkvarg1}%
+ {\cxkvarg2}{\cxkvarg3}}}}
+ \uppercase{\immediate\write\cxkv@write{\string\csarg\string\def
+ {\x}\cxkvarg1\cxkvarg2{c^^J\cxkv@TAB
+ \string\def\string\thisxkvF@mily{\cxkvarg1}\string
+ \def\string\thisxkvV@lues{\cxkvarg2}\string
+ \let\string\cxkv@scratch\string\@empty\string
+ \cxkv@tmptoks={}c^^J\cxkv@TAB
+ \string\@nameuse{\y}\cxkvarg2,%
+ \cxkv@dummy\@nameuse{\z}\cxkv@dummy,\string\@nil}}}
+ \immediate\write\cxkv@write{\string\makeatother}%
+ \immediate\closeout \cxkv@write
+}%
+\egroup}
+% \end{macrocode}
+% \end{macro}
+% \cs{cxkv@cnvrtDelimniiEquali} continues \cs{cxkv@cnvrtDelimniiEqual}. It is
+% the part that does not need to be redefined.
+% \begin{macrocode}
+\newif\ifcxkv@keyonly \cxkv@keyonlyfalse
+\def\cxkv@comma{,}
+\def\cxkv@removecomma#1,\@nil{\def\cxkv@key{#1}}
+\def\cxkv@parsecomma#1,#2\@nil{\def\@rgi{#1}\def\@rgii{#2}%
+ \ifx\@rgii\@empty\cxkv@keyonlyfalse\else
+ \cxkv@keyonlytrue\cxkv@removecomma#2\@nil\fi}
+\newif\ifcxkv@skip \cxkv@skipfalse
+\def\cxkv@cnvrtDelimniiEquali#1#2#3#4{%
+ \def\cxkv@rgiii{#3}\def\cxkv@rgiv{#4}%
+% \end{macrocode}
+% If the fourth argument is empty, that means there were no delimiters in the argument,
+% so we pass the original argument \cs{thisxkvF@mily} to \cs{setkeys}.
+% \changes{v1.1}{2017/01/03}{Try to detect if the expected delimiter is present at all}
+% \begin{macrocode}
+ \ifx\thisxkvV@lues\@empty\else
+ \ifx\cxkv@rgiv\@empty
+ \edef\cxkv@next{\noexpand
+ \setkeys\cxkv@skOpts{\thisxkvV@lues}}%
+ \cxkv@skiptrue
+ \fi
+ \fi
+ \let\thisxkvV@lues\@empty
+ \ifcxkv@skip\else
+ \ifx\cxkv@rgiii\cxkv@dummy
+ \cxkv@parsecomma#2,\@nil
+ \ifcxkv@keyonly
+ \edef\cxkv@tmp{\the\cxkv@tmptoks,\@rgi}%
+ \cxkv@tmptoks=\expandafter{\cxkv@tmp}%
+ \edef\cxkv@scratch{\the\cxkv@tmptoks}%
+ \edef\cxkv@next{\noexpand
+ \setkeys\cxkv@skOpts{\the\cxkv@tmptoks}}%
+ \else
+ \edef\cxkv@next{\noexpand
+ \setkeys\cxkv@skOpts{\the\cxkv@tmptoks}}%
+ \fi
+ \else
+ \cxkv@parsecomma#2,\@nil
+ \ifcxkv@keyonly
+ \edef\cxkv@tmp{\the\cxkv@tmptoks,\@rgi}%
+ \cxkv@tmptoks=\expandafter{\cxkv@tmp}%
+ \edef\cxkv@scratch{\the\cxkv@tmptoks}%
+ \edef\cxkv@next{\noexpand
+ \@nameuse{cxkv@cnvrtDelimniiEqual-#1}\cxkv@key
+ \@nameuse{kvdelim-#1}#3,#4\noexpand\@nil}
+ \else
+% \end{macrocode}
+% (2017/02/17) Enclose \texttt{\#3} in braces
+% \changes{v1.1c}{2017/02/17}{Enclose \string\texttt{\#3} in braces}
+% \begin{macrocode}
+ \cxkv@tmptoks=\expandafter{\cxkv@scratch,#2={#3}}%
+ \edef\cxkv@scratch{\the\cxkv@tmptoks}%
+ \def\cxkv@next{%
+ \@nameuse{cxkv@cnvrtDelimniiEqual-#1}#4\@nil}\fi
+ \fi\fi\cxkv@next
+}
+\ckv@RestoreCatcodes
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \Finale
+\endinput
diff --git a/macros/latex/contrib/conv-xkv/conv-xkv.ins b/macros/latex/contrib/conv-xkv/conv-xkv.ins
new file mode 100644
index 0000000000..0267adec6c
--- /dev/null
+++ b/macros/latex/contrib/conv-xkv/conv-xkv.ins
@@ -0,0 +1,63 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 1999-2006 D. P. Story
+%%
+%% This file is part of the `AcroTeX eDucation Bundle'.
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2016/12/21}
+\def\batchfile{conv-xkv.ins}
+%
+% If you can assume that the target audience for the document all have
+% Acrobat Reader 5.0 or later, then chance the following switch to true,
+% else, leave it as false.
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate{%
+ \file{conv-xkv.sty}{\from{conv-xkv.dtx}{copyright,package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
diff --git a/macros/latex/contrib/conv-xkv/doc/conv-xkv.pdf b/macros/latex/contrib/conv-xkv/doc/conv-xkv.pdf
new file mode 100644
index 0000000000..73e51289e4
--- /dev/null
+++ b/macros/latex/contrib/conv-xkv/doc/conv-xkv.pdf
Binary files differ
diff --git a/macros/latex/contrib/conv-xkv/examples/convert2xkeyval.tex b/macros/latex/contrib/conv-xkv/examples/convert2xkeyval.tex
new file mode 100644
index 0000000000..001e1c0325
--- /dev/null
+++ b/macros/latex/contrib/conv-xkv/examples/convert2xkeyval.tex
@@ -0,0 +1,119 @@
+\documentclass{article}
+\usepackage{conv-xkv}
+\usepackage{fancyvrb}
+
+% Use ordinary askii characters to declare a delimiter, usually
+% the delimiter is some combination of special characters: !@#:%^&*()_+=
+\DeclareDelimiter{arrow}{->}
+% The colon delimiter is already defined, and need not be declared
+%\DeclareDelimiter{colon}{:}
+
+% formatting cmd
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+
+\makeatletter
+\define@key{dps}{fname}[]{\def\fname{#1}}
+\define@key{dps}{mname}[]{\def\mname{#1}}
+\define@key{dps}{lname}[]{\def\lname{#1}}
+\define@choicekey{dps}{favorite}{AeB, AeB Pro, conv-xkv}[AeB]{\def\favoritepkg{#1}}
+\define@key{kaf}{home}[]{\def\myhome{#1}}
+\makeatother
+
+% Process keys using the arrow delimiter
+\def\setName#1{\cxkvsetkeys(arrow){dps,kaf}{#1}}
+% we use the default delimiter, colon (:)
+\def\setOtherName#1{\cxkvsetkeys{dps}{#1}}
+% we define the dps family for xkeyval
+\def\setStandName#1{\setkeys{dps}{#1}}
+
+\let\pkg\textsf
+\newcommand{\cs}[1]{\texttt{\char`\\#1}}
+\def\newtopic{\par\medskip}
+
+\parindent0pt
+
+\begin{document}
+
+In the preamble, we declare \verb~\DeclareDelimiter{arrow}{->}~.
+
+\newtopic
+The \pkg{conv-xkv} package converts key-values with alternate key-value delimiter
+to a form the \pkg{xkeyval} package expects them to be in.
+
+\setName {
+ fname-> D.,
+ mname-> P.,
+ lname-> Story,
+ favorite-> conv-xkv,
+ home-> {Niceville, FL}
+}
+\begin{Verbatim}[xleftmargin=\leftmargini,fontsize=\small]
+\def\setName#1{\cxkvsetkeys(arrow){dps,kaf}{#1}}
+\setName {
+ fname-> D.,
+ mname-> P.,
+ lname-> Story,
+ favorite-> conv-xkv,
+ home-> {Niceville, FL}
+}
+\end{Verbatim}
+The script above converts the notation \texttt{\ameta{key}\usekvdelim{arrow}\ameta{value}} to
+the notation of \pkg{xkeyval}, \texttt{\ameta{key}=\ameta{value}}. It is then passed to the
+\cs{setkeys} command of \pkg{xkeyval}.
+
+\newtopic\textbf{Results:}
+My name is {\fname} {\mname} {\lname} and my favorite {\LaTeX} package is
+\textsf{\favoritepkg}, my home is \myhome.
+
+\setOtherName {
+ fname: D.,
+ mname: Paul,
+ lname: Story,
+ favorite % use default
+}
+
+\newtopic Now we use the colon (:) delimiter:
+\begin{Verbatim}[xleftmargin=\leftmargini,fontsize=\small]
+\def\setOtherName#1{\cxkvsetkeys{dps}{#1}}
+\setOtherName {
+ fname: D.,
+ mname: Paul,
+ lname: Story,
+ favorite % use default
+}
+\end{Verbatim}
+The script above converts the colon notation \texttt{\ameta{key}\usekvdelim{colon}\ameta{value}} to
+the notation of \pkg{xkeyval}, \texttt{\ameta{key}=\ameta{value}}. This enables the implementation of
+\pkg{xkeyval} in packages that want to use object-property notation. Other variations are
+possible.
+
+\newtopic\textbf{Results:}
+My name is {\fname} {\mname} {\lname} and my favorite {\LaTeX} package is
+\textsf{\favoritepkg}.
+
+\newtopic
+Now here are the same results using the \pkg{xkeyval} package with the key-value delimiter
+\texttt{\ameta{key}=\ameta{value}} to verify that nothing has been disturbed.
+
+\setStandName {
+ fname= Don,
+ mname= Paulo,
+ lname= Story,
+ favorite
+}
+\begin{Verbatim}[xleftmargin=\leftmargini,fontsize=\small]
+\def\setStandName#1{\setkeys{dps}{#1}}
+\setStandName {
+ fname=Don,
+ mname=Paulo,
+ lname=Story,
+ favorite
+}
+\end{Verbatim}
+\textbf{Results:}
+My name is {\fname} {\mname} {\lname} and my favorite {\LaTeX} package is
+\textsf{\favoritepkg}.
+
+
+\end{document}
+