cccb-formulare/cccbform.cls
2024-11-12 17:25:27 +01:00

368 lines
10 KiB
TeX

\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}
% 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.94}
\definecolor{bordercolor}{gray}{0.5}
% 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]{\huge\bfseries #1}\\[1.5cm]
}
% AddressTitle{title} - title at the top, address, then the form below
\NewDocumentCommand{\AddressTitle}{m}{
\@dinaddress
\\[1cm]\smash{{\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]
}