Compare commits
15 Commits
31052a65c8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7aaec7388d | |||
| 7e6fb22d03 | |||
| ac1c0eacd9 | |||
| e0ceefa399 | |||
| a9d105b639 | |||
| 1c31f4064a | |||
| 4e343fde99 | |||
| d967188e18 | |||
| 694136b643 | |||
| 32a45b3a16 | |||
| 5472d93cff | |||
| 32dad302f0 | |||
| 7fbc5c8059 | |||
| 55dd22f220 | |||
| dcaac98252 |
17
default.nix
17
default.nix
@@ -33,8 +33,8 @@ let
|
|||||||
];
|
];
|
||||||
|
|
||||||
doerg-config = writeText "doerg-extra-config.edn" ''
|
doerg-config = writeText "doerg-extra-config.edn" ''
|
||||||
#:net.deertopia.doerg
|
#:net.deertopia.doerg.config
|
||||||
{:ibm-plex-web "${ibm-plex-web}"
|
{:ibm-plex-web "${ibm-plex-web}/share/ibm-plex-web"
|
||||||
:latex "${lib.getExe' our-tex "xelatex"}"
|
:latex "${lib.getExe' our-tex "xelatex"}"
|
||||||
:dvisvgm "${lib.getExe' our-tex "dvisvgm"}"
|
:dvisvgm "${lib.getExe' our-tex "dvisvgm"}"
|
||||||
:doerg-temml-worker "${lib.getExe doerg-temml-worker}"
|
:doerg-temml-worker "${lib.getExe doerg-temml-worker}"
|
||||||
@@ -43,15 +43,21 @@ let
|
|||||||
in mkCljBin' {
|
in mkCljBin' {
|
||||||
name = "net.deertopia/doerg";
|
name = "net.deertopia/doerg";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
projectSrc = lib.cleanSource ./.;
|
projectSrc = lib.cleanSourceWith {
|
||||||
|
filter = path: type:
|
||||||
|
lib.sources.cleanSourceFilter path type
|
||||||
|
|| lib.hasSuffix ".nix" path;
|
||||||
|
src = ./.;
|
||||||
|
};
|
||||||
lockfile = ./deps-lock.json;
|
lockfile = ./deps-lock.json;
|
||||||
main-ns = "net.deertopia.doerg.main";
|
main-ns = "net.deertopia.doerg.main";
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
plex
|
plex
|
||||||
makeWrapper
|
makeWrapper
|
||||||
];
|
];
|
||||||
buildInputs = [
|
propagatedBuildInputs = [
|
||||||
doerg-parser
|
doerg-parser
|
||||||
|
ibm-plex-web
|
||||||
doerg-temml-worker
|
doerg-temml-worker
|
||||||
plex
|
plex
|
||||||
our-tex
|
our-tex
|
||||||
@@ -73,5 +79,6 @@ in mkCljBin' {
|
|||||||
XDG_STATE_HOME=$(mktemp -d "state-home-XXXXXX")
|
XDG_STATE_HOME=$(mktemp -d "state-home-XXXXXX")
|
||||||
clojure -M:test
|
clojure -M:test
|
||||||
'';
|
'';
|
||||||
passthru = { inherit plex our-tex test-emacs; };
|
passthru = { inherit plex our-tex test-emacs doerg-config; };
|
||||||
|
meta.mainProgram = "doerg";
|
||||||
}
|
}
|
||||||
|
|||||||
17
dev/user.clj
Normal file
17
dev/user.clj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
(ns user
|
||||||
|
(:require [net.deertopia.doerg.server :as server]
|
||||||
|
[net.deertopia.doerg.config :as cfg]
|
||||||
|
[net.deertopia.doerg.cached-file :as cached-file]
|
||||||
|
[babashka.fs :as fs]))
|
||||||
|
|
||||||
|
(cfg/load-config! :profile :dev)
|
||||||
|
|
||||||
|
(when (not= :running (server/status))
|
||||||
|
(server/start!))
|
||||||
|
|
||||||
|
(defn invalidate-html-cache! []
|
||||||
|
(fs/delete-tree (server/html-dir))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defn toggle-html-cache! []
|
||||||
|
(alter-var-root #'cached-file/*use-cache?* not))
|
||||||
27
flake.nix
27
flake.nix
@@ -14,12 +14,15 @@
|
|||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
];
|
];
|
||||||
|
|
||||||
each-system = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec {
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [
|
overlays = [
|
||||||
inputs.sydpkgs.overlays.default
|
inputs.sydpkgs.overlays.default
|
||||||
clj-nix.overlays.default
|
clj-nix.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
each-system = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec {
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = overlays ++ [
|
||||||
self.overlays.default
|
self.overlays.default
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -36,13 +39,17 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
overlays.default = final: prev:
|
overlays.default = final: prev:
|
||||||
let graal = x: final.mkGraalBin { cljDrv = x; };
|
let
|
||||||
|
# is this really the correct way to satisfy our
|
||||||
|
# dependencies? lmfao
|
||||||
|
final' = final.appendOverlays overlays;
|
||||||
|
graal = x: final'.mkGraalBin { cljDrv = x; };
|
||||||
in {
|
in {
|
||||||
ibm-plex-web = final.callPackage ./ibm-plex-web.nix {};
|
ibm-plex-web = final'.callPackage ./ibm-plex-web.nix {};
|
||||||
doerg = final.callPackage ./. {};
|
doerg = final'.callPackage ./. {};
|
||||||
doerg-parser = final.callPackage ./doerg-parser {};
|
doerg-parser = final'.callPackage ./doerg-parser {};
|
||||||
doerg-temml-worker = final.callPackage ./doerg-temml-worker {};
|
doerg-temml-worker = final'.callPackage ./doerg-temml-worker {};
|
||||||
our-tex = final.callPackage ./our-tex.nix {};
|
our-tex = final'.callPackage ./our-tex.nix {};
|
||||||
};
|
};
|
||||||
|
|
||||||
checks = each-system ({ pkgs, system, ... }: {
|
checks = each-system ({ pkgs, system, ... }: {
|
||||||
@@ -52,6 +59,8 @@
|
|||||||
(pkgs.lib.attrValues self.packages.${system});
|
(pkgs.lib.attrValues self.packages.${system});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nixosModules.default = import ./module.nix { inherit self; };
|
||||||
|
|
||||||
devShells = each-system ({ pkgs, system, ... }: {
|
devShells = each-system ({ pkgs, system, ... }: {
|
||||||
default = pkgs.mkShell {
|
default = pkgs.mkShell {
|
||||||
inputsFrom = [
|
inputsFrom = [
|
||||||
|
|||||||
107
module.nix
Normal file
107
module.nix
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
{ self, ... }:
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.doerg;
|
||||||
|
doerg-config = pkgs.writeText "doerg-config.edn" ''
|
||||||
|
#:net.deertopia.doerg.config
|
||||||
|
{:org-roam-db-path "${cfg.databasePath}"
|
||||||
|
:state-directory "${cfg.stateDir}"
|
||||||
|
:port ${builtins.toString cfg.port}}
|
||||||
|
'';
|
||||||
|
|
||||||
|
inherit (lib) types;
|
||||||
|
|
||||||
|
org-roam-db-sync = pkgs.writeText "org-roam-db-sync.el" ''
|
||||||
|
#!/usr/bin/env -S emacs -Q -x
|
||||||
|
|
||||||
|
(require 'org-roam)
|
||||||
|
|
||||||
|
(setq org-roam-directory (expand-file-name (car command-line-args-left)))
|
||||||
|
(setq org-roam-db-location (expand-file-name (cadr command-line-args-left)))
|
||||||
|
|
||||||
|
(org-roam-db-sync)
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
options.services.doerg = {
|
||||||
|
enable = lib.mkEnableOption "Doerg";
|
||||||
|
org-roam-db-sync.enable = lib.mkEnableOption "Org-roam db sync";
|
||||||
|
port = lib.mkOption {
|
||||||
|
default = 21984;
|
||||||
|
type = lib.types.port;
|
||||||
|
description = ''
|
||||||
|
The port on which Doerg will listen.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
stateDir = lib.mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/private/doerg";
|
||||||
|
description = "Daemon's state directory.";
|
||||||
|
};
|
||||||
|
orgDir = lib.mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Org roam directory.";
|
||||||
|
};
|
||||||
|
package = lib.mkPackageOption pkgs "doerg" {};
|
||||||
|
databasePath = lib.mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Org roam database path";
|
||||||
|
default = cfg.orgDir + "org-roam.db";
|
||||||
|
};
|
||||||
|
openFirewall = lib.mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Open doerg ports?";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
nixpkgs.overlays = [ self.overlays.default ];
|
||||||
|
|
||||||
|
systemd.services.org-roam-db-sync = lib.mkIf cfg.org-roam-db-sync.enable {
|
||||||
|
script = lib.escapeShellArgs [
|
||||||
|
(lib.getExe cfg.package.test-emacs)
|
||||||
|
"-Q" "-x" org-roam-db-sync cfg.orgDir cfg.databasePath
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ReadOnlyBindPaths = [
|
||||||
|
cfg.orgDir
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.org-roam-db-sync = lib.mkIf cfg.org-roam-db-sync.enable {
|
||||||
|
unitConfig.StopWhenUnneeded = true;
|
||||||
|
timerConfig = {
|
||||||
|
OnActiveSec = "1h";
|
||||||
|
RandomizedDelaySec = "30m";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
|
||||||
|
cfg.port
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.doerg = {
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" "org-roam-db-sync.timer" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment.DOERG_CONFIG = doerg-config;
|
||||||
|
serviceConfig = {
|
||||||
|
# WorkingDirectory = cfg.stateDir;
|
||||||
|
StateDirectory = "doerg";
|
||||||
|
ExecStart = lib.getExe cfg.package;
|
||||||
|
DynamicUser = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
PrivateTmp = true;
|
||||||
|
BindReadOnlyPaths = [
|
||||||
|
cfg.orgDir
|
||||||
|
# cfg.databasePath
|
||||||
|
"/nix"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#:net.deertopia.doerg.config
|
#:net.deertopia.doerg.config
|
||||||
{:ibm-plex-web #or [#xdg-data-dir "ibm-plex-web"
|
{:ibm-plex-web #or [#env IBM_PLEX_WEB
|
||||||
#env IBM_PLEX_WEB]
|
#xdg-data-dir "ibm-plex-web"]
|
||||||
:latex "xelatex"
|
:latex "xelatex"
|
||||||
:dvisvgm "dvisvgm"
|
:dvisvgm "dvisvgm"
|
||||||
:doerg-temml-worker
|
:doerg-temml-worker
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
calling `compute` with no arguments only if stale? is logical true."
|
calling `compute` with no arguments only if stale? is logical true."
|
||||||
[& {:keys [file stale? compute]}]
|
[& {:keys [file stale? compute]}]
|
||||||
(when (or (not *use-cache?*) stale?)
|
(when (or (not *use-cache?*) stale?)
|
||||||
(let [r (compute)]
|
(let [r (compute)
|
||||||
|
dir (fs/parent file)]
|
||||||
(assert (string? r))
|
(assert (string? r))
|
||||||
(fs/create-dirs (fs/parent file))
|
(when-not (fs/exists? dir)
|
||||||
|
(fs/create-dirs dir))
|
||||||
(spit file r)))
|
(spit file r)))
|
||||||
file)
|
file)
|
||||||
|
|||||||
@@ -46,7 +46,8 @@
|
|||||||
"Aero tag to search for a directory on $XDG_DATA_DIRS."
|
"Aero tag to search for a directory on $XDG_DATA_DIRS."
|
||||||
(some #(let [x (fs/path % value)]
|
(some #(let [x (fs/path % value)]
|
||||||
(and (fs/exists? x) x))
|
(and (fs/exists? x) x))
|
||||||
(fs/split-paths (System/getenv "XDG_DATA_DIRS"))))
|
(some-> (System/getenv "XDG_DATA_DIRS")
|
||||||
|
fs/split-paths)))
|
||||||
|
|
||||||
(defmethod aero/reader 'file
|
(defmethod aero/reader 'file
|
||||||
[{:keys [source]} tag value]
|
[{:keys [source]} tag value]
|
||||||
@@ -66,9 +67,6 @@
|
|||||||
(throw (ex-info "Failed to conform config"
|
(throw (ex-info "Failed to conform config"
|
||||||
(s/explain-data ::config r))))))
|
(s/explain-data ::config r))))))
|
||||||
|
|
||||||
(defn load-config! [var spec files & {:as opts}]
|
|
||||||
(alter-var-root var (constantly (read-config files opts))))
|
|
||||||
|
|
||||||
(def sources
|
(def sources
|
||||||
[;; Default config.
|
[;; Default config.
|
||||||
(io/resource "net/deertopia/doerg/default-config.edn")
|
(io/resource "net/deertopia/doerg/default-config.edn")
|
||||||
@@ -80,3 +78,10 @@
|
|||||||
(def default (read-config sources))
|
(def default (read-config sources))
|
||||||
|
|
||||||
(def ^:dynamic *cfg* default)
|
(def ^:dynamic *cfg* default)
|
||||||
|
|
||||||
|
(defn load-config!
|
||||||
|
([& {:as opts :keys [files]
|
||||||
|
:or {files sources}}]
|
||||||
|
(let [passthru-opts (-> opts (dissoc :files))]
|
||||||
|
(alter-var-root
|
||||||
|
#'*cfg* (constantly (read-config files passthru-opts))))))
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
[babashka.process :as p]
|
[babashka.process :as p]
|
||||||
[cheshire.core :as json]
|
[cheshire.core :as json]
|
||||||
[clojure.core.match :refer [match]]
|
[clojure.core.match :refer [match]]
|
||||||
[net.deertopia.doerg :as-alias doerg]
|
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
@@ -35,7 +34,7 @@
|
|||||||
:or {in *in*}}]
|
:or {in *in*}}]
|
||||||
(let [r (-> (p/process
|
(let [r (-> (p/process
|
||||||
{:in in :out :string}
|
{:in in :out :string}
|
||||||
(-> cfg/*cfg* ::doerg/doerg-parser str))
|
(-> cfg/*cfg* ::cfg/doerg-parser str))
|
||||||
(common/deref-with-timeout *uniorg-timeout-duration*))]
|
(common/deref-with-timeout *uniorg-timeout-duration*))]
|
||||||
(when (zero? (:exit r))
|
(when (zero? (:exit r))
|
||||||
(-> r :out (json/parse-string (comp keyword camel->kebab))))))
|
(-> r :out (json/parse-string (comp keyword camel->kebab))))))
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
(ns net.deertopia.doerg.main
|
(ns net.deertopia.doerg.main
|
||||||
|
(:require [net.deertopia.doerg.server :as server]
|
||||||
|
[net.deertopia.doerg.config :as cfg])
|
||||||
(:gen-class))
|
(:gen-class))
|
||||||
|
|
||||||
(defn -main []
|
(defn -main [& _]
|
||||||
(println "hello from doerg"))
|
(binding [cfg/*cfg* (cfg/read-config cfg/sources)]
|
||||||
|
(server/start!)))
|
||||||
|
|||||||
@@ -63,16 +63,19 @@
|
|||||||
|
|
||||||
(defn org-document
|
(defn org-document
|
||||||
"Recursively render an Org-mode document to Hiccup."
|
"Recursively render an Org-mode document to Hiccup."
|
||||||
[doc & {:as opts :keys [postamble]}]
|
[doc & {:as opts :keys [postamble header title]}]
|
||||||
(binding [*opts* opts]
|
(binding [*opts* opts]
|
||||||
(tex-temml/binding-worker
|
(tex-temml/binding-worker
|
||||||
(let [rendered (-> doc gather-footnotes render-tex-snippets
|
(let [rendered (-> doc gather-footnotes render-tex-snippets
|
||||||
org-element-recursive)]
|
org-element-recursive)]
|
||||||
[:html
|
[:html
|
||||||
[:head
|
[:head
|
||||||
[:title "org document"]
|
(when title
|
||||||
|
[:title title])
|
||||||
doerg-html/head]
|
doerg-html/head]
|
||||||
[:body {:lang default-language}
|
[:body {:lang default-language}
|
||||||
|
(when header
|
||||||
|
[:header header])
|
||||||
[:article
|
[:article
|
||||||
rendered
|
rendered
|
||||||
(when postamble
|
(when postamble
|
||||||
@@ -273,11 +276,14 @@
|
|||||||
(defmethod org-element "bold" [{:keys [children]}]
|
(defmethod org-element "bold" [{:keys [children]}]
|
||||||
[:b children])
|
[:b children])
|
||||||
|
|
||||||
|
(defmethod org-element "strike-through" [{:keys [children]}]
|
||||||
|
[:s children])
|
||||||
|
|
||||||
(defmethod org-element "subscript" [{:keys [children]}]
|
(defmethod org-element "subscript" [{:keys [children]}]
|
||||||
[:sub children])
|
[:sub children])
|
||||||
|
|
||||||
(defmethod org-element "superscript" [{:keys [children]}]
|
(defmethod org-element "superscript" [{:keys [children]}]
|
||||||
[:super children])
|
[:sup children])
|
||||||
|
|
||||||
(defmethod org-element "italic" [{:keys [children]}]
|
(defmethod org-element "italic" [{:keys [children]}]
|
||||||
[:em children])
|
[:em children])
|
||||||
@@ -382,9 +388,18 @@
|
|||||||
(defmethod org-keyword "TITLE" [{:keys [value]}]
|
(defmethod org-keyword "TITLE" [{:keys [value]}]
|
||||||
[:h1 value])
|
[:h1 value])
|
||||||
|
|
||||||
|
(defmethod org-keyword "SUBTITLE" [{:keys [value]}]
|
||||||
|
[:p.subtitle value])
|
||||||
|
|
||||||
(defmethod org-keyword "LATEX_COMPILER" [_] nil)
|
(defmethod org-keyword "LATEX_COMPILER" [_] nil)
|
||||||
(defmethod org-keyword "LATEX_HEADER" [_] nil)
|
(defmethod org-keyword "LATEX_HEADER" [_] nil)
|
||||||
|
|
||||||
|
;; TODO: A bunch of things I'd rather hide for now, but should be
|
||||||
|
;; implemented eventually.
|
||||||
|
(defmethod org-keyword "FILETAGS" [_] nil)
|
||||||
|
(defmethod org-element "planning" [_] nil)
|
||||||
|
(defmethod org-element "timestamp" [_] nil)
|
||||||
|
|
||||||
;; Not sure how to deal with this one yet.
|
;; Not sure how to deal with this one yet.
|
||||||
(defmethod org-keyword "AUTHOR" [_] nil)
|
(defmethod org-keyword "AUTHOR" [_] nil)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
(fs/create-dirs dest)
|
(fs/create-dirs dest)
|
||||||
(fs/create-dirs resource-dir)
|
(fs/create-dirs resource-dir)
|
||||||
(force-create-sym-link (fs/file resource-dir "ibm-plex-web")
|
(force-create-sym-link (fs/file resource-dir "ibm-plex-web")
|
||||||
(-> cfg/*cfg* ::doerg/ibm-plex-web))
|
(-> cfg/*cfg* ::cfg/ibm-plex-web))
|
||||||
(doseq [x #{"Temml-Plex.css" "tuftesque.css" "deerstar.css"}]
|
(doseq [x #{"Temml-Plex.css" "tuftesque.css" "deerstar.css"}]
|
||||||
(force-create-sym-link
|
(force-create-sym-link
|
||||||
(fs/file resource-dir x)
|
(fs/file resource-dir x)
|
||||||
|
|||||||
@@ -133,11 +133,15 @@
|
|||||||
elisp/read-alist)))
|
elisp/read-alist)))
|
||||||
|
|
||||||
(defn public? [node]
|
(defn public? [node]
|
||||||
(-> node properties (get "DEERTOPIAVISIBILITY") (= "public")))
|
(some-> (properties node) (get "DEERTOPIAVISIBILITY") (= "public")))
|
||||||
|
|
||||||
|
(defn get-public-node [node]
|
||||||
|
(when-let [n (get-node node)]
|
||||||
|
(when (public? n) n)))
|
||||||
|
|
||||||
(defn graph-visible? [node]
|
(defn graph-visible? [node]
|
||||||
(#{"public" "graphonly"}
|
(#{"public" "graphonly"}
|
||||||
(-> node properties (get "DEERTOPIAVISIBILITY"))))
|
(some-> (properties node) (get "DEERTOPIAVISIBILITY"))))
|
||||||
|
|
||||||
(defn backlinks
|
(defn backlinks
|
||||||
"Returns a collection of nodes linking to `node`."
|
"Returns a collection of nodes linking to `node`."
|
||||||
@@ -149,7 +153,8 @@
|
|||||||
where links.dest = ?"
|
where links.dest = ?"
|
||||||
(elisp/print (str (:id node)))])
|
(elisp/print (str (:id node)))])
|
||||||
:let [id' (elisp/read-string id)]
|
:let [id' (elisp/read-string id)]
|
||||||
:when (-> id' parse-uuid get-node public?)]
|
:when (some-> (-> id' parse-uuid get-node)
|
||||||
|
public?)]
|
||||||
(make-node id' {:title (elisp/read-string title)})))
|
(make-node id' {:title (elisp/read-string title)})))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@
|
|||||||
[net.deertopia.doerg.cached-file :as cached-file]
|
[net.deertopia.doerg.cached-file :as cached-file]
|
||||||
[babashka.fs :as fs]
|
[babashka.fs :as fs]
|
||||||
[aero.core :as aero]
|
[aero.core :as aero]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]))
|
||||||
[net.deertopia.doerg :as-alias doerg]
|
|
||||||
[net.deertopia.doerg.config :as doerg-config]))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Routes
|
;;; Routes
|
||||||
@@ -51,8 +49,13 @@
|
|||||||
(defn html-dir []
|
(defn html-dir []
|
||||||
(-> cfg/*cfg* ::cfg/state-directory (fs/file "html")))
|
(-> cfg/*cfg* ::cfg/state-directory (fs/file "html")))
|
||||||
|
|
||||||
(defn not-found [req]
|
(declare node-by-slug)
|
||||||
(response/not-found "not found"))
|
|
||||||
|
;; This could infinitely loop if the 404 page can't be found. lmfao.
|
||||||
|
(defn not-found [_req]
|
||||||
|
(-> (node-by-slug {:path-params {:slug not-found-slug}})
|
||||||
|
(assoc :status 404))
|
||||||
|
#_(response/not-found "not found"))
|
||||||
|
|
||||||
(defn org-file->html-file [org-file]
|
(defn org-file->html-file [org-file]
|
||||||
(fs/file (html-dir)
|
(fs/file (html-dir)
|
||||||
@@ -73,17 +76,34 @@
|
|||||||
#_[:a {:href (str "/n/" (slug/from-uuid path))}
|
#_[:a {:href (str "/n/" (slug/from-uuid path))}
|
||||||
(or (seq children) raw-link)]])
|
(or (seq children) raw-link)]])
|
||||||
|
|
||||||
|
(def navbar
|
||||||
|
"Hiccup element for Deertopia.net's navbar."
|
||||||
|
[:nav.navbar
|
||||||
|
[:ol.navbar-list
|
||||||
|
[:li
|
||||||
|
[:a.home-link {:href "/"}
|
||||||
|
"🦌 deertopia.net"]]
|
||||||
|
#_[:li
|
||||||
|
[:a.home-link {:href "/graph"}
|
||||||
|
"graph"]]
|
||||||
|
#_
|
||||||
|
[:li
|
||||||
|
[:a.home-link {:onclick "alert('unimplemented }:(')"}
|
||||||
|
"search"]]]])
|
||||||
|
|
||||||
(defn backlinks-postamble [node]
|
(defn backlinks-postamble [node]
|
||||||
|
(let [backlinks (roam/backlinks node)]
|
||||||
|
(when-not (empty? backlinks)
|
||||||
[:section#backlinks
|
[:section#backlinks
|
||||||
[:h2 "Backlinks"]
|
[:h2 "Backlinks"]
|
||||||
[:ul
|
[:ul
|
||||||
(for [n (->> (roam/backlinks node)
|
(for [n (->> backlinks
|
||||||
(sort-by (comp str/lower-case roam/title)))]
|
(sort-by (comp str/lower-case roam/title)))]
|
||||||
[:li (slug-link (roam/slug n)
|
[:li (slug-link (roam/slug n)
|
||||||
(roam/title n))])]])
|
(roam/title n))])]])))
|
||||||
|
|
||||||
(defn node-by-slug [{{:keys [slug]} :path-params :as req}]
|
(defn node-by-slug [{{:keys [slug]} :path-params :as req}]
|
||||||
(if-some [node (some-> slug slug/from-string roam/get-node)]
|
(if-some [node (some-> slug slug/from-string roam/get-public-node)]
|
||||||
(let [org-file (roam/org-file node)
|
(let [org-file (roam/org-file node)
|
||||||
html-file (org-file->html-file org-file)]
|
html-file (org-file->html-file org-file)]
|
||||||
(cached-file/cached-file
|
(cached-file/cached-file
|
||||||
@@ -91,7 +111,9 @@
|
|||||||
:stale? (cached-file/newer-than? org-file html-file)
|
:stale? (cached-file/newer-than? org-file html-file)
|
||||||
:compute #(doerg-render/to-html
|
:compute #(doerg-render/to-html
|
||||||
org-file
|
org-file
|
||||||
:postamble (backlinks-postamble node)))
|
:postamble (backlinks-postamble node)
|
||||||
|
:header navbar
|
||||||
|
:title (roam/title node)))
|
||||||
(-> (str html-file)
|
(-> (str html-file)
|
||||||
response/file-response
|
response/file-response
|
||||||
(response/content-type "text/html")))
|
(response/content-type "text/html")))
|
||||||
@@ -118,7 +140,7 @@
|
|||||||
(if-some [[_ resource] (re-matches #"^/resource/ibm-plex-web/(.*)" uri)]
|
(if-some [[_ resource] (re-matches #"^/resource/ibm-plex-web/(.*)" uri)]
|
||||||
(-> resource
|
(-> resource
|
||||||
(response/file-response
|
(response/file-response
|
||||||
{:root (-> doerg-config/*cfg* ::doerg/ibm-plex-web str)}))
|
{:root (-> cfg/*cfg* ::cfg/ibm-plex-web str)}))
|
||||||
(-> uri
|
(-> uri
|
||||||
(str/replace-first #"^/resource/" "")
|
(str/replace-first #"^/resource/" "")
|
||||||
(response/resource-response
|
(response/resource-response
|
||||||
|
|||||||
@@ -83,14 +83,14 @@
|
|||||||
acc))))
|
acc))))
|
||||||
|
|
||||||
(defn- invoke-latex [& {:keys [file output-dir]}]
|
(defn- invoke-latex [& {:keys [file output-dir]}]
|
||||||
(let [latex (-> cfg/*cfg* ::doerg/latex)]
|
(let [latex (-> cfg/*cfg* ::cfg/latex)]
|
||||||
(invoke
|
(invoke
|
||||||
{:dir output-dir}
|
{:dir output-dir}
|
||||||
latex "-no-pdf" "-interaction" "nonstopmode"
|
latex "-no-pdf" "-interaction" "nonstopmode"
|
||||||
"-output-directory" output-dir file)))
|
"-output-directory" output-dir file)))
|
||||||
|
|
||||||
(defn- invoke-dvisvgm [& {:keys [file output-dir]}]
|
(defn- invoke-dvisvgm [& {:keys [file output-dir]}]
|
||||||
(let [dvisvgm (-> cfg/*cfg* ::doerg/dvisvgm)]
|
(let [dvisvgm (-> cfg/*cfg* ::cfg/dvisvgm)]
|
||||||
(invoke
|
(invoke
|
||||||
{:dir output-dir}
|
{:dir output-dir}
|
||||||
dvisvgm "--page=1-" "--optimize" "--clipjoin"
|
dvisvgm "--page=1-" "--optimize" "--clipjoin"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
fs/file))
|
fs/file))
|
||||||
|
|
||||||
(defn worker []
|
(defn worker []
|
||||||
(let [doerg-temml-worker (-> cfg/*cfg* ::doerg/doerg-temml-worker)]
|
(let [doerg-temml-worker (-> cfg/*cfg* ::cfg/doerg-temml-worker)]
|
||||||
(when (or (not (fs/exists? prelude-file))
|
(when (or (not (fs/exists? prelude-file))
|
||||||
(zero? (fs/size prelude-file)))
|
(zero? (fs/size prelude-file)))
|
||||||
(-> "net/deertopia/doerg/prelude.tex"
|
(-> "net/deertopia/doerg/prelude.tex"
|
||||||
|
|||||||
Reference in New Issue
Block a user