%%
%% This is file `qrbill.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% qrbill.dtx  (with options: `qrbill.sty,package')
%% 
%% Copyright (C) 2020–2023 by Marei Peischl (peiTeX) <marei@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.3c
%% 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 2005/12/01 or later.
%% 
%% This work has the LPPL maintenance status `maintained'.
%% 
%% The Current Maintainer of this work is
%%   Marei Peischl <qrbill@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,
%% and qrbill-epc-demo.tex.
%% 
%% The development repository can be found at
%% https://github.com/peitex/qrbill
%% Please use the issue tracker for feedback!
%% 
\RequirePackage{expl3}
\ProvidesExplPackage{qrbill}{2023/07/24}{2.01}{
  Template for QR-bills based on the Swiss Payment Standards
}
\RequirePackage{iftex}
\RequirePackage{l3keys2e}

\tl_new:N \g__qrbill_font_tl
\bool_new:N \g__qrbill_top_frame_bool
\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.
}

\tl_new:N \g__qrbill_qrscheme_tl

\keys_define:nn {qrbill} {
  font .choices:nn = {Frutiger, Arial, Helvetica, Liberation Sans} {
\tl_gset_eq:NN \g__qrbill_font_tl \l_keys_choice_tl
  },
  font .initial:n = Liberation Sans,
  font / custom .code:n = {\tl_gclear:N \g__qrbill_font_tl},
  qrscheme .choice:,
  qrscheme / epc .code:n = \tl_gset:Nn \g__qrbill_qrscheme_tl {epc}\tl_gclear:N \g__qrbill_font_tl,
  qrscheme / unknown .code:n = \tl_gset:Nn  \g__qrbill_qrscheme_tl {
  #1},
  qrscheme .initial:n = swiss,
  qrsize .dim_gset:N =  \g_qrbill_QRcode_dim,
  qrsize .initial:n = 46mm,
  creditorprefix .tl_gset:N = \g__qrbill_creditorprefix_tl,
  creditorprefix .initial:n = CR-,
  debtorprefix .tl_gset:N = \g__qrbill_debtorprefix_tl,
  debtorprefix .initial:n = UD-,
  qrmode .choice:,
  qrmode / package .code:n = \bool_gset_false:N \g__qrbill_luamode_bool,
  qrmode / lua .code:n = \bool_gset_true:N \g__qrbill_luamode_bool,
  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_bottom_frame_bool
\bool_gset_false:N \g__qrbill_left_frame_bool
\bool_gset_false:N \g__qrbill_right_frame_bool
  },
  frame / true .code:n = {
\bool_gset_true:N \g__qrbill_top_frame_bool
\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
  },
  frame / top .code:n = {
\bool_gset_true: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
  },
  frame / bottom .code:n = {
\bool_gset_false:N \g__qrbill_top_frame_bool
\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
  },
  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
\keys_set:nn {qrbill} {vrule=false}
  },
  frame .initial:n = true,
  vrule .choice:,
  vrule / true .code:n = \tl_gset:Nn \g__qrbill_vrule_tl {\rule{\g__qrbill_rule_dim}{\c_qrbill_height_dim}},
  vrule / false .code:n = \tl_gset:Nn \g__qrbill_vrule_tl {\rule{\g__qrbill_rule_dim}{\c_zero_dim}},
vrule / symbol .code:n =  {
\RequirePackage{marvosym}
\tl_gset:Nn \g__qrbill_vrule_tl {
\rotatebox{90}{
\hbox_to_wd:nn {\c_qrbill_height_dim}{
\leaders\hbox{\rule{1mm}{\g__qrbill_rule_dim}\hspace{1mm}}\hskip 0pt\@plus1 fill\relax
\llap{\raisebox{-.5\height}[\c_zero_dim][\c_zero_dim]{\LeftScissors}}
\leaders\hbox{\rule{1mm}{\g__qrbill_rule_dim}\hspace{1mm}}\hskip 0pt\@plus4 fill\relax
\hbox{\rule{1mm}{\g__qrbill_rule_dim}}
}
}
}
},
vrule .initial:n = true,
  billinginfo .bool_gset:N = \g__grbill_billinginfo_auto_bool,
  billinginfo .default:n = true,
  billinginfo .initial:n = true,
  icon .choice:,
  icon / swiss-cross .meta:n = {icon=qrbill_swiss-cross.pdf},
  icon / unknown .code:n = \tl_gset:Nn \g_qrbill_icon_tl {#1},
  icon .initial:n =,
  iconwidth .dim_gset:N = \g_qrbill_iconwidth_dim,
  iconwidth .initial:n = 7mm,
  separate .choice:,
  separate / symbol .code:n = {
\bool_gset_true:N \g__qrbill_separateinfo_bool
\RequirePackage{marvosym}
\cs_set:Nn \qrbill_print_separate_info: {
\par\leaders\vbox_to_ht:nn {1sp} {
\smash{
\hbox_to_wd:nn {\c_qrbill_width_dim }{
\leaders\hbox{\rule{1mm}{\g__qrbill_rule_dim}\hspace{1mm}}\hskip 0pt\@plus1 fill\relax
\llap{\raisebox{-.5\height}{\LeftScissors}}
\leaders\hbox{\rule{1mm}{\g__qrbill_rule_dim}\hspace{1mm}}\hskip 0pt\@plus4 fill\relax
}
}
}
\vskip 1sp
\vskip -1sp
}
},
  separate / text .code:n = {
\bool_gset_true:N \g__qrbill_separateinfo_bool
\cs_set:Nn \qrbill_print_separate_info: {
\centerline{\raisebox{\dimexpr\depth+.3ex\relax}[0pt][0pt]{\footnotesize\qrbillseparatename}}
\par\nointerlineskip
\rule{\c_qrbill_width_dim}{\g__qrbill_rule_dim}
}
  },
  separate / false .code:n = {\bool_gset_false:N \g__qrbill_separateinfo_bool},
  separate .initial:n = text,
  sep-iban .int_gset:N = \g__qrbill_ibansep_int,
  sep-iban .initial:n = 0,
  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,
  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,
  ignore-if-empty  .clist_gset:N = \g__qrbill_ignore_if_empty_clist,
  ignore-if-empty .initial:n = ,
}

\ProcessKeysOptions{qrbill}

\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}
}{
  \RequirePackage{fontspec}
  \newfontfamily{\qrbillfont}{\g__qrbill_font_tl}
  \RequirePackage{anyfontsize}
}

\bool_if:NT \g__qrbill_luamode_bool {
\lua_load_module:n {qrbill-latexluaqrcode}

\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 {
 \__qrbill_setup_lua_qrcode:x {#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]}
\raisebox{\dimexpr\depth-\l__qrbill_QRblocksize_dim}[\dimexpr\height+\depth-\l__qrbill_QRblocksize_dim][0pt]{
\noindent\parbox{\g_qrbill_QRcode_dim}{
\lua_now:n {tex.sprint(string)}
\hss
}
}
}

\cs_new:Nn  \__qrbill_setup_lua_qrcode:n {
\lua_now:e {
num, string = printQRcode("\lua_escape:n {#1}")
}
}

\cs_generate_variant:Nn \__qrbill_setup_lua_qrcode:n {x}
}


\bool_if:NF \g__qrbill_luamode_bool {
  \usepackage{qrcode}
  % modified version of \qr@encode@binary to allow utf8 qrcodes required by swiss qrbill scheme
  % Copyright (C) 2015 by Anders Hendrickson <ahendric@cord.edu>
\cs_set:Nn \__qrbill_encode_unicode_binary:n {
\edef\qr@plaintext{#1}%
\def\qr@codetext{4}% %This means `binary'
\__qrbill_qr_get_string_length_encoded:n { \qr@plaintext }
\edef\qr@charactercountlengthinhex{\int_eval:n {\qr@charactercountbits@byte / 4}}%
\qr@decimaltohex[\qr@charactercountlengthinhex]{\qr@charactercount}{\qr@stringlength}%
\xa\g@addto@macro\xa\qr@codetext\xa{\qr@charactercount}%
\exp_args:NNx \str_set_convert:Nnnn \l_tmpa_str  { \qr@plaintext }  {} {utf8/hex}

\str_gput_right:NV \qr@codetext \l_tmpa_str
\xdef\qr@codetext{\exp_args:No \str_lowercase:n {\qr@codetext}}
\g@addto@macro\qr@codetext{0}% %This is '0000' in binary.
\setcounter{qr@hexchars}{\tl_count:o {\qr@codetext}}%
\edef\qr@numpaddingcodewords{\int_eval:n {(-\c@qr@hexchars / 2)+\qr@totaldatacodewords}}
\int_compare:nNnT {\qr@numpaddingcodewords} < {0} {
\edef\ds{ERROR:~Too~much~data!~Over~by~\qr@numpaddingcodewords~bytes.}
}
\int_compare:nNnT {\qr@numpaddingcodewords} > {0} {
\int_step_inline:nnnn {2} {2} {\qr@numpaddingcodewords} {
\g@addto@macro{\qr@codetext}{ec11}%
}
\int_if_odd:nT {\qr@numpaddingcodewords} {
\g@addto@macro{\qr@codetext}{ec}%
}
}
}
  \cs_set:Nn \qrbill_parse_QRcode:n {
\cs_set_eq:NN \qr@encode@binary \__qrbill_encode_unicode_binary:n
\raisebox{\depth}{
\__qrbill_enable_unicode_qrcode_patch:
\qrcode[nolink,height= \g_qrbill_QRcode_dim]{#1}
}
  }

\cs_new:Nn \__qrbill_qr_get_string_length_encoded:n {%
\exp_args:NNx \str_set_convert:Nnnn \l_tmpa_str  { #1 }  {} {utf8/hex}
\xdef\qr@stringlength{\int_eval:n {\str_count:N \l_tmpa_str / 2}}
}

\cs_new:Nn \__qrbill_qr_padatfront:nn {%
\prg_replicate:nn {\int_max:nn {0} {#2- \tl_count:N #1}} {
\qr@g@preface@macro{#1}{0}
}
}

\let\orig@qr@getstringlength\qr@getstringlength

\cs_new:Nn \__qrbill_enable_unicode_qrcode_patch: {
\cs_set_eq:NN \qr@padatfront \__qrbill_qr_padatfront:nn
\AddToHook{cmd/qr@choose@best@version/before}{\cs_set_eq:NN \qr@getstringlength\__qrbill_qr_get_string_length_encoded:n}
\AddToHook{cmd/qr@choose@best@version/after}{\let\qr@getstringlength\orig@qr@getstringlength}
}
}

\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}
\npthousandsep{\,}
\npdecimalsign{.}

\dim_new:N \g__qrbill_rule_dim
\dim_gset:Nn \g__qrbill_rule_dim {.5pt}
\dim_const:Nn \c_qrbill_sep_dim {5mm}
\dim_const:Nn \c_qrbill_width_dim {210mm}
\dim_const:Nn \c_qrbill_height_dim {105mm}

\cs_new:Nn \qrbill_title_font: {\fontsize{11bp}{11bp}\selectfont\bfseries}

\cs_new:Nn \qrbill_headingR_font: {\fontsize{6bp}{9bp}\selectfont\bfseries}
\cs_new:Nn \qrbill_valueR_font: {\fontsize{8bp}{9bp}\selectfont}
\cs_new:Nn \qrbill_amountR_font: {\fontsize{8bp}{11bp}\selectfont}
\cs_new:Nn \qrbill_acceptance_font: {\fontsize{6bp}{8bp}\selectfont\bfseries}

\cs_new:Nn \qrbill_headingP_font: {\fontsize{8bp}{11bp}\selectfont\bfseries}
\cs_new:Nn \qrbill_valueP_font: {\fontsize{10bp}{11bp}\selectfont}
\cs_new:Nn \qrbill_amountP_font: {\fontsize{10bp}{13bp}\selectfont}

\cs_new:Nn \qrbill_infoheading_font: {\fontsize{7bp}{8bp}\selectfont\bfseries}
\cs_new:Nn \qrbill_info_font: {\fontsize{7bp}{8bp}\selectfont}

\dim_new:N \g_qrbill_placeholder_rule_dim
\dim_gset:Nn \g_qrbill_placeholder_rule_dim {.75pt}
\dim_new:N \g_qrbill_placeholder_corner_dim
\dim_gset:Nn \g_qrbill_placeholder_corner_dim {3mm}
\cs_new:Nn \__qrbill_placeholder_hmark: {
  \rule{\g_qrbill_placeholder_corner_dim}{\g_qrbill_placeholder_rule_dim}
}
\cs_new:Nn \__qrbill_placeholder_vmark: {
  \rule{\g_qrbill_placeholder_rule_dim}{\g_qrbill_placeholder_corner_dim}
}

\cs_new:Nn \__qrbill_placeholder:nn {
  \vbox_to_ht:nn {#2} {
\hbox_to_wd:nn {#1} {\__qrbill_placeholder_hmark: \hfill \__qrbill_placeholder_hmark:}
\nointerlineskip
\hbox_to_wd:nn {#1} {\__qrbill_placeholder_vmark: \hfill \__qrbill_placeholder_vmark:}
\vfill
\hbox_to_wd:nn {#1} {\__qrbill_placeholder_vmark: \hfill \__qrbill_placeholder_vmark:}
\nointerlineskip
\hbox_to_wd:nn {#1} {\__qrbill_placeholder_hmark: \hfill \__qrbill_placeholder_hmark:}
  }
}

\cs_new:Nn \qrbill_bill_create: {
  \begingroup
  \qrbill_parse_BillingInfo:
  \qrbillfont
  \setlength{\parindent}{\z@}
  \parbox{\c_qrbill_width_dim }{
\vbox to \c_qrbill_height_dim {
\bool_if:NTF \g__qrbill_top_frame_bool
{
\bool_if:NTF \g__qrbill_separateinfo_bool
{\qrbill_print_separate_info:}
{\rule{\c_qrbill_width_dim}{\g__qrbill_rule_dim}}
}
{\rule{\c_zero_dim}{\g__qrbill_rule_dim}}
\par\nointerlineskip
\skip_vertical:n {\c_qrbill_sep_dim-\g__qrbill_rule_dim}
\skip_horizontal:n {\c_qrbill_sep_dim-\g__qrbill_rule_dim}
\begin{minipage}[c][95mm][t]{52mm}
\vbox_to_ht:nn {7mm} {\qrbill_title_font:\qrbillreceiptname\vfill}
\par\nointerlineskip
\vbox_to_ht:nn {56mm}{
{\qrbill_headingR_font:\qrbillaccountname\par}
{
\qrbill_valueR_font:
\__qrbill_sep_tl:nV {iban} \l_qrbill_data_Account_tl\par
\qrbill_insert_address:N \g__qrbill_creditorprefix_tl
\par\vskip\baselineskip
}
\tl_if_empty:NF \l_qrbill_data_Reference_tl {
{\qrbill_headingR_font:\qrbillreferencename\par}
{
\qrbill_valueR_font:
\__qrbill_sep_tl:nV {reference} \l_qrbill_data_Reference_tl
\par\vskip\baselineskip
}
}
\tl_if_empty:cTF {l_qrbill_data_\g__qrbill_debtorprefix_tl Name_tl}
 {
 {\qrbill_headingR_font:\qrbilldebtoraddrname\par}
 \__qrbill_placeholder:nn {52mm} {20mm}
 }{
 {\qrbill_headingR_font:\qrbilldebtorname\par}
 {
 \qrbill_valueR_font:
 \qrbill_insert_address:N \g__qrbill_debtorprefix_tl
 \par
 }
 }
 \vfill
}
\par\nointerlineskip
\vbox_to_ht:nn {14mm}{
\qrbill_headingR_font:
\begin{tabular}[t]{@{}ll@{}}
\qrbillcurrencyname&\qrbill_headingR_font:\qrbillamountname\\
\qrbill_amountR_font:\l_qrbill_data_Currency_tl
&\qrbill_amountR_font:
\tl_if_empty:NF \l_qrbill_data_Amount_tl
 {\numprint{\l_qrbill_data_Amount_tl}}
\end{tabular}
\tl_if_empty:NTF \l_qrbill_data_Amount_tl {
\hfill
\raisebox{\dimexpr-\height+\ht\strutbox}[\z@]{\llap{
\__qrbill_placeholder:nn {30mm} {10mm}
}}
}
\vfill
}
\par\nointerlineskip
\vbox_to_ht:nn {18mm} {
\makebox[\linewidth][r]{\qrbill_headingR_font:\qrbillacceptantname}\par
\vfill
}
\end{minipage}%
\skip_horizontal:n {2\c_qrbill_sep_dim}
\begin{minipage}[c][95mm][t]{138mm}
\begin{minipage}[c][85mm][t]{51mm}
\parbox[t][7mm][t]{\linewidth}{\qrbill_title_font:\qrbillpaymentpartname\vfill}
\par\nointerlineskip
\skip_vertical:n {\c_qrbill_sep_dim}
\qrcode_setup_QRcode:
\leavevmode\qrbill_parse_QRcode:V \l_qrbill_data_str
\tl_if_empty:NF \g_qrbill_icon_tl {
\llap{\hbox_to_wd:nn {\g_qrbill_QRcode_dim} {
\hfill
\raisebox{\dimexpr-.5\height+.5\g_qrbill_QRcode_dim}[0pt][0pt]{
\includegraphics[width=\g_qrbill_iconwidth_dim]{\g_qrbill_icon_tl}
}
\hfill
}}
}
\skip_vertical:n {\c_qrbill_sep_dim}
\vbox_to_ht:nn {22mm}{
\begin{tabular}[b]{@{}ll@{}}
\qrbill_headingP_font:\qrbillcurrencyname&\qrbill_headingP_font:
\qrbillamountname\\
\qrbill_amountP_font:\tl_use:c {l_qrbill_data_Currency_tl}&
\tl_if_empty:NF \l_qrbill_data_Amount_tl {
\qrbill_amountP_font:\numprint{\l_qrbill_data_Amount_tl}
}
\end{tabular}
\tl_if_empty:NTF \l_qrbill_data_Amount_tl {
\hfill
\raisebox{\dimexpr-\height+\ht\strutbox}[\z@]{
\llap{\__qrbill_placeholder:nn {40mm} {15mm}}
}
}
\vfill
}
\end{minipage}
\begin{minipage}[c][85mm][t]{87mm}
\par\nointerlineskip
{\qrbill_headingP_font:\qrbillaccountname\par}
{
\qrbill_valueP_font:
\__qrbill_sep_tl:nV {iban} \l_qrbill_data_Account_tl \par
\qrbill_insert_address:N \g__qrbill_creditorprefix_tl
\par\vskip\baselineskip
}
\raggedright
\tl_if_empty:NF \l_qrbill_data_Reference_tl {
{\qrbill_headingP_font:\qrbillreferencename\par}
{\qrbill_valueP_font:
\__qrbill_sep_tl:nV {reference} \l_qrbill_data_Reference_tl
\par\vskip\baselineskip}
}
\exp_args:Nf \tl_if_empty:nF  {
\l_qrbill_data_BillingInfo_tl
\l_qrbill_data_Message_tl
}{
{\qrbill_headingP_font:\qrbilladdinfoname\par}
{
\qrbill_valueP_font:
\l_qrbill_data_Message_tl\par
\tl_replace_all:Nnn \l_qrbill_data_BillingInfo_tl {/} {\discretionary{}{}{}/}
\l_qrbill_data_BillingInfo_tl
\par\vskip\baselineskip
}
}
\tl_if_empty:cTF {l_qrbill_data_\g__qrbill_debtorprefix_tl Name_tl} {
{\qrbill_headingP_font:\qrbilldebtoraddrname\par}
\__qrbill_placeholder:nn {65mm} {25mm}
}{
{\qrbill_headingP_font:\qrbilldebtorname\par}
{
\qrbill_valueP_font:
\qrbill_insert_address:N \g__qrbill_debtorprefix_tl
\par
}
}
\end{minipage}\par\nointerlineskip
\begin{minipage}[b][10mm][t]{\linewidth}
\strut
\qrbill_insert_AV_parameters:NNn
\qrbill_infoheading_font:
\qrbill_info_font:
{AV1,AV2}
\end{minipage}
\end{minipage}
\par\nointerlineskip\skip_vertical:n  {\c_qrbill_sep_dim}
\smash{
\bool_if:NT \g__qrbill_bottom_frame_bool
{\rlap{\rule{\c_qrbill_width_dim}{\g__qrbill_rule_dim}}}
\bool_if:NTF \g__qrbill_left_frame_bool
{\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}
\g__qrbill_vrule_tl
\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}}
{\rule{\g__qrbill_rule_dim}{\c_zero_dim}}
}
\vfill
}
  }
  \endgroup
}

\NewDocumentCommand{\QRbill}{so}{
\begingroup
\IfNoValueF{#2} {\keys_set:nn {qrbill/data} {#2}}
\IfBooleanTF {#1}
{
\qrcode_setup_QRcode:
\leavevmode\qrbill_parse_QRcode:V \l_qrbill_data_str
\tl_if_empty:NF \g_qrbill_icon_tl {
\llap{\hbox_to_wd:nn {\g_qrbill_QRcode_dim} {
\hfill
\raisebox{\dimexpr-.5\height+.5\g_qrbill_QRcode_dim}[0pt][0pt]{
\includegraphics[width=\g_qrbill_iconwidth_dim]{\g_qrbill_icon_tl}
}
\hfill
}}
}
}{
\qrbill_bill_create:
}
\endgroup
}

\ior_new:N \qrbill_ior
\clist_new:N \l_qrbill_tmpa_clist
\ior_open:Nn \qrbill_ior {qrbill-vocab.csv}

\ior_get:NN \qrbill_ior \l_tmpa_tl
\clist_set:Nx \l_qrbill_tmpa_clist {\l_tmpa_tl}
\int_set:Nn \l_tmpa_int {\clist_count:N \l_qrbill_tmpa_clist}

\ior_str_map_inline:Nn \qrbill_ior {
  \int_step_inline:nnn {2} {\l_tmpa_int } {
\exp_args:Nnx \use:n {\exp_args:NNx \exp_args:Nnc \defcaptionname
{\clist_item:Nn \l_qrbill_tmpa_clist {##1}}
{qrbill\clist_item:nn {#1} {1}name}}
{\clist_item:nn {#1} {##1}}
  }
}

\ior_close:N \qrbill_ior

\seq_new:N \l_qrbill_tmp_seq

\cs_new:Nn \qrbill_set_address_combined:nn {
\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}},
#1Address1={\seq_item:Nn \l_qrbill_tmp_seq {2}},
#1Address2={\seq_item:Nn \l_qrbill_tmp_seq {3}},
#1PostalCode=,
#1City=,
#1Country={\seq_item:Nn \l_qrbill_tmp_seq {4}},
  }
}

\cs_new:Nn \qrbill_set_address_structured:nn {
\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}},
#1Address1={\seq_item:Nn \l_qrbill_tmp_seq {2}},
#1Address2={\seq_item:Nn \l_qrbill_tmp_seq {3}},
#1PostalCode={\seq_item:Nn \l_qrbill_tmp_seq {4}},
#1City={\seq_item:Nn \l_qrbill_tmp_seq {5}},
#1Country={\seq_item:Nn \l_qrbill_tmp_seq {6}},
  }
}

\cs_new:Nn \qrbill_insert_address:N {
  \tl_use:c {l_qrbill_data_#1Name_tl}\ifhmode\\\fi
  \str_case_e:nnF {\use:c {l_qrbill_data_#1AddressType_tl}}
  {
{K}     {
  \tl_use:c {l_qrbill_data_#1Address1_tl}
  \tl_if_empty:cF {l_qrbill_data_#1Address2_tl} {
\ifhmode\\\fi
\tl_if_empty:cF {l_qrbill_data_#1Country_tl}
  {\tl_use:c {l_qrbill_data_#1Country_tl}-}
  \tl_use:c {l_qrbill_data_#1Address2_tl}
   }
}
  }{
\tl_use:c {l_qrbill_data_#1Address1_tl}~
\tl_use:c {l_qrbill_data_#1Address2_tl}
\tl_if_empty:cF {l_qrbill_data_#1City_tl} {
  \ifhmode\\\fi
  \tl_if_empty:cF {l_qrbill_data_#1Country_tl}
{\tl_use:c {l_qrbill_data_#1Country_tl}-}
  \tl_use:c {l_qrbill_data_#1PostalCode_tl}~
  \tl_use:c {l_qrbill_data_#1City_tl}
}
  }
}

\cs_new:Nn \__qrbill_sep_tl:nn {
\int_compare:nTF  {\int_use:c {g__qrbill_#1sep_int} = 0} {
#2
}{
\str_set:Nn \l_tmpa_str {#2}
\int_compare:nT {\int_use:c  {g__qrbill_#1sep_int} < 0} {
\tl_reverse:N \l_tmpa_str
}
\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: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}
}
\int_add:Nn \l_tmpa_int {\l_tmpb_int}
\tl_put_right:Nn \l_tmpa_tl {{\tl_use:c {g__qrbill_#1sep_tl}}}
}
\tl_put_right:Nx \l_tmpa_tl {
\str_range:Nnn \l_tmpa_str {\l_tmpa_int} {\str_count:N \l_tmpa_str}
}
\int_compare:nT {\int_use:c  {g__qrbill_#1sep_int} < 0} {
\tl_reverse:N \l_tmpa_tl
}
\l_tmpa_tl
}
}
\cs_generate_variant:Nn \__qrbill_sep_tl:nn {nV}

\newcommand*{\insertdebtor}{\null\qrbill_insert_address:N \g__qrbill_debtorprefix_tl}
\newcommand*{\insertcreditor}{\null\qrbill_insert_address:N \g__qrbill_creditorprefix_tl}
\newcommand*{\insertcurrency}{\l_qrbill_data_Currency_tl}

\keys_define:nn {qrbill/data} {
  creditor .code:n = \qrbill_set_address_combined:nn {\g__qrbill_creditorprefix_tl}{#1},
  creditor* .code:n = \qrbill_set_address_structured:nn {\g__qrbill_creditorprefix_tl} {#1},
  debtor .code:n = \qrbill_set_address_combined:nn {\g__qrbill_debtorprefix_tl}{#1},
  debtor* .code:n = \qrbill_set_address_structured:nn {\g__qrbill_debtorprefix_tl} {#1},
  account .tl_set:N = \l_qrbill_iban_tl,
}

\clist_map_inline:nn {AV1, AV2} {
  \keys_define:nn {qrbill/data} {
#1 .code:n = {
\tl_if_empty:nF {##1}{
\exp_args:Nnx \keys_set:nn {qrbill/data} {
#1-Parameters={\qrbill_av_prefix:n {#1}##1}
}
}
\tl_set:cn {l_qrbill_#1_tl} {##1}
},
#1 .initial:n =,
  }
}

\newcommand*{\SetupQrBill}[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: {
  \str_clear:N \l_qrbill_data_str
  \bool_set_false:N \l_tmpa_bool
  \seq_map_inline:Nn \g__qrbill_qrscheme_seq {
\clist_if_in:NnTF \g__qrbill_ignore_if_empty_clist {##1}
{
\tl_if_empty:cTF {l_qrbill_data_##1_tl} \use_none:n \use:n
}
\use:n
{
\bool_if:NTF \l_tmpa_bool
       {\str_put_right:Nn\l_qrbill_data_str  {^^J}}
       {\bool_set_true:N \l_tmpa_bool}
     \exp_args:NNv \str_put_right:Nn \l_qrbill_data_str {l_qrbill_data_##1_tl}
    }
  }
  %necessary to preserve spaces!
  \bool_if:NF \g__qrbill_luamode_bool
{ \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}
}

\seq_new:N \g__qrbill_qrscheme_seq
\newcommand*\SetQrScheme[1]{
\seq_gset_from_clist:Nn \g__qrbill_qrscheme_seq {#1}
\seq_map_inline:Nn \g__qrbill_qrscheme_seq {
\keys_define:nn {qrbill/data} {
##1 .tl_set:c = l_qrbill_data_##1_tl,
##1 .initial:n =,
}
}
}

\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 {
\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,
##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: }
{ \sort_return_same: }
  }
}

\tl_new:N \l_qrbill_data_BillingInfo_tl

\cs_new:Nn \qrbill_parse_BillingInfo: {
  \bool_if:NT \g__grbill_billinginfo_auto_bool {
\str_put_right:Nx \l_qrbill_data_BillingInfo_tl {
\prop_item:Nn \g__qrbill_billing_info_prop  {prefix}
}
\seq_map_inline:Nn \g__qrbill_billing_info_seq {
\prop_get:NnN \g__qrbill_billing_info_prop {##1} \l_tmpa_tl
\tl_if_empty:cF {l_qrbill_\l_tmpa_tl _tl} {
\str_put_right:Nx \l_qrbill_data_BillingInfo_tl {
/##1/\tl_use:c {l_qrbill_\l_tmpa_tl _tl}
}
}
}
  }
}

\cs_set:Nn \qrbill_parse_date:nnn {
#1-
\int_compare:nNnT {#2} < {10} {0}#2-
\int_compare:nNnT {#3} < {10} {0}#3
}

\cs_generate_variant:Nn \qrbill_parse_date:nnn {eee}

\cs_set:Npn \QRbillParseDate #1#2#3 {
\qrbill_parse_date:eee {#1}{#2}{#3}
}

\cs_new:Nn \qrbill_insert_AV_parameters:NNn {
  \clist_map_inline:nn {#3} {
\tl_if_empty:cF {l_qrbill_##1_tl}
 {{#1\qrbill_av_prefix:n {##1}}{#2 \tl_use:c {l_qrbill_##1_tl}}}
}
}

\cs_new:Nn \qrbill_av_prefix:n {Name~#1:~}

\input{\g__qrbill_qrscheme_tl.qrbill-cfg}

\endinput
%%
%% End of file `qrbill.sty'.
