aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatasha Moongrave <natasha@256phi.eu>2026-04-24 10:34:44 +0200
committerNatasha Moongrave <natasha@256phi.eu>2026-04-24 10:35:29 +0200
commitc8fadfcf949b9a722a956f3f0bf08c1906d0e7e8 (patch)
tree0b5d0e8b76c0dadfd55845ab0496678c8fbf9e0d
parentb8dfd233dbb16a65235865daf2d3a067ff44bb59 (diff)
Added scpzine as a latex package
-rw-r--r--assets/texmf/tex/latex/scpzine/scpzine.sty467
-rw-r--r--flake.nix6
-rw-r--r--home/mun/default.nix1
-rw-r--r--pkgs/scpzine-texlive.nix38
4 files changed, 511 insertions, 1 deletions
diff --git a/assets/texmf/tex/latex/scpzine/scpzine.sty b/assets/texmf/tex/latex/scpzine/scpzine.sty
new file mode 100644
index 0000000..a46f0e0
--- /dev/null
+++ b/assets/texmf/tex/latex/scpzine/scpzine.sty
@@ -0,0 +1,467 @@
+% ============================================================
+% scpzine.sty — SCP Foundation Zine Package
+% Reusable formatting for SCP personnel briefing zines
+%
+% Usage: \usepackage[options]{scpzine}
+%
+% PRINTING:
+% Compile TWICE (TikZ needs two passes).
+% Print > Booklet > A3 paper > flip on long edge.
+% ============================================================
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{scpzine}[2026/04/23 SCP Foundation Zine Package]
+
+% ── Package options ─────────────────────────────────────────
+\newif\ifscpzine@impose\scpzine@imposefalse
+\DeclareOption{impose}{\scpzine@imposetrue}
+\ProcessOptions\relax
+
+% ── Required packages ──────────────────────────────────────
+\RequirePackage[a5paper,
+ top=9mm, bottom=9mm,
+ left=9mm, right=9mm]{geometry}
+\RequirePackage[T1]{fontenc}
+\RequirePackage[utf8]{inputenc}
+\RequirePackage{lmodern}
+\RequirePackage{courier}
+\renewcommand{\familydefault}{\ttdefault}
+\RequirePackage{microtype}
+\RequirePackage{parskip}
+\setlength{\parskip}{2pt plus 1pt minus 1pt}
+\setlength{\parindent}{0pt}
+\RequirePackage{setspace}
+\RequirePackage{ragged2e}
+\sloppy
+\setlength{\emergencystretch}{3em}
+\RequirePackage{graphicx}
+\RequirePackage{wrapfig}
+\RequirePackage[dvipsnames]{xcolor}
+\RequirePackage{tikz}
+\usetikzlibrary{calc}
+\RequirePackage{booktabs}
+\RequirePackage{tabularx}
+\RequirePackage{array}
+\RequirePackage{soul}
+\RequirePackage{textcase}
+\RequirePackage{eso-pic}
+\RequirePackage[hidelinks]{hyperref}
+\RequirePackage{fancyhdr}
+\RequirePackage{environ}
+
+% ── Imposition (optional) ──────────────────────────────────
+\ifscpzine@impose
+ \RequirePackage{pgfpages}
+ \pgfpagesuselayout{2 on 1}[a3paper,landscape,border shrink=3mm]
+\fi
+
+% ============================================================
+% COLOUR PALETTE
+% ============================================================
+\definecolor{paperbg}{RGB}{240, 232, 208}
+\definecolor{fadedink}{RGB}{48, 44, 36}
+\definecolor{stampred}{RGB}{158, 26, 26}
+\definecolor{rulercolor}{RGB}{100, 88, 68}
+\definecolor{redactbg}{RGB}{10, 10, 10}
+
+% ============================================================
+% PAGE BACKGROUND — aged paper on every page
+% ============================================================
+\AddToShipoutPictureBG{%
+ \AtPageLowerLeft{%
+ \textcolor{paperbg}{\rule{\paperwidth}{\paperheight}}%
+ }%
+}
+
+% ============================================================
+% DOCUMENT METADATA — set these in your document preamble
+% ============================================================
+\newcommand{\scpnumber}[1]{\def\scp@number{#1}}
+\newcommand{\scpclass}[1]{\def\scp@class{#1}}
+\newcommand{\scpsite}[1]{\def\scp@site{#1}}
+\newcommand{\scpsector}[1]{\def\scp@sector{#1}}
+\newcommand{\scpdocid}[1]{\def\scp@docid{#1}}
+\newcommand{\scpissue}[1]{\def\scp@issue{#1}}
+\newcommand{\scpclearance}[1]{\def\scp@clearance{#1}}
+\newcommand{\scptype}[1]{\def\scp@type{#1}}
+\newcommand{\scpseries}[1]{\def\scp@series{#1}}
+
+% Defaults
+\def\scp@number{SCP-XXX}
+\def\scp@class{Euclid}
+\def\scp@site{Site-19}
+\def\scp@sector{Sector C}
+\def\scp@docid{PB-XXX-X}
+\def\scp@issue{1}
+\def\scp@clearance{LEVEL 2}
+\def\scp@type{HUMANOID}
+\def\scp@series{SECTOR ORIENTATION SERIES}
+
+% ============================================================
+% HEADERS / FOOTERS
+% ============================================================
+\pagestyle{fancy}
+\fancyhf{}
+\renewcommand{\headrulewidth}{0pt}
+\renewcommand{\footrulewidth}{0pt}
+
+\fancyhead[L]{%
+ \scriptsize\underline{\texttt{RESTRICTED --- \scp@clearance\ PERSONNEL ONLY}}%
+}
+\fancyhead[R]{%
+ \scriptsize\underline{\texttt{\today}}%
+}
+\fancyfoot[R]{%
+ \scriptsize\textit{\texttt{continue to next page}}%
+}
+\fancyfoot[L]{%
+ \scriptsize\texttt{\scp@docid\ / ISSUE \scp@issue}%
+}
+
+% Last page — no "continue"
+\fancypagestyle{lastpage}{%
+ \fancyfoot[R]{}%
+ \fancyfoot[L]{\scriptsize\texttt{\scp@docid\ / ISSUE \scp@issue}}%
+}
+
+% Cover pages — no header/footer
+\fancypagestyle{coverpage}{%
+ \fancyhf{}%
+ \renewcommand{\headrulewidth}{0pt}%
+}
+
+% Blank pages
+\fancypagestyle{blankpage}{%
+ \fancyhf{}%
+ \renewcommand{\headrulewidth}{0pt}%
+}
+
+% ============================================================
+% BASIC COMMANDS
+% ============================================================
+
+% Redaction — black box hiding text
+\newcommand{\redact}[1]{%
+ \NoCaseChange{%
+ \mbox{\colorbox{redactbg}{\textcolor{redactbg}{\texttt{#1}}}}%
+ }%
+}
+
+% [DATA EXPUNGED]
+\newcommand{\expunged}{%
+ \NoCaseChange{%
+ \mbox{\colorbox{redactbg}{\textcolor{white}{\texttt{[DATA EXPUNGED]}}}}%
+ }%
+}
+
+% [SEE LEVEL N FILE] — optional argument for clearance level
+\newcommand{\seelevel}[1][3]{%
+ \NoCaseChange{%
+ \mbox{\colorbox{redactbg}%
+ {\textcolor{white}{\texttt{[SEE LEVEL #1 FILE]}}}}%
+ }%
+}
+
+% Field label — bold inline label
+\newcommand{\field}[1]{\textbf{#1}}
+
+% Horizontal rule
+\newcommand{\ruleline}{%
+ \vspace{2pt}%
+ {\color{rulercolor}\hrule height 0.4pt}%
+ \vspace{2pt}%
+}
+
+% Stamp overlay — \stampat[color]{rotation}{x}{y}{text}
+\newcommand{\stampat}[5][stampred]{%
+ \begin{tikzpicture}[overlay, remember picture]
+ \node[
+ rotate=#2,
+ text=#1,
+ font=\fontsize{13}{13}\selectfont\bfseries\ttfamily,
+ draw=#1, line width=1.6pt,
+ inner xsep=5pt, inner ysep=3pt,
+ opacity=0.55, anchor=center
+ ] at ($(current page.center)+(#3,#4)$) {#5};
+ \end{tikzpicture}%
+}
+
+% Photo with fallback placeholder
+% Usage: \photoblock{filename}{caption}
+\newcommand{\photoblock}[2]{%
+ \IfFileExists{#1}{%
+ \includegraphics[width=\linewidth, keepaspectratio]{#1}%
+ }{%
+ \begin{tikzpicture}
+ \draw[fill=black!5, draw=black!25, line width=0.5pt]
+ (0,0) rectangle (3.8cm, 3.2cm);
+ \draw[black!15, line width=0.4pt]
+ (0,0)--(3.8cm,3.2cm);
+ \draw[black!15, line width=0.4pt]
+ (3.8cm,0)--(0,3.2cm);
+ \node[font=\tiny\ttfamily, text=black!35]
+ at (1.9cm,1.7cm) {[PHOTO]};
+ \node[font=\tiny\ttfamily, text=black!25]
+ at (1.9cm,1.3cm) {\texttt{#1}};
+ \end{tikzpicture}%
+ }%
+ \par
+ \vspace{2pt}
+ {\tiny\texttt{#2}}%
+}
+
+% Corner marks (used on covers)
+\newcommand{\cornermarks}{%
+ \begin{tikzpicture}[overlay, remember picture]
+ \foreach \corner/\xd/\yd in {
+ north west/1/-1, north east/-1/-1,
+ south west/1/1, south east/-1/1}{
+ \draw[fadedink, line width=1pt]
+ ($(current page.\corner)+(\xd*0.4cm,\yd*0.4cm)$) --
+ ($(current page.\corner)+(\xd*0.9cm,\yd*0.4cm)$);
+ \draw[fadedink, line width=1pt]
+ ($(current page.\corner)+(\xd*0.4cm,\yd*0.4cm)$) --
+ ($(current page.\corner)+(\xd*0.4cm,\yd*0.9cm)$);
+ }
+ \end{tikzpicture}%
+}
+
+% ============================================================
+% ENVIRONMENTS
+% ============================================================
+
+% ── scpinterview — Interview/Dialog transcript ─────────────
+% Usage:
+% \begin{scpinterview}{Interview title}{Archive ref and notes}
+% \say{Speaker}{Dialog text}
+% \say{Speaker}{\textit{(action)} Dialog text}
+% \end{scpinterview}
+%
+\newenvironment{scpinterview}[2]{%
+ \field{#1}%
+ \par\vspace{1pt}%
+ {\scriptsize\textit{#2}}%
+ \vspace{3pt}%
+ \ruleline%
+ \vspace{3pt}%
+}{%
+ \vspace{3pt}%
+}
+\newcommand{\say}[2]{%
+ \vspace{2pt}%
+ \hspace{8pt}\field{#1:} #2%
+ \par%
+}
+
+% ── scpextract — Interview sub-extract label ───────────────
+% Usage: \scpextract{Extract from Interview 049-INT-B-\redact{XX}:}
+\newcommand{\scpextract}[1]{%
+ \textit{#1}%
+ \vspace{3pt}%
+}
+
+% ── scptimeline — Incident timeline table ──────────────────
+% Usage:
+% \begin{scptimeline}
+% \event{02:14}{Motion sensor alert.}
+% \event{02:19}{Guard fails check-in.}
+% \end{scptimeline}
+%
+\newenvironment{scptimeline}{%
+ \vspace{2pt}%
+ {\scriptsize%
+ \begin{tabular}{@{}p{1.1cm} p{6.1cm}@{}}
+ \toprule
+ \field{TIME} & \field{EVENT} \\
+ \midrule
+}{%
+ \bottomrule
+ \end{tabular}}%
+ \vspace{3pt}%
+}
+\newcommand{\event}[2]{%
+ \texttt{#1} & #2 \\[2pt]%
+}
+
+% ── scpreftable — Reference/documentation table ───────────
+% Usage:
+% \begin{scpreftable}
+% \docref{049-INT-B}{Full interview series. Level 3.}
+% \end{scpreftable}
+%
+\newenvironment{scpreftable}{%
+ \vspace{3pt}%
+ {\scriptsize%
+ \begin{tabular}{@{}p{2.4cm} p{4.8cm}@{}}
+ \toprule
+ \field{REFERENCE} & \field{CONTENTS} \\
+ \midrule
+}{%
+ \bottomrule
+ \end{tabular}}%
+}
+\newcommand{\docref}[2]{%
+ \texttt{#1} & #2 \\[2pt]%
+}
+
+% ── scpincident — Incident summary header ─────────────────
+% Usage:
+% \begin{scpincident}{Breach BR-2012-049-\redact{7}}
+% {Summarised for Level 2 distribution. Full report Level 3.}
+% ... content ...
+% \end{scpincident}
+%
+\newenvironment{scpincident}[2]{%
+ \field{Incident Summary: #1}%
+ \par\vspace{1pt}%
+ {\scriptsize\textit{#2}}%
+ \ruleline%
+}{%
+}
+
+% ── scpfoundnote — Hidden/found note ──────────────────────
+% Usage:
+% \begin{scpfoundnote}{Discovery context text}{Follow-up text}
+% Note body text here...
+% \end{scpfoundnote}
+%
+\NewEnviron{scpfoundnote}[2]{%
+ \begin{center}
+ \begin{minipage}{0.82\linewidth}
+ \setstretch{1.4}
+ {\scriptsize\textit{#1}}%
+ \vspace{8pt}
+ {\color{rulercolor}\hrule height 0.3pt}
+ \vspace{8pt}
+ {\small\itshape\BODY}%
+ \vspace{8pt}
+ {\color{rulercolor}\hrule height 0.3pt}
+ \vspace{5pt}
+ {\scriptsize\texttt{#2}}%
+ \end{minipage}
+ \end{center}%
+}
+
+% ── scpaddendum — Classified addendum block ───────────────
+% Usage:
+% \begin{scpaddendum}{Filed by \redact{XX}, Senior Researcher}
+% \expunged
+% {\scriptsize\textit{[Withheld from Level 2. Level 3 required.]}}
+% \end{scpaddendum}
+%
+\newenvironment{scpaddendum}[1]{%
+ \vspace{3pt}%
+ \ruleline%
+ \field{Addendum --- #1:}%
+ \vspace{2pt}%
+}{%
+}
+
+% ── scpguidance — Personnel guidance numbered items ───────
+% Usage:
+% \begin{scpguidance}{If SCP-049 Addresses You}
+% \guidanceitem{Do not engage.}{Explanation text.}
+% \guidanceitem{Do not argue.}{Explanation text.}
+% \end{scpguidance}
+%
+\newenvironment{scpguidance}[1]{%
+ \field{Personnel Guidance --- #1:}%
+ \par%
+}{%
+}
+\newcommand{\guidanceitem}[2]{%
+ \vspace{2pt}%
+ \field{#1} #2%
+ \par%
+}
+
+% ── scpsidephoto — Wrapped sidebar photo ──────────────────
+% Usage: \scpsidephoto{r}{0.42}{assets/photo.jpg}{Caption text}
+\newcommand{\scpsidephoto}[4]{%
+ \begin{wrapfigure}{#1}{#2\linewidth}
+ \vspace{-4pt}
+ \photoblock{#3}{#4}
+ \vspace{-8pt}
+ \end{wrapfigure}%
+}
+
+% ============================================================
+% COVER PAGE COMMANDS
+% ============================================================
+
+% Classification header (multilingual)
+\newcommand{\classificationheader}[1]{%
+ \noindent
+ \begin{tabular*}{\linewidth}{@{}l@{\extracolsep{\fill}}r@{}}
+ {\scriptsize\texttt{RESTRICTED --- \scp@clearance\ PERSONNEL ONLY}} &
+ {\scriptsize\smash{\raisebox{-50pt}{\includegraphics[scale=0.03]{#1}}}} \\
+ \end{tabular*}%
+ {\scriptsize\texttt{RESTREINT --- PERSONNEL DE NIVEAU 2 UNIQUEMENT}}\\
+ {\scriptsize\texttt{VERTRAULICH --- NUR FUR PERSONAL DER STUFE 2}}\\
+ {\scriptsize\texttt{RESERVADO --- SOLO PERSONAL DE NIVEL 2}}%
+}
+
+% Cover metadata block
+\newcommand{\covermetadata}{%
+ {\scriptsize\texttt{PERSONNEL BRIEFING DOCUMENT}}\\[1pt]
+ {\scriptsize\texttt{\MakeUppercase{\scp@series}}}\\[3pt]
+ {\normalsize\bfseries\texttt{\scp@number}}\\[1pt]
+ {\scriptsize\texttt{\MakeUppercase{\scp@type} / \MakeUppercase{\scp@class} / \MakeUppercase{\scp@sector}}}\\[3pt]
+ {\scriptsize\texttt{DOCUMENT: \scp@docid\quad ISSUE: \scp@issue}}%
+}
+
+% Signature block
+% Usage: \signatureblock{Name or \redact{XX}}{Title}{Location}
+\newcommand{\signatureblock}[3]{%
+ \begin{tabular}{l}
+ {\scriptsize\texttt{Authorised for distribution by:}} \\[2pt]
+ \hline \\[-8pt]
+ {\scriptsize\texttt{#1, #2}} \\
+ {\scriptsize\texttt{#3}} \\
+ \hline \\[-4pt]
+ \end{tabular}%
+}
+
+% Cover disclaimer block
+\newcommand{\coverdisclaimer}[1]{%
+ \begin{minipage}{0.9\linewidth}
+ {\scriptsize\texttt{#1}}%
+ \end{minipage}%
+}
+
+% Back cover info block
+\newcommand{\backcoverbody}{%
+ {\small\bfseries\texttt{\scp@number}}\\[2pt]
+ {\scriptsize\texttt{\MakeUppercase{\scp@sector} PERSONNEL BRIEFING}}\\[1pt]
+ {\scriptsize\texttt{DOCUMENT \scp@docid\ / ISSUE \scp@issue}}\\[1pt]
+ {\scriptsize\texttt{\MakeUppercase{\scp@site} / CONTAINMENT DIVISION}}%
+}
+
+% ============================================================
+% ITEM HEADER — standard SCP description header
+% ============================================================
+% Usage: \scpheader (uses metadata set in preamble)
+\newcommand{\scpheader}{%
+ \field{Item \#:} \scp@number \hfill
+ \field{Object Class:} \scp@class \hfill
+ \field{Site:} \scp@site%
+ \ruleline%
+}
+
+% ============================================================
+% BLANK PAGE with centered message
+% ============================================================
+\newcommand{\blankpagemessage}[1]{%
+ \thispagestyle{blankpage}%
+ \vspace*{\fill}
+ \begin{center}
+ {\small\texttt{#1}}%
+ \end{center}
+ \vfill%
+}
+
+% ============================================================
+% SET DEFAULT TEXT COLOR
+% ============================================================
+\AtBeginDocument{\color{fadedink}}
+
+\endinput
diff --git a/flake.nix b/flake.nix
index 5468b6f..a908605 100644
--- a/flake.nix
+++ b/flake.nix
@@ -54,6 +54,10 @@
})
# Fenix Rust overlay
fenix.overlays.default
+ # Local TeXLive packages
+ (final: prev: {
+ scpzine-texlive = final.callPackage ./pkgs/scpzine-texlive.nix {};
+ })
];
# Per-host home-manager configuration
@@ -98,7 +102,7 @@
};
in {
nixosConfigurations = {
- kronos = mkSystem "kronos" "nord-blue";
+ kronos = mkSystem "kronos" "schrottkatze";
herra = mkSystem "herra" "schrottkatze";
mystra = mkSystem "mystra" "nord-blue";
};
diff --git a/home/mun/default.nix b/home/mun/default.nix
index 2d229e0..0263f13 100644
--- a/home/mun/default.nix
+++ b/home/mun/default.nix
@@ -98,6 +98,7 @@
inherit (texlive) scheme-full;
notestex = texlivePackages.notestex;
screenplay = texlivePackages.screenplay;
+ scpzine = pkgs.scpzine-texlive;
})
# RetroArch
diff --git a/pkgs/scpzine-texlive.nix b/pkgs/scpzine-texlive.nix
new file mode 100644
index 0000000..b9ce910
--- /dev/null
+++ b/pkgs/scpzine-texlive.nix
@@ -0,0 +1,38 @@
+# Local TeXLive package for scpzine.sty
+# Builds a texlivePackages-compatible derivation from the local .sty file.
+{
+ lib,
+ runCommand,
+ texlive,
+}: let
+ scpzine-src = ../assets/texmf/tex/latex/scpzine;
+in
+ runCommand "texlive-scpzine" {
+ passthru.tlDeps = with texlive; [
+ courier
+ lm
+ microtype
+ parskip
+ setspace
+ ragged2e
+ graphics
+ wrapfig
+ xcolor
+ pgf # tikz
+ booktabs
+ tabularx
+ tools # array
+ soul
+ textcase
+ eso-pic
+ hyperref
+ fancyhdr
+ environ
+ geometry
+ fontenc
+ ];
+ tlType = "run";
+ } ''
+ mkdir -p "$out/tex/latex/scpzine"
+ cp ${scpzine-src}/scpzine.sty "$out/tex/latex/scpzine/"
+ ''