Files
FoldableNamecards-Latex/foldable-namecard.sty
T
2026-07-02 01:09:58 +02:00

211 lines
6.1 KiB
TeX

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{foldable-namecard}[2026/07/01 A4 foldable namecard]
\RequirePackage[a4paper,margin=0mm]{geometry}
\RequirePackage{graphicx}
\RequirePackage{keyval}
\RequirePackage{iftex}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{xcolor}
\ifXeTeX\else
\PackageError{foldable-namecard}{%
This package requires XeLaTeX.\MessageBreak
Please compile with xelatex instead of lualatex or pdflatex%
}{%
Compilation will abort. Re-run with: xelatex <your-file>.tex%
}%
\stop
\fi
\tracinglostchars=0 % Suppress warnings about missing glyphs
\RequirePackage{fontspec}
\IfFontExistsTF{Hind}{%
\setmainfont{Hind}[
BoldFont = Hind-Bold,
UprightFont = Hind-Regular,
SemiBoldFont = Hind-SemiBold,
]%
% Try multiple font options for fallback support
\IfFontExistsTF{Liberation Sans}{%
\newfontfamily\NC@namefont{Liberation Sans}[
BoldFont = Liberation Sans Bold,
]%
}{%
\IfFontExistsTF{DejaVu Sans}{%
\newfontfamily\NC@namefont{DejaVu Sans}[
BoldFont = DejaVu Sans Bold,
]%
}{%
\let\NC@namefont\relax
}%
}%
}{%
\PackageWarningNoLine{foldable-namecard}{Hind font not found; using default font}%
}
\ifXeTeX
\RequirePackage{xeCJK}
\setCJKmainfont[
BoldFont = RODE Noto Sans CJK SC B,
]{RODE Noto Sans CJK SC R}
\fi
\makeatletter
\newsavebox{\NC@namebox}
\newcommand\NC@name{Your Name}
\newcommand\NC@subtitle{}
\newcommand\NC@country{Country}
\newcommand\NC@logo{}
\newlength\NC@logoheight
\newlength\NC@logowidth
\newif\ifNC@debugboxes
\NC@debugboxesfalse
\setlength\NC@logoheight{10mm}
\setlength\NC@logowidth{2cm}
\define@key{NC}{name}{\renewcommand\NC@name{#1}}
\define@key{NC}{subtitle}{\renewcommand\NC@subtitle{#1}}
\define@key{NC}{country}{\renewcommand\NC@country{#1}}
\define@key{NC}{logo}{\renewcommand\NC@logo{#1}}
\define@key{NC}{logoheight}{\setlength\NC@logoheight{#1}}
\define@key{NC}{logowidth}{\setlength\NC@logowidth{#1}}
\define@key{NC}{debugboxes}[true]{\NC@debugboxestrue}
\define@key{NC}{nodebugboxes}[true]{\NC@debugboxesfalse}
\newcommand{\namecardsetup}[1]{%
\setkeys{NC}{#1}%
}
\newcommand{\NC@dbgbox}[1]{%
\ifNC@debugboxes
\fbox{#1}%
\else
#1%
\fi
}
\newcommand{\NC@renderlogo}{%
\ifx\NC@logo\@empty
% No logo configured.
\else
\begingroup
\edef\NC@logofile{\NC@logo}%
\IfFileExists{\NC@logofile}{%
\NC@dbgbox{\includegraphics[width=\NC@logowidth,keepaspectratio]{\NC@logofile}}%
}{%
\fbox{\parbox[c][\NC@logoheight][c]{5cm}{\centering Logo file not found}}%
}%
\endgroup
\fi
}
\newcommand{\NC@panelcontent}{%
\NC@dbgbox{%
\begin{minipage}[c][0.92\paperwidth][c]{0.98\paperheight}
\centering
% Measure height of name resized to 25cm width
\savebox{\NC@namebox}{%
\resizebox{0.95\linewidth}{!}{\bfseries\ifx\NC@namefont\relax\NC@name\else{\NC@namefont\NC@name}\fi}%
}%
% If height > 3.5cm, scale down to 3cm; otherwise use 0.95\linewidth version
\ifdim\ht\NC@namebox>3.5cm
{\NC@dbgbox{\makebox[0.95\linewidth][c]{\resizebox{!}{3.cm}{\bfseries\ifx\NC@namefont\relax\NC@name\else{\NC@namefont\NC@name}\fi}}}}%
\else
{\NC@dbgbox{\makebox[0.95\linewidth][c]{\usebox{\NC@namebox}}}}%
\fi\par
\ifx\NC@subtitle\@empty\else
\savebox{\NC@namebox}{%
\resizebox{0.95\linewidth}{!}{\bfseries\ifx\NC@namefont\relax\NC@subtitle\else{\NC@namefont\NC@subtitle}\fi}%
}%
\vspace{2mm}
\ifdim\ht\NC@namebox>2cm
{\NC@dbgbox{\makebox[0.95\linewidth][c]{\resizebox{!}{2cm}{\bfseries\ifx\NC@namefont\relax\NC@subtitle\else{\NC@namefont\NC@subtitle}\fi}}}}%
\else
{\NC@dbgbox{\makebox[0.95\linewidth][c]{\usebox{\NC@namebox}}}}%
\fi\par
\fi
\vspace{5mm}
{\NC@dbgbox{\makebox[0.9\linewidth][c]{\resizebox{!}{7.5mm}{\large \NC@country}}}\par}
\end{minipage}%
}%
}
\ExplSyntaxOn
\seq_new:N \l_nc_fields_seq
\ior_new:N \l_nc_input_ior
\cs_new_protected:Npn \NC_process_csv_line:n #1
{
\tl_set:Nn \l_tmpa_tl {#1}
\tl_trim_spaces:N \l_tmpa_tl
\tl_if_blank:VTF \l_tmpa_tl
{ }
{
\seq_set_split:NnV \l_nc_fields_seq { , } \l_tmpa_tl
\seq_pop_left:NN \l_nc_fields_seq \l_tmpa_tl
\tl_trim_spaces:N \l_tmpa_tl
\seq_pop_left:NN \l_nc_fields_seq \l_tmpb_tl
\tl_trim_spaces:N \l_tmpb_tl
\seq_if_empty:NTF \l_nc_fields_seq
{
\typeout{===\ Printing\ namecard:\ \l_tmpa_tl,\ \l_tmpb_tl\ ===}
\namecardsetup{name=\l_tmpa_tl,subtitle=,country=\l_tmpb_tl}
}
{
\seq_pop_left:NN \l_nc_fields_seq \l_tmpc_tl
\tl_trim_spaces:N \l_tmpc_tl
\typeout{===\ Printing\ namecard:\ \l_tmpa_tl,\ \l_tmpb_tl,\ \l_tmpc_tl\ ===}
\namecardsetup{name=\l_tmpa_tl,subtitle=\l_tmpb_tl,country=\l_tmpc_tl}
}
\NC@renderpage
\newpage
}
}
\NewDocumentCommand{\makefoldablenamecard}{ }
{
\NC@renderpage
\newpage
}
\NewDocumentCommand{\makefoldablenamecardsfromfile}{m}
{
\ior_open:Nn \l_nc_input_ior {#1}
\ior_map_inline:Nn \l_nc_input_ior
{ \NC_process_csv_line:n {##1} }
\ior_close:N \l_nc_input_ior
}
\ExplSyntaxOff
\newcommand{\NC@renderpage}{%
\thispagestyle{empty}%
\begin{tikzpicture}[remember picture,overlay]
% Fold guide at the center of the A4 page (parallel to long edge).
\draw[dashed,gray!70,line width=0.4pt]
([xshift=0.5\paperwidth]current page.south west) --
([xshift=0.5\paperwidth]current page.north west);
% Left panel with text parallel to the long edge.
\node[anchor=center] at ([xshift=0.30\paperwidth]current page.west) {\rotatebox{270}{\NC@panelcontent}};
% Right panel with opposite orientation for the folded side.
\node[anchor=center] at ([xshift=0.70\paperwidth]current page.west) {\rotatebox{90}{\NC@panelcontent}};
% Logos at the outer edges of the page.
\node[anchor=west] at ([xshift=10mm]current page.west) {\rotatebox{270}{\NC@renderlogo}};
\node[anchor=east] at ([xshift=-10mm]current page.east) {\rotatebox{90}{\NC@renderlogo}};
\end{tikzpicture}%
\null
}
\makeatother