{ w_filter_diag
printf '
[form class="newcard" action="/cards/new_card.sh" method="POST"
+ [a href="#top" . %s]
[button type="submit" %s]
- [input name="seed" placeholder="%s"]
- ]' "$(l10n newcard)" "$(l10n vcf_seed_label)"
+ ]' "$(l10n top)" "$(l10n newcard)"
-
[ "$edit" ] && edit_card "$edit"
list_cards
- } | yield_page cards /cards/cards.css
+ } | yield_page cards #/cards/cards.css
hi_status) printf %s "Ver­sich­er­ten­sta­tus";;
X-HEALTH-INSURANCE-NOCONTRIB) printf %s "Zu­zahl­ungs­be­frei­ung";;
X-CLIENT-REFERRAL) printf %s "Empfehl­ung durch";;
- prescriptions) printf %s "Verordnungen";;
- new_prescription) printf %s "Neue Verordnung";;
+ prescriptions) printf %s "Verord­nungen";;
+ new_prescription) printf %s "Neue Verord­nung";;
no_icd) printf %s "Kein ICD Code";;
+ therapy) printf %s "Therapie";;
+ therapies) printf %s "Therapien";;
- X-ZACK-JOINDATE) printf %s "An­mel­de­da­tum";;
- X-ZACK-LEAVEDATE) printf %s "Ab­mel­de­da­tum";;
+ X-ZACK-JOINDATE) printf %s "Anmelde­datum";;
+ X-ZACK-LEAVEDATE) printf %s "Abmelde­datum";;
X-ZACK-JOINDATE_short) printf %s "Anm.";;
X-ZACK-LEAVEDATE_short) printf %s "Abm.";;
-
- top) printf 'Seitenanfang';;
- edit) printf %s "Bearbeiten";;
- edit_categories) printf %s "Kategorien Bearbeiten";;
- vcf_export) printf %s "Vcard Exportieren";;
- control) printf %s "Aktionen";;
- edit_update) printf %s "Daten übernehmen";;
- edit_cancel) printf %s "Abbrechen";;
- edit_delete) printf %s "Eintrag löschen";;
- edit_addfieldtext) printf %s "Neues Feld";;
- edit_addfield) printf %s "+";;
- edit_deletefield) printf %s "X";;
- filter_label) printf %s "Filter";;
- filter_placeholder) printf %s "Begriffe zur Eingrenzung eingeben";;
- filter_type) printf %s "Filtertyp";;
- filter_order) printf %s "Sortierung";;
- filter_any) printf %s "Alles";;
- filter_name) printf %s "Name";;
- filter_firstname) printf %s "Vorname";;
- filter_lastname) printf %s "Nachname";;
- filter_street) printf %s "Straße";;
- filter_zip) printf %s "PLZ.";;
- filter_TEL) printf %s "Telefon";;
- filter_BDAY) printf %s "Geburtsjahr";;
- filter_bdate) printf %s "Geburtsdatum";;
- filter_course) printf %s "Kurs";;
- filter_CATEGORIES) printf %s "Kategorien";;
- filter_apply) printf %s "Filtern";;
- filter_cancel) printf %s "Filter löschen";;
- newcard) printf %s "Neuen Eintrag anlegen";;
- course_attendance) printf %s "Kursteilnahme";;
-
- gender_none) printf %s "keine Angabe";;
- gender_female) printf %s "Weiblich";;
- gender_male) printf %s "Männlich";;
- gender_other) printf %s "Sonstiges";;
-
- female) printf %s "♀";;
- male) printf %s "♂";;
- other) printf %s "⚥";;
- none) printf %s "⚪";;
-
- *) printf %s "$1";;
+ *) l10n_global "$word";;
esac
}
[ "$(pdi_count "$card" NICKNAME)" -gt 0 ] \
&& edit_item "$card" NICKNAME
edit_item "$card" BDAY
- edit_item "$card" X-ZACK-JOINDATE
- [ "$(pdi_count "$card" X-ZACK-LEAVEDATE)" -gt 0 ] \
- && edit_item "$card" X-ZACK-LEAVEDATE
card_item "$card" SOUND PHOTO LOGO
)]
- [div .section .phone $(edit_item "$card" TEL)]
- [div .section .message $(
- edit_item "$card" EMAIL
- [ $(pdi_count "$card" IMPP) -gt 0 ] && edit_item "$card" IMPP
- [ $(pdi_count "$card" URL ) -gt 0 ] && edit_item "$card" URL
- )]
+ [div .section .phone $(
+ edit_item "$card" TEL EMAIL
+ [ $(pdi_count "$card" IMPP) -gt 0 ] \
+ && edit_item "$card" IMPP
+ [ $(pdi_count "$card" URL ) -gt 0 ] \
+ && edit_item "$card" URL
+ )]
[div .section .address $(edit_item "$card" ADR)]
- [div .section .note $(edit_item "$card" NOTE)]
- [div .section .attendance
- [h3 $(l10n course_attendance) ] $(
- for course in "$_DATA"/ical/*.ics; do
- printf '[label [input type="checkbox" name="attendance" value="%s" %s] %s]' \
- "${course##*/}" \
- "$(grep -qF "${course##*/} ${cardfile##*/}" "$_DATA/mappings/attendance" \
- && printf 'checked="checked"'
- )" \
- "$(pdi_value "$(pdi_load "$course")" SUMMARY || l10n "(unnamed course)" |unescape |HTML)"
- done)
- [h3 $(l10n CATEGORIES) ] $(
- grep -xE '[^ ]+' "$_DATA"/mappings/categories |while read -r cat; do
- printf '[label [input type="checkbox" name="CATEGORIES" value="%s" %s] %s]' \
- "$(HTML "$cat")" \
- "$(seq 1 $(pdi_count "$card" CATEGORIES) |while read c; do
- pdi_value "$card" CATEGORIES $c |grep -qxF "$cat" \
- && printf 'checked="checked"' && break
- done)" \
- "$(HTML "$cat")"
- done)
- ]
+ [div .section .insurance $(edit_item "$card" X-HEALTH-INSURANCE)]
+ [div .section .note $(edit_item "$card" NOTE X-CLIENT-REFERRAL)]
[div .control
- [select .item name="newfield"
- [option value="" disabled="disabled" selected="selected" $(l10n edit_addfieldtext)]
- $(for f in NICKNAME EMAIL TEL IMPP ADR URL NOTE; do
- printf '[option value="%s" %s] ' "$f" "$(l10n "$f")"
- done)
- ][button .item type="submit" name="action" value="addfield" $(l10n edit_addfield)]
+ [div .item .delete label="$(l10n edit_delete)"
+ [input type="checkbox" #delete]
+ [label for="delete" $(l10n edit_delete)]
+ [button type="submit" name="action" value="delete" $(l10n edit_delete)]
+ ]
+ [div .item .newfield
+ [select name="newfield"
+ [option value="" disabled="disabled" selected="selected" $(l10n edit_addfieldtext)]
+ $(for f in NICKNAME EMAIL TEL IMPP ADR URL NOTE; do
+ printf '[option value="%s" %s] ' "$f" "$(l10n "$f")"
+ done)
+ ][button type="submit" name="action" value="addfield" $(l10n edit_addfield)]
+ ]
[button .item type="submit" name="action" value="update" $(l10n edit_update)]
- [input type="checkbox" #delete] [label .item for="delete" $(l10n edit_delete)]
- [button .item type="submit" name="action" value="delete"]
[button .item type="submit" name="action" value="cancel" $(l10n edit_cancel)]
]
[input type="hidden" name="UID" value="$(pdi_value "$card" UID |HTML)"]
print_card(){
local cardfile="$1"
local card="$(pdi_load "$cardfile")"
+ local N1 N2 N3 N4 N5
+ IFS=\; read N1 N2 N3 N4 N5 <<-EOF
+ $(pdi_value "$card" N |pdi_unescape |HTML)
+ EOF
+
cat <<-EOF
- [span .card-anchor #${cardfile##*/}]
- [div .card
+ [div .card #${cardfile##*/}
- [div .section .basic . $(
- card_item "$card" FN GENDER NICKNAME BDAY X-ZACK-JOINDATE X-ZACK-LEAVEDATE SOUND PHOTO LOGO
+ [div .section .basic
+ [h2 .item .FN . $N4 $N1 $N5]
+ [span .item .firstname . $N2 $N3]
+ $(
+ card_item "$card" GENDER NICKNAME BDAY X-ZACK-JOINDATE X-ZACK-LEAVEDATE SOUND PHOTO LOGO
)]
- [div .section .phone . $(card_item "$card" TEL)]
- [div .section .message . $(card_item "$card" EMAIL IMPP URL)]
- [div .section .address . $(card_item "$card" ADR)]
- [div .section .note . $(card_item "$card" NOTE)]
- [div .section .attendance [h3 $(l10n course_attendance) ] [ul
- $(grep -F " ${cardfile##*/}" "$_DATA/mappings/attendance" |while read each discard; do
- printf '[li [a .item .attendance href="/courses#%s" . %s]]' \
- "$each" \
- "$(pdi_value "$(pdi_load "$_DATA/ical/$each")" SUMMARY || l10n "(unnamed course)" |unescape |HTML)"
- done)]
- $(card_item "$card" CATEGORIES)
- ]
+ [div .section .address $(card_item "$card" ADR)]
+ [div .section .phone $(card_item "$card" TEL EMAL IMPP URL)]
+ [div .section .insurance $(card_item "$card" X-HEALTH-INSURANCE)]
+ [div .section .note $(card_item "$card" NOTE X-CLIENT-REFERRAL)]
+ [div .section .therapies $(card_item "$card" therapies)]
[div .control
[a .item href="/cards/edit_card.sh?card=${cardfile##*/}" $(l10n edit)]
[a .item href="/cards/export_card.sh?card=${cardfile##*/}" $(l10n vcf_export)]
case $f in
'') break
;;
- ANY:*) fex="/\n.*(\;[^:]*)?:.*(${f#*:}).*\r?\n/{${fex}}"
- COURSE:*) fatt="${fatt}${fatt:+ }${f#*:}"
- ;;
+ ANY:*) fex="/\n.*(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ NAME:*) fex="/\n(N|FN|NICKNAME)(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- STREET:*|ZIP:*) fex="/\nADR(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ STREET:*|ZIP:*) fex="/\nADR(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
- *) fex="/\n${f%%:*}(\;[^:]*)?:[^\n]*(${f#*:}).*\r?\n/{${fex}}"
+ *) fex="/\n${f%%:*}(\;[^:]*)?:[^\n]*(${f#*:})[^\n]*\r?\n/{${fex}}"
;;
esac
done
. "$_EXEC/pdiread.sh"
. "$_EXEC/session_lock.sh"
+ . "$_EXEC/cgilite/storage.sh"
unset filter order card action newfield
--unset cardfile attfile tempfile
++unset cardfile tempfile
unset vcf field cnt delete_key
filter="$(REF f)"
order="$(REF o)"
- card="$(POST card |PATH)"
- cardfile="$_DATA/vcard/${card##*/}"
- attfile="$_DATA/mappings/attendance"
+ card="$(POST card |PATH)"; card="${card##*/}"
+ cardfile="$_DATA/vcard/${card}"
-attfile="$_DATA/mappings/attendance"
action="$(POST action)"
newfield="$(POST newfield |grep -m 1 -xE '[A-Z][A-Z0-9-]*')"
exit 0
fi
-vcf_escape(){
- for each in "$@"; do
- printf %s\\n "$each" \
- | sed -E ':X;$!{N;bX}; s;\r\n;\n;g; s;([;,\\]);\\\1;g; s;\n;\\n;g;'
- done \
- | sed -E ':X;$!{N;bX}; s;\n;\;;g'
-}
-
# [ "${_POST[hi_select]}" = "list" ] || _POST[hi_company]="${_POST[hi_other]}"
# [ -n "${_POST[hi_company]}${_POST[hi_number]}${_POST[hi_status]}" ] \
-# && _POST[X-HEALTH-INSURANCE]="$(vcf_escape "${_POST[hi_company]}" "${_POST[hi_number]}" "${_POST[hi_status]}")"
+# && _POST[X-HEALTH-INSURANCE]="$(pdi_escape "${_POST[hi_company]}" "${_POST[hi_number]}" "${_POST[hi_status]}")"
- # vcf="$(pdi_load "$cardfile")"
vcf="$(pdi_load "$tempfile")"
- vcf="$(pdi_update_value "$vcf" N 1 "$(pdi_escape "$(POST 1N)" "$(POST 2N)" "$(POST 3N)" "$(POST 4N)" "$(POST 5N)")")"
- vcf="$(pdi_update_value "$vcf" FN 1 "$(pdi_escape "$(POST 4N) $(POST 2N) $(POST 3N) $(POST 1N) $(POST 5N)" \
- | sed -E 's;^ +;;; s; +$;;; s; +; ;g;')" )"
+ n1="$(POST 1N)" n2="$(POST 2N)" n3="$(POST 3N)" n4="$(POST 4N)" n5="$(POST 5N)"
+ # 3N (Middle Names) is not actually used
+ n3="${n2#${n2%% *}}"
+
+ vcf="$(pdi_update_value "$vcf" N 1 "$(vcf_escape "$n1" "${n2%% *}" "${n3# }" "$n4" "$n5")")"
+ vcf="$(pdi_update_value "$vcf" FN 1 "$(vcf_escape "$n4 $n2 $n1 $n5" |sed -E 's;(^ +| +$);;g; s; +; ;g;')")"
+ vcf="$(printf '%s\n' "$vcf" |sed -E "/^CATEGORIES;[^:]*:.*$/d")"
for field in $(POST_KEYS |grep -xE '[A-Z][A-Z0-9-]*'); do
for cnt in $(seq 1 $(POST_COUNT "$field")); do
case "$action" in
addfield)
- REDIRECT "/cards/?o=${order}&f=${filter}&e=${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}&e=${card#/}"
;;
update)
- # attendance=()
- # for att in attendance attendance{0..100}; do
- # [ -n "${_POST[$att]}" ] && attendance+=("${_POST[$att]}")
- # done
- # sed -rn 's:^(.+)'$card'$:\1:p' "$attfile" |while read course; do
- # touch "$_DATA/ical/$course"
- # done
- # sed -i -r '/^(.+)\t'$card'$/d' "$attfile"
- # for each in $attendance; do
- # echo "$each\t$card"
- # done >>"$attfile"
- # sed -rn 's:^(.+)'$card'$:\1:p' "$attfile" |while read course; do
- # touch "$_DATA/ical/$course"
- # done
- if LOCK "$attfile"; then
- grep -F " ${card}" "$attfile" |while read course junk; do
- touch "$_DATA/ical/${course}"
- done
- sed -i -E "/^.+ ${card}\$/d" "$attfile"
- seq 1 $(POST_COUNT attendance) |while read n; do
- printf '%s %s\n' "$(POST attendance $n)" "$card"
- done >>"$attfile"
- grep -F " ${card}" "$attfile" |while read course junk; do
- touch "$_DATA/ical/${course}"
- done
- RELEASE "$attfile"
- else
- SET_COOKIE 0 message="COULD NOT UPDATE COURSE MAPPINGS"
- fi
--
cp "$tempfile" "$cardfile"
RELEASE_SLOCK "$cardfile"
- REDIRECT "/cards/?o=${order}&f=${filter}#${card}"
+ REDIRECT "/cards/?o=${order}&f=${filter}#${card#/}"
;;
cancel)
RELEASE_SLOCK "$cardfile"
w_filter_item "${fil%%:*}" "${fil#*:}" $n
n=$((n + 1))
done
- w_filter_item any '' $n
+ [ "$n" -eq 0 -o "$(GET newfilter)" ] && w_filter_item any '' $n
)
-
+ [button type="submit" name="choice" value="new_filter" $(l10n filter_more)]
[fieldset class="order"
[legend $(l10n filter_order):]
- [label [radio "order" "firstname" $( [ "$order" = firstname ] && printf checked )] $(l10n filter_firstname)]
[label [radio "order" "lastname" $( [ "$order" = lastname ] && printf checked )] $(l10n filter_lastname)]
+ [label [radio "order" "firstname" $( [ "$order" = firstname ] && printf checked )] $(l10n filter_firstname)]
[label [radio "order" "bdate" $( [ "$order" = bdate ] && printf checked )] $(l10n filter_bdate)]
]
- [button type="submit" name="choice" value="new_filter" $(l10n filter_apply)]
+ [button type="submit" name="choice" value="filter" $(l10n filter_apply)]
[button type="submit" name="choice" value="del_filter" $(l10n filter_cancel)]
+ [button type="submit" name="choice" value="export_csv" $(l10n export_csv)]
]
EOF
}
[ "$teltype" ] \
&& printf '[span .item .TEL [span .type . %s:] %s]' \
"$(l10n "TYPE=$teltype" |HTML)" \
- "$(pdi_value "$card" TEL $c |pdi_unescape |HTML)" \
+ "$(pdi_value "$card" TEL $c |unescape |HTML)" \
|| printf '[span .item .TEL . %s]' \
- "$(pdi_value "$card" TEL $c |pdi_unescape |HTML)"
+ "$(pdi_value "$card" TEL $c |unescape |HTML)"
done
;;
- ' "$(pdi_unescape "$hi_name" |HTML)" \
- "$(l10n hi_number)" "$(pdi_unescape "$hi_number" |HTML)" \
- "$(l10n hi_status)" "$(pdi_unescape "$hi_status" |HTML)"
+ X-HEALTH-INSURANCE)
+ [ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n X-HEALTH-INSURANCE)"
+ seq 1 $cnt |while read c; do
+ IFS=\; read -r hi_name hi_number hi_status <<-EOF
+ $(pdi_value "$card" X-HEALTH-INSURANCE $c)
+ EOF
+ printf '[span .item .hi_company . %s]
+ [span .item .hi_number [label %s:] %s]
+ [span .item .hi_status [label %s:] %s]
++ ' "$(unescape "$hi_name" |HTML)" \
++ "$(l10n hi_number)" "$(unescape "$hi_number" |HTML)" \
++ "$(l10n hi_status)" "$(unescape "$hi_status" |HTML)"
+ done
+ ;;
+ therapies)
+ client="$(pdi_value "$card" UID)"
+ printf '[h3 %s]' "$(l10n therapies)"
+ (cd "$_DATA/therapies/"; printf '%s\n' "${client}".*.tpy) \
+ | while read tpyfile; do
+ [ "$tpyfile" = "${client}.*.tpy" ] \
+ && printf '[a .item .therapy href="/therapies/%s/new" . +]' "${client}" \
+ && break
+ tpy="${tpyfile%.tpy}";
+ tpydates="$(sed -En 's;^session[0-9]+_date:;;p;' "$_DATA/therapies/$tpyfile" \
+ | sort \
+ | sed -E ':X;N;$!bX; s;^[\n ]+;;; s;[\n ]+$;;; s;(\n.*\n|\n); - ;;'
+ )"
+ printf '[a .item .therapy href="/therapies/%s" . %s] ' \
+ "${tpy%.*}/${tpy#*.}" "$(HTML "${tpydates:--}")"
+ done |sort -n
+ ;;
*)[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n "$item")"
+ shy="$(printf '\302\255')"
seq 1 $cnt |while read c; do
printf '[span .item .%s . %s]' "$item" \
- "$(pdi_value "$card" "$item" $c |sed -r "s;(straße|weg|damm|allee|ufer);${shy}\1;g" |pdi_unescape |HTML)"
- "$(pdi_value "$card" "$item" $c |unescape |HTML)"
++ "$(pdi_value "$card" "$item" $c |sed -r "s;(straße|weg|damm|allee|ufer);${shy}\1;g" |unescape |HTML)"
done
;;
esac
for n in "$@"; do case ${n%%=*} in
data) _DATA="${n#data=}";;
exec) _EXEC="${n#exec=}";;
- noerr) exec 2>&-;;
+ debug) DEBUG="${n#debug=}";;
esac; done
- [ -z "${_EXEC%/}" ] && _EXEC="$(realpath "${0%/*}")" || _EXEC="${_EXEC%/}"
- [ -z "${_DATA%/}" ] && _DATA=. || _DATA="${_DATA%/}"
+ [ ! "${_EXEC%/}" ] && _EXEC="$(realpath "${0%/*}")" || _EXEC="${_EXEC%/}"
+ [ ! "${_DATA%/}" ] && _DATA=. || _DATA="${_DATA%/}"
+ [ "$DEBUG" ] && exec 2>>"$DEBUG"
+
+ mkdir -p "${_DATA}/cache" "${_DATA}/mappings" "${_DATA}/export" "${_DATA}/lock" "${_DATA}/ical" "${_DATA}/vcard"
+
+ debug() {
+ local dbg=/dev/stderr
+ if [ ! "$DEBUG" ]; then
+ [ "$#" -gt 0 ] && : || cat;
+ elif [ "$#" -gt 0 ]; then
+ printf '%s\n' "$@" >>"$dbg"
+ else
+ tee -a "$dbg"
+ fi
+ }
+debug() {
+ local dbg=/dev/stderr
+ if [ ! "$DEBUG" ]; then
+ [ "$#" -gt 0 ] && : || cat;
+ elif [ "$#" -gt 0 ]; then
+ printf '%s\n' "$@" >>"$dbg"
+ else
+ tee -a "$dbg"
+ fi
+}
+
. "$_EXEC/cgilite/cgilite.sh"
. "$_EXEC/cgilite/session.sh"
topdir="${_PATH#/}"
topdir="/${topdir%%/*}"
- if [ "${_PATH}" = / ]; then
- REDIRECT /cards/
- elif [ -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}/index.cgi" ]; then
- . "${_EXEC}/${_PATH}/index.cgi"
- elif [ ! -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}" ]; then
- . "${_EXEC}/${_PATH}"
- elif [ ! -x "${_EXEC}/${_PATH}" -a -r "${_EXEC}/${_PATH}" ]; then
- . "$_EXEC/cgilite/file.sh"
- FILE "${_EXEC}/${_PATH}"
- elif [ -d "${_EXEC}/${topdir}" -a -x "${_EXEC}/${topdir}/index.cgi" ]; then
- . "${_EXEC}/${topdir}/index.cgi"
- else
- printf 'Status: 404 Not Found\r\nContent-Length: 0\r\n\r\n'
- fi
+ case ${_PATH} in
+ /) REDIRECT /cards/
+ ;;
- /export/*.pdf) . "$_EXEC/cgilite/file.sh"
- FILE "${_DATA}/${_PATH}" "application/pdf"
- ;;
- /export/*) . "$_EXEC/cgilite/file.sh"
- FILE "${_DATA}/${_PATH}"
- ;;
++# /export/*.pdf) . "$_EXEC/cgilite/file.sh"
++# FILE "${_DATA}/${_PATH}" "application/pdf"
++# ;;
++# /export/*) . "$_EXEC/cgilite/file.sh"
++# FILE "${_DATA}/${_PATH}"
++# ;;
+ *)
+ if [ -d "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}/index.cgi" ]; then
+ . "${_EXEC}/${_PATH}/index.cgi"
+ elif [ -f "${_EXEC}/${_PATH}" -a -x "${_EXEC}/${_PATH}" ]; then
+ . "${_EXEC}/${_PATH}"
+ elif [ -f "${_EXEC}/${_PATH}" -a -r "${_EXEC}/${_PATH}" ]; then
+ . "$_EXEC/cgilite/file.sh"
+ FILE "${_EXEC}/${_PATH}"
+ elif [ -d "${_EXEC}/${topdir}" -a -x "${_EXEC}/${topdir}/index.cgi" ]; then
+ . "${_EXEC}/${topdir}/index.cgi"
+ else
+ printf '%s\r\n' 'Status: 404 Not Found' 'Content-Length: 0' ''
+ fi
+ ;;
+ esac
# === Update obsolete LABEL property ===
s;\nLABEL((\;[A-Za-z0-9-]+|\;[A-Za-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)\n;\nADR\1\;LABEL="\5":\n;g;
- p;' "$1"
+ p;' "$@"
}
+pdi_escape(){
+ local in out=''
+ for in in "$@"; do
+ out="${out}${out:+;}"
+ while [ "$in" ]; do case $in in
+ \\*) out="${out}\\\\"; in="${in#\\}" ;;
+ ,*) out="${out}\\,"; in="${in#,}" ;;
+ \;*) out="${out}\\;"; in="${in#;}" ;;
+ "$BR"*) out="${out}\\n"; in="${in#${BR}}" ;;
+ *) out="${out}${in%%[\\,;${BR}]*}"; in="${in#"${in%%[\\,;${BR}]*}"}" ;;
+ esac; done
+ done
+ printf '%s\n' "$out"
+}
+
+pdi_unescape(){
+ local in out=''
+ [ $# -gt 0 ] && in="$*" || in="$(cat)"
+ while [ "$in" ]; do case $in in
+ \\\\*) out="${out}\\"; in="${in#\\\\}" ;;
+ \\n*) out="${out}${BR}"; in="${in#\\n}" ;;
+ \\*) in="${in#\\}" ;;
+ *) out="${out}${in%%\\*}"; in="${in#"${in%%\\*}"}" ;;
+ esac; done
+ printf '%s\n' "$out"
+}
+
pdi_count(){
local card="$1" name="$2" rc='' cnt=0
while rc="${card#*${BR}${name};}"; do