Compare commits

...

2 Commits

Author SHA1 Message Date
9a48e5b5e6 feat: publisher에서 configuration을 씀
Some checks failed
build / build (push) Failing after 1m18s
2026-03-22 16:10:33 -06:00
4c32397a48 feat: doerg에서 configuration을 씀 2026-03-22 14:31:50 -06:00
14 changed files with 116 additions and 69 deletions

View File

@@ -10,7 +10,8 @@
lambdaisland/deep-diff2 {:mvn/version "2.12.219"} lambdaisland/deep-diff2 {:mvn/version "2.12.219"}
mvxcvi/clj-cbor {:mvn/version "1.1.1"} mvxcvi/clj-cbor {:mvn/version "1.1.1"}
ch.qos.logback/logback-classic {:mvn/version "1.1.3"} ch.qos.logback/logback-classic {:mvn/version "1.1.3"}
org.clojure/test.check {:mvn/version "1.1.3"}} org.clojure/test.check {:mvn/version "1.1.3"}
aero/aero {:mvn/version "1.1.6"}}
:paths ["src" "resources" "test"] :paths ["src" "resources" "test"]
:aliases :aliases
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}} {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}

View File

@@ -0,0 +1,13 @@
#:net.deertopia.doerg
{:ibm-plex-web #or [#xdg-data-dir "ibm-plex-web"
#env IBM_PLEX_WEB]
:latex "xelatex"
:dvisvgm "dvisvgm"
:doerg-temml-worker
#profile {:dev-publisher "../doerg/doerg-temml-worker/index.js"
:dev-doerg "./doerg-temml-worker/index.js"
:default "doerg-temml-worker"}
:doerg-parser
#profile {:dev-publisher "../doerg/doerg-parser/index.js"
:dev-doerg "./doerg-parser/index.js"
:default "doerg-parser"}}

View File

@@ -1,42 +1,62 @@
(ns net.deertopia.doerg.config (ns net.deertopia.doerg.config
(:require [clojure.spec.alpha :as s] (:require [clojure.spec.alpha :as s]
[babashka.fs :as fs] [babashka.fs :as fs]
[spec-dict.main :refer [dict]])) [spec-dict.main :refer [dict]]
[aero.core :as aero]
[net.deertopia.doerg :as-alias d]
[clojure.java.io :as io]))
(s/def ::config (s/def ::d/config
(s/keys :req [::ibm-plex-web (s/keys :req [::d/ibm-plex-web
::latex ::d/latex
::dvisvgm ::d/dvisvgm
::doerg-temml-worker ::d/doerg-temml-worker
::doerg-parser])) ::d/doerg-parser]))
(s/def ::file (s/def ::d/directory
(s/conformer (comp fs/file fs/absolutize fs/expand-home))) (s/conformer #(if-some [x (fs/file %)]
(if (fs/directory? x) x ::s/invalid)
::s/invalid)))
(s/def ::executable #(or (fs/executable? %) (s/def ::d/file
(and (fs/relative? %) (s/conformer #(or (-> % fs/expand-home fs/file)
(fs/which %)))) ::s/invalid)))
(s/def ::d/executable
(s/conformer
#(or (some-> (fs/which %) fs/file)
::s/invalid)))
(s/def ::d/ibm-plex-web ::d/directory)
(s/def ::d/latex ::d/executable)
(s/def ::d/dvisvgm ::d/executable)
(s/def ::d/doerg-temml-worker ::d/executable)
(s/def ::d/doerg-parser ::d/executable)
(defmethod aero/reader 'xdg-data-dir
[_opts tag value]
"Aero tag to search for a directory on $XDG_DATA_DIRS."
(some #(let [x (fs/path % value)]
(and (fs/exists? x) x))
(fs/split-paths (System/getenv "XDG_DATA_DIRS"))))
(defn read-config [& files]
(->> files
(filter identity)
(map aero/read-config)
(apply merge)
(s/conform ::d/config)))
(def default (def default
{::ibm-plex-web (let [r (-> "net/deertopia/doerg/config.edn"
(fs/file (some #(let [x (fs/path % "ibm-plex-web")] io/resource (read-config (System/getenv "DOERG_CONFIG")))]
(and (fs/exists? x) x)) (if (s/invalid? r)
(fs/split-paths (System/getenv "XDG_DATA_DIRS")))) (throw (IllegalArgumentException.
::latex "xelatex" "default config is bad!"))
::dvisvgm "dvisvgm" r)))
;; TODO: Can we automatically set this to "./doerg-temml-worker/index.js" in
;; a development environment?
::doerg-temml-worker "doerg-temml-worker"
::doerg-parser "doerg-parser"})
(def ^:dynamic *cfg* default) (def ^:dynamic *cfg* default)
(s/def ::ibm-plex-web ::file)
(s/def ::latex ::executable)
(s/def ::dvisvgm ::executable)
(s/def ::doerg-temml-worker ::executable)
(s/def ::doerg-parser ::executable)

View File

@@ -4,6 +4,7 @@
[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.spec.alpha :as s] [clojure.spec.alpha :as s]
@@ -36,7 +37,7 @@
:or {in *in*}}] :or {in *in*}}]
(let [r (-> (p/process (let [r (-> (p/process
{:in in :out :string} {:in in :out :string}
(::cfg/doerg-parser cfg/*cfg*)) (-> cfg/*cfg* ::doerg/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))))))

View File

@@ -1,7 +1,6 @@
(ns net.deertopia.doerg.html (ns net.deertopia.doerg.html
"Common HTML elements and utilities" "Common HTML elements and utilities"
(:require [clojure.java.io :as io] (:require [clojure.java.io :as io]
[net.deertopia.doerg.config :as cfg]
[babashka.fs :as fs])) [babashka.fs :as fs]))
#_ #_

View File

@@ -5,7 +5,8 @@
[clojure.java.io :as io] [clojure.java.io :as io]
[hiccup2.core :as h] [hiccup2.core :as h]
[clojure.pprint] [clojure.pprint]
[babashka.fs :as fs])) [babashka.fs :as fs]
[net.deertopia.doerg :as-alias doerg]))
(def some-org-file (def some-org-file
#_ #_
@@ -27,19 +28,12 @@
(fs/delete-if-exists path) (fs/delete-if-exists path)
(fs/create-sym-link path target)) (fs/create-sym-link path target))
(defn reconfigure-doerg! []
(alter-var-root
#'cfg/*cfg*
#(assoc %
::cfg/doerg-temml-worker "./doerg-temml-worker/index.js"
::cfg/doerg-parser "./doerg-parser/index.js")))
(defn render-html [& {:keys [src dest] (defn render-html [& {:keys [src dest]
:or {src some-org-file :or {src some-org-file
dest "/tmp/doerg-test"}}] dest "/tmp/doerg-test"}}]
(fs/create-dirs dest) (fs/create-dirs dest)
(force-create-sym-link (fs/file dest "ibm-plex-web") (force-create-sym-link (fs/file dest "ibm-plex-web")
(-> cfg/*cfg* ::cfg/ibm-plex-web)) (-> cfg/*cfg* ::doerg/ibm-plex-web))
(force-create-sym-link (fs/file dest "deerstar.css") (force-create-sym-link (fs/file dest "deerstar.css")
(io/resource "net/deertopia/doerg/deerstar.css")) (io/resource "net/deertopia/doerg/deerstar.css"))
(force-create-sym-link (fs/file dest "tuftesque.css") (force-create-sym-link (fs/file dest "tuftesque.css")

View File

@@ -7,7 +7,8 @@
[clojure.string :as str] [clojure.string :as str]
[clojure.tools.logging :as l] [clojure.tools.logging :as l]
[babashka.fs :as fs] [babashka.fs :as fs]
[net.deertopia.doerg.config :as cfg]) [net.deertopia.doerg.config :as cfg]
[net.deertopia.doerg :as-alias doerg])
(:import (java.io ByteArrayOutputStream))) (:import (java.io ByteArrayOutputStream)))
(def ^:private scale-divisor 66873.46948423679) (def ^:private scale-divisor 66873.46948423679)
@@ -82,14 +83,14 @@
acc)))) acc))))
(defn- invoke-latex [& {:keys [file output-dir]}] (defn- invoke-latex [& {:keys [file output-dir]}]
(let [latex (::cfg/latex cfg/*cfg*)] (let [latex (-> cfg/*cfg* ::doerg/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/dvisvgm cfg/*cfg*)] (let [dvisvgm (-> cfg/*cfg* ::doerg/dvisvgm)]
(invoke (invoke
{:dir output-dir} {:dir output-dir}
dvisvgm "--page=1-" "--optimize" "--clipjoin" dvisvgm "--page=1-" "--optimize" "--clipjoin"

View File

@@ -6,7 +6,8 @@
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
[clojure.tools.logging :as l] [clojure.tools.logging :as l]
[babashka.fs :as fs]) [babashka.fs :as fs]
[net.deertopia.doerg :as-alias doerg])
(:import (java.io ByteArrayOutputStream))) (:import (java.io ByteArrayOutputStream)))
(def ^:dynamic *worker-timeout-duration* (def ^:dynamic *worker-timeout-duration*
@@ -21,7 +22,7 @@
:suffix ".tex"})) :suffix ".tex"}))
(defn worker [] (defn worker []
(let [doerg-temml-worker (::cfg/doerg-temml-worker cfg/*cfg*)] (let [doerg-temml-worker (-> cfg/*cfg* ::doerg/doerg-temml-worker)]
(when-not (fs/exists? prelude-file) (when-not (fs/exists? prelude-file)
(-> "net/deertopia/doerg/prelude.tex" (-> "net/deertopia/doerg/prelude.tex"
io/resource io/resource

View File

@@ -1,8 +0,0 @@
(ns net.deertopia.doerg.config-test
(:require [net.deertopia.doerg.config :as sut]
[clojure.test :as t]
[clojure.spec.alpha :as s]))
(t/deftest default-config-is-config
(t/testing "default config is valid"
(t/is (s/valid? ::sut/config sut/default))))

View File

@@ -11,5 +11,6 @@
net.deertopia/doerg {:local/root "../doerg"} net.deertopia/doerg {:local/root "../doerg"}
metosin/reitit {:mvn/version "0.10.1"} metosin/reitit {:mvn/version "0.10.1"}
http-kit/http-kit {:mvn/version "2.8.0"} http-kit/http-kit {:mvn/version "2.8.0"}
instaparse/instaparse {:mvn/version "1.5.0"}} instaparse/instaparse {:mvn/version "1.5.0"}
aero/aero {:mvn/version "1.1.6"}}
:paths ["src" "resources" "test"]} :paths ["src" "resources" "test"]}

View File

@@ -0,0 +1,5 @@
#:net.deertopia.publisher
{:state-directory #join [#or [#env XDG_STATE_HOME
#envf ["%s/.local/share" HOME]]
"/doerg-publisher"]
:org-roam-db-path #join [#env HOME "/.cache/emacs/org-roam.db"]}

View File

@@ -1,17 +1,32 @@
(ns net.deertopia.publisher.config (ns net.deertopia.publisher.config
(:require [babashka.fs :as fs] (:require [babashka.fs :as fs]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[net.deertopia.doerg.config :as doerg])) [net.deertopia.doerg :as-alias doerg]
[net.deertopia.publisher :as-alias p]
[aero.core :as aero]
[clojure.java.io :as io]))
(s/def ::config (s/def ::p/config
(s/keys :req [::state-directory (s/keys :req [::p/state-directory
::org-roam-db-path])) ::p/org-roam-db-path]))
(s/def ::p/state-directory ::doerg/file)
(s/def ::p/org-roam-db-path ::doerg/file)
(defn read-config [& files]
(->> files
(filter identity)
(map aero/read-config)
(apply merge)
(s/conform ::p/config)))
(def default (def default
{::state-directory (fs/xdg-state-home "doerg-publisher") (let [r (-> "net/deertopia/publisher/config.edn"
::org-roam-db-path (fs/file (fs/home) ".cache" "emacs" "org-roam.db")}) io/resource
(read-config (System/getenv "DOERG_PUBLISHER_CONFIG")))]
(if (s/invalid? r)
(throw (IllegalArgumentException.
"default config is bad!"))
r)))
(def ^:dynamic *cfg* default) (def ^:dynamic *cfg* default)
(s/def ::state-directory ::doerg/file)
(s/def ::org-roam-db-path ::doerg/file)

View File

@@ -3,6 +3,7 @@
[net.deertopia.publisher.config :as cfg] [net.deertopia.publisher.config :as cfg]
[net.deertopia.publisher.elisp :as elisp] [net.deertopia.publisher.elisp :as elisp]
[net.deertopia.publisher.slug :as slug] [net.deertopia.publisher.slug :as slug]
[net.deertopia.publisher :as-alias publisher]
[next.jdbc :as sql]) [next.jdbc :as sql])
(:import (java.util UUID))) (:import (java.util UUID)))
@@ -11,7 +12,7 @@
(defonce ^:dynamic *use-db-cache?* true) (defonce ^:dynamic *use-db-cache?* true)
(def db-path (-> cfg/*cfg* ::cfg/org-roam-db-path (def db-path (-> cfg/*cfg* ::publisher/org-roam-db-path
fs/expand-home str)) fs/expand-home str))
(def db {:dbtype "sqlite" (def db {:dbtype "sqlite"

View File

@@ -18,7 +18,10 @@
[reitit.spec] [reitit.spec]
[reitit.dev.pretty] [reitit.dev.pretty]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[net.deertopia.doerg.render :as doerg-render])) [net.deertopia.doerg.render :as doerg-render]
[net.deertopia.publisher.cached-file :as cached-file]
[babashka.fs :as fs]
[aero.core :as aero]))
;;; Routes ;;; Routes