summaryrefslogtreecommitdiff
path: root/macros/latex/contrib
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-04-12 03:01:16 +0000
committerNorbert Preining <norbert@preining.info>2024-04-12 03:01:16 +0000
commit230773c2e42cd0257e4150d0b500aa7ca6c1c02a (patch)
treebe69af5c4925af979fe367b30051daa2458042a9 /macros/latex/contrib
parentd0af7e48198e8633e9bc60a77a66515bf39ad69f (diff)
CTAN sync 202404120301
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r--macros/latex/contrib/epcqrcode/README46
-rw-r--r--macros/latex/contrib/epcqrcode/epcqrcode-doc.pdfbin0 -> 160738 bytes
-rw-r--r--macros/latex/contrib/epcqrcode/epcqrcode.dtx710
-rw-r--r--macros/latex/contrib/epcqrcode/epcqrcode.ins51
-rw-r--r--macros/latex/contrib/fgruler/README2
-rw-r--r--macros/latex/contrib/fgruler/fgruler.dtx8
-rw-r--r--macros/latex/contrib/fgruler/fgruler.ins4
-rw-r--r--macros/latex/contrib/fgruler/fgruler.pdfbin486281 -> 486314 bytes
-rw-r--r--macros/latex/contrib/jsonparse/README.md37
-rw-r--r--macros/latex/contrib/jsonparse/jsonparse-doc.pdfbin380391 -> 386673 bytes
-rw-r--r--macros/latex/contrib/jsonparse/jsonparse-doc.tex32
-rw-r--r--macros/latex/contrib/jsonparse/jsonparse.sty100
12 files changed, 926 insertions, 64 deletions
diff --git a/macros/latex/contrib/epcqrcode/README b/macros/latex/contrib/epcqrcode/README
new file mode 100644
index 0000000000..e9c0ab8f86
--- /dev/null
+++ b/macros/latex/contrib/epcqrcode/README
@@ -0,0 +1,46 @@
+==============================================================================
+
+The `epcqrcode' package v1.0
+Copyright (C) 2024 by David Wedekind, Paul Kantiem, Dr. rer. nat. Wolf Müller (epc-qr-code@proton.me)
+
+This package is a wrapper for the 'qrcode' package.
+It generates valid EPC QR codes by providing syntax and validity checks for given inputs.
+
+Changes:
+- 2024-02-07 Initial version
+==============================================================================
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+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.3 or later is part of all distributions of LaTeX
+version 2008-05-04 or later.
+
+
+==============================================================================
+
+ This work consists of the files:
+README (this file)
+epcqrcode.dtx
+epcqrcode.ins
+ and the derived file:
+epcqrcode.sty
+
+ The distribution consists of the files:
+README (this file)
+epcqrcode.dtx
+epcqrcode.ins
+epcqrcode-doc.pdf (the user manual)
+
+-----------------------------------------------------------------
+
+ To install the package:
+- run: latex epcqrcode.ins (which will generate epcqrcode.sty)
+- Move epcqrqcode.sty to a location where LaTeX will find it (typically
+ in a local texmf tree at tex/latex/epcqrcode) and refresh the
+ file database. See the FAQ on CTAN at help/uk-tex-faq or
+ http://www.tug.ac.uk/faq for more information on this.
+ To process the user manual
+- run: pdflatex epcqrcode.dtx
diff --git a/macros/latex/contrib/epcqrcode/epcqrcode-doc.pdf b/macros/latex/contrib/epcqrcode/epcqrcode-doc.pdf
new file mode 100644
index 0000000000..f3241ce045
--- /dev/null
+++ b/macros/latex/contrib/epcqrcode/epcqrcode-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/epcqrcode/epcqrcode.dtx b/macros/latex/contrib/epcqrcode/epcqrcode.dtx
new file mode 100644
index 0000000000..ef2d1c8441
--- /dev/null
+++ b/macros/latex/contrib/epcqrcode/epcqrcode.dtx
@@ -0,0 +1,710 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2024 by David Wedekind, Paul Kantiem, Dr. rer. nat. Wolf Müller (epc-qr-code@proton.me)
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 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.3c or later is part of all distributions of
+% LaTeX version 2008-05-04 or later.
+%
+% \fi
+%
+% \iffalse
+%<package>\NeedsTeXFormat{LaTeX2e}[2022-06-01]%
+%<package>\ProvidesPackage{epcqrcode}[2024-02-07 v1.0 dtx epcqrcode file]%
+%<package>\RequirePackage{qrcode}%
+%<package>\RequirePackage{xstring}%
+%<package>\RequirePackage{calculator}%
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{epcqrcode}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\PrintChanges
+\PrintIndex
+\OnlyDescription
+\begin{document}
+ \DocInput{epcqrcode.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \changes{v1.0}{2024/02/07}{Initial version}
+% \GetFileInfo{epcqrcode.sty}
+%
+% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ }
+% \DoNotIndex{\@ne}
+% \DoNotIndex{\advance,\begingroup,\catcode,\closein}
+% \DoNotIndex{\closeout,\day,\def,\edef,\else,\empty,\endgroup}
+%
+% \title{The \textsf{epcqrcode} package\thanks{This document
+% corresponds to \textsf{epcqrcode}~\fileversion,
+% dated~\filedate.}}
+% \author{David Wedekind, Paul Kantiem, Dr. rer. nat. Wolf Müller \\ epc-qr-code@proton.me}
+% \date{February 07, 2024}
+%
+% \maketitle
+%
+% \section{Introduction}
+% This package is a wrapper for the \texttt{qrcode} package.
+% It offers an easy way to generate valid EPC QR codes by providing
+% syntax and validity checks, e.g. verifiying the correctness of the
+% IBAN.
+%
+% \section{Usage}
+%
+% \DescribeMacro{\epcqr}
+% The \texttt{\textbackslash epcqr} command uses the \LaTeX -builtin key-value system
+% to parse the user input. There are 3 mandatory keys to produce a
+% valid EPC QR code: \texttt{name}, \texttt{iban} and \texttt{amount}.
+% The following code produces a minimal example.
+% \\
+% \\
+%{
+%\tt
+%|\epcqr{| \\
+%| name=Wikimedia Foerdergesellschaft,| \\
+%| iban=DE33100205000001194700,| \\
+%| amount=123.45,| \\
+%|}|
+%}
+% \begin{center}
+% \epcqr{name=Wikimedia Foerdergesellschaft,iban=DE33100205000001194700,amount=123.45}
+% \end{center}
+% Note, that the maximum payload is limited to 334 bytes.
+% More specific information can be found in the guidelines\footnote{https://www.europeanpaymentscouncil.eu/document-library/guidance-documents/quick-response-code-guidelines-enable-data-capture-initiation}.
+% As of now the user is responsible to stay within this limit,
+% if they are using characters which are not part of following
+% character set:
+% (As specified under section 1.4 in the Customer-to-PSP Implementation Guidelines\footnote{https://www.europeanpaymentscouncil.eu/document-library/implementation-guidelines/sepa-credit-transfer-customer-psp-implementation})
+% \begin{center}
+% \texttt{a b c d e f g h i j k l m n o p q r s t u v w x y z}
+% \\
+% \texttt{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+% \\
+% \texttt{0 1 2 3 4 5 6 7 8 9}
+% \\
+% \texttt{/ - ? : ( ) . , ' +}
+% \\
+% \texttt{Space}
+% \end{center}
+% Additionally to the mandatory arguments, the user can provide more information:
+% \\
+% \\
+% \DescribeMacro{bic}
+% (Optional) The BIC code of the Beneficiary Payment Service Provider.
+% \\
+% \\
+% \DescribeMacro{name}
+% (Mandatory) The name of the Beneficiary. Maximum length is 70 characters.
+% \\
+% \\
+% \DescribeMacro{iban}
+% (Mandatory) The IBAN of the account of the Beneficiary
+% \\
+% \\
+% \DescribeMacro{amount}
+% (Mandatory)
+% Amount of the SEPA Credit Transfer in euro.
+% Amount must be larger than or equal to 0.01, and
+% cannot be larger than 999999999.99.
+% \\
+% \\
+% \DescribeMacro{reason}
+% (Optional)
+% Purpose of the SEPA Credit Transfer.
+% \\
+% \\
+% \DescribeMacro{ref}
+% (Optional)
+% The Remittance Information (a structured creditor reference code).
+% Note: If a reference code is given \texttt{text} must be empty.
+% \\
+% \\
+% \DescribeMacro{text}
+% (Optional)
+% The Remittance Information (an unstructured text).
+% Maximum Length is 140 characters.
+% Note: If a text is given \texttt{ref} must be empty.
+% \\
+% \\
+% \DescribeMacro{information}
+% (Optional)
+% Additional information for the user.
+% Maximum Length is 70 characters.
+%
+% \section{Options}
+% Since this package is a wrapper for the \texttt{qrcode} package, all of its
+% options can also be specified here using the \texttt{\textbackslash qrset} command.
+% \\
+% \\
+%{\tt
+%|\begin{document}| \\
+%| \qrset{height=5cm}%| \\
+%| \epcqr{| \\
+%| name=Wikimedia Foerdergesellschaft,| \\
+%| iban=DE33100205000001194700,| \\
+%| amount=123.45,| \\
+%| }| \\
+%|\end{document}|
+%}
+% \\
+% \\
+% Changing the level of the QR code does not have an effect, as EPC QR codes
+% have a set level.
+%
+%\StopEventually
+
+\newcommand{\epcqrcode@panic}[1]{\PackageError{epcqr}{#1}{Get some help...}}%
+
+\makeatletter%
+\DeclareKeys[epcqr]{%
+charset .store = \epcqr@charset,%
+bic .store = \epcqr@bic,%
+name .store = \epcqr@name,%
+iban .store = \epcqr@iban,%
+amount .store = \epcqr@amount,%
+reason .store = \epcqr@reason,%
+ref .store = \epcqr@ref,%
+text .store = \epcqr@text,%
+information .store = \epcqr@information%
+}%
+
+\newcounter{epcqrcode@IsBiggerIndex}%
+\newcommand{\epcqrcode@IsBiggerResult}{\empty}%
+\newcommand{\epcqrcode@IsBiggerIter}[2]{%
+ \StrChar{#1}{\value{epcqrcode@IsBiggerIndex}}[\epcqrcode@Firstepcqrcode@Current]%
+ \StrChar{#2}{\value{epcqrcode@IsBiggerIndex}}[\epcqrcode@Secondepcqrcode@Current]%
+ \ifx\epcqrcode@Firstepcqrcode@Current\empty%
+ \renewcommand{\epcqrcode@IsBiggerResult}{equal}%
+ \else%
+ \ifnum\epcqrcode@Firstepcqrcode@Current>\epcqrcode@Secondepcqrcode@Current%
+ \renewcommand{\epcqrcode@IsBiggerResult}{true}%
+ \else
+ \ifnum\epcqrcode@Firstepcqrcode@Current<\epcqrcode@Secondepcqrcode@Current%
+ \renewcommand{\epcqrcode@IsBiggerResult}{false}%
+ \else%
+ \stepcounter{epcqrcode@IsBiggerIndex}%
+ \epcqrcode@IsBiggerIter{#1}{#2}%
+ \fi%
+ \fi%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@IsBigger}[2]{%
+ \renewcommand{\epcqrcode@IsBiggerResult}{\empty}%
+ \StrLen{#1}[\epcqrcode@FirstLength]%
+ \StrLen{#2}[\epcqrcode@SecondLength]%
+ \ifnum\epcqrcode@FirstLength>\epcqrcode@SecondLength%
+ \renewcommand{\epcqrcode@IsBiggerResult}{true}%
+ \else%
+ \ifnum\epcqrcode@FirstLength<\epcqrcode@SecondLength%
+ \renewcommand{\epcqrcode@IsBiggerResult}{false}%
+ \else%
+ \renewcommand{\epcqrcode@IsBiggerResult}{\empty}%
+ \setcounter{epcqrcode@IsBiggerIndex}{1}%
+ \epcqrcode@IsBiggerIter{#1}{#2}%
+ \fi%
+ \fi%
+}%
+
+\newcounter{epcqrcode@ModuloIndex}%
+\newcommand{\epcqrcode@Current}{\empty}%
+\newcommand{\epcqrcode@NextNumberIter}{%
+ \stepcounter{epcqrcode@ModuloIndex}%
+ \StrChar{\epcqrcode@Dividend}{\value{epcqrcode@ModuloIndex}}[\epcqrcode@tmp]%
+ \ifx\epcqrcode@tmp\empty%
+ \relax%
+ \else%
+ \edef\epcqrcode@Current{\epcqrcode@Current\epcqrcode@tmp}%
+ \epcqrcode@IsBigger{\epcqrcode@Current}{\epcqrcode@Divisor}%
+ \IfStrEq{\epcqrcode@IsBiggerResult}{true}{}{%
+ \epcqrcode@NextNumberIter%
+ }%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@Dividend}{\empty}%
+\newcommand{\epcqrcode@Divisor}{\empty}%
+\newcommand{\epcqrcode@ModuloIter}{%
+ \StrLen{\epcqrcode@Dividend}[\epcqrcode@DividendLength]%
+ \ifnum\epcqrcode@DividendLength=\theepcqrcode@ModuloIndex%
+ \renewcommand{\epcqrcode@ModuloResult}{\epcqrcode@Current}%
+ \else%
+ \epcqrcode@NextNumberIter%
+ \epcqrcode@IsBigger{\epcqrcode@Divisor}{\epcqrcode@Current}%
+ \IfStrEq{\epcqrcode@IsBiggerResult}{true}{\renewcommand{\epcqrcode@ModuloResult}{\epcqrcode@Current}}{%
+ \INTEGERQUOTIENT{\epcqrcode@Current}{\epcqrcode@Divisor}{\epcqrcode@tmp}%
+ \MULTIPLY{\epcqrcode@Divisor}{\epcqrcode@tmp}{\epcqrcode@tmp}%
+ \SUBTRACT{\epcqrcode@Current}{\epcqrcode@tmp}{\epcqrcode@Current}%
+ \epcqrcode@ModuloIter%
+ }%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@ModuloResult}{\empty}%
+\newcommand{\epcqrcode@Modulo}[2]{%
+ \renewcommand{\epcqrcode@Current}{\empty}%
+ \renewcommand{\epcqrcode@Dividend}{#1}%
+ \renewcommand{\epcqrcode@Divisor}{#2}%
+ \epcqrcode@IsBigger{\epcqrcode@Divisor}{\epcqrcode@Dividend}%
+ \IfStrEq{\epcqrcode@IsBiggerResult}{true}{\renewcommand{\epcqrcode@ModuloResult}{\epcqrcode@Dividend}}{%
+ \IfStrEq{\epcqrcode@IsBiggerResult}{equal}{\renewcommand{\epcqrcode@ModuloResult}{0}}{%
+ \setcounter{epcqrcode@ModuloIndex}{0}%
+ \epcqrcode@ModuloIter%
+ }%
+ }%
+}%
+
+\newcommand{\epcqrcode@CheckCountryCode}[1]{%
+ \IfSubStr{,RU,LC,MT,SC,JO,KW,MU,EG,BR,QA,PS,UA,AL,AZ,BY,BJ,CI,DO,SV,GT,LB,ML,NI,PL,SN,HU,CY,BF,BI,FR,GA,GR,IT,CM,CG,MG,MR,MC,SM,CF,IR,IS,TR,AO,CV,LY,MZ,PT,ST,DZ,AD,VG,MD,PK,RO,SA,SE,SK,ES,CZ,TN,GI,IQ,IL,TL,AE,BH,BG,CR,DE,GE,IE,ME,RS,VA,GB,HR,LV,LI,CH,BA,EE,KZ,XK,LT,LU,MN,AT,MK,SI,DK,FO,FI,GL,NL,SD,BE,NO,}{,#1,}{}{\epcqrcode@panic{Wrong Country Code}}%
+}%
+
+\newcommand{\epcqrcode@CheckIbanLength}[2]{%
+ \IfStrEq{#1}{RU}{\ifnum 33=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LC}{\ifnum 32=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MT}{\ifnum 31=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SC}{\ifnum 31=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{JO}{\ifnum 30=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{KW}{\ifnum 30=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MU}{\ifnum 30=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{EG}{\ifnum 29=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BR}{\ifnum 29=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{QA}{\ifnum 29=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{PS}{\ifnum 29=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{UA}{\ifnum 29=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AL}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AZ}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BY}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BJ}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CI}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{DO}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SV}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GT}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LB}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{ML}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{NI}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{PL}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SN}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{HU}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CY}{\ifnum 28=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BF}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BI}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{FR}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GA}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GR}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IT}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CM}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CG}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MG}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MR}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MC}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SM}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CF}{\ifnum 27=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IR}{\ifnum 26=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IS}{\ifnum 26=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{TR}{\ifnum 26=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AO}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CV}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LY}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MZ}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{PT}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{ST}{\ifnum 25=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{DZ}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AD}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{VG}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MD}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{PK}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{RO}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SA}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SE}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SK}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{ES}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CZ}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{TN}{\ifnum 24=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GI}{\ifnum 23=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IQ}{\ifnum 23=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IL}{\ifnum 23=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{TL}{\ifnum 23=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AE}{\ifnum 23=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BH}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BG}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CR}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{DE}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GE}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{IE}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{ME}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{RS}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{VA}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GB}{\ifnum 22=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{HR}{\ifnum 21=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LV}{\ifnum 21=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LI}{\ifnum 21=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{CH}{\ifnum 21=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BA}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{EE}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{KZ}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{XK}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LT}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{LU}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MN}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{AT}{\ifnum 20=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{MK}{\ifnum 19=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SI}{\ifnum 19=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{DK}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{FO}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{FI}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{GL}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{NL}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{SD}{\ifnum 18=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{BE}{\ifnum 16=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+ \IfStrEq{#1}{NO}{\ifnum 15=#2\relax\else\epcqrcode@panic{Wrong Iban length for #1}\fi}{}%
+}%
+
+\newcommand{\epcqrcode@TranslateLetterResult}{\empty}%
+\newcommand{\epcqrcode@TranslateLetter}[1]{%
+ \renewcommand{\epcqrcode@TranslateLetterResult}{\empty}%
+ \IfStrEq{#1}{0}{\renewcommand{\epcqrcode@TranslateLetterResult}{0}}{}%
+ \IfStrEq{#1}{1}{\renewcommand{\epcqrcode@TranslateLetterResult}{1}}{}%
+ \IfStrEq{#1}{2}{\renewcommand{\epcqrcode@TranslateLetterResult}{2}}{}%
+ \IfStrEq{#1}{3}{\renewcommand{\epcqrcode@TranslateLetterResult}{3}}{}%
+ \IfStrEq{#1}{4}{\renewcommand{\epcqrcode@TranslateLetterResult}{4}}{}%
+ \IfStrEq{#1}{5}{\renewcommand{\epcqrcode@TranslateLetterResult}{5}}{}%
+ \IfStrEq{#1}{6}{\renewcommand{\epcqrcode@TranslateLetterResult}{6}}{}%
+ \IfStrEq{#1}{7}{\renewcommand{\epcqrcode@TranslateLetterResult}{7}}{}%
+ \IfStrEq{#1}{8}{\renewcommand{\epcqrcode@TranslateLetterResult}{8}}{}%
+ \IfStrEq{#1}{9}{\renewcommand{\epcqrcode@TranslateLetterResult}{9}}{}%
+ \IfStrEq{#1}{A}{\renewcommand{\epcqrcode@TranslateLetterResult}{10}}{}%
+ \IfStrEq{#1}{B}{\renewcommand{\epcqrcode@TranslateLetterResult}{11}}{}%
+ \IfStrEq{#1}{C}{\renewcommand{\epcqrcode@TranslateLetterResult}{12}}{}%
+ \IfStrEq{#1}{D}{\renewcommand{\epcqrcode@TranslateLetterResult}{13}}{}%
+ \IfStrEq{#1}{E}{\renewcommand{\epcqrcode@TranslateLetterResult}{14}}{}%
+ \IfStrEq{#1}{F}{\renewcommand{\epcqrcode@TranslateLetterResult}{15}}{}%
+ \IfStrEq{#1}{G}{\renewcommand{\epcqrcode@TranslateLetterResult}{16}}{}%
+ \IfStrEq{#1}{H}{\renewcommand{\epcqrcode@TranslateLetterResult}{17}}{}%
+ \IfStrEq{#1}{I}{\renewcommand{\epcqrcode@TranslateLetterResult}{18}}{}%
+ \IfStrEq{#1}{J}{\renewcommand{\epcqrcode@TranslateLetterResult}{19}}{}%
+ \IfStrEq{#1}{K}{\renewcommand{\epcqrcode@TranslateLetterResult}{20}}{}%
+ \IfStrEq{#1}{L}{\renewcommand{\epcqrcode@TranslateLetterResult}{21}}{}%
+ \IfStrEq{#1}{M}{\renewcommand{\epcqrcode@TranslateLetterResult}{22}}{}%
+ \IfStrEq{#1}{N}{\renewcommand{\epcqrcode@TranslateLetterResult}{23}}{}%
+ \IfStrEq{#1}{O}{\renewcommand{\epcqrcode@TranslateLetterResult}{24}}{}%
+ \IfStrEq{#1}{P}{\renewcommand{\epcqrcode@TranslateLetterResult}{25}}{}%
+ \IfStrEq{#1}{Q}{\renewcommand{\epcqrcode@TranslateLetterResult}{26}}{}%
+ \IfStrEq{#1}{R}{\renewcommand{\epcqrcode@TranslateLetterResult}{27}}{}%
+ \IfStrEq{#1}{S}{\renewcommand{\epcqrcode@TranslateLetterResult}{28}}{}%
+ \IfStrEq{#1}{T}{\renewcommand{\epcqrcode@TranslateLetterResult}{29}}{}%
+ \IfStrEq{#1}{U}{\renewcommand{\epcqrcode@TranslateLetterResult}{30}}{}%
+ \IfStrEq{#1}{V}{\renewcommand{\epcqrcode@TranslateLetterResult}{31}}{}%
+ \IfStrEq{#1}{W}{\renewcommand{\epcqrcode@TranslateLetterResult}{32}}{}%
+ \IfStrEq{#1}{X}{\renewcommand{\epcqrcode@TranslateLetterResult}{33}}{}%
+ \IfStrEq{#1}{Y}{\renewcommand{\epcqrcode@TranslateLetterResult}{34}}{}%
+ \IfStrEq{#1}{Z}{\renewcommand{\epcqrcode@TranslateLetterResult}{35}}{}%
+}%
+
+\newcounter{epcqrcode@c}%
+\newcommand{\epcqrcode@TranslateLettersResult}{\empty}%
+\newcommand{\epcqrcode@TranslateLetters}[1]{%
+ \renewcommand{\epcqrcode@TranslateLettersResult}{\empty}%
+ \setcounter{epcqrcode@c}{1}%
+ \epcqrcode@TranslateLettersIter{#1}%
+}%
+
+\newcommand{\epcqrcode@TranslateLettersIter}[1]{%
+ \StrChar{#1}{\theepcqrcode@c}[\epcqrcode@tmp]%
+ \ifx\epcqrcode@tmp\empty%
+ \relax%
+ \else%
+ \epcqrcode@TranslateLetter{\epcqrcode@tmp}%
+ \edef\epcqrcode@current{\epcqrcode@TranslateLetterResult}%
+ \edef\epcqrcode@TranslateLettersResult{\epcqrcode@TranslateLettersResult\epcqrcode@current}%
+ \stepcounter{epcqrcode@c}%
+ \epcqrcode@TranslateLettersIter{#1}%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@CheckIban}[1]{%
+ \StrLen{#1}[\epcqrcode@IbanLength]%
+ \StrLeft{#1}{4}[\epcqrcode@CountryPlusCheck]%
+ \StrRight{\epcqrcode@CountryPlusCheck}{2}[\epcqrcode@Check]%
+ \StrGobbleRight{\epcqrcode@CountryPlusCheck}{2}[\epcqrcode@Country]%
+ \epcqrcode@CheckCountryCode{\epcqrcode@Country}%
+ \epcqrcode@CheckIbanLength{\epcqrcode@Country}{\epcqrcode@IbanLength}%
+ \StrGobbleLeft{#1}{4}[\epcqrcode@Iban]%
+ \epcqrcode@TranslateLetters{\epcqrcode@Iban\epcqrcode@CountryPlusCheck}%
+ \edef\epcqrcode@TranslatedIban{\epcqrcode@TranslateLettersResult}%
+ \epcqrcode@Modulo{\epcqrcode@TranslatedIban}{97}%
+ \ifnum\epcqrcode@ModuloResult=1%
+ \relax%
+ \else%
+ \epcqrcode@panic{Iban check failed}%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@CheckCreditorReference}[1]{%
+ \StrLen{#1}[\epcqrcode@CreditorReferenceLength]%
+ \ifnum\epcqrcode@CreditorReferenceLength>25%
+ \epcqrcode@panic{Creditor reference too long}%
+ \else%
+ \ifnum\epcqrcode@CreditorReferenceLength<5%
+ \epcqrcode@panic{Creditor reference too short}%
+ \fi%
+ \fi%
+ \StrLeft{#1}{4}[\epcqrcode@IdentifierPlusCheck]%
+ \StrGobbleLeft{#1}{4}[\epcqrcode@Reference]%
+ \epcqrcode@TranslateLetters{\epcqrcode@Reference\epcqrcode@IdentifierPlusCheck}%
+ \edef\epcqrcode@TranslatedCreditorReference{\epcqrcode@TranslateLettersResult}%
+ \epcqrcode@Modulo{\epcqrcode@TranslatedCreditorReference}{97}%
+ \ifnum\epcqrcode@ModuloResult=1%
+ \relax%
+ \else%
+ \epcqrcode@panic{Creditor reference check failed}%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@CheckBIC}[1]{%
+ \StrLen{#1}[\epcqrcode@length]%
+ \ifnum8=\epcqrcode@length%
+ \relax%
+ \else%
+ \ifnum11=\epcqrcode@length%
+ \relax%
+ \else%
+ \epcqrcode@panic{Wrong BIC length}%
+ \fi%
+ \fi%
+ \StrChar{#1}{5}[\epcqrcode@FirstCountry]%
+ \StrChar{#1}{6}[\epcqrcode@SecondCountry]%
+ \epcqrcode@CheckCountryCode{\epcqrcode@FirstCountry\epcqrcode@SecondCountry}%
+}%
+
+\newcommand{\epcqrcode@CheckTextLength}[1]{%
+ \StrLen{#1}[\epcqrcode@length]%
+ \ifnum\epcqrcode@length<141\relax\else\PackageWarning{epcqr}{Text possibly too long}\fi%
+}%
+
+\newcommand{\epcqrcode@CheckNameLength}[1]{%
+ \StrLen{#1}[\epcqrcode@length]%
+ \ifnum\epcqrcode@length<71\relax\else\PackageWarning{epcqr}{Name possibly too long}\fi%
+}%
+
+\newcommand{\epcqrcode@CheckReason}[1]{%
+ \IfSubStr{,BENE,BONU,CBFF,CHAR,GOVT,PENS,SALA,SSBE,CBLK,CDCB,CDCD,CDCS,CDOC,CDQC,ETUP,FCOL,MTUP,ACCT,CASH,COLL,CSDB,DEPT,INTC,LIMA,NETT,AGRT,AREN,BEXP,BOCE,COMC,CPYR,GDDS,GDSV,GSCB,LICF,POPE,ROYA,SCVE,SUBS,SUPP,TRAD,COMT,CLPR,DBTC,GOVI,HLRP,INPC,INSU,INTE,LBRI,LIFI,LOAN,LOAR,PENO,PPTI,RINP,TRFD,ADMG,ADVA,BLDM,CCRD,CDBL,CFEE,COST,DCRD,FAND,ICCP,IDCP,IHRP,INSM,MSVC,NOWS,OFEE,OTHR,PADD,PTSP,RCKE,RCPT,REFU,RENT,STDY,TELI,WEBI,ANNI,CAFI,CFDI,CMDT,DERI,DIVD,FREX,HEDG,PRME,SAVG,SECU,SEPI,TREA,ANTS,CVCF,DMEQ,DNTS,HLTC,HLTI,HSPC,ICRF,LTCF,MDCS,VIEW,ALMY,AEMP,BECH,COMM,CSLP,GFRP,GVEA,GVEB,GVEC,GVED,GWLT,EPAY,PAYR,PRCP,RHBS,ESTX,HSTX,INTX,NITX,TAXS,VATX,WHLD,TAXR,AIRB,BUSB,FERB,RLWY,CBTV,ELEC,ENRG,GASB,NWCH,NWCM,OTLC,PHON,WTER,}{,#1,}{}{\epcqrcode@panic{Wrong reason}}%
+}%
+
+\newcommand{\epcqrcode@CheckIfNumber}[1]{%
+ \IfSubStr{,0,1,2,3,4,5,6,7,8,9,}{,#1,}{\relax}{\epcqrcode@panic{Amount has wrong format (not a number)}}%
+}%
+
+\newcommand{\epcqrcode@IterateAmount}[1]{%
+ \StrChar{#1}{\theepcqrcode@c}[\epcqrcode@tmp]%
+ \ifx\epcqrcode@tmp\empty%
+ \relax%
+ \else%
+ \epcqrcode@CheckIfNumber{\epcqrcode@tmp}%
+ \stepcounter{epcqrcode@c}%
+ \epcqrcode@IterateAmount{#1}%
+ \fi%
+}%
+
+\newcommand{\epcqrcode@CheckAmount}[1]{%
+ \edef\epcqrcode@Amount{#1}%
+ \IfSubStr[1]{\epcqrcode@Amount}{.}{%
+ \StrRight{#1}{2}[\epcqrcode@LastTwoChars]%
+ \StrChar{\epcqrcode@LastTwoChars}{1}[\epcqrcode@PotentialDot]%
+ \IfStrEq{\epcqrcode@PotentialDot}{.}{\edef\epcqrcode@Amount{\epcqrcode@Amount0}}{\relax}%
+ }{%
+ \edef\epcqrcode@Amount{\epcqrcode@Amount.00}%
+ }%
+ \StrLen{\epcqrcode@Amount}[\epcqrcode@AmountLength]%
+ \ifnum\epcqrcode@AmountLength>12\epcqrcode@panic{Amount too big}\fi%
+ \ifnum\epcqrcode@AmountLength<4\epcqrcode@panic{Amount too small}\fi%
+ \StrRight{\epcqrcode@Amount}{3}[\epcqrcode@LastThreeChars]%
+ \StrChar{\epcqrcode@LastThreeChars}{1}[\epcqrcode@PotentialDot]%
+ \IfStrEq{\epcqrcode@PotentialDot}{.}{}{\epcqrcode@panic{Amount has wrong format}}%
+ \StrDel[1]{\epcqrcode@Amount}{.}[\epcqrcode@AmountWithoutDot]%
+ \setcounter{epcqrcode@c}{1}%
+ \epcqrcode@IterateAmount{\epcqrcode@AmountWithoutDot}%
+ \ifnum\epcqrcode@AmountLength=4\IfStrEq{\epcqrcode@Amount}{0.00}{\epcqrcode@panic{Amount too small}}{\relax}\fi%
+}%
+
+\newcommand{\epcqrcode@EscapeWhitespaceResult}{\empty}%
+\newcommand{\epcqrcode@EscapeWhitespace}[1]{%
+ \renewcommand{\epcqrcode@EscapeWhitespaceResult}{\empty}%
+ \setcounter{epcqrcode@c}{1}%
+ \epcqrcode@EscapeWhitespaceIter{#1}%
+}%
+
+\newcommand{\epcqrcode@EscapeWhitespaceIter}[1]{%
+ \StrChar{#1}{\theepcqrcode@c}[\epcqrcode@tmp]%
+ \ifx\epcqrcode@tmp\empty%
+ \relax%
+ \else%
+ \IfStrEq{\epcqrcode@tmp}{ }{%
+ \edef\epcqrcode@EscapeWhitespaceResult{\epcqrcode@EscapeWhitespaceResult\ }%
+ }{%
+ \edef\epcqrcode@EscapeWhitespaceResult{\epcqrcode@EscapeWhitespaceResult\epcqrcode@tmp}%
+ }%
+ \stepcounter{epcqrcode@c}%
+ \epcqrcode@EscapeWhitespaceIter{#1}%
+ \fi%
+}%
+
+\newcounter{epcqrcode@OverallLength}%
+\newcommand{\epcqrcode@OverallSize}{%
+ \setcounter{epcqrcode@OverallLength}{22}%
+ \ifx\epcqr@bic\empty%
+ \relax%
+ \else%
+ \StrLen{\epcqrcode@CleanedBic}[\epcqrcode@BicLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@BicLength}%
+ \fi%
+ \StrLen{\epcqrcode@EscapedName}[\epcqrcode@NameLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@NameLength}%
+ \StrLen{\epcqrcode@CleanedIban}[\epcqrcode@IbanLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@IbanLength}%
+ \ifreasonx\epcqr@amount\empty%
+ \relax%
+ \else%
+ \StrLen{\epcqr@amount}[\epcqrcode@AmountLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@AmountLength}%
+ \addtocounter{epcqrcode@OverallLength}{3}%
+ \fi%
+ \ifx\epcqr@reason\empty%
+ \relax%
+ \else%
+ \StrLen{\ecpqr@reason}[\epcqrcode@ReasonLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@ReasonLength}%
+ \fi%
+ \ifx\epcqr@ref\empty%
+ \relax%
+ \else%
+ \StrLen{\epcqr@ref}[\epcqrcode@RefLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@RefLength}%
+ \fi%
+ \ifx\epcqr@text\empty%
+ \relax%
+ \else%
+ \StrLen{\epcqrcode@EscapedText}[\epcqrcode@TextLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@TextLength}%
+ \fi%
+ \ifx\epcqr@information\empty%
+ \relax%
+ \else%
+ \StrLen{\epcqrcode@EscapedInformation}[\epcqrcode@InformationLength]%
+ \addtocounter{epcqrcode@OverallLength}{\epcqrcode@InformationLength}%
+ \fi%
+ \ifnum\theepcqrcode@OverallLength>331%
+ \epcqrcode@panic{Overall payload too big}%
+ \fi%
+}%
+
+\newcounter{epcqrcode@z}%
+\NewDocumentCommand\epcqr{m}{%
+ \begingroup%
+ \SetKeys[epcqr]{#1}%
+
+ \ifx\epcqr@name\@empty\epcqrcode@panic{No name provided}\fi%
+ \epcqrcode@CheckNameLength{\epcqr@name}%
+ \epcqrcode@EscapeWhitespace{\epcqr@name}%
+ \edef\epcqrcode@EscapedName{\epcqrcode@EscapeWhitespaceResult}%
+
+ \ifx\epcqr@iban\@empty\epcqrcode@panic{No iban provided}\fi%
+ \StrDel[0]{\epcqr@iban}{ }[\epcqrcode@CleanedIban]%
+ \epcqrcode@CheckIban{\epcqrcode@CleanedIban}%
+
+ \ifx\epcqr@amount\@empty%
+ \relax%
+ \else%
+ \epcqrcode@CheckAmount{\epcqr@amount}%
+ \fi%
+
+ \ifx\epcqr@ref\@empty%
+ \relax%
+ \else%
+ \ifx\epcqr@text\@empty%
+ \StrDel[0]{\epcqr@ref}{ }[\epcqrcode@CleanedRef]%
+ \epcqrcode@CheckCreditorReference{\epcqrcode@CleanedRef}%
+ \else%
+ \epcqrcode@panic{Either ref or text}%
+ \fi%
+ \fi%
+
+ \ifx\epcqr@text\@empty%
+ \relax%
+ \else%
+ \epcqrcode@EscapeWhitespace{\epcqr@text}%
+ \edef\epcqrcode@EscapedText{\epcqrcode@EscapeWhitespaceResult}%
+ \fi%
+
+ \epcqrcode@CheckTextLength{\epcqr@text}%
+ \ifx\epcqr@bic\@empty%
+ \relax%
+ \else%
+ \StrDel[0]{\epcqr@bic}{ }[\epcqrcode@CleanedBic]%
+ \epcqrcode@CheckBIC{\epcqrcode@CleanedBic}%
+ \fi%
+
+ \ifx\epcqr@reason\@empty\else\epcqrcode@CheckReason{\epcqr@reason}\fi%
+
+ \ifx\epcqr@information\empty%
+ \relax%
+ \else%
+ \epcqrcode@EscapeWhitespace{\epcqr@information}%
+ \edef\epcqrcode@EscapedInformation{\epcqrcode@EscapeWhitespaceResult}%
+ \StrLen{\epcqrcode@EscapedInformation}[\epcqrcode@InfLength]%
+ \ifnum\epcqrcode@InfLength>70%
+ \PackageWarning{epcqr}{Information possibly too long}%
+ \fi%
+ \fi%
+
+ \epcqrcode@OverallSize%
+
+ \setcounter{epcqrcode@z}{5}%
+ \ifx\epcqr@information\empty%
+ \setcounter{epcqrcode@z}{4}%
+ \ifx\epcqr@text\empty%
+ \setcounter{epcqrcode@z}{3}%
+ \ifx\epcqr@ref\empty%
+ \setcounter{epcqrcode@z}{2}%
+ \ifx\epcqr@reason\empty%
+ \setcounter{epcqrcode@z}{1}%
+ \ifx\epcqr@amount\empty%
+ \setcounter{epcqrcode@z}{0}%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+
+ \qrcode[level=M, nolinks]{%
+ BCD\?%
+ 002\?%
+ \ifx\epcqr@charset\@empty 1\?\else\epcqr@charset\?\fi%
+ SCT\?%
+ \ifx\epcqr@bic\@empty\?\else\epcqrcode@CleanedBic\?\fi%
+ \epcqrcode@EscapedName\?%
+ \epcqrcode@CleanedIban%
+ \ifnum\theepcqrcode@z>0\?\fi%
+ \ifx\epcqr@amount\@empty\else EUR\epcqr@amount\fi%
+ \ifnum\theepcqrcode@z>1\?\fi%
+ \ifx\epcqr@reason\@empty\else\epcqr@reason\fi%
+ \ifnum\theepcqrcode@z>2\?\fi%
+ \ifx\epcqr@ref\@empty\else\epcqrcode@CleanedRef\fi%
+ \ifnum\theepcqrcode@z>3\?\fi%
+ \ifx\epcqr@text\@empty\else\epcqrcode@EscapedText\fi%
+ \ifnum\theepcqrcode@z>4\?\fi%
+ \ifx\epcqr@information\@empty\else\epcqrcode@EscapedInformation\fi%
+ }%
+ \endgroup%
+}%
+\makeatother%
+% \Finale
+\endinput
diff --git a/macros/latex/contrib/epcqrcode/epcqrcode.ins b/macros/latex/contrib/epcqrcode/epcqrcode.ins
new file mode 100644
index 0000000000..e0bd9d6bb3
--- /dev/null
+++ b/macros/latex/contrib/epcqrcode/epcqrcode.ins
@@ -0,0 +1,51 @@
+%%
+%% Copyright (C) 2024 by David Wedekind, Paul Kantiem, Dr. rer. nat. Wolf Müller (epc-qr-code@proton.me)
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3 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.3c or later is part of all distributions of
+%% LaTeX version 2008-05-04 or later.
+%%
+\input docstrip.tex
+\keepsilent
+\usedir{tex/latex/epcqrcode}
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2024 by David Wedekind, Paul Kantiem, Dr. rer. nat. Wolf Müller (epc-qr-code@proton.me)
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3 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.3c or later is part of all distributions of
+LaTeX version 2008-05-04 or later.
+
+\endpreamble
+
+\generate{\file{epcqrcode.sty}{\from{epcqrcode.dtx}{package}}}
+
+\obeyspaces
+\Msg{****************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the *}
+\Msg{* following file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* epcqrcode.sty *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file *}
+\Msg{* epcqrcode.dtx through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{****************************************************}
+
+\endbatchfile
diff --git a/macros/latex/contrib/fgruler/README b/macros/latex/contrib/fgruler/README
index 3e9b6c5821..2b4492a07d 100644
--- a/macros/latex/contrib/fgruler/README
+++ b/macros/latex/contrib/fgruler/README
@@ -1,6 +1,6 @@
fgruler.sty package
-Copyright 2017-2022 by Tibor Tomacs
+Copyright 2017-2024 by Tibor Tomacs
Package for drawing rulers on the foreground or in the text
diff --git a/macros/latex/contrib/fgruler/fgruler.dtx b/macros/latex/contrib/fgruler/fgruler.dtx
index e49d112cef..233c515bc6 100644
--- a/macros/latex/contrib/fgruler/fgruler.dtx
+++ b/macros/latex/contrib/fgruler/fgruler.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright 2017-2022 by Tibor Tomacs
+% Copyright 2017-2024 by Tibor Tomacs
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -21,7 +21,7 @@
\ProvidesFile{fgruler.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
-%<package>\ProvidesPackage{fgruler}[2022/06/25 v1.5 Package for drawing rulers on the foreground or in the text]
+%<package>\ProvidesPackage{fgruler}[2024/04/11 v1.6 Package for drawing rulers on the foreground or in the text]
%
%<*driver>
\documentclass{ltxdoc}
@@ -64,8 +64,8 @@ keepspaces]}
%
% \GetFileInfo{fgruler.sty}
%
-% \title{The \texorpdfstring{{\bfseries\sffamily fgruler} package\\{\large v1.5 (2022/06/25)}}{fgruler package}}
-% \author{\texorpdfstring{Tibor T\'{o}m\'{a}cs\\{\normalsize\url{tomacs.tibor@uni-eszterhazy.hu}}}{Tibor T\'{o}m\'{a}cs}}
+% \title{The \texorpdfstring{{\bfseries\sffamily fgruler} package\\{\large v1.6 (2024/04/11)}}{fgruler package}}
+% \author{\texorpdfstring{Tibor T\'{o}m\'{a}cs\\{\normalsize\href{mailto:tomacs.tibor@gmail.com}{\texttt{tomacs.tibor@gmail.com}}}}{Tibor T\'{o}m\'{a}cs}}
% \date{}
% \maketitle
%
diff --git a/macros/latex/contrib/fgruler/fgruler.ins b/macros/latex/contrib/fgruler/fgruler.ins
index 85d39020bf..3bca829acb 100644
--- a/macros/latex/contrib/fgruler/fgruler.ins
+++ b/macros/latex/contrib/fgruler/fgruler.ins
@@ -1,5 +1,5 @@
-% Copyright 2017-2022 by Tibor Tomacs
+% Copyright 2017-2024 by Tibor Tomacs
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -19,7 +19,7 @@
\preamble
This is a generated file.
-Copyright 2017-2022 by Tibor Tomacs
+Copyright 2017-2024 by Tibor Tomacs
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/fgruler/fgruler.pdf b/macros/latex/contrib/fgruler/fgruler.pdf
index 89e49aac7b..7f1454b436 100644
--- a/macros/latex/contrib/fgruler/fgruler.pdf
+++ b/macros/latex/contrib/fgruler/fgruler.pdf
Binary files differ
diff --git a/macros/latex/contrib/jsonparse/README.md b/macros/latex/contrib/jsonparse/README.md
index 9576069ea3..b2253c2a85 100644
--- a/macros/latex/contrib/jsonparse/README.md
+++ b/macros/latex/contrib/jsonparse/README.md
@@ -1,4 +1,4 @@
-![Version 0.5.5](https://img.shields.io/badge/version-0.5.5-blue)
+![Version 0.5.6](https://img.shields.io/badge/version-0.5.6-blue)
# The `jsonparse` package
@@ -12,35 +12,34 @@ Let's assume a file with the name `example.json` is stored in the working direct
```
{
- "first_name": "John",
- "last_name": "Smith",
- "is_alive": true,
- "age": 27,
+ "givenName": "Joe",
+ "familyName": "Public",
+ "points": 1.7,
+ "hasCertification": true,
"address": {
- "street_address": "21 2nd Street",
- "city": "New York",
- "state": "NY",
- "postal_code": "10021-3100"
+ "streetAddress": "10 Main St",
+ "locality": "Cityville",
+ "postalCode": "12345"
},
- "phone_numbers": [
+ "contactPoint": [
{
- "type": "home",
- "number": "212 555-1234"
+ "contactType": "office",
+ "telephone": "+1 (555) 555-1234"
},
{
- "type": "office",
- "number": "646 555-4567"
+ "contactType": "mobile",
+ "telephone": "+1 (555) 555-6789"
}
],
"children": [
- "Catherine",
- "Thomas",
- "Trevor"
+ "Tom,
+ "Doug",
+ "Harry"
],
- "spouse": null
+ "memberOf": null
}
```
-We can store it in the token variable `\myJSONdata` using the command `\JSONParseFromFile{\myJSONdata}{example.json}`. Calling the command `\JSONParseGetValue{\myJSONdata}{phone_numbers[0].number}` would then result in the output `212 555-1234` (indices are zero-based per default).
+We can store it in the token variable `\myJSONdata` using the command `\JSONParseFromFile{\myJSONdata}{example.json}`. Calling the command `\JSONParseGetValue{\myJSONdata}{contactPoint[0].telephone}` would then result in the output `+1 (555) 555-1234` (indices are zero-based per default).
This package including all files is subject to the LPPL 1.3c license.
diff --git a/macros/latex/contrib/jsonparse/jsonparse-doc.pdf b/macros/latex/contrib/jsonparse/jsonparse-doc.pdf
index 127c25d2a5..6e81ca7c44 100644
--- a/macros/latex/contrib/jsonparse/jsonparse-doc.pdf
+++ b/macros/latex/contrib/jsonparse/jsonparse-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/jsonparse/jsonparse-doc.tex b/macros/latex/contrib/jsonparse/jsonparse-doc.tex
index 3fe058a3ea..2b0eff21c8 100644
--- a/macros/latex/contrib/jsonparse/jsonparse-doc.tex
+++ b/macros/latex/contrib/jsonparse/jsonparse-doc.tex
@@ -11,8 +11,8 @@
% This work has the LPPL maintenance status `author-maintained'.
%
\documentclass[a4paper]{article}
-\def\jsonparsefileversion{0.5.5}
-\def\jsonparsefiledate{9 April 2024}
+\def\jsonparsefileversion{0.5.6}
+\def\jsonparsefiledate{11 April 2024}
\usepackage[T1]{fontenc}
\usepackage{Alegreya}
@@ -189,6 +189,7 @@
\changes{v0.3.0}{2024/04/08}{First public beta release.}
\changes{v0.5.0}{2024/04/09}{Changed from string token variables to token lists to support Unicode.}
\changes{v0.5.5}{2024/04/09}{Bug fixes, introduction and enhancement of user functions.}
+\changes{v0.5.6}{2024/04/11}{Bug fixes, escaping of special chars added.}
\begin{document}
@@ -200,6 +201,8 @@
The \macro{jsonparse} package provides an easy way to read in JSON data from files or strings in LaTeX documents, parse the data and store it in a user-defined token variable. The package allows accessing the stored data via a JavaScript-flavored syntax.
+This package is still in a beta stage and not thoroughly tested. Bugs or improvements can be issued via GitHub at \url{https://github.com/jasperhabicht/jsonparse/issues}.
+
\section{Loading the package}
To install the package, copy the package file \macro{jsonparse.sty} into the working directory or into the \macro{texmf} directory. After the package has been installted, the \macro{jsonparse} package is loaded by calling \macro{\usepackage{jsonparse}} in the preamble of the document.
@@ -209,6 +212,20 @@ The package does not load any dependencies.
\begin{macrodef}debug\end{macrodef}
The package can be loaded with the option \macro{debug}. It will then output to the log file every instance of a string, a boolean (true or false) value, a null value, a number as well as the start and end of every object and the start and end of every array that is found while parsing the JSON string or JSON file.
+\section{Escaping and special treatment of the input}
+
+The package allows for empty lines in JSON strings. During parsing, every instance of the TeX macro \macro{\par} is replaced by a space.
+
+JSON strings cannot contain the two characters \macro{"} and \macro{\}. These two characters need to be escaped with a preceding backslash (\macro{\}). This package therefore redefines locally the TeX macros \macro{\"}, \macro{\/} and \macro{\\}. During parsing, \macro{\"} expands to \macro{\exp_not:N \"} (i.\,e. it is prevented to expand during parsing) and only when typeset, \macro{\"} is expanded to \macro{"}, which ensures that strings are parsed properly. Similarly, \macro{\/} expands to \macro{\exp_not:N \/} and finally to \macro{/} while \macro{\\} expands to \macro{\exp_not:N \\} and finally to \macro{\c_backslash_str} (i.\,e. a backslash with category code 12).
+
+Due to the above procedure, the TeX macros \macro{\"} and \macro{\\} must be escaped twice in the JSON source, so that they become \macro{\\\"} and \macro{\\\\} respectively.
+
+Other escape sequences defined by JSON, such as \macro{\b}, \macro{\f}, \macro{\n}, \macro{\r}, \macro{\t} or \macro{\u} (the latter followed by a hex value) are not escaped and it is up to the user to process these sequences before feeding them into the commands provided by this package.
+
+Characters that are special to TeX are not handled in a special way and will be treated by TeX the same way as if the user had input them in the document.
+
+Setting the internal boolean \macro{\l_jsonparse_escape_input_bool} to false disables the treatment of the input as described in this section.
+
\section{Main user commands}
\begin{macrodef}
@@ -225,6 +242,7 @@ The command \macro{\JSONParseFromFile} is used to parse a JSON file and store th
\begin{macrodef}
|\JSONParseGetValue|{<token variable>}{<key>}
+|\JSONParseGetValue*|{<token variable>}{<key>}
\end{macrodef}
The command \macro{\JSONParseGetValue} is used to select values from the token variable (property list) that has been created using the commands \macro{\JSONParse} or \macro{\JSONParseFromFile}. The first argument takes the token variable that holds the parsed JSON data. The second argument takes the key to select the relevant entry from the parsed JSON data using JavaScript syntax.
@@ -232,10 +250,13 @@ If the JSON string \macro{{ "key" : "value" }} is parsed into the token variable
Nested objects and arrays are assigned keys that adhere to JavaScript syntax. For example, if the JSON string \macro{{ "outer_key" : { "inner_key" : "value" } }} is parsed into the token variable \macro{\myJSONdata}, to select the value associated with the key \macro{inner_key}, the command \macro{\JSONParseGetValue{\myJSONdata}{outer_key.inner_key}} can be used. The command \macro{\JSONParseGetValue{\myJSONdata}{key[0]}} selects the first value of the array associated with the key \macro{key} in the parsed JSON string \macro{{ "key" : [ "one" , "two" ] }}.
-When a key is associated with an object or array, the whole object or array is output as JSON string. This string can again be parsed using \macro{\JSONParse}. The special key \macro{.} (or the string defined using \macro{\JSONParseSetChildSeparator}) return the whole JSON object.
+When a key is associated with an object or array, the whole object or array is output as JSON string. The special key \macro{.} (or the string defined using \macro{\JSONParseSetChildSeparator}) returns the whole JSON object as string. The output of whole objects or arrays is not meant to be printed, but it can again be parsed using \macro{\JSONParse}.
+
+The starred variant, \macro{\JSONParseGetValue*}, rescans the token list before it is typeset, making it possible to place TeX commands in the JSON file. The starred variants of this and similar commands should not be placed in a \macro{\JSONParse} command. In order to adhere to proper JSON syntax, backslashes need to be escaped in the JSON source with another backslash.
\begin{macrodef}
|\JSONParseGetArrayValues|{<token variable>}{<key>}[<subkey>]{<string>}
+|\JSONParseGetArrayValues*|{<token variable>}{<key>}[<subkey>]{<string>}
\end{macrodef}
The command \macro{\JSONParseGetArrayValues} is used to select all values from an array from a parsed JSON string or JSON file. The first argument takes the token variable that holds the parsed JSON data. The second argument takes the key to select the relevant entry from the parsed JSON data using JavaScript syntax. The third argument is optional an can be used to pass a subkey, i.\,e. a key that is used to select a value for every item. The last argument takes a string that is inserted between all values when they are typeset.
@@ -258,8 +279,11 @@ For example, let us assume the following JSON data structure is parsed into the
Then using \macro{\JSONParseGetArrayValues{\myJSONdata}{array}[key_a]{, }}, the text \macro{one, three} is typeset to the document.
+The starred variant, \macro{\JSONParseGetArrayValues*}, rescans the token lists before they are typeset.
+
\begin{macrodef}
|\JSONParseUseArrayValues|{<token variable>}{<key>}[<subkey>]{<command name>}
+|\JSONParseUseArrayValues*|{<token variable>}{<key>}[<subkey>]{<command name>}
\end{macrodef}
The command \macro{\JSONParseUseArrayValues} takes the same first three arguments as the command \macro{\JSONParseGetArrayValues} and works in a similar way. However, instead of a string that is added between the array items, it takes a command name as fourth argument. This command can be defined beforehand and will be called for every array item. Inside its defintion, the commands \macro{\JSONParseArrayIndex}, \macro{\JSONParseArrayKey} and \macro{\JSONParseArrayValue} can be used which are updated for each item and output the index, the key and the value of the current item respectively.
@@ -278,6 +302,8 @@ For example, let us assume the same JSON data structure as defined above parsed
\end{itemize}
\end{codeexamplecolumns}
+The starred variant, \macro{\JSONParseUseArrayValues*}, rescans the token lists before they are typeset.
+
\begin{macrodef}
|\JSONParseGetArrayCount|{<token variable>}{<key>}
\end{macrodef}
diff --git a/macros/latex/contrib/jsonparse/jsonparse.sty b/macros/latex/contrib/jsonparse/jsonparse.sty
index 64ce2e2193..a50bafc52d 100644
--- a/macros/latex/contrib/jsonparse/jsonparse.sty
+++ b/macros/latex/contrib/jsonparse/jsonparse.sty
@@ -10,7 +10,7 @@
%
% This work has the LPPL maintenance status `author-maintained'.
%
-\ProvidesExplPackage {jsonparse} {2024-04-09} {0.5.5}
+\ProvidesExplPackage {jsonparse} {2024-04-11} {0.5.6}
{JSON Parse}
\bool_new:N \l_jsonparse_debug_mode_bool
@@ -48,6 +48,9 @@
\bool_new:N \l_jsonparse_array_index_zero_based_bool
\bool_set_true:N \l_jsonparse_array_index_zero_based_bool
+\bool_new:N \l_jsonparse_escape_input_bool
+\bool_set_true:N \l_jsonparse_escape_input_bool
+
\NewDocumentCommand { \JSONParseSetChildSeparator } { m } {
\str_set:Nn \l_jsonparse_child_sep_str { #1 }
}
@@ -79,14 +82,19 @@
% ===
+\cs_generate_variant:Nn \tl_count:n { e }
\cs_generate_variant:Nn \tl_range:nnn { nne , nen }
\cs_generate_variant:Nn \tl_range:Nnn { Nne , Nen }
\cs_generate_variant:Nn \tl_remove_once:Nn { Ne }
+\cs_generate_variant:Nn \tl_rescan:nn { ne }
\cs_generate_variant:Nn \tl_set:Nn { Ne }
-\cs_generate_variant:Nn \str_count:n { e }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nne }
+\cs_generate_variant:Nn \tl_trim_spaces:n { V }
+\cs_generate_variant:Nn \str_case_e:nn { en }
\cs_generate_variant:Nn \str_head_ignore_spaces:n { e }
\cs_generate_variant:Nn \str_set:Nn { Ne }
\cs_generate_variant:Nn \prop_gput:Nnn { Nee }
+\cs_generate_variant:Nn \prop_put:Nnn { Nee }
\cs_generate_variant:Nn \seq_use:Nn { Ne }
\cs_generate_variant:Nn \msg_log:nnn { nno }
@@ -117,7 +125,7 @@
\bool_new:N \l__prop_map_first_bool
\ior_new:N \l__jsonparse_json_ior
-
+
% ===
\cs_new:Npn \jsonparse_parse_to_prop:Nn #1#2 {
@@ -129,7 +137,12 @@
}
\prop_gclear:N \g_jsonparse_entries_prop
\group_begin:
- \tl_set_eq:NN \par \c_space_tl
+ \bool_if:NT \l_jsonparse_escape_input_bool {
+ \tl_set_eq:NN \par \c_space_tl
+ \tl_set:Nn \" { \exp_not:N \" }
+ \tl_set:Nn \/ { \exp_not:N \/ }
+ \tl_set:Nn \\ { \exp_not:N \\ }
+ }
\jsonparse_parse:n {#2}
\group_end:
\prop_set_eq:NN #1 \g_jsonparse_entries_prop
@@ -270,17 +283,22 @@
\str_if_eq:enTF { \tl_head:n { #2 } } { : } {
\tl_remove_once:Ne \l__jsonparse_remainder_tl { \c_colon_str }
\tl_set:Ne \l__jsonparse_key_tl { \l__jsonparse_prefix_tl #1 }
- } {
- \tl_set:Ne \l__jsonparse_val_tl {#1}
- \prop_gput:Nee \g_jsonparse_entries_prop
- { \l__jsonparse_key_tl } { \l__jsonparse_val_tl }
- % string
- \bool_if:NT \l_jsonparse_debug_mode_bool {
- \msg_log:nne { jsonparse } { debug-info } {
- (key) ~ \str_use:N \l__jsonparse_key_tl : \iow_newline:
- \iow_char:N \ \iow_char:N \ (str) ~ \str_use:N \l__jsonparse_val_tl
- }
- }
+ } {
+ \group_begin:
+ \tl_set:Nn \" { " }
+ \tl_set:Nn \/ { / }
+ \tl_set:Nn \\ { \c_backslash_str }
+ \tl_set:Ne \l__jsonparse_val_tl {#1}
+ \prop_gput:Nee \g_jsonparse_entries_prop
+ { \l__jsonparse_key_tl } { \l__jsonparse_val_tl }
+ % string
+ \bool_if:NT \l_jsonparse_debug_mode_bool {
+ \msg_log:nne { jsonparse } { debug-info } {
+ (key) ~ \str_use:N \l__jsonparse_key_tl : \iow_newline:
+ \iow_char:N \ \iow_char:N \ (str) ~ \str_use:N \l__jsonparse_val_tl
+ }
+ }
+ \group_end:
}
\__jsonparse_parse_remainder:
}
@@ -419,30 +437,38 @@
\jsonparse_parse_to_prop:Nn #1 { \l__jsonparse_json_tl }
}
-\NewExpandableDocumentCommand { \JSONParseGetValue } { m m } {
- \prop_item:Nn #1 {#2}
+\NewExpandableDocumentCommand { \JSONParseGetValue } { s m m } {
+ \bool_if:NTF #1 {
+ \tl_rescan:ne { } { \prop_item:Nn #2 {#3} }
+ } {
+ \prop_item:Nn #2 {#3}
+ }
}
-\NewExpandableDocumentCommand { \JSONParseGetArrayValues } { m m O{} m } {
+\NewExpandableDocumentCommand { \JSONParseGetArrayValues } { s m m O{} m } {
\group_begin:
- \jsonparse_filter:Nn #1 {#2}
+ \jsonparse_filter:Nn #2 {#3}
\bool_set_true:N \l__prop_map_first_bool
- \prop_map_inline:Nn #1 {
+ \prop_map_inline:Nn #2 {
\str_if_eq:enT {
- \tl_range:nen {##1} { \int_eval:n { -1 * \tl_count:n {#3} } } { -1 }
- } {#3} {
+ \tl_range:nen {##1} { \int_eval:n { -1 * \tl_count:n {#4} } } { -1 }
+ } {#4} {
\bool_if:NTF \l__prop_map_first_bool {
\bool_set_false:N \l__prop_map_first_bool
} {
- #4
+ #5
+ }
+ \bool_if:NTF #1 {
+ \tl_rescan:ne { } {##2}
+ } {
+ ##2
}
- ##2
}
}
\group_end:
}
-\cs_new:Npn \__jsonparse_get_array_index_aux:w [ #1 ] #2 \q_stop {
+\cs_new:Npn \__jsonparse_get_array_index:w [ #1 ] #2 \q_stop {
#1
}
@@ -453,30 +479,34 @@
\int_set:Nn \l__jsonparse_array_count_last_int { -1 }
\prop_map_inline:Nn #1 {
\int_compare:nNnF {
- \__jsonparse_get_array_index_aux:w ##1 \q_stop
+ \__jsonparse_get_array_index:w ##1 \q_stop
} = { \l__jsonparse_array_count_last_int } {
\int_incr:N \l__jsonparse_array_count_int
}
\int_set:Nn \l__jsonparse_array_count_last_int {
- \__jsonparse_get_array_index_aux:w ##1 \q_stop
+ \__jsonparse_get_array_index:w ##1 \q_stop
}
}
\int_use:N \l__jsonparse_array_count_int
\group_end:
}
-\NewExpandableDocumentCommand { \JSONParseUseArrayValues } { m m O{} m } {
+\NewExpandableDocumentCommand { \JSONParseUseArrayValues } { s m m O{} m } {
\group_begin:
- \jsonparse_filter:Nn #1 {#2}
- \prop_map_inline:Nn #1 {
+ \jsonparse_filter:Nn #2 {#3}
+ \prop_map_inline:Nn #2 {
\str_if_eq:enT {
- \tl_range:nen {##1} { \int_eval:n { -1 * \tl_count:n {#3} } } { -1 }
- } {#3} {
+ \tl_range:nen {##1} { \int_eval:n { -1 * \tl_count:n {#4} } } { -1 }
+ } {#4} {
\int_incr:N \l__jsonparse_array_index_int
- \tl_set:Ne \JSONParseArrayIndex { \__jsonparse_get_array_index_aux:w ##1 \q_stop }
+ \tl_set:Ne \JSONParseArrayIndex { \__jsonparse_get_array_index:w ##1 \q_stop }
\tl_set:Ne \JSONParseArrayKey { ##1 }
- \tl_set:Ne \JSONParseArrayValue { \prop_item:Nn #1 {##1} }
- \use:c {#4}
+ \bool_if:NTF #1 {
+ \tl_set_rescan:Nne \JSONParseArrayValue { } { \prop_item:Nn #2 {##1} }
+ } {
+ \tl_set:Ne \JSONParseArrayValue { \prop_item:Nn #2 {##1} }
+ }
+ \use:c {#5}
}
}
\group_end: