texlive[64406] Master/texmf-dist: qrbill (15sep22)

commits+karl at tug.org commits+karl at tug.org
Thu Sep 15 21:58:08 CEST 2022


Revision: 64406
          http://tug.org/svn/texlive?view=revision&revision=64406
Author:   karl
Date:     2022-09-15 21:58:08 +0200 (Thu, 15 Sep 2022)
Log Message:
-----------
qrbill (15sep22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/qrbill/README.md
    trunk/Master/texmf-dist/doc/latex/qrbill/qrbill.pdf
    trunk/Master/texmf-dist/source/latex/qrbill/qrbill.dtx
    trunk/Master/texmf-dist/tex/latex/qrbill/qrbill.sty
    trunk/Master/texmf-dist/tex/latex/qrbill/swiss.qrbill-cfg.tex

Added Paths:
-----------
    trunk/Master/texmf-dist/scripts/qrbill/
    trunk/Master/texmf-dist/scripts/qrbill/qrbill-latexluaqrcode.lua

Removed Paths:
-------------
    trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-letter-demo.tex
    trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-standalone-demo.tex

Modified: trunk/Master/texmf-dist/doc/latex/qrbill/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/qrbill/README.md	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/doc/latex/qrbill/README.md	2022-09-15 19:58:08 UTC (rev 64406)
@@ -4,7 +4,7 @@
 
 This work is part of a collaborative project of Marei Peischl (peiTeX) and Alex Antener (foobar LLC).
 
-qrbill 2022/07/02 v1.04
+qrbill 2022/09/15 v1.05
 
 ***************************************************************************
 
@@ -38,7 +38,22 @@
 
 To simplify this, you can have a look at the qrbill.tds.zip, which provides an already prestructured variant to be extracted to any tds tree.
 
+### Use the Repository directly
 
+The repository provides a l3build script. You can build the documentation by running
+
+```
+l3build doc
+```
+This will unpack the package files and build the the docs within `build/`.
+
+To install the files into your local texmf tree run
+```
+l3build install
+```
+
+For further information on l3build and other options please have a look at the corresponding documentation `texdoc l3build`.
+
 ## Version History
 
  * v1.00 (2020-06-28) First official version
@@ -52,4 +67,10 @@
    - Add seb-iban and sep-reference to the example files
  * v1.04 (2022/07/02)
    - add basic support for EPC QR codes
-   - add date parsing mechanism to preset the dates to values of `\today`
\ No newline at end of file
+   - add date parsing mechanism to preset the dates to values of `\today`
+ * v1.05 (2022/09/15)
+   - add option to convert all data to strings
+   - add mechanism to do custom replacements within the data
+   - fix qrcode encoding to support UTF-8
+   - add support for speedata's luaqrcode library for qrcode generation http://speedata.github.io/luaqrcode/
+   - small layout and documentation fixes
\ No newline at end of file

Deleted: trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-letter-demo.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-letter-demo.tex	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-letter-demo.tex	2022-09-15 19:58:08 UTC (rev 64406)
@@ -1,95 +0,0 @@
-%%
-%% This is file `qrbill-letter-demo.tex',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% qrbill.dtx  (with options: `qrbill-letter-demo.tex')
-%% 
-%% Copyright (C) 2020–2022 by Marei Peischl (peiTeX) <marei at peitex.de>
-%% 
-%% This work is a collaboration of
-%%   Marei Peischl (peiTeX) and Alex Antener (foobar LLC).
-%% 
-%% 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 2005/12/01 or later.
-%% 
-%% This work has the LPPL maintenance status `maintained'.
-%% 
-%% The Current Maintainer of this work is
-%%   Marei Peischl <qrbill at peitex.de>.
-%% 
-%% This work consists of the files
-%% qrbill.dtx and qrbill.ins, qrbill-vocab.csv
-%% and the derived files
-%% qrbill.sty, swiss.qrbill-cfg.tex, epc.qrbill-cfg.tex,
-%% qrbill-letter-demo.tex, qrbill-standalone-demo.tex.
-%% 
-%% The development repository can be found at
-%% https://github.com/peitex/qrbill
-%% Please use the issue tracker for feedback!
-%% 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\documentclass[foldmarks=b]{scrletter}
-\usepackage[
-  frame=top,
-  sep-iban=4,
-  sep-reference=-5,
-]{qrbill}
-
-\DeclareNewLayer[
-align=bl,
-voffset=\paperheight,
-hoffset=0pt,
-contents={\QRbill},
-width=\paperwidth,
-height=105mm,
-]{qrbill}
-
-\begin{document}
-
-\qrbillsetdata{
-  creditor*={foobar LLC\\
-    Postfach\\
-    404\\
-    2342\\
-    Zurich\\
-    CH},
-  Account=CH1280808005649899718,
-  vat=123123123,% VAT number with stripped CH and periods
-  debtor*={peiTeX\\
-    TeXnikerweg\\
-    78\\
-    23420\\
-    Hamburg\\
-    DE},
-  Amount=1337.42,
-  Message=Bestellung vom 27.06.2020,
-  invoicenum=100-4242,
-  vatdetails=0,% 0% VAT
-  AV1=LX;F00BAR;2342,
-}
-
-\setkomavar{fromaddress}{\insertcreditor}
-
-\begin{letter}{\insertdebtor}
-
-\opening{opening}
-
-Text
-
-\closing{closing}
-
-\AddLayersToPageStyle{@everystyle@}{qrbill}
-
-\end{letter}
-\end{document}
-\endinput
-%%
-%% End of file `qrbill-letter-demo.tex'.

Deleted: trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-standalone-demo.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-standalone-demo.tex	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/doc/latex/qrbill/qrbill-standalone-demo.tex	2022-09-15 19:58:08 UTC (rev 64406)
@@ -1,77 +0,0 @@
-%%
-%% This is file `qrbill-standalone-demo.tex',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% qrbill.dtx  (with options: `qrbill-standalone-demo.tex')
-%% 
-%% Copyright (C) 2020–2022 by Marei Peischl (peiTeX) <marei at peitex.de>
-%% 
-%% This work is a collaboration of
-%%   Marei Peischl (peiTeX) and Alex Antener (foobar LLC).
-%% 
-%% 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 2005/12/01 or later.
-%% 
-%% This work has the LPPL maintenance status `maintained'.
-%% 
-%% The Current Maintainer of this work is
-%%   Marei Peischl <qrbill at peitex.de>.
-%% 
-%% This work consists of the files
-%% qrbill.dtx and qrbill.ins, qrbill-vocab.csv
-%% and the derived files
-%% qrbill.sty, swiss.qrbill-cfg.tex, epc.qrbill-cfg.tex,
-%% qrbill-letter-demo.tex, qrbill-standalone-demo.tex.
-%% 
-%% The development repository can be found at
-%% https://github.com/peitex/qrbill
-%% Please use the issue tracker for feedback!
-%% 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\documentclass{standalone}
-\usepackage[nswissgerman]{babel}
-
-\RequirePackage{xcolor}
-\usepackage[
-  icon=swiss-cross,
-  separate=false,
-  sep-iban=4,
-  sep-reference=-5
-]{qrbill}
-
-\begin{document}
-
-\QRbill[
-  creditor*={foobar LLC\\
-    Postfach\\
-    404\\
-    2342\\
-    Zurich\\
-    CH},
-  Account=CH1280808005649899718,
-  vat=123123123,% VAT number with stripped CH and periods
-  debtor*={peiTeX\\
-    TeXnikerweg\\
-    78\\
-    23420\\
-    Hamburg\\
-    DE},
-  Amount=1337.42,
-  Message=Bestellung vom 27.06.2020,
-  invoicenum=100-4242,
-  vatdetails=0,% 0% VAT
-  AV1=LX;F00BAR;2342,
-]
-
-\end{document}
-\endinput
-%%
-%% End of file `qrbill-standalone-demo.tex'.

Modified: trunk/Master/texmf-dist/doc/latex/qrbill/qrbill.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/scripts/qrbill/qrbill-latexluaqrcode.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/qrbill/qrbill-latexluaqrcode.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/qrbill/qrbill-latexluaqrcode.lua	2022-09-15 19:58:08 UTC (rev 64406)
@@ -0,0 +1,24 @@
+qrencode = require("qrencode.lua")
+
+function printQRcode(codestring)
+	local ok, tab = qrencode.qrcode(codestring, 2)
+	local count = 0
+	local tabstr = ""
+	local qrrows = ""
+	if ok then
+		for k,v in pairs(tab) do
+
+			count = count + 1 
+			for t,s in pairs(v) do
+				if s > 0 then
+					tabstr=tabstr.."\\qrblack"
+				else
+					tabstr=tabstr.."\\qrwhite"
+				end
+			end
+			qrrows=tabstr.."\\qrnewline"..qrrows
+			tabstr=""
+		end	
+	end
+	return count, qrrows
+end
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/scripts/qrbill/qrbill-latexluaqrcode.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/qrbill/qrbill.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/qrbill/qrbill.dtx	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/source/latex/qrbill/qrbill.dtx	2022-09-15 19:58:08 UTC (rev 64406)
@@ -54,7 +54,7 @@
 % \fi
 % \iffalse
 %<*driver>
-\ProvidesFile{qrbill.dtx}[2022/07/02 v1.04 \ create QR-bills based on the Swiss standard]
+\ProvidesFile{qrbill.dtx}[2022/09/15 v1.05 \ create QR-bills based on the Swiss standard]
 \documentclass[english, parskip=half-]{scrartcl}
 \usepackage{iftex}
 \ifPDFTeX
@@ -180,6 +180,7 @@
 % \publishers{A collaborative project of pei\TeX{} and foobar LLC}
 % \date{\filedate}
 % \maketitle
+% \tableofcontents
 % \section{Introduction}
 % qrbill.sty, the \LaTeX-package, is the Free Software and Open Source answer to the launch of the swiss payments conversion, introduced mid 2020, replacing the former payment order slip by a restructured, QR enhanced slip. The published source code is based on the payment standard guidelines issued for Switzerland and intentionally has a modular structure to enable further development and adaptation for international use.
 %
@@ -247,6 +248,10 @@
 % \item[creditorprefix\\debtorprefix (String) (CR-/UD-)]
 % For custom setups the predefined prefixes for the debtor and creditoraddress can be changes. The initial configuration is a requirement of the Swiss standards.
 %
+% \item[data-to-string (true/false) (false)]
+% Converts data to be used to setup the billing QRcode into a string. This option has to be updated if the data should not be treated as ordinary \LaTeX{} code.
+% You can use this to automatically escape special characters.\changes{v1.05}{2022/09/15}{add data-to-string option}
+%
 % \item[font (Frutiger/Arial/Helvetica/Liberation Sans/custom) (Liberation Sans)]
 % \label{opt:font}
 % The official guideline for the Swiss qrbill limits the choice of the font to the first four values of this option. The font selection and sizes currently hardcoded to fit to the size. Custom setups might be provided in the future.
@@ -258,8 +263,9 @@
 % \renewcommand*{\qrbillfont}{\fontspec{Laconic}}
 % \end{doccode}
 %
-% \item[frame (true/false/top/bottom) (true)]
+% \item[frame (true/false/top/bottom/none) (true)]
 % Switch to disable the frame around the created QRbill. The top/bottom options should be prefered when the bill is embedded into a document of a4 papersize.
+% The option none also disables the vertical line inside the bill as this may be included on preprinted paper.
 %
 % \changes{v1.02}{2020/08/25}{add ibanseparator option}
 % \item[ibanseparator (tokenlist) (\textbackslash,)]
@@ -271,7 +277,11 @@
 %
 % \item[iconwidth (length) (7mm)]
 % This option allows custom scaling for custom icons.
-
+%
+% \item[qrmode (package/lua) (package)] Selects the mechanism for QRcode generation.
+% With Version 2.0 the package supports usage of the the luaqrcode library \cite{luaqrcode}. This can be enabled by using the \latexinline{qmode=lua} option.
+% In that case the luaqrcode libary has to be installed within the \verb+$LUAINPUTS+.
+%
 % \item[qrscheme (Name of a custom QRbill scheme) (swiss)]
 % Loads the definitions for the QRcode and the BillingInformation. Currently only the
 % swiss qrbill scheme is available, but one can define own variants based on this file.
@@ -299,8 +309,19 @@
 % \changes{v1.02}{2020/08/25}{Fix placement issue with separate option}
 % \item[separate (false/text/symbol) (text)]
 % Setup the separation rule between the document and the qrbill. If the value is text or symbol the Info \enquote{\qrbillseparatename} or the corresponding translation will be printed on top of the frame. This option will be ignored it the frame has no top rule.
+%
+% \item[replace-tilde\\replace-umlauts (true/false) (false)]
+% Add automatic string replacements for \latexinline{~} and Umlauts.
+% In general the Data has either to be parsed as string or be expandable.
+% There are some specials about active characters like \latexinline{~}.
+% The option \latexinline{replace-tilde=true} will replace this by an ordinary space within the data string for the QRcode.
+%
+% Similarly the replace-umlauts options is mapping Umlauts to the two character representation. This can be used  if UTF-8 is not supported.
+% Custom replacements can be set up using \latexinline{\QRbillAddCustomReplacement} as described in section \ref{sec:custom-replacement}.
+% \changes{v1.05}{2022/09/15}{Add replace-tilde/replace-umlauts options}
+% 
 % \end{optionlist}
-% 
+%
 % \section{Data setup}
 % \label{sec:data-setup}
 % \changes{v1.04}{2022/07/02}{Add starrred variant of qrbillsetdata}
@@ -323,6 +344,16 @@
 % \end{doccode}
 % By default this setting will return the ISO date (YYYY-MM-DD) but the swiss scheme is already changing this to the desired (YYMMDD) structure.
 %
+% \section{String replacements}\label{sec:custom-replacement}
+% \changes{v1.05}{2022/09/15}{Add support for custom string replacements}
+% Following a feature request qrbill received support for custom replacements.
+% Those allow the use of special characters within the data fields.
+% The corresponding options \latexinline{replace-tilde} and \latexinline{replace-umlauts} provide preset variants for the most common replacements.
+% In case you want to add another you can use the following structure:
+% \begin{doccode}
+%	\AddQRbillCustomReplacement{Ä}{Ae}
+% \end{doccode}
+%
 % \section{Setup for the preconfigured Swiss QR-bill}
 % \subsection{Preconfigured data}
 % \changes{v1.03}{2021/05/07}{Update to swiss qrbill standard version 2.2}
@@ -353,7 +384,7 @@
 % \begin{center}
 % \begin{tabular}{@{}>{\ttfamily}l>{\centering}p{.25\linewidth}>{\centering\arraybackslash}p{.25\linewidth}@{}}
 % \toprule
-% AddressType&K&S\\\cmidrule(r){1-1}\cmidrule(l){2-3}
+% AddressType&S&K\\\cmidrule(r){1-1}\cmidrule(l){2-3}
 % Name& \multicolumn{2}{c}{Name}\\\cmidrule(r){1-1}\cmidrule(l){2-3}
 % Address1&Street&Street with number\\\cmidrule(r){1-1}\cmidrule(l){2-3}
 % Address2&Number&Postal code with City\\\cmidrule(r){1-1}\cmidrule(l){2-3}
@@ -474,7 +505,7 @@
 % \section{Implementation}
 %    \begin{macrocode}
 \RequirePackage{expl3}
-\ProvidesExplPackage{qrbill}{2022/07/02}{1.04}{
+\ProvidesExplPackage{qrbill}{2022/09/15}{1.05}{
   Template for QR-bills based on the Swiss Payment Standards
 }
 \RequirePackage{iftex}
@@ -485,11 +516,19 @@
 \bool_new:N \g__qrbill_bottom_frame_bool
 \bool_new:N \g__qrbill_left_frame_bool
 \bool_new:N \g__qrbill_right_frame_bool
+\bool_new:N \g__qrbill_vrule_bool
 \bool_new:N \g__qrbill_separateinfo_bool
+\prop_new:N \g__qrbill_replacement_prop
 
+\msg_new:nnn {qrbill} {typo-in-option} {
+	A~typo~within~the~option~#1~was~removed.\\
+	The~correct~name~for~the~option~is~#2.\\
+	Please~use~#2~instead~of~#1,~which~only\\
+	exists~for~backwards~compatibility~and~will~be~removed.
+}
+
 \keys_define:nn {qrbill} {
   font .choices:nn = {Frutiger, Arial, Helvetica, Liberation Sans} {
-    \bool_gset_true:N \g__qrbill_fontsetup_bool
     \tl_gset_eq:NN \g__qrbill_font_tl \l_keys_choice_tl
   },
   font .initial:n = Liberation Sans,
@@ -506,10 +545,11 @@
   qrmode .initial:n = package,
   frame .choice:,
   frame / false .code:n = {
-    \bool_gset_false:N \__g__qrbill_top_frame_bool
+    \bool_gset_false:N \g__qrbill_top_frame_bool
     \bool_gset_false:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / true .code:n = {
     \bool_gset_true:N \g__qrbill_top_frame_bool
@@ -516,6 +556,7 @@
     \bool_gset_true:N \g__qrbill_bottom_frame_bool
     \bool_gset_true:N \g__qrbill_left_frame_bool
     \bool_gset_true:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / top .code:n = {
     \bool_gset_true:N \g__qrbill_top_frame_bool
@@ -522,6 +563,7 @@
     \bool_gset_false:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / bottom .code:n = {
     \bool_gset_false:N \g__qrbill_top_frame_bool
@@ -528,7 +570,16 @@
     \bool_gset_true:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
+  frame / none .code:n = {
+    \bool_gset_false:N \g__qrbill_top_frame_bool
+    \bool_gset_false:N \g__qrbill_bottom_frame_bool
+    \bool_gset_false:N \g__qrbill_left_frame_bool
+    \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_false:N \g__qrbill_vrule_bool
+  },
+
   frame .initial:n = true,
   billinginfo .bool_gset:N = \g__grbill_billinginfo_auto_bool,
   billinginfo .default:n = true,
@@ -570,12 +621,21 @@
   separate .initial:n = text,
   sep-iban .int_gset:N = \g__qrbill_ibansep_int,
   sep-iban .initial:n = 0,
-  ibanseperator .tl_gset:N = \g__qrbill_ibansep_tl,
-  ibanseperator  .initial:n = {\,},
+  ibanseparator .tl_gset:N = \g__qrbill_ibansep_tl,
+  ibanseparator .initial:n = {\,},
+  ibanseperator .code:n = \keys_set:nn {qrbill} {ibanseparator=#1}\msg_warning:nnnn {qrbill} {typo-in-option} {ibanseperator} {ibanseparator},
   sep-reference .int_gset:N = \g__qrbill_referencesep_int,
   sep-reference .initial:n = 0,
-  referenceseperator .tl_gset:N = \g__qrbill_referencesep_tl,
-  referenceseperator .initial:n = {\,}
+  referenceseparator .tl_gset:N = \g__qrbill_referencesep_tl,
+  referenceseparator .initial:n = {\,},
+  referenceseperator .code:n = \keys_set:nn {qrbill} {referenceseparator=#1}\msg_warning:nnnn {qrbill} {typo-in-option} {referenceseperator} {referenceseparator},
+  replace-tilde .choice:,
+  replace-tilde / true .code:n = \prop_gput:Nxx \g__qrbill_replacement_prop  {\char_generate:nn {126} {12}} {\ },
+  replace-tilde / false  .code:n = \exp_args:NNx \prop_gremove:Nn \g__qrbill_replacement_prop  {\char_generate:nn {126} {12}},
+  replace-umlauts .choice:,
+  replace-umlauts / true .code:n = \prop_gput_from_keyval:Nn \g__qrbill_replacement_prop {ä=ae,Ä=AE,ü=ue,Ü=UE,ö=oe,Ö=OE,ß=ss,ẞ=SS},
+  replace-umlauts / false .code:n = \clist_map_inline:nn {ä,Ä,ü,Ü,ö,Ö,ß,ẞ} {\prop_gremove:Nn \g__qrbill_replacement_prop {##1}},
+  data-to-string .bool_gset:N = \g__qrbill_to_string_bool,
 }
 
 \ProcessKeysOptions{qrbill}
@@ -582,10 +642,19 @@
 
 \newcommand*{\qrbillsetup}[1]{\keys_set:nn {qrbill}{#1}}
 \NewDocumentCommand{\qrbillsetdata}{sm}{
+	\bool_if:NTF \g__qrbill_to_string_bool {
+		\IfBooleanTF {#1} {
+			\tl_set:Nx \l_tmpa_tl {#2}
+			\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:V \l_tmpa_tl}
+		}{
+			\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:n {#2}}
+		}
+	} {
 	\IfBooleanT {#1}
 		\exp_args:Nnx
 	\keys_set:nn
 		{qrbill/data}{#2}
+	}
 }
 
 \tl_if_empty:NTF \g__qrbill_font_tl {
@@ -593,18 +662,101 @@
 }{
   \RequirePackage{fontspec}
   \newfontfamily{\qrbillfont}{\g__qrbill_font_tl}
+  \RequirePackage{anyfontsize}
 }
 
 \dim_new:N \g_qrbill_QRcode_dim
 \dim_gset:Nn \g_qrbill_QRcode_dim {46mm}
+\bool_if:NT \g__qrbill_luamode_bool {
+	\file_if_exist:nTF {qrencode.lua} {
+		\lua_load_module:n {qrbill-latexluaqrcode}
+	} {
+		\msg_new:nnn {qrbill} {luaqrcode-not-found} {
+			Could~not~find~the~required~library~for~qrmode=lua.\\
+			I~will~switch~to~qrmode=package.
+		}
+		\msg_warning:nn {qrbill} {luaqrcode-not-found}
+		\bool_gset_false:N \g__qrbill_luamode_bool
+	}
+
+	% qrcode setup
+	\dim_new:N \l__qrbill_QRblocksize_dim
+	\cs_set_protected:Npn \qrbill_qrcode_black: {\rule{\l__qrbill_QRblocksize_dim}{\l__qrbill_QRblocksize_dim}}
+	\cs_set_protected:Npn \qrbill_qrcode_white: {\rule{\l__qrbill_QRblocksize_dim}{0pt}\rule{0pt}{\l__qrbill_QRblocksize_dim}}
+	\cs_new:Nn \qrbill_parse_QRcode:n {
+		\lua_now:e {
+			num, string = printQRcode("\lua_escape:n {#1}")
+		}
+		\dim_set:Nn \l__qrbill_QRblocksize_dim {\g_qrbill_QRcode_dim/\lua_now:n {tex.print(num)}}
+		\let\qrblack\qrbill_qrcode_black:
+		\let\qrwhite\qrbill_qrcode_white:
+		\def\qrnewline{\\[\dimexpr-\baselineskip+\l__qrbill_QRblocksize_dim]}
+		\noindent\parbox{\g_qrbill_QRcode_dim}{
+			\lua_now:n {tex.sprint(string)}
+		}
+	}
+}
+
 \bool_if:NF \g__qrbill_luamode_bool {
   \usepackage{qrcode}
-  \cs_new:Nn \qrbill_parse_QRcode:n {
-    \raisebox{\depth}{\qrcode[height= \g_qrbill_QRcode_dim]{#1}}
+  % modified version of \qr at encode@binary to allow utf8 qrcodes required by swiss qrbill scheme
+  % Copyright (C) 2015 by Anders Hendrickson <ahendric at cord.edu>
+	\cs_set:Nn \__qrbill_encode_unicode_binary:n {
+		% #1 = string of ascii characters, to be converted into bitstream
+		%
+		% We do this one entirely in hex, rather than binary, because we can.
+		\edef\qr at plaintext{#1}%
+		%
+		%First, the mode indicator.
+		\def\qr at codetext{4}% %This means `binary'
+		%
+		%Next, the character count.
+		\xdef\qr at stringlength{\tl_count:o {\qr at plaintext}}%
+		%Set \qr at charactercountlengthinhex to \qr at charactercountbits@byte/4%
+		\edef\qr at charactercountlengthinhex{\int_eval:n {\qr at charactercountbits@byte / 4}}%
+		\qr at decimaltohex[\qr at charactercountlengthinhex]{\qr at charactercount}{\qr at stringlength}%
+		\xa\g at addto@macro\xa\qr at codetext\xa{\qr at charactercount}%
+		%
+		%Now comes the actual data.
+		\exp_args:NNx \str_set_convert:Nnnn \l_tmpa_str  { \qr at plaintext }  {iso88591} {utf8}
+		\exp_args:NNV \str_set_convert:Nnnn \l_tmpa_str  \l_tmpa_str {} {latin1/hex}
+		\str_gput_right:NV \qr at codetext \l_tmpa_str
+		\xdef\qr at codetext{\exp_args:No \str_lowercase:n {\qr at codetext}}
+		%Now the terminator.
+		\g at addto@macro\qr at codetext{0}% %This is '0000' in binary.
+		%
+		%There is no need to pad bits to make a multiple of 8,
+		%because the data length is already 4 + 8 + 8n + 4.
+		%
+		%Now add padding codewords if needed.
+		\setcounter{qr at hexchars}{\tl_count:o {\qr at codetext}}%
+		%Set \qr at numpaddingcodewords equal to \qr at totaldatacodewords - qr at hexchars/2.
+		\edef\qr at numpaddingcodewords{\int_eval:n {(-\c at qr@hexchars / 2)+\qr at totaldatacodewords}}
+		%
+		\int_compare:nNnT {\qr at numpaddingcodewords} < {0} {
+			\edef\ds{ERROR:~Too~much~data!~Over~by~\qr at numpaddingcodewords~bytes.}
+		}
+		\int_compare:nNnT {\qr at numpaddingcodewords} > {0} {
+			\int_step_inline:nnnn {2} {2} {\qr at numpaddingcodewords} {
+			\g at addto@macro{\qr at codetext}{ec11}%
+		}
+		\int_if_odd:nT {\qr at numpaddingcodewords} {
+				\g at addto@macro{\qr at codetext}{ec}%
+			}
+		}
+	}
+  \cs_set:Nn \qrbill_parse_QRcode:n {
+		\cs_set_eq:NN \qr at encode@binary \__qrbill_encode_unicode_binary:n
+		\raisebox{\depth}{\cs_set_eq:NN \qr at encode@binary \__qrbill_encode_unicode_binary:n\qrcode[height= \g_qrbill_QRcode_dim]{#1}}
   }
-  \cs_generate_variant:Nn \qrbill_parse_QRcode:n {V}
 }
 
+\cs_generate_variant:Nn \qrbill_parse_QRcode:n {V}
+
+\newcommand*{\QRbillAddCustomReplacement}[2]{
+	 \prop_gput:Nxx \g__qrbill_replacement_prop  {#1} {#2},
+}
+
 \RequirePackage{scrbase}
 \RequirePackage{graphicx}
 \RequirePackage{numprint}
@@ -818,7 +970,9 @@
         {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
         {\rule{\g__qrbill_rule_dim}{\c_zero_dim}}
       \hspace{\dimexpr62mm-1.5\g__qrbill_rule_dim}
-      \rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}
+      \bool_if:NTF \g__qrbill_vrule_bool
+        {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
+        {\rule{\g__qrbill_rule_dim}{\c_zero_dim}}
       \hspace{\dimexpr148mm-1.5\g__qrbill_rule_dim}
       \bool_if:NTF \g__qrbill_right_frame_bool
         {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
@@ -864,7 +1018,13 @@
 \seq_new:N \l_qrbill_tmp_seq
 
 \cs_new:Nn \qrbill_set_address_combined:nn {
-  \seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+	\bool_if:NTF \g__qrbill_to_string_bool {
+		\exp_args:NNxx \seq_set_split:Nnn \l_qrbill_tmp_seq
+			{\tl_to_str:n {\\}}
+			{ \str_range:nnn { #2 } { 2 } { -2 } }
+	} {
+		\seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+	}
   \exp_args:Nnx \keys_set:nn {qrbill/data} {
     #1AddressType=K,
     #1Name=\seq_item:Nn \l_qrbill_tmp_seq {1},
@@ -877,7 +1037,13 @@
 }
 
 \cs_new:Nn \qrbill_set_address_structured:nn {
-  \seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+	\bool_if:NTF \g__qrbill_to_string_bool {
+		\exp_args:NNxx \seq_set_split:Nnn \l_qrbill_tmp_seq
+			{\tl_to_str:n {\\}}
+			{ \str_range:nnn { #2 } { 2 } { -2 } }
+	} {
+		\seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+	}
   \exp_args:Nnx \keys_set:nn {qrbill/data} {
     #1AddressType=S,
     #1Name=\seq_item:Nn \l_qrbill_tmp_seq {1},
@@ -926,7 +1092,7 @@
 		\int_set:Nn \l_tmpb_int {\int_abs:n {\int_use:c {g__qrbill_#1sep_int}}}
 		\int_set:Nn \l_tmpa_int {1}
 		\tl_clear:N \l_tmpa_tl
-		\int_while_do:nn {\l_tmpa_int < \str_count:N \l_tmpa_str} {
+		\int_while_do:nNnn {\l_tmpa_int} < {\str_count:N \l_tmpa_str - \l_tmpb_int +1 } {
 			\tl_put_right:Nx \l_tmpa_tl {
 				\str_range:Nnn \l_tmpa_str {\l_tmpa_int} {\l_tmpa_int + \l_tmpb_int-1}
 			}
@@ -960,7 +1126,7 @@
   \keys_define:nn {qrbill/data} {
     #1 .code:n = {
       \tl_if_empty:nF {##1}{
-        \keys_set:nx {qrbill/data} {
+        \exp_args:Nnx \keys_set:nn {qrbill/data} {
           #1-Parameters={\qrbill_av_prefix:n {#1}##1}
         }
       }
@@ -971,7 +1137,11 @@
 }
 
 \newcommand*{\SetupQrBill}[1]{
-  \keys_set:nn {qrbill/data} {#1}
+	\bool_if:NTF \g__qrbill_to_string_bool {
+		\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:n {#1}}
+	} {
+		\keys_set:nn {qrbill/data} {#1}
+	}
 }
 
 \str_new:N \l_qrbill_data_str
@@ -985,7 +1155,10 @@
          \exp_args:NNv \str_put_right:Nn \l_qrbill_data_str {l_qrbill_data_##1_tl}
   }
   %necessary to preserve spaces!
-  \str_replace_all:Nnn \l_qrbill_data_str  {~ } {\ }
+  \str_replace_all:Nnn \l_qrbill_data_str {~ } {\ }
+  \prop_map_inline:Nn \g__qrbill_replacement_prop {
+		\str_replace_all:Nnn \l_qrbill_data_str {##1} {##2}
+	}
   \tl_set_rescan:Nno \l_qrbill_data_str {\ExplSyntaxOff} {\l_qrbill_data_str}
 }
 
@@ -1004,12 +1177,16 @@
 
 \prop_new:N \g__qrbill_billing_info_prop 
 \seq_new:N \g__qrbill_billing_info_seq
+
+\clist_new:N \g__qrbill_billing_info_static_clist
+\newcommand*{\SetStaticData}[1]{\clist_gset:Nx \g__qrbill_billing_info_static_clist {\tl_to_str:n {#1}}}
+
 \newcommand*{\SetBillingInfoScheme}[1]{
   \prop_gset_from_keyval:Nn \g__qrbill_billing_info_prop {#1}
   \seq_gclear:N  \g__qrbill_billing_info_seq
   \prop_map_inline:Nn \g__qrbill_billing_info_prop {
-    \exp_args:Nx \clist_if_in:nnF {\tl_to_str:n {prefix , postfix}} {##1} {
-      \seq_push:Nn  \g__qrbill_billing_info_seq {##1}
+    \clist_if_in:NnF \g__qrbill_billing_info_static_clist {##1} {
+      \seq_push:Nn \g__qrbill_billing_info_seq {##1}
     }
     \keys_define:nn {qrbill/data} {
       ##2 .tl_set:c = l_qrbill_##2_tl,
@@ -1016,6 +1193,15 @@
       ##2 .initial:n =,
     }
   }
+	\seq_if_empty:NF \g__qrbill_billing_info_seq {
+		\prop_map_inline:Nn \g__qrbill_billing_info_prop {
+			\clist_if_in:NnT \g__qrbill_billing_info_static_clist {##1} {
+				\exp_args:Nx \clist_if_in:nnF {\tl_to_str:n {prefix , postfix}} {##1} {
+					\seq_push:Nn  \g__qrbill_billing_info_seq {##1}
+		    }
+			}
+		}
+	}
   \seq_sort:Nn \g__qrbill_billing_info_seq {
     \int_compare:nNnTF { ##1 } > { ##2 }
         { \sort_return_swapped: }
@@ -1111,6 +1297,8 @@
   AV2-Parameters
 }
 
+\SetStaticData{prefix,11,31}
+
 \SetBillingInfoScheme{
   prefix=//S1,
   10=invoicenum,
@@ -1183,8 +1371,10 @@
 %
 % \PrintChanges
 % \begin{thebibliography}{99}
-% \bibitem{qrbill-spec} Swiss Implementation Guidelines QR-bill: Technical and professional specifications of the payment part with Swiss QR Code and of the receipt. Version 2.2, with effect from 22 February 2021. \url{https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-en.pdf}. Last checked 2021-05-07
+% \bibitem{qrbill-spec} Swiss Implementation Guidelines QR-bill: Technical and professional specifications of the payment part with Swiss QR Code and of the receipt. Version 2.2, with effect from 22 February 2021. \url{https://www.paymentstandards.ch/dam/downloads/ig-qr-bill-en.pdf}. Last checked 2022-08-28
 % \bibitem{qrbill-design} Style Guide QR-billStyle Guide QR-bill: The right layout pays off. Layout rules and recommendations for the payment part with Swiss QR Code and for the receipt. \url{https://www.paymentstandards.ch/dam/downloads/style-guide-en.pdf}
+% \bibitem{luaqrcode} Luaqrcode – Pure Lua QR Code library.  By Patrick Gundlach (SPEEDATA GMBH) and contributors.
+% \url{http://speedata.github.io/luaqrcode/}. Last checked 2022-08-28
 % \end{thebibliography}
 % \appendix
 % \section{Example of standalone qrbill}
@@ -1252,7 +1442,8 @@
   sep-reference=-5,
 ]{qrbill}
 
-% Setup layer
+% Setup layer:
+% This requires the scrlayer package which is already loaded by scrletter
 \DeclareNewLayer[
 	align=bl,
 	voffset=\paperheight,

Modified: trunk/Master/texmf-dist/tex/latex/qrbill/qrbill.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/qrbill/qrbill.sty	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/tex/latex/qrbill/qrbill.sty	2022-09-15 19:58:08 UTC (rev 64406)
@@ -36,9 +36,8 @@
 %% 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 \RequirePackage{expl3}
-\ProvidesExplPackage{qrbill}{2022/07/02}{1.04}{
+\ProvidesExplPackage{qrbill}{2022/09/15}{1.05}{
   Template for QR-bills based on the Swiss Payment Standards
 }
 \RequirePackage{iftex}
@@ -49,11 +48,19 @@
 \bool_new:N \g__qrbill_bottom_frame_bool
 \bool_new:N \g__qrbill_left_frame_bool
 \bool_new:N \g__qrbill_right_frame_bool
+\bool_new:N \g__qrbill_vrule_bool
 \bool_new:N \g__qrbill_separateinfo_bool
+\prop_new:N \g__qrbill_replacement_prop
 
+\msg_new:nnn {qrbill} {typo-in-option} {
+A~typo~within~the~option~#1~was~removed.\\
+The~correct~name~for~the~option~is~#2.\\
+Please~use~#2~instead~of~#1,~which~only\\
+exists~for~backwards~compatibility~and~will~be~removed.
+}
+
 \keys_define:nn {qrbill} {
   font .choices:nn = {Frutiger, Arial, Helvetica, Liberation Sans} {
-    \bool_gset_true:N \g__qrbill_fontsetup_bool
     \tl_gset_eq:NN \g__qrbill_font_tl \l_keys_choice_tl
   },
   font .initial:n = Liberation Sans,
@@ -70,10 +77,11 @@
   qrmode .initial:n = package,
   frame .choice:,
   frame / false .code:n = {
-    \bool_gset_false:N \__g__qrbill_top_frame_bool
+    \bool_gset_false:N \g__qrbill_top_frame_bool
     \bool_gset_false:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / true .code:n = {
     \bool_gset_true:N \g__qrbill_top_frame_bool
@@ -80,6 +88,7 @@
     \bool_gset_true:N \g__qrbill_bottom_frame_bool
     \bool_gset_true:N \g__qrbill_left_frame_bool
     \bool_gset_true:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / top .code:n = {
     \bool_gset_true:N \g__qrbill_top_frame_bool
@@ -86,6 +95,7 @@
     \bool_gset_false:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
   frame / bottom .code:n = {
     \bool_gset_false:N \g__qrbill_top_frame_bool
@@ -92,7 +102,16 @@
     \bool_gset_true:N \g__qrbill_bottom_frame_bool
     \bool_gset_false:N \g__qrbill_left_frame_bool
     \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_true:N \g__qrbill_vrule_bool
   },
+  frame / none .code:n = {
+    \bool_gset_false:N \g__qrbill_top_frame_bool
+    \bool_gset_false:N \g__qrbill_bottom_frame_bool
+    \bool_gset_false:N \g__qrbill_left_frame_bool
+    \bool_gset_false:N \g__qrbill_right_frame_bool
+    \bool_gset_false:N \g__qrbill_vrule_bool
+  },
+
   frame .initial:n = true,
   billinginfo .bool_gset:N = \g__grbill_billinginfo_auto_bool,
   billinginfo .default:n = true,
@@ -134,12 +153,21 @@
   separate .initial:n = text,
   sep-iban .int_gset:N = \g__qrbill_ibansep_int,
   sep-iban .initial:n = 0,
-  ibanseperator .tl_gset:N = \g__qrbill_ibansep_tl,
-  ibanseperator  .initial:n = {\,},
+  ibanseparator .tl_gset:N = \g__qrbill_ibansep_tl,
+  ibanseparator .initial:n = {\,},
+  ibanseperator .code:n = \keys_set:nn {qrbill} {ibanseparator=#1}\msg_warning:nnnn {qrbill} {typo-in-option} {ibanseperator} {ibanseparator},
   sep-reference .int_gset:N = \g__qrbill_referencesep_int,
   sep-reference .initial:n = 0,
-  referenceseperator .tl_gset:N = \g__qrbill_referencesep_tl,
-  referenceseperator .initial:n = {\,}
+  referenceseparator .tl_gset:N = \g__qrbill_referencesep_tl,
+  referenceseparator .initial:n = {\,},
+  referenceseperator .code:n = \keys_set:nn {qrbill} {referenceseparator=#1}\msg_warning:nnnn {qrbill} {typo-in-option} {referenceseperator} {referenceseparator},
+  replace-tilde .choice:,
+  replace-tilde / true .code:n = \prop_gput:Nxx \g__qrbill_replacement_prop  {\char_generate:nn {126} {12}} {\ },
+  replace-tilde / false  .code:n = \exp_args:NNx \prop_gremove:Nn \g__qrbill_replacement_prop  {\char_generate:nn {126} {12}},
+  replace-umlauts .choice:,
+  replace-umlauts / true .code:n = \prop_gput_from_keyval:Nn \g__qrbill_replacement_prop {ä=ae,Ä=AE,ü=ue,Ü=UE,ö=oe,Ö=OE,ß=ss,ẞ=SS},
+  replace-umlauts / false .code:n = \clist_map_inline:nn {ä,Ä,ü,Ü,ö,Ö,ß,ẞ} {\prop_gremove:Nn \g__qrbill_replacement_prop {##1}},
+  data-to-string .bool_gset:N = \g__qrbill_to_string_bool,
 }
 
 \ProcessKeysOptions{qrbill}
@@ -146,11 +174,20 @@
 
 \newcommand*{\qrbillsetup}[1]{\keys_set:nn {qrbill}{#1}}
 \NewDocumentCommand{\qrbillsetdata}{sm}{
+\bool_if:NTF \g__qrbill_to_string_bool {
+\IfBooleanTF {#1} {
+\tl_set:Nx \l_tmpa_tl {#2}
+\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:V \l_tmpa_tl}
+}{
+\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:n {#2}}
+}
+} {
 \IfBooleanT {#1}
 \exp_args:Nnx
 \keys_set:nn
 {qrbill/data}{#2}
 }
+}
 
 \tl_if_empty:NTF \g__qrbill_font_tl {
   \def\qrbillfont{\normalfont}
@@ -157,18 +194,82 @@
 }{
   \RequirePackage{fontspec}
   \newfontfamily{\qrbillfont}{\g__qrbill_font_tl}
+  \RequirePackage{anyfontsize}
 }
 
 \dim_new:N \g_qrbill_QRcode_dim
 \dim_gset:Nn \g_qrbill_QRcode_dim {46mm}
+\bool_if:NT \g__qrbill_luamode_bool {
+\file_if_exist:nTF {qrencode.lua} {
+\lua_load_module:n {qrbill-latexluaqrcode}
+} {
+\msg_new:nnn {qrbill} {luaqrcode-not-found} {
+Could~not~find~the~required~library~for~qrmode=lua.\\
+I~will~switch~to~qrmode=package.
+}
+\msg_warning:nn {qrbill} {luaqrcode-not-found}
+\bool_gset_false:N \g__qrbill_luamode_bool
+}
+
+\dim_new:N \l__qrbill_QRblocksize_dim
+\cs_set_protected:Npn \qrbill_qrcode_black: {\rule{\l__qrbill_QRblocksize_dim}{\l__qrbill_QRblocksize_dim}}
+\cs_set_protected:Npn \qrbill_qrcode_white: {\rule{\l__qrbill_QRblocksize_dim}{0pt}\rule{0pt}{\l__qrbill_QRblocksize_dim}}
+\cs_new:Nn \qrbill_parse_QRcode:n {
+\lua_now:e {
+num, string = printQRcode("\lua_escape:n {#1}")
+}
+\dim_set:Nn \l__qrbill_QRblocksize_dim {\g_qrbill_QRcode_dim/\lua_now:n {tex.print(num)}}
+\let\qrblack\qrbill_qrcode_black:
+\let\qrwhite\qrbill_qrcode_white:
+\def\qrnewline{\\[\dimexpr-\baselineskip+\l__qrbill_QRblocksize_dim]}
+\noindent\parbox{\g_qrbill_QRcode_dim}{
+\lua_now:n {tex.sprint(string)}
+}
+}
+}
+
 \bool_if:NF \g__qrbill_luamode_bool {
   \usepackage{qrcode}
-  \cs_new:Nn \qrbill_parse_QRcode:n {
-    \raisebox{\depth}{\qrcode[height= \g_qrbill_QRcode_dim]{#1}}
+  % modified version of \qr at encode@binary to allow utf8 qrcodes required by swiss qrbill scheme
+  % Copyright (C) 2015 by Anders Hendrickson <ahendric at cord.edu>
+\cs_set:Nn \__qrbill_encode_unicode_binary:n {
+\edef\qr at plaintext{#1}%
+\def\qr at codetext{4}% %This means `binary'
+\xdef\qr at stringlength{\tl_count:o {\qr at plaintext}}%
+\edef\qr at charactercountlengthinhex{\int_eval:n {\qr at charactercountbits@byte / 4}}%
+\qr at decimaltohex[\qr at charactercountlengthinhex]{\qr at charactercount}{\qr at stringlength}%
+\xa\g at addto@macro\xa\qr at codetext\xa{\qr at charactercount}%
+\exp_args:NNx \str_set_convert:Nnnn \l_tmpa_str  { \qr at plaintext }  {iso88591} {utf8}
+\exp_args:NNV \str_set_convert:Nnnn \l_tmpa_str  \l_tmpa_str {} {latin1/hex}
+\str_gput_right:NV \qr at codetext \l_tmpa_str
+\xdef\qr at codetext{\exp_args:No \str_lowercase:n {\qr at codetext}}
+\g at addto@macro\qr at codetext{0}% %This is '0000' in binary.
+\setcounter{qr at hexchars}{\tl_count:o {\qr at codetext}}%
+\edef\qr at numpaddingcodewords{\int_eval:n {(-\c at qr@hexchars / 2)+\qr at totaldatacodewords}}
+\int_compare:nNnT {\qr at numpaddingcodewords} < {0} {
+\edef\ds{ERROR:~Too~much~data!~Over~by~\qr at numpaddingcodewords~bytes.}
+}
+\int_compare:nNnT {\qr at numpaddingcodewords} > {0} {
+\int_step_inline:nnnn {2} {2} {\qr at numpaddingcodewords} {
+\g at addto@macro{\qr at codetext}{ec11}%
+}
+\int_if_odd:nT {\qr at numpaddingcodewords} {
+\g at addto@macro{\qr at codetext}{ec}%
+}
+}
+}
+  \cs_set:Nn \qrbill_parse_QRcode:n {
+\cs_set_eq:NN \qr at encode@binary \__qrbill_encode_unicode_binary:n
+\raisebox{\depth}{\cs_set_eq:NN \qr at encode@binary \__qrbill_encode_unicode_binary:n\qrcode[height= \g_qrbill_QRcode_dim]{#1}}
   }
-  \cs_generate_variant:Nn \qrbill_parse_QRcode:n {V}
 }
 
+\cs_generate_variant:Nn \qrbill_parse_QRcode:n {V}
+
+\newcommand*{\QRbillAddCustomReplacement}[2]{
+ \prop_gput:Nxx \g__qrbill_replacement_prop  {#1} {#2},
+}
+
 \RequirePackage{scrbase}
 \RequirePackage{graphicx}
 \RequirePackage{numprint}
@@ -381,7 +482,9 @@
         {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
         {\rule{\g__qrbill_rule_dim}{\c_zero_dim}}
       \hspace{\dimexpr62mm-1.5\g__qrbill_rule_dim}
-      \rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}
+      \bool_if:NTF \g__qrbill_vrule_bool
+        {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
+        {\rule{\g__qrbill_rule_dim}{\c_zero_dim}}
       \hspace{\dimexpr148mm-1.5\g__qrbill_rule_dim}
       \bool_if:NTF \g__qrbill_right_frame_bool
         {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}}
@@ -427,7 +530,13 @@
 \seq_new:N \l_qrbill_tmp_seq
 
 \cs_new:Nn \qrbill_set_address_combined:nn {
-  \seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+\bool_if:NTF \g__qrbill_to_string_bool {
+\exp_args:NNxx \seq_set_split:Nnn \l_qrbill_tmp_seq
+{\tl_to_str:n {\\}}
+{ \str_range:nnn { #2 } { 2 } { -2 } }
+} {
+\seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+}
   \exp_args:Nnx \keys_set:nn {qrbill/data} {
     #1AddressType=K,
     #1Name=\seq_item:Nn \l_qrbill_tmp_seq {1},
@@ -440,7 +549,13 @@
 }
 
 \cs_new:Nn \qrbill_set_address_structured:nn {
-  \seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+\bool_if:NTF \g__qrbill_to_string_bool {
+\exp_args:NNxx \seq_set_split:Nnn \l_qrbill_tmp_seq
+{\tl_to_str:n {\\}}
+{ \str_range:nnn { #2 } { 2 } { -2 } }
+} {
+\seq_set_split:Nnn \l_qrbill_tmp_seq {\\} {#2}
+}
   \exp_args:Nnx \keys_set:nn {qrbill/data} {
     #1AddressType=S,
     #1Name=\seq_item:Nn \l_qrbill_tmp_seq {1},
@@ -489,7 +604,7 @@
 \int_set:Nn \l_tmpb_int {\int_abs:n {\int_use:c {g__qrbill_#1sep_int}}}
 \int_set:Nn \l_tmpa_int {1}
 \tl_clear:N \l_tmpa_tl
-\int_while_do:nn {\l_tmpa_int < \str_count:N \l_tmpa_str} {
+\int_while_do:nNnn {\l_tmpa_int} < {\str_count:N \l_tmpa_str - \l_tmpb_int +1 } {
 \tl_put_right:Nx \l_tmpa_tl {
 \str_range:Nnn \l_tmpa_str {\l_tmpa_int} {\l_tmpa_int + \l_tmpb_int-1}
 }
@@ -523,7 +638,7 @@
   \keys_define:nn {qrbill/data} {
     #1 .code:n = {
       \tl_if_empty:nF {##1}{
-        \keys_set:nx {qrbill/data} {
+        \exp_args:Nnx \keys_set:nn {qrbill/data} {
           #1-Parameters={\qrbill_av_prefix:n {#1}##1}
         }
       }
@@ -534,8 +649,12 @@
 }
 
 \newcommand*{\SetupQrBill}[1]{
-  \keys_set:nn {qrbill/data} {#1}
+\bool_if:NTF \g__qrbill_to_string_bool {
+\exp_args:Nnx \keys_set:nn {qrbill/data} {\tl_to_str:n {#1}}
+} {
+\keys_set:nn {qrbill/data} {#1}
 }
+}
 
 \str_new:N \l_qrbill_data_str
 \cs_new:Nn \qrcode_setup_QRcode: {
@@ -548,7 +667,10 @@
          \exp_args:NNv \str_put_right:Nn \l_qrbill_data_str {l_qrbill_data_##1_tl}
   }
   %necessary to preserve spaces!
-  \str_replace_all:Nnn \l_qrbill_data_str  {~ } {\ }
+  \str_replace_all:Nnn \l_qrbill_data_str {~ } {\ }
+  \prop_map_inline:Nn \g__qrbill_replacement_prop {
+\str_replace_all:Nnn \l_qrbill_data_str {##1} {##2}
+}
   \tl_set_rescan:Nno \l_qrbill_data_str {\ExplSyntaxOff} {\l_qrbill_data_str}
 }
 
@@ -565,12 +687,16 @@
 
 \prop_new:N \g__qrbill_billing_info_prop
 \seq_new:N \g__qrbill_billing_info_seq
+
+\clist_new:N \g__qrbill_billing_info_static_clist
+\newcommand*{\SetStaticData}[1]{\clist_gset:Nx \g__qrbill_billing_info_static_clist {\tl_to_str:n {#1}}}
+
 \newcommand*{\SetBillingInfoScheme}[1]{
   \prop_gset_from_keyval:Nn \g__qrbill_billing_info_prop {#1}
   \seq_gclear:N  \g__qrbill_billing_info_seq
   \prop_map_inline:Nn \g__qrbill_billing_info_prop {
-    \exp_args:Nx \clist_if_in:nnF {\tl_to_str:n {prefix , postfix}} {##1} {
-      \seq_push:Nn  \g__qrbill_billing_info_seq {##1}
+    \clist_if_in:NnF \g__qrbill_billing_info_static_clist {##1} {
+      \seq_push:Nn \g__qrbill_billing_info_seq {##1}
     }
     \keys_define:nn {qrbill/data} {
       ##2 .tl_set:c = l_qrbill_##2_tl,
@@ -577,6 +703,15 @@
       ##2 .initial:n =,
     }
   }
+\seq_if_empty:NF \g__qrbill_billing_info_seq {
+\prop_map_inline:Nn \g__qrbill_billing_info_prop {
+\clist_if_in:NnT \g__qrbill_billing_info_static_clist {##1} {
+\exp_args:Nx \clist_if_in:nnF {\tl_to_str:n {prefix , postfix}} {##1} {
+\seq_push:Nn  \g__qrbill_billing_info_seq {##1}
+    }
+}
+}
+}
   \seq_sort:Nn \g__qrbill_billing_info_seq {
     \int_compare:nNnTF { ##1 } > { ##2 }
         { \sort_return_swapped: }

Modified: trunk/Master/texmf-dist/tex/latex/qrbill/swiss.qrbill-cfg.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/qrbill/swiss.qrbill-cfg.tex	2022-09-15 19:57:45 UTC (rev 64405)
+++ trunk/Master/texmf-dist/tex/latex/qrbill/swiss.qrbill-cfg.tex	2022-09-15 19:58:08 UTC (rev 64406)
@@ -78,6 +78,8 @@
   AV2-Parameters
 }
 
+\SetStaticData{prefix,11,31}
+
 \SetBillingInfoScheme{
   prefix=//S1,
   10=invoicenum,



More information about the tex-live-commits mailing list.