diff --git a/README.md b/README.md index ecfc9c9..46f9c65 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,8 @@ Note: direct commands like `\paperwidth{...}` or `\color{...}` would clash with - `padding=`: inner padding, default `2mm` - `cutdist=`: crop-mark distance, default `2` - `cutlen=`: crop-mark length, default `1` +- `cutmarks` / `nocutmarks`: enable/disable cut marks, default `cutmarks` +- `nocutmark`: alias for `nocutmarks` ### Typography and Layout @@ -185,6 +187,7 @@ Note: direct commands like `\paperwidth{...}` or `\color{...}` would clash with ### Logo and Background - `logoheight=`: default logo height near name (with unit). Auto-default: `4em` if company exists, else `2em` +- `background=`: default background file-or-color at class/runtime option level (equivalent target as `\background{...}`) - `bgscale=`: background image scale, default `1.0` - `bgopacity=`: background image opacity, default `1.0` @@ -308,9 +311,9 @@ Recognized Commands - geometry: `\setpaperwidth`, `\setpaperheight`, `\setcontentwidth`, `\setcontentheight`, `\setpadding`, `\setcutdist`, `\setcutlen` - layout/typography: `\setfontsize`, `\settextwidth`, `\setqrwidth`, `\setqreclevel`, `\setqrlogoscale`, `\setqrlogoborder`, `\setlogoheight`, `\setlayout`, `\setheaderemphasis` -- booleans (`true`/`false`): `\setcrlf`, `\setaddress`, `\sethint`, `\seticon`, `\setrightalign`, `\seticonleft`, `\setfill`, `\setqrfirst`, `\setheader`, `\setqr`, `\sethttps` -- colors/language/format: `\setlang`, `\setcardcolor`, `\setqrcolor`, `\setcountryformat`, `\setbgscale`, `\setbgopacity`, `\setqrbgopacity`, `\setvcardversion` -- convenience toggles: `\noheader`, `\withheader`, `\noqr`, `\withqr`, `\standardlayout`, `\centeredlayout` +- booleans (`true`/`false`): `\setcrlf`, `\setaddress`, `\sethint`, `\seticon`, `\setrightalign`, `\seticonleft`, `\setfill`, `\setqrfirst`, `\setheader`, `\setqr`, `\sethttps`, `\setcutmarks` +- colors/language/format: `\setlang`, `\setcardcolor`, `\setqrcolor`, `\setcountryformat`, `\setbackground`, `\setbgscale`, `\setbgopacity`, `\setqrbgopacity`, `\setvcardversion` +- convenience toggles: `\noheader`, `\withheader`, `\noqr`, `\withqr`, `\nocutmarks`, `\withcutmarks`, `\standardlayout`, `\centeredlayout` ### Document Title Interop diff --git a/businesscard-qrcode.cls b/businesscard-qrcode.cls index 03eb019..afd4e49 100644 --- a/businesscard-qrcode.cls +++ b/businesscard-qrcode.cls @@ -10,6 +10,7 @@ family=BCQ, prefix=BCQ@ } +% Paper/content geometry \DeclareStringOption[89mm]{paperwidth} \DeclareStringOption[59mm]{paperheight} \DeclareStringOption[85mm]{contentwidth} @@ -20,18 +21,23 @@ \DeclareStringOption[1]{cutlen} \DeclareStringOption[0.50]{textwidth} \DeclareStringOption[0.40]{qrwidth} +% QR rendering \DeclareStringOption[H]{qreclevel} % QR code error correction level (L,M,Q,H) \DeclareStringOption[0.25]{qrlogoscale} % logo size in QR code as fraction of QR width (1.0 = 100%), default 0.25 \DeclareStringOption[0.02]{qrlogoborder} % white padding around logo in QR as fraction of QR width (1.0 = 100%), default 0.02 +% Header/background \DeclareStringOption{logoheight} % logo height next to name (with unit, e.g., 4em), default: 4em if company set, 2em otherwise \DeclareStringOption[1.0]{bgscale} % background image scale (1.0 = 100% card height), default 1.0 \DeclareStringOption[1.0]{bgopacity} % background image opacity (1.0 = 100% visible, 0.0 = invisible), default 1.0 \DeclareStringOption[1.0]{qrbgopacity} % QR code background opacity (1.0 = white solid, 0.0 = transparent), default 1.0 +\DeclareStringOption[]{background} % default background (file or color), equivalent to \background{...} +% Formatting/content behavior \DeclareStringOption[de]{lang} \DeclareStringOption[black]{color} \DeclareStringOption[black]{qrcolor} \DeclareBoolOption[true]{crlf} % use CRLF line endings in vCard (iOS compatibility) -\DeclareComplementaryOption{nocrlf}{crlf}\DeclareBoolOption[true]{address} +\DeclareComplementaryOption{nocrlf}{crlf} +\DeclareBoolOption[true]{address} \DeclareComplementaryOption{noaddress}{address} \DeclareBoolOption[true]{hint} \DeclareComplementaryOption{nohint}{hint} @@ -51,12 +57,9 @@ \DeclareComplementaryOption{noqr}{qr} \DeclareBoolOption[true]{https} \DeclareComplementaryOption{www}{https} -\DeclareBoolOption[true]{vcardaddress} -\DeclareComplementaryOption{novcardaddress}{vcardaddress} -\DeclareBoolOption[false]{vcardcompat} -\DeclareComplementaryOption{novcardcompat}{vcardcompat} -\DeclareBoolOption[false]{vcardminimal} -\DeclareComplementaryOption{novcardminimal}{vcardminimal} +\DeclareBoolOption[true]{cutmarks} +\DeclareComplementaryOption{nocutmark}{cutmarks} +\DeclareComplementaryOption{nocutmarks}{cutmarks} \DeclareStringOption[standard]{layout} % standard, centered \DeclareStringOption[auto]{countryformat} % auto: <4 chars inline with mdash, >=4 separate line; inline: always inline; below: always separate line \DeclareStringOption[person]{headeremphasis} % person, company, balanced @@ -78,6 +81,7 @@ \def\protdisplay{\ifBCQ@https https://\else www.\fi} \def\protprefix{\ifBCQ@https https://\fi} \ifBCQ@address\def\printaddress{}\fi +\ifx\BCQ@background\@empty\else\def\Xbackground{\BCQ@background}\fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -124,16 +128,24 @@ }% } % Runtime configuration keys (usable via \cardsetup and \drawcard[...]) +% Geometry / dimensions \define@key{BCQ@runtime}{paperwidth}{\def\BCQ@paperwidth{#1}} \define@key{BCQ@runtime}{paperheight}{\def\BCQ@paperheight{#1}} -\define@key{BCQ@runtime}{contentwidth}{\def\BCQ@contentwidth{#1}\def\content{paperwidth=\BCQ@contentwidth,paperheight=\BCQ@contentheight}} -\define@key{BCQ@runtime}{contentheight}{\def\BCQ@contentheight{#1}\def\content{paperwidth=\BCQ@contentwidth,paperheight=\BCQ@contentheight}} +\define@key{BCQ@runtime}{contentwidth}{% + \def\BCQ@contentwidth{#1}% + \def\content{paperwidth=\BCQ@contentwidth,paperheight=\BCQ@contentheight}% +} +\define@key{BCQ@runtime}{contentheight}{% + \def\BCQ@contentheight{#1}% + \def\content{paperwidth=\BCQ@contentwidth,paperheight=\BCQ@contentheight}% +} \define@key{BCQ@runtime}{fontsize}{\def\BCQ@fontsize{#1}} \define@key{BCQ@runtime}{padding}{\def\BCQ@padding{#1}\def\padding{\BCQ@padding}} \define@key{BCQ@runtime}{cutdist}{\def\BCQ@cutdist{#1}\def\border{\BCQ@cutdist}} \define@key{BCQ@runtime}{cutlen}{\def\BCQ@cutlen{#1}\def\cutlen{\BCQ@cutlen}} \define@key{BCQ@runtime}{textwidth}{\def\BCQ@textwidth{#1}\def\textpercents{\BCQ@textwidth}} \define@key{BCQ@runtime}{qrwidth}{\def\BCQ@qrwidth{#1}\def\imagepercents{\BCQ@qrwidth}} +% QR / background / visuals \define@key{BCQ@runtime}{qreclevel}{\def\BCQ@qreclevel{#1}} \define@key{BCQ@runtime}{qrlogoscale}{\def\BCQ@qrlogoscale{#1}} \define@key{BCQ@runtime}{qrlogoborder}{\def\BCQ@qrlogoborder{#1}} @@ -148,9 +160,17 @@ \define@key{BCQ@runtime}{layout}{\def\BCQ@layout{#1}} \define@key{BCQ@runtime}{headeremphasis}{\def\BCQ@headeremphasis{#1}} \define@key{BCQ@runtime}{vcardversion}{\def\BCQ@vcardversion{#1}} +% Boolean toggles \define@key{BCQ@runtime}{crlf}[true]{\BCQ@setbool{crlf}{#1}} \define@key{BCQ@runtime}{nocrlf}[true]{\BCQ@setbool{crlf}{false}} -\define@key{BCQ@runtime}{address}[true]{\BCQ@setbool{address}{#1}\ifBCQ@address\def\printaddress{}\else\csundef{printaddress}\fi} +\define@key{BCQ@runtime}{address}[true]{% + \BCQ@setbool{address}{#1}% + \ifBCQ@address + \def\printaddress{}% + \else + \csundef{printaddress}% + \fi +} \define@key{BCQ@runtime}{noaddress}[true]{\BCQ@setbool{address}{false}\csundef{printaddress}} \define@key{BCQ@runtime}{hint}[true]{\BCQ@setbool{hint}{#1}} \define@key{BCQ@runtime}{nohint}[true]{\BCQ@setbool{hint}{false}} @@ -170,12 +190,10 @@ \define@key{BCQ@runtime}{noqr}[true]{\BCQ@setbool{qr}{false}} \define@key{BCQ@runtime}{https}[true]{\BCQ@setbool{https}{#1}} \define@key{BCQ@runtime}{www}[true]{\BCQ@setbool{https}{false}} -\define@key{BCQ@runtime}{vcardaddress}[true]{\BCQ@setbool{vcardaddress}{#1}} -\define@key{BCQ@runtime}{novcardaddress}[true]{\BCQ@setbool{vcardaddress}{false}} -\define@key{BCQ@runtime}{vcardcompat}[true]{\BCQ@setbool{vcardcompat}{#1}} -\define@key{BCQ@runtime}{novcardcompat}[true]{\BCQ@setbool{vcardcompat}{false}} -\define@key{BCQ@runtime}{vcardminimal}[true]{\BCQ@setbool{vcardminimal}{#1}} -\define@key{BCQ@runtime}{novcardminimal}[true]{\BCQ@setbool{vcardminimal}{false}} +\define@key{BCQ@runtime}{background}{\def\Xbackground{#1}} +\define@key{BCQ@runtime}{cutmarks}[true]{\BCQ@setbool{cutmarks}{#1}} +\define@key{BCQ@runtime}{nocutmark}[true]{\BCQ@setbool{cutmarks}{false}} +\define@key{BCQ@runtime}{nocutmarks}[true]{\BCQ@setbool{cutmarks}{false}} \newcommand\cardsetup[1]{\setkeys{BCQ@runtime}{#1}} \newcommand\setoption[2]{\setkeys{BCQ@runtime}{#1=#2}} @@ -216,20 +234,15 @@ \newcommand\setheader[1]{\setoption{header}{#1}} \newcommand\setqr[1]{\setoption{qr}{#1}} \newcommand\sethttps[1]{\setoption{https}{#1}} -\newcommand\setvcardaddress[1]{\setoption{vcardaddress}{#1}} -\newcommand\setvcardcompat[1]{\setoption{vcardcompat}{#1}} -\newcommand\setvcardminimal[1]{\setoption{vcardminimal}{#1}} +\newcommand\setbackground[1]{\setoption{background}{#1}} +\newcommand\setcutmarks[1]{\setoption{cutmarks}{#1}} % convenience toggles \newcommand\noheader{\cardsetup{noheader}} \newcommand\withheader{\cardsetup{header}} \newcommand\noqr{\cardsetup{noqr}} \newcommand\withqr{\cardsetup{qr}} -\newcommand\novcardaddress{\cardsetup{novcardaddress}} -\newcommand\withvcardaddress{\cardsetup{vcardaddress}} -\newcommand\novcardcompat{\cardsetup{novcardcompat}} -\newcommand\withvcardcompat{\cardsetup{vcardcompat}} -\newcommand\novcardminimal{\cardsetup{novcardminimal}} -\newcommand\withvcardminimal{\cardsetup{vcardminimal}} +\newcommand\nocutmarks{\cardsetup{nocutmarks}} +\newcommand\withcutmarks{\cardsetup{cutmarks}} \newcommand\standardlayout{\cardsetup{layout=standard}} \newcommand\centeredlayout{\cardsetup{layout=centered}} \def\BCQ@registeredfields{} @@ -429,6 +442,18 @@ \newcommand\conddisplay[1]{% \ifvisible{#1}{\exec{#1}}{}% } +\newcommand\BCQ@resolveusedoption[3]{% + \ifcsdef{#1}{% + \edef#3{\csname #1\endcsname}% + }{% + \edef#3{#2}% + }% +} +\newcommand\BCQ@insertcompanyline{% + \ifhaspersonalname{% + \ifhaspositionblock{\\[0.7ex]\BCQ@headercompanyformat{\companybrandingline}}{}% + }{}% +} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % auxiliary commands @@ -716,46 +741,15 @@ \BCQ@cachedname \fi } -\newcommand\BCQ@vcardversionline{% - \ifBCQ@vcardcompat - 3.0% - \else - \BCQ@vcardversion% - \fi -} -\def\BCQ@typeprivate{private} -\newcommand\BCQ@vcardtypemapped{% - \ifcsdef{Xtype}{% - \ifBCQ@vcardcompat - \ifx\Xtype\BCQ@typeprivate - home% - \else - \Xtype - \fi - \else - \Xtype - \fi - }{}% -} +\newcommand\BCQ@vcardversionline{\BCQ@vcardversion} \newcommand\BCQ@vcardtypeparam{% - \ifBCQ@vcardminimal - \else - \ifcsdef{Xtype}{;TYPE=\BCQ@vcardtypemapped}{}% - \fi + \ifcsdef{Xtype}{;TYPE=\Xtype}{}% } \newcommand\BCQ@vcardteltype{% - \ifcsdef{Xtype}{\BCQ@vcardtypemapped,voice}{voice}% + \ifcsdef{Xtype}{\Xtype,voice}{voice}% } \newcommand\BCQ@vcardtel{% - \ifBCQ@vcardcompat - \ifBCQ@vcardminimal - TEL:\Xphone\BCQ@nl - \else - TEL;TYPE=\BCQ@vcardteltype:\Xphone\BCQ@nl - \fi - \else - TEL;VALUE=uri;TYPE=\BCQ@vcardteltype,text:tel:\Xphone\BCQ@nl - \fi + TEL;VALUE=uri;TYPE=\BCQ@vcardteltype,text:tel:\Xphone\BCQ@nl } \newcommand\BCQ@vcardaddressfull{% \ifcsdef{Xpobox}{\Xpobox\ }{}% @@ -766,15 +760,6 @@ \ifcsdef{Xregion}{\Xregion\ }{}% \ifcsdef{Xcountry}{\Xcountry}{}% } -\newcommand\BCQ@vcardaddressnote{% - \ifcsdef{Xstreet}{\Xstreet\ }{}% - \ifcsdef{Xzip}{\Xzip\ }{}% - \ifcsdef{Xcity}{\Xcity\ }{}% - \ifcsdef{Xregion}{\Xregion\ }{}% - \ifcsdef{Xcountry}{\Xcountry}{}% -} - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % vcard - the content of the vcard % newline selection: default LF (robust for qrcode). Optional CRLF if crlf option set. @@ -793,11 +778,7 @@ VERSION:\BCQ@vcardversionline\BCQ@nl \ifexists{Xcompany}{ORG:\Xcompany\BCQ@nl} \ifexists{Xtitle}{TITLE:\Xtitle\BCQ@nl} \ifexists{Xrole}{ROLE:\Xrole\BCQ@nl} -\ifBCQ@vcardaddress - \ifexists{printaddress}{\ifhasaddressvcard{ADR:;;\BCQ@vcardaddressfull;;;;\BCQ@nl}{}} -\else - \ifexists{printaddress}{\ifhasaddressvcard{NOTE:Address\space \BCQ@vcardaddressnote\BCQ@nl}{}} -\fi +\ifexists{printaddress}{\ifhasaddressvcard{ADR:;;\BCQ@vcardaddressfull;;;;\BCQ@nl}{}} \ifexists{Xphone}{\BCQ@vcardtel} \ifexists{Xemail}{EMAIL\BCQ@vcardtypeparam:\Xemail\BCQ@nl} \ifexists{Xjabber}{IMPP;TYPE=XMPP:\Xjabber\BCQ@nl} @@ -935,16 +916,8 @@ END:VCARD\BCQ@nl} % insertqrcode - insert the qr-code with optional white background \newcommand\insertqrcode{ % Use local overrides if specified, otherwise use global options - \ifcsdef{BCQ@qrbgopacity@local}{% - \edef\BCQ@qrbgopacity@used{\BCQ@qrbgopacity@local}% - }{% - \edef\BCQ@qrbgopacity@used{\BCQ@qrbgopacity}% - }% - \ifcsdef{BCQ@qrlogoscale@local}{% - \edef\BCQ@qrlogoscale@used{\BCQ@qrlogoscale@local}% - }{% - \edef\BCQ@qrlogoscale@used{\BCQ@qrlogoscale}% - }% + \BCQ@resolveusedoption{BCQ@qrbgopacity@local}{\BCQ@qrbgopacity}{\BCQ@qrbgopacity@used}% + \BCQ@resolveusedoption{BCQ@qrlogoscale@local}{\BCQ@qrlogoscale}{\BCQ@qrlogoscale@used}% %\frame { \begin{minipage}[c][\heightscale][c]{\imagepercents\textwidth} @@ -984,11 +957,7 @@ END:VCARD\BCQ@nl} \ifcsdef{Xcompany}{\def\BCQ@logoheight{4em}}{\def\BCQ@logoheight{2em}}% \fi % Use local height override if specified, otherwise use global logoheight - \ifcsdef{BCQ@logoheight@local}{% - \edef\BCQ@logoheight@used{\BCQ@logoheight@local}% - }{% - \edef\BCQ@logoheight@used{\BCQ@logoheight}% - }% + \BCQ@resolveusedoption{BCQ@logoheight@local}{\BCQ@logoheight}{\BCQ@logoheight@used}% % Store logo height as dimension for heightscale calculation \ifcsdef{Xlogo}{% \sbox{\BCQ@logobox}{\BCQ@graphiccontent{\Xlogo}{height=\BCQ@logoheight@used}}% @@ -1018,16 +987,12 @@ END:VCARD\BCQ@nl} \begin{minipage}[c]{\BCQ@namewidth}% name column \ifBCQ@rightalign\raggedleft\fi% apply alignment \BCQ@headernameformat{\cond{displayname}}% - \ifhaspersonalname{% - \ifhaspositionblock{\\[0.7ex]\BCQ@headercompanyformat{\companybrandingline}}{}% - }{}% + \BCQ@insertcompanyline \end{minipage} \end{minipage} }{% no logo: just name \BCQ@headernameformat{\cond{displayname}}% - \ifhaspersonalname{% - \ifhaspositionblock{\\[0.7ex]\BCQ@headercompanyformat{\companybrandingline}}{}% - }{}% + \BCQ@insertcompanyline } } @@ -1077,16 +1042,8 @@ END:VCARD\BCQ@nl} \setkeys{BCQ@runtime}{#1}% \fi % Use local overrides if specified, otherwise use global options - \ifcsdef{BCQ@bgscale@local}{% - \edef\BCQ@bgscale@used{\BCQ@bgscale@local}% - }{% - \edef\BCQ@bgscale@used{\BCQ@bgscale}% - }% - \ifcsdef{BCQ@bgopacity@local}{% - \edef\BCQ@bgopacity@used{\BCQ@bgopacity@local}% - }{% - \edef\BCQ@bgopacity@used{\BCQ@bgopacity}% - }% + \BCQ@resolveusedoption{BCQ@bgscale@local}{\BCQ@bgscale}{\BCQ@bgscale@used}% + \BCQ@resolveusedoption{BCQ@bgopacity@local}{\BCQ@bgopacity}{\BCQ@bgopacity@used}% % Handle background \ifcsdef{Xbackground}{% \IfFileExists{\Xbackground}{% @@ -1147,7 +1104,11 @@ END:VCARD\BCQ@nl} \end{picture} } \cropdef[]\tl\tr\bl\br{cut} -\crop[cut] +\ifBCQ@cutmarks + \crop[cut] +\else + \crop[off] +\fi \newcommand\companylogocontent{% \begingroup \edef\BCQ@companylogoscan{\expandafter\detokenize\expandafter{\Xcompanylogo}}% diff --git a/examples/centered-backside-example.pdf b/examples/centered-backside-example.pdf index 2942d30..dd926ba 100644 Binary files a/examples/centered-backside-example.pdf and b/examples/centered-backside-example.pdf differ diff --git a/examples/example.pdf b/examples/example.pdf index f472d1c..d42663a 100644 Binary files a/examples/example.pdf and b/examples/example.pdf differ diff --git a/examples/john-doe-hongkong.pdf b/examples/john-doe-hongkong.pdf index f25905a..cb958de 100644 Binary files a/examples/john-doe-hongkong.pdf and b/examples/john-doe-hongkong.pdf differ diff --git a/examples/peter-muster-example-company-zuerich.pdf b/examples/peter-muster-example-company-zuerich.pdf index d9d18fb..5d13575 100644 Binary files a/examples/peter-muster-example-company-zuerich.pdf and b/examples/peter-muster-example-company-zuerich.pdf differ diff --git a/examples/photo-example.pdf b/examples/photo-example.pdf index 806e686..182445d 100644 Binary files a/examples/photo-example.pdf and b/examples/photo-example.pdf differ diff --git a/examples/photo-in-qr-example.pdf b/examples/photo-in-qr-example.pdf index 46686d6..2bd54c7 100644 Binary files a/examples/photo-in-qr-example.pdf and b/examples/photo-in-qr-example.pdf differ diff --git a/examples/special-papersize.pdf b/examples/special-papersize.pdf index 70946b8..bc17e4d 100644 Binary files a/examples/special-papersize.pdf and b/examples/special-papersize.pdf differ