\NeedsTeXFormat{LaTeX2e} \ProvidesClass{cccbform}[2024-11-08 In the Beginning, There Was Chaos] \LoadClass{scrartcl} \RequirePackage{geometry, calc, xparse, xcolor, hyperref, tikz, fontspec, changepage, letltxmacro, textpos} % address \newcommand{\address}{% Chaos Computer Club Berlin / CCC~(B)~e.~V.\\ Marienstr.~11\\ 10117~Berlin } % page \geometry{a4paper, margin=1.5cm, inner=2.5cm} \pagestyle{empty} \setmainfont[ Renderer=HarfBuzz, ItalicFont=Recursive, BoldFont=Recursive, BoldItalicFont=Recursive, Scale=0.9, UprightFeatures={ RawFeature={+ss01,+ss02,+ss08,+case}, RawFeature={+axis={MONO=0.2,CASL=0.2,slnt=0,CRSV=0,wght=400}} }, BoldFeatures={RawFeature={+axis={MONO=0.2,CASL=0.2,slnt=0,CRSV=0,wght=700}}}, BoldItalicFeatures={RawFeature={+axis={MONO=0.2,CASL=0.2,slnt=-15,CRSV=1,wght=700}}}, ItalicFeatures={RawFeature={+axis={MONO=0.2,CASL=0.2,slnt=-15,CRSV=1,wght=400}}} ]{Recursive} \setmonofont[ Renderer=HarfBuzz, ItalicFont=Recursive, BoldFont=Recursive, BoldItalicFont=Recursive, Scale=0.9, UprightFeatures={ RawFeature={+ss01,+ss02,+ss08,+case}, RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=0,CRSV=0,wght=400}} }, BoldFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=0,CRSV=0,wght=700}}}, BoldItalicFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=-15,CRSV=1,wght=700}}}, ItalicFeatures={RawFeature={+axis={MONO=1.0,CASL=0.2,slnt=-15,CRSV=1,wght=400}}} ]{Recursive} \renewfontfamily\titlefont[ Renderer=HarfBuzz, ItalicFont=Recursive, BoldFont=Recursive, BoldItalicFont=Recursive, Scale=0.9, UprightFeatures={ RawFeature={+ss01,+ss02,+ss08,+case}, RawFeature={+axis={MONO=0.0,CASL=1.0,slnt=-5,CRSV=1,wght=500}} }, BoldFeatures={RawFeature={+axis={MONO=0.0,CASL=1.0,slnt=-5,CRSV=1,wght=800}}}, BoldItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=1.0,slnt=-15,CRSV=1,wght=800}}}, ItalicFeatures={RawFeature={+axis={MONO=0.0,CASL=1.0,slnt=-15,CRSV=1,wght=500}}} ]{Recursive} % fonts % cmr: 0 / 2.502 / 1.251 / 0.834 / 2.586 / 6.0 / 0.834 || -3 %\setmainfont{Barlow} % 0 / 1.2 / 0.6 / 0.4 / 3.036 / 6.0 / 0.4 || -2 %\setmainfont{Monaspace Neon} % 0 / 3.72 / 1.86 / 1.24 / 3.081 / 6.0 / 1.24 || -7 %\setmainfont{Baltic Sund} % 0 / 1.476 / 0.738 / 0.492 / 3.0 / 6.0 / 0.492 || -3 %\setmainfont{Cabin Sketch} % 0 / 1.35 / 0.675 / 0.45 / 3.03 / 6.0 / 0.45 || -2 %\setmainfont{Consolas} % 0 / 3.2988 / 0 / 0 / 2.941 / 6.0 / 0 || -6 %\setmainfont{Eagle Lake} % 0 / 1.787 / 0.89355 / 0.5957 / 3.2 / 6.0 / 0.5957 || -3 %\setmainfont{Fira Sans} % 0 / 1.59 / 0.795 / 0.53 / 3.162 / 6.0 / 0.53 || -3 %\setmainfont{Gentium Book Plus} % 0 / 1.32 / 0.66 / 0.44 / 2.72 / 6.0 / 0.44 || -2 %\setmainfont{Ubuntu} % 0 / 1.38 / 0.69 / 0.46 / 3.12 / 6.0 / 0.46 || -2 %\setmainfont{Ubuntu Condensed} % 0 / 1.17 / 0.58 / 0.39 / 3.12 / 6.0 / 0.39 || -2 %\setmainfont{Ubuntu Mono} % 0 / 3.0 / 0 / 0 / 3.12 / 6.0 / 0 || -5 % colors \definecolor{fieldcolor}{gray}{0.8} \definecolor{bordercolor}{gray}{0.1} % lengths \def\deflength#1#2{\newlength{#1}\setlength{#1}{#2}} \setlength{\parindent}{0pt} \setlength{\fboxsep}{0pt} \deflength{\formfieldheight}{14pt} \deflength{\formshrink}{4pt} \deflength{\formskip}{0.5em} \deflength{\colsep}{1.0em} \deflength{\indentstep}{1cm} \deflength{\borderwidth}{0.5pt} \def\checkboxtextshrink{\dimexpr \formfieldheight % width of checkbox +1em % the \quad separator's width +\formshrink % wild guess, -2\borderwidth leaves 1pt overfull \relax} \deflength{\htweak}{0.5pt} % manual adjustment of horizontal alignment of form elements \deflength{\hadj}{\dimexpr -0.5\formshrink - 0.5\fontdimen2\font + \htweak \relax} % counters \newcounter{fieldnum} \def\@autofieldname{field\thefieldnum} % abbreviations \def\@formdefaults{% backgroundcolor=fieldcolor,bordercolor=fieldcolor,% borderwidth=0pt,charsize=\formfieldheight% } % address placement helper \newcommand{\@dinaddress}{% \begin{tikzpicture}[remember picture, overlay] \node[anchor=north west] at (current page.north west) [xshift=2.35cm, yshift=-5cm] {% \begin{minipage}{10cm} \emph{an den} \par \vspace{\formskip} \noindent\address \end{minipage} }; \end{tikzpicture} } % % % form@, fake@, and full@ variants of the form elements: % % (raw@: renamed / prefixed hyperref command) % form@: PDF form element (some viewers don't print it) % fake@: A colored box, non-interactive (but will be printed!) % full@: a stack of fake@ and form@ on top of each other % % The general parameter convention here is: height, width multiplier % - height is optional and defaults to \formfieldheight, giving the right size % for a single-line text field % - width is "mandatory" but always used followed by \linewidth, so passing an % empty argument works and is effectively equivalent to passing 1 % rename commands to make nice names available \LetLtxMacro\raw@TextField\TextField \LetLtxMacro\raw@CheckBox\CheckBox \let\CheckBox\relax % wrapped form fields with defaults filled in \NewDocumentCommand{\form@TextField}{O{\formfieldheight} m}{% \stepcounter{fieldnum} \expandafter\raw@TextField\expandafter[\@formdefaults, name=\@autofieldname, width=\dimexpr #2\linewidth - \formshrink \relax, height=\dimexpr #1 - \formshrink \relax ]{}% } \NewDocumentCommand{\form@MultilineTextField}{O{\formfieldheight} m}{% \stepcounter{fieldnum} \expandafter\raw@TextField\expandafter[\@formdefaults, name=\@autofieldname, multiline=true, width=\dimexpr #2\linewidth - \formshrink \relax, height=\dimexpr #1 - \formshrink \relax ]{}% } \NewDocumentCommand{\form@CheckBox}{}{% \stepcounter{fieldnum} \expandafter\raw@CheckBox\expandafter[\@formdefaults, name=\@autofieldname, width=\dimexpr \formfieldheight - \formshrink \relax, height=\dimexpr \formfieldheight - \formshrink \relax ]{}% } % fake form fields to put *under* the PDF form fields \NewDocumentCommand{\fake@TextField}{O{\formfieldheight} m}{% \begin{tikzpicture}[baseline=0.6ex] \fill[fieldcolor] (0,0) rectangle (#2\linewidth - 2\borderwidth,#1); \draw[dash pattern=on 0.5\borderwidth off 5\borderwidth,bordercolor, line width=\borderwidth, line cap=round] (0,0) -- (#2\linewidth - 2\borderwidth,0); \end{tikzpicture}% } \LetLtxMacro\fake@MultilineTextField\fake@TextField \NewDocumentCommand{\fake@CheckBox}{}{% \begin{tikzpicture}[baseline=0.6ex] \fill[fieldcolor] (0,0) rectangle (\formfieldheight,\formfieldheight); \draw[bordercolor,line width=\borderwidth] (0,0) rectangle (\formfieldheight,\formfieldheight); \end{tikzpicture}% } % "full" stacked version of fake + actual form field \NewDocumentCommand{\full@TextField}{O{\formfieldheight} m}{% \begin{tikzpicture}[baseline] \node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) { \fake@TextField[#1]{#2} }; \node[anchor=center, inner sep=0pt, outer sep=0pt] at (background.center) { \kern\hadj\form@TextField[#1]{#2} }; \end{tikzpicture} } \NewDocumentCommand{\full@MultilineTextField}{O{\formfieldheight} m}{% \begin{tikzpicture}[baseline] \node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) { \fake@MultilineTextField[#1]{#2} }; \node[anchor=center, inner sep=0pt, outer sep=0pt] at (background.center) { \kern\hadj\form@MultilineTextField[#1]{#2} }; \end{tikzpicture} } \NewDocumentCommand{\full@CheckBox}{}{% \begin{tikzpicture}[baseline] \node (background) [anchor=base west, inner sep=0pt, outer sep=0pt] at (0,0) { \fake@CheckBox }; \node [anchor=center, inner sep=0pt] at (background.center) { \kern\hadj\form@CheckBox }; \end{tikzpicture} } % % % exposed form elements % Text{text…} - just text, with proper spacing \NewDocumentCommand{\Text}{m}{% \par#1\par\vspace{\formskip} } % TextField{label} - a single-line input \RenewDocumentCommand{\TextField}{m}{% \par% {\small #1\strut}\\% \full@TextField{}% \par\vspace{\formskip}% } % ShortTextField[width]{label} - a single-line input that doesn't have full width % (50% by default) \NewDocumentCommand{\ShortTextField}{O{0.5} m}{% \par% {\small #2\strut}\\% \full@TextField{#1}% \par\vspace{\formskip}% } % MultilineTextField[height]{label} - a multi-line input \NewDocumentCommand{\MultilineTextField}{O{} m}{% \par% {\small #2\strut}\\% \full@MultilineTextField[#1]{}% \par\vspace{\formskip}% } % Signature[label] - a field not fillable on the computer, big enough for a signature \NewDocumentCommand{\Signature}{O{Datum, Unterschrift}}{% \par% {\small #1\strut}\\% \fake@MultilineTextField[1.0cm]{0.5}% \par\vspace{\formskip}% } % Notes[label] - a slightly taller fake field that fills the whole width \NewDocumentCommand{\Notes}{O{Vermerke}}{% \par% {\small #1\strut}\\% \fake@MultilineTextField[1.5cm]{}% \par\vspace{\formskip}% } % Checkbox{label} - a checkbox; label can be long and will linebreak reasonably pretty \NewDocumentCommand{\Checkbox}{m}{% \par% \full@CheckBox\quad% \begin{minipage}[t]{\dimexpr \linewidth - \checkboxtextshrink \relax}% #1% \end{minipage}% \par\vspace{\formskip}% } % InlineCheckbox - just the box \NewDocumentCommand{\InlineCheckbox}{}{\full@CheckBox} % CheckboxOther[width]{label} - a checkbox for a write-in option \NewDocumentCommand{\CheckboxOther}{O{0.5} m}{% \par% \full@CheckBox\quad#2\quad\full@TextField{#1}% \par\vspace{\formskip}% } % high-level structure % Section{title} - a form section \NewDocumentCommand{\Section}{m}{% \vspace{1.5cm}% {\Large\bfseries #1}% \par\vspace{2\formskip}% } % Subsection{title} - slightly smaller than section \NewDocumentCommand{\Subsection}{m}{% \vspace{1.0cm}% {\large\bfseries #1}% \par\vspace{\formskip}% } % Rule - a horizontal rule, with correct spacing \NewDocumentCommand{\Rule}{}{% \vspace{\formskip}% \rule{\linewidth}{\borderwidth}% \vspace{2\formskip}% } % RuleSection - rule followed by a small note *immediately* below, before the spacing % (e.g. to separate public / internal sections of a form) \NewDocumentCommand{\RuleSection}{m}{% \vspace{\formskip}% \leavevmode\rule{\linewidth}{\borderwidth}\\% {\details{#1}}% \par\vspace{2\formskip} } % \begin{Indented}[factor] ... \end{Indented} - indent a section \NewDocumentEnvironment{Indented}{O{}}{% \begin{adjustwidth}{#1\indentstep}{0pt}% }{% \end{adjustwidth}% } % TwoColumns{left}{right} - put two sections side-by-side \NewDocumentCommand{\TwoColumns}{m m}{% \begin{minipage}[t]{0.5\linewidth - 0.5\colsep}% #1% \end{minipage}% \hfill \begin{minipage}[t]{0.5\linewidth - 0.5\colsep}% #2% \end{minipage}% \par } \NewDocumentCommand{\ThreeColumns}{m m m}{% \begin{minipage}[t]{0.333\linewidth - 0.66\colsep}% #1% \end{minipage}% \hfill \begin{minipage}[t]{0.333\linewidth - 0.66\colsep}% #2% \end{minipage}% \hfill \begin{minipage}[t]{0.333\linewidth - 0.66\colsep}% #3% \end{minipage}% \par } \NewDocumentCommand{\FiveColumns}{m m m m m}{% \begin{minipage}[t]{0.2\linewidth - 0.8\colsep}% #1% \end{minipage}% \hfill \begin{minipage}[t]{0.2\linewidth - 0.8\colsep}% #2% \end{minipage}% \hfill \begin{minipage}[t]{0.2\linewidth - 0.8\colsep}% #3% \end{minipage}% \hfill \begin{minipage}[t]{0.2\linewidth - 0.8\colsep}% #4% \end{minipage}% \hfill \begin{minipage}[t]{0.2\linewidth - 0.8\colsep}% #5% \end{minipage}% \par } % details{text} - (use instead of font sizes, small text) \NewDocumentCommand{\details}{m}{% {\scriptsize #1}% } % % % common title patterns % LogoTitle{title} - logo on the right, title on the left \NewDocumentCommand{\LogoTitle}{m}{ \begin{tikzpicture}[remember picture, overlay] \node[anchor=north east] at (current page.north east) [xshift=-1.5cm, yshift=-1.5cm] {% \includegraphics[width=3cm]{logo.pdf}% }; \end{tikzpicture}% \\[1cm]{\titlefont\huge\bfseries #1}\\[1.5cm] } % AddressTitle{title} - title at the top, address, then the form below \NewDocumentCommand{\AddressTitle}{m}{ \@dinaddress \\[1cm]\smash{{\titlefont\huge\bfseries #1}}\\[4cm] } % need to emit \Form ; hyperref generates incomplete CheckBox appearance data, % which causes problems with some viewers - so it's currently better not to % generate any at all \AtBeginDocument{ \Form[NeedAppearances=false] }