feat: o pona e ijo Config kepeken lipu Library
All checks were successful
build / build (push) Successful in 5s

This commit was merged in pull request #22.
This commit is contained in:
2026-03-22 13:24:59 -06:00
parent d4ff27ada4
commit 29d5cdc85a
19 changed files with 146 additions and 75 deletions

View File

@@ -1,42 +1,73 @@
(ns net.deertopia.doerg.config
(:require [clojure.spec.alpha :as s]
[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/keys :req [::ibm-plex-web
::latex
::dvisvgm
::doerg-temml-worker
::doerg-parser]))
(s/def ::d/config
(s/keys :req [::d/ibm-plex-web
::d/latex
::d/dvisvgm
::d/doerg-temml-worker
::d/doerg-parser]))
(s/def ::file
(s/conformer (comp fs/file fs/absolutize fs/expand-home)))
(s/def ::d/directory
(s/conformer #(fs/file %)))
(s/def ::executable #(or (fs/executable? %)
(and (fs/relative? %)
(fs/which %))))
(s/def ::d/file
(s/conformer #(-> % fs/expand-home fs/file)))
(s/def ::d/executable
(s/conformer
;; I'd love to use `fs/which` here, but it's fairly problematic to
;; check `fs/executable?` at… build time (which `fs/which` does)?
;; Wait… what? Do I know how Clojure compilation works?
#(or #_(some-> % fs/expand-home fs/which fs/file)
(some-> % fs/expand-home 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 make-read-config [spec]
(fn [& files]
(let [r (->> files
(filter identity)
(map aero/read-config)
(apply merge))
conformed (s/conform spec r)]
(if-not (s/invalid? conformed)
conformed
(throw (IllegalArgumentException.
"bad config"
(ex-info "couldn't conform"
(s/explain-data spec r))))))))
(def read-config (make-read-config ::d/config))
(def default
{::ibm-plex-web
(fs/file (some #(let [x (fs/path % "ibm-plex-web")]
(and (fs/exists? x) x))
(fs/split-paths (System/getenv "XDG_DATA_DIRS"))))
::latex "xelatex"
::dvisvgm "dvisvgm"
;; 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"})
(read-config
;; Default config.
(io/resource "net/deertopia/doerg/default-config.edn")
;; Defaults set at build time, if any.
(io/resource "net/deertopia/doerg/extra-config.edn")
;; Config set at runtime.
(System/getenv "DOERG_CONFIG")))
(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]
[cheshire.core :as json]
[clojure.core.match :refer [match]]
[net.deertopia.doerg :as-alias doerg]
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.spec.alpha :as s]
@@ -36,7 +37,7 @@
:or {in *in*}}]
(let [r (-> (p/process
{:in in :out :string}
(::cfg/doerg-parser cfg/*cfg*))
(-> cfg/*cfg* ::doerg/doerg-parser str))
(common/deref-with-timeout *uniorg-timeout-duration*))]
(when (zero? (:exit r))
(-> r :out (json/parse-string (comp keyword camel->kebab))))))

View File

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

View File

@@ -5,7 +5,8 @@
[clojure.java.io :as io]
[hiccup2.core :as h]
[clojure.pprint]
[babashka.fs :as fs]))
[babashka.fs :as fs]
[net.deertopia.doerg :as-alias doerg]))
(def some-org-file
#_
@@ -27,19 +28,12 @@
(fs/delete-if-exists path)
(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]
:or {src some-org-file
dest "/tmp/doerg-test"}}]
(fs/create-dirs dest)
(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")
(io/resource "net/deertopia/doerg/deerstar.css"))
(force-create-sym-link (fs/file dest "tuftesque.css")

View File

@@ -7,7 +7,8 @@
[clojure.string :as str]
[clojure.tools.logging :as l]
[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)))
(def ^:private scale-divisor 66873.46948423679)
@@ -82,14 +83,14 @@
acc))))
(defn- invoke-latex [& {:keys [file output-dir]}]
(let [latex (::cfg/latex cfg/*cfg*)]
(let [latex (-> cfg/*cfg* ::doerg/latex)]
(invoke
{:dir output-dir}
latex "-no-pdf" "-interaction" "nonstopmode"
"-output-directory" output-dir file)))
(defn- invoke-dvisvgm [& {:keys [file output-dir]}]
(let [dvisvgm (::cfg/dvisvgm cfg/*cfg*)]
(let [dvisvgm (-> cfg/*cfg* ::doerg/dvisvgm)]
(invoke
{:dir output-dir}
dvisvgm "--page=1-" "--optimize" "--clipjoin"

View File

@@ -6,7 +6,8 @@
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.tools.logging :as l]
[babashka.fs :as fs])
[babashka.fs :as fs]
[net.deertopia.doerg :as-alias doerg])
(:import (java.io ByteArrayOutputStream)))
(def ^:dynamic *worker-timeout-duration*
@@ -21,7 +22,7 @@
:suffix ".tex"}))
(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)
(-> "net/deertopia/doerg/prelude.tex"
io/resource