From b52cc9e48fb687adb1b61436a3b13759f07ca36e Mon Sep 17 00:00:00 2001 From: Dan Baker Date: Wed, 22 May 2024 12:23:20 -0700 Subject: [PATCH] Add cheat sheets (#7) * Got the new cheat sheet to build. * Fix inkscape/Fontconfig warnings. * Use filesets to restrict the files in the cheat sheet derivation. * Clean up main tex file. * Extracted paper and color styling from the main tex file. * add .gitignore * Renamed files for consistency. * Cheat sheets now available as the product of a4/letter and color/bw. * Remove unnecessary attributes from callPackage. * Fixed the dollar to pound sign bug. * Patched out pygment formatting on comments and strings. Didn't like the way the fonts looked. * The grayscale/bw name from bw to print. * Change variables named 'set' to 's' so as to not confuse the reader. They might think 'set' is a keyword. --- .gitignore | 2 + cheatsheet/background.svg | 45 ++ cheatsheet/color-default.tex | 7 + cheatsheet/color-print.tex | 7 + cheatsheet/default.nix | 95 ++++ cheatsheet/main.tex | 346 +++++++++++++ cheatsheet/nixos.svg | 462 ++++++++++++++++++ cheatsheet/paper-a4.tex | 1 + cheatsheet/paper-letter.tex | 1 + cheatsheet/unformatted-comments-strings.patch | 25 + flake.lock | 61 +++ flake.nix | 28 ++ 12 files changed, 1080 insertions(+) create mode 100644 .gitignore create mode 100644 cheatsheet/background.svg create mode 100644 cheatsheet/color-default.tex create mode 100644 cheatsheet/color-print.tex create mode 100644 cheatsheet/default.nix create mode 100644 cheatsheet/main.tex create mode 100644 cheatsheet/nixos.svg create mode 100644 cheatsheet/paper-a4.tex create mode 100644 cheatsheet/paper-letter.tex create mode 100644 cheatsheet/unformatted-comments-strings.patch create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c8211a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +### Nix ### +result* diff --git a/cheatsheet/background.svg b/cheatsheet/background.svg new file mode 100644 index 0000000..6070aa4 --- /dev/null +++ b/cheatsheet/background.svg @@ -0,0 +1,45 @@ + + + + + OpenSCAD Model + + diff --git a/cheatsheet/color-default.tex b/cheatsheet/color-default.tex new file mode 100644 index 0000000..5e7d019 --- /dev/null +++ b/cheatsheet/color-default.tex @@ -0,0 +1,7 @@ +\usepackage{minted} +\usemintedstyle{default} + +% Define colors +\usepackage{xcolor} +\definecolor{nixdarkblue}{HTML}{5277C3} +\definecolor{codelight}{HTML}{f8f8f8} diff --git a/cheatsheet/color-print.tex b/cheatsheet/color-print.tex new file mode 100644 index 0000000..f22dd00 --- /dev/null +++ b/cheatsheet/color-print.tex @@ -0,0 +1,7 @@ +\usepackage{minted} +\usemintedstyle{bw} + +% Define colors +\usepackage{xcolor} +\definecolor{nixdarkblue}{HTML}{747474} +\definecolor{codelight}{HTML}{ffffff} diff --git a/cheatsheet/default.nix b/cheatsheet/default.nix new file mode 100644 index 0000000..db19b36 --- /dev/null +++ b/cheatsheet/default.nix @@ -0,0 +1,95 @@ +{ pkgs }: +let + tex = pkgs.texlive.combine { + inherit (pkgs.texlive) + scheme-basic + environ + etoolbox + fancyvrb + koma-script + latexmk + listings + listingsutf8 + metafont + hyperref + minted + pdfcol + pgf + svg + tcolorbox + texlive-scripts + tikzfill + transparent + upquote + xcolor + ; + }; + + pygments = pkgs.python3Packages.pygments.overridePythonAttrs (old: { + patches = (old.patches or [ ]) ++ [ + # removed bold and italics formatting for comments and strings + ./unformatted-comments-strings.patch + ]; + }); + + inherit (pkgs) lib; + + combinations = lib.cartesianProduct { + paper = [ + "a4" + "letter" + ]; + color = [ + "default" + "print" + ]; + }; +in +lib.listToAttrs ( + builtins.map (elem: { + name = "cheat-sheet-${elem.paper}-${elem.color}"; + + value = pkgs.stdenvNoCC.mkDerivation { + name = "nixos-cheat-sheet"; + + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.unions [ + ./main.tex + ./paper-${elem.paper}.tex + ./color-${elem.color}.tex + ./nixos.svg + ./background.svg + ]; + }; + + buildInputs = [ + tex + pkgs.inkscape # for svg images + pygments # for minted code blocks + ]; + + # HOME needs to be set to keep inkscape/Fontconfig from complaining + buildPhase = '' + mv paper-${elem.paper}.tex paper.tex + mv color-${elem.color}.tex color.tex + + DIR=$(mktemp -d) + env TEXMFHOME="$DIR/.cache" \ + TEXMFVAR="$DIR/.cache/texmf-var" \ + HOME="$DIR/home" \ + latexmk \ + -interaction=nonstopmode \ + -pdf -pdflatex \ + -output-directory="." \ + -shell-escape \ + main.tex + ''; + + installPhase = '' + mkdir $out + cp main.pdf $out/cheat-sheet-${elem.paper}-${elem.color}.pdf + ''; + }; + }) combinations +) diff --git a/cheatsheet/main.tex b/cheatsheet/main.tex new file mode 100644 index 0000000..c8cdb52 --- /dev/null +++ b/cheatsheet/main.tex @@ -0,0 +1,346 @@ +\documentclass[landscape, 10pt]{article} +\input{paper.tex} +\input{color.tex} +\usepackage{multicol} +\usepackage[most]{tcolorbox} +\usepackage{svg} + +\usepackage[hidelinks]{hyperref} +\hypersetup{ + colorlinks=true, + urlcolor=nixdarkblue, +} + +% Set typewriter font everywhere +\usepackage[T1]{fontenc} +\renewcommand{\familydefault}{\ttdefault} + +% Declare Unicode characters +\DeclareUnicodeCharacter{21D2}{$\Rightarrow$} + +% Get rid of red boxes around minted "errors" +\AtBeginEnvironment{minted}{% + \renewcommand{\fcolorbox}[4][]{#4}% +} + +% Create the box that is used everywhere +\newtcolorbox{ctexpression}[2][]{ + enhanced, + breakable, + colback=codelight, + colframe=nixdarkblue, + before skip=1mm, after skip=1mm,left=1mm, right=1mm, top=1mm, bottom=1mm, + attach boxed title to top left={yshift*=-\tcboxedtitleheight}, + boxed title size=title, + boxed title style={% + sharp corners, + rounded corners=northwest, + colback=tcbcolframe, + boxrule=0pt, + }, + underlay boxed title={% + \path[fill=tcbcolframe] + (title.south west)-- + (title.south east) + to [out=0, in=180] ([xshift=5mm]title.east)-- + (title.center-|frame.east) + [rounded corners] |- (frame.north) -| + cycle; + },fonttitle=\bfseries, title={#2},#1 +} + +% Shrink the top and bottom separation around minted environments +\newlength{\fancyvrbtopsep} +\newlength{\fancyvrbpartopsep} +\makeatletter +\FV@AddToHook{\FV@ListParameterHook}{\topsep=\fancyvrbtopsep\partopsep=\fancyvrbpartopsep} +\makeatother +\setlength{\fancyvrbtopsep}{0pt} +\setlength{\fancyvrbpartopsep}{0pt} + +\newenvironment{tightcenter}{% + \setlength\topsep{0pt} + \setlength\parskip{0pt} + \begin{center} +}{% + \end{center} +} + +\begin{document} + +\renewcommand{\arraystretch}{1.5} + +% Set the background image +\AddToHook{shipout/background}{% + \put (0in,-0.9\paperheight){\scalebox{-1}[1]{\includesvg[width=\paperwidth,height=\paperheight]{background.svg}}}% +} + +\begin{multicols*}{3} + +\begin{ctexpression}{Types \& Syntax} + \begin{tabular}{l p{0.5\textwidth}} + String & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +"this is a string" +'' + a multi-line string +'' + \end{minted} + \end{minipage} + \\ + % \hdashline + Boolean & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +true, false + \end{minted} + \end{minipage} + \\ + % \hdashline + Null & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +null + \end{minted} + \end{minipage} + \\ + % \hdashline + Integer & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +123, -123 + \end{minted} + \end{minipage} + \\ + % \hdashline + Float & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +3.14, -3.14 + \end{minted} + \end{minipage} + \\ + % \hdashline + Path & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +/an/absolute/path +./a/relative/path + \end{minted} + \end{minipage} + \\ + % \hdashline + Attribute Set & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +{ a = 1; b = 2; } + \end{minted} + \end{minipage} + \\ + % \hdashline + List & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +[ 1 2.0 "thing" null ] + \end{minted} + \end{minipage} + \\ + % \hdashline + Comment & + \begin{minipage}{0.5\textwidth} + \begin{minted}{nix} +# A single line comment. +/* + A multi-line comment. +*/ + \end{minted} + \end{minipage} + \end{tabular} +\end{ctexpression} + +\vfill + +\begin{ctexpression}{Scoping} +{\color{nixdarkblue}Define local variables using} let...in + \begin{minted}{nix} +let + x = 1; + y = 2; +in + x + y # ⇒ returns 3 + \end{minted} + \tcbline +{\color{nixdarkblue}Add variables into scope using} inherit + \begin{minted}{nix} +let x = 1; in { inherit x; } + \end{minted} +{\color{nixdarkblue}desugars to} + \begin{minted}{nix} +let x = 1; in { x = x; } + \end{minted} + \tcbline +{\color{nixdarkblue}Add attributes into scope using} inherit + \begin{minted}{nix} +let x = { y = 1; }; in { inherit (x) y; } + \end{minted} +{\color{nixdarkblue}desugars to} + \begin{minted}{nix} +let x = { y = 1; }; in { y = x.y; } + \end{minted} + \tcbline +{\color{nixdarkblue}Add all attributes into scope using} with + \begin{minted}{nix} +let + s = { x = 1; y = 2; }; +in + with s; + x + y # ⇒ returns 3 + \end{minted} +\end{ctexpression} + +\begin{ctexpression}{Conditionals} +{\color{nixdarkblue}Define conditionals using} if...then...else + \begin{minted}{nix} +if x > 0 +then 1 +else -1 + \end{minted} +\end{ctexpression} + +\vfill + +\begin{ctexpression}{Attribute Sets} +{\color{nixdarkblue}Update attribute sets using} // + \begin{minted}{nix} +{ x = 1; } // { y = 2; } +# ⇒ returns { x = 1; y = 2;} +{ x = 1; } // { x = 2; } +# ⇒ returns { x = 2; } + \end{minted} + \tcbline +{\color{nixdarkblue}Check if an attribute exists using} ? + \begin{minted}{nix} +let + s = { x = 1; }; +in + s ? x # ⇒ returns true + \end{minted} + \tcbline +{\color{nixdarkblue}Reference attribute keys using} . + \begin{minted}{nix} +let + s = { x = { y = 1; }; }; +in + s.x.y # ⇒ returns 1 + \end{minted} + \tcbline +{\color{nixdarkblue}Reference optional attribute keys using} or + \begin{minted}{nix} +let + s = { x = 1; }; +in + s.y or 2 # ⇒ returns 2 + \end{minted} +\end{ctexpression} + +\vfill + +\begin{ctexpression}{Concatenation \& Interpolation} +{\color{nixdarkblue}Concatenate lists using} ++ + \begin{minted}{nix} +[ 1 2 ] ++ [ 3 4 ] # ⇒ returns [ 1 2 3 4 ] + \end{minted} + \tcbline +{\color{nixdarkblue}Concatenate paths and strings use} + + \begin{minted}{nix} +/bin + /sh # ⇒ returns /bin/sh +/bin + "/sh" # ⇒ returns /bin/sh +"/bin" + "/sh" # ⇒ returns "/bin/sh" + \end{minted} + \tcbline +{\color{nixdarkblue}Interpolate strings using} \$\string{\string} + \begin{minted}{nix} +let + x = "bar"; +in + "foo ${x} baz" # ⇒ returns "foo bar baz" + \end{minted} +\end{ctexpression} + +\begin{ctexpression}{Functions} +{\color{nixdarkblue}Simple function} + \begin{minted}{nix} +let + f = x: x + 1; +in + f 1 # ⇒ returns 2 + \end{minted} + \tcbline +{\color{nixdarkblue}Multiple arguments} + \begin{minted}{nix} +let + f = x: y: [ x y ]; +in + f 1 2 # ⇒ returns [ 1 2 ] + \end{minted} + \tcbline +{\color{nixdarkblue}Named arguments with attribute sets} + \begin{minted}{nix} +let + f = { x, y }: x + y; +in + f { x=1; y=2; } # ⇒ returns 3 + \end{minted} + \tcbline +{\color{nixdarkblue}Named arguments; ignores extras using} ... + \begin{minted}{nix} +let + f = { x, y, ... }: x + y; +in + f { x=1; y=2; z=3; } # ⇒ returns 3 + \end{minted} + \tcbline +{\color{nixdarkblue}Named arguments; default values using} ? + \begin{minted}{nix} +let + f = { x, y ? 2 }: x + y; +in + f { x=1; } # ⇒ returns 3 + \end{minted} + \tcbline +{\color{nixdarkblue}Bind set arguments to a variable using} @ + \begin{minted}{nix} +let + f = { x, y }@args: args.x + args.y; +in + f { x=1; y=2; } # ⇒ returns 3 + \end{minted} +\end{ctexpression} + +\vfill + +{\setlength\parindent{0pt} +\includesvg[width=\columnwidth]{nixos.svg} + +\begin{tightcenter} +{\large Official Nix Language Cheat Sheet} +\end{tightcenter} + +\vfill + +Additional Resources: + +{\small +\href{https://nixos.org/manual/nix/stable/language/builtins}{nixos.org/manual/nix/stable/language/builtins} + +\href{https://nixos.org/manual/nixpkgs/stable/\#id-1.4}{nixos.org/manual/nixpkgs/stable/\#id-1.4} +} + +\vspace{0.2cm} +} + +\end{multicols*} + +\end{document} + diff --git a/cheatsheet/nixos.svg b/cheatsheet/nixos.svg new file mode 100644 index 0000000..5abca43 --- /dev/null +++ b/cheatsheet/nixos.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cheatsheet/paper-a4.tex b/cheatsheet/paper-a4.tex new file mode 100644 index 0000000..675bdfa --- /dev/null +++ b/cheatsheet/paper-a4.tex @@ -0,0 +1 @@ +\usepackage[a4paper, left=1cm, right=1cm, bottom=0.2cm, top=0.2cm]{geometry} diff --git a/cheatsheet/paper-letter.tex b/cheatsheet/paper-letter.tex new file mode 100644 index 0000000..8953f87 --- /dev/null +++ b/cheatsheet/paper-letter.tex @@ -0,0 +1 @@ +\usepackage[letterpaper, left=1cm, right=1cm, bottom=0.2cm, top=0.2cm]{geometry} diff --git a/cheatsheet/unformatted-comments-strings.patch b/cheatsheet/unformatted-comments-strings.patch new file mode 100644 index 0000000..e073620 --- /dev/null +++ b/cheatsheet/unformatted-comments-strings.patch @@ -0,0 +1,25 @@ +diff --git a/pygments/styles/bw.py b/pygments/styles/bw.py +index aadcf5df..eb0856c3 100644 +--- a/pygments/styles/bw.py ++++ b/pygments/styles/bw.py +@@ -22,9 +22,6 @@ class BlackWhiteStyle(Style): + background_color = "#ffffff" + + styles = { +- Comment: "italic", +- Comment.Preproc: "noitalic", +- + Keyword: "bold", + Keyword.Pseudo: "nobold", + Keyword.Type: "nobold", +@@ -37,10 +34,6 @@ class BlackWhiteStyle(Style): + Name.Entity: "bold", + Name.Tag: "bold", + +- String: "italic", +- String.Interpol: "bold", +- String.Escape: "bold", +- + Generic.Heading: "bold", + Generic.Subheading: "bold", + Generic.Emph: "italic", diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1aa6da9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1715037484, + "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e94b252 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "NixOS Marketing Team"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = + { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + cheatsheets = builtins.removeAttrs (pkgs.callPackage ./cheatsheet { }) [ + "override" + "overrideDerivation" + ]; + in + { + packages = { } // cheatsheets; + } + ); +}