grace/typst_web_magic

git clone https://git.gae.moe/grace/typst_web_magic

Grace Yoderadded template, readme, and minor changes5b6c1ba

main
4.1 KiB130 linesraw
1{ pkgs ? import <nixpkgs> { } }:
2
3let
4  inherit (pkgs) lib;
5
6  package = pkgs.runCommand "typst_web_magic-0.1.0" { } ''
7    destination="$out/share/typst/packages/local/typst_web_magic/0.1.0"
8    mkdir -p "$destination"
9    cp ${./lib.typ} "$destination/lib.typ"
10    cp ${./pdf.typ} "$destination/pdf.typ"
11    cp ${./metadata.typ} "$destination/metadata.typ"
12    cp ${./blog.typ} "$destination/blog.typ"
13    cp ${./default.css} "$destination/default.css"
14    cp -r ${./color} "$destination/color"
15    cp ${./typst.toml} "$destination/typst.toml"
16  '';
17
18  files = directory:
19    let entries = builtins.readDir directory;
20    in lib.concatMap (name:
21      if entries.${name} == "directory" then
22        map (child: "${name}/${child}") (files (directory + "/${name}"))
23      else lib.optional (entries.${name} == "regular") name
24    ) (builtins.attrNames entries);
25
26  content = src:
27    let
28      pages = builtins.filter (lib.hasSuffix ".typ") (files (src + "/src"));
29      assets = directory: prefix:
30        if builtins.pathExists (src + "/${directory}") then
31          map (file: ''
32            (path: ${builtins.toJSON (prefix + file)}, source: path(${builtins.toJSON "/${directory}/${file}"})),
33          '') (files (src + "/${directory}"))
34        else [];
35    in pkgs.writeText "content.typ" ''
36      #let pages = (
37      ${lib.concatMapStrings (file: ''
38        (path: ${builtins.toJSON (lib.removeSuffix ".typ" file + ".html")}, entry: {
39          import ${builtins.toJSON "/src/${file}"} as source
40          source.entry
41        }, body: include ${builtins.toJSON "/src/${file}"}),
42      '') pages}
43      )
44      #let assets = (
45      ${lib.concatStrings (assets "assets" "assets/" ++ assets "public" "")}
46      )
47    '';
48
49  clean = src: lib.cleanSourceWith {
50    src = lib.cleanSource src;
51    filter = path: type:
52      let name = baseNameOf path;
53      in !(builtins.elem name [ "site" ".generated" ".jj" "__pycache__" ])
54        && !(lib.hasPrefix "result" name);
55  };
56
57  environment = fonts: {
58    nativeBuildInputs = [ pkgs.typst ];
59    TYPST_PACKAGE_PATH = "${package}/share/typst/packages";
60    TYPST_FONT_PATHS = lib.makeSearchPath "share/fonts" ([ pkgs.montserrat pkgs.fira-math ] ++ fonts);
61  };
62
63  mkSite = { src, name ? "website", fonts ? [] }:
64    let
65      source = clean src;
66      prepare = ''
67        mkdir -p .generated
68        cp -f ${content (toString source)} .generated/content.typ
69      '';
70    in pkgs.stdenvNoCC.mkDerivation ((environment fonts) // {
71      pname = name;
72      version = "0.1.0";
73      src = source;
74      shellHook = prepare;
75      passthru.shell = pkgs.mkShell ((environment fonts) // {
76        packages = [ pkgs.tinymist ];
77        shellHook = prepare;
78      });
79      buildPhase = ''
80        runHook preBuild
81        ${prepare}
82        typst compile --format bundle --features bundle,html site.typ site
83        runHook postBuild
84      '';
85      installPhase = ''
86        runHook preInstall
87        mkdir -p "$out"
88        cp -r site/. "$out/"
89        runHook postInstall
90      '';
91    });
92
93  mkPdf = { src, name ? "document", main ? "main.typ", fonts ? [] }:
94    pkgs.stdenvNoCC.mkDerivation ((environment fonts) // {
95      pname = name;
96      version = "0.1.0";
97      src = clean src;
98      passthru.shell = pkgs.mkShell ((environment fonts) // {
99        packages = [ pkgs.tinymist ];
100      });
101      buildPhase = ''
102        runHook preBuild
103        typst compile --root . ${lib.escapeShellArg main} document.pdf
104        runHook postBuild
105      '';
106      installPhase = ''
107        runHook preInstall
108        mkdir -p "$out"
109        cp document.pdf "$out/"${lib.escapeShellArg (name + ".pdf")}
110        runHook postInstall
111      '';
112    });
113in {
114  inherit package mkSite mkPdf;
115  init = pkgs.writeShellApplication {
116    name = "typst-web-init";
117    runtimeInputs = [ pkgs.coreutils ];
118    text = ''
119      if [ "$#" -ne 1 ]; then
120        echo "Usage: typst-web-init DIRECTORY" >&2
121        exit 1
122      fi
123
124      destination="$1"
125      mkdir -- "$destination"
126      cp -R --no-preserve=mode ${./template}/. "$destination/"
127      echo "Created $destination. Edit site.typ, then run nix-build inside it."
128    '';
129  };
130}