Compare commits
58 Commits
85fb3b1ee4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| dcaac98252 | |||
| 5ca59fdb5e | |||
| 55fa2473a2 | |||
| 9349293684 | |||
| 4d310afa18 | |||
| 7634303b13 | |||
| cf242b778d | |||
| 9cc0def4d5 | |||
| e02b77e1e4 | |||
| c74e36d8af | |||
| 36e328915e | |||
| b607ab8cae | |||
| fb2974bb21 | |||
| 79735cc0ba | |||
| 931f6f9006 | |||
| 811d07de39 | |||
| 29d5cdc85a | |||
| d4ff27ada4 | |||
| 5bca7890c4 | |||
| befa724551 | |||
| 2b80c15cc8 | |||
| 7805de06f2 | |||
| 1629efb378 | |||
| 2198b5f409 | |||
| bc5138086d | |||
| 6d1d94194b | |||
| fd9322740d | |||
| e5b47898a5 | |||
| 26410655d9 | |||
| faa84f986d | |||
| 9ec8bca383 | |||
| d946c57bff | |||
| 7c4ad64d58 | |||
| 56742cf72d | |||
| a92b387e63 | |||
| 98c106b3cf | |||
| b336aa873e | |||
| e49f847f20 | |||
| ec4ad7c9c2 | |||
| 762324d9f0 | |||
| c97b7ab0dc | |||
| c45852097b | |||
| 74e48264ea | |||
| 283c18fd9e | |||
| 570fca833d | |||
| eb53516a2d | |||
| 8b2fb7a010 | |||
| 6ef81a4a45 | |||
| 17e61aabc8 | |||
| c34b239d01 | |||
| de96a6245b | |||
| c077186c10 | |||
| c0a69bdbed | |||
| 99bf9aae03 | |||
| 18350f6600 | |||
| 5c92dc153c | |||
| 66586e6239 | |||
| 49990228c9 |
1
.dir-locals.el
Normal file
1
.dir-locals.el
Normal file
@@ -0,0 +1 @@
|
||||
((nil . ((cider-clojure-cli-aliases . ":dev:test"))))
|
||||
11
.gitea/workflows/build.yaml
Normal file
11
.gitea/workflows/build.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
name: build
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: nixos
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: build doerg
|
||||
run: nix build -L .#doerg
|
||||
@@ -1,26 +0,0 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: nixos
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- name: build doerg
|
||||
run: nix build -L .#doerg
|
||||
Explore-Gitea-Actions:
|
||||
runs-on: nixos
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,7 +9,6 @@ result-*
|
||||
.lsp
|
||||
.nrepl
|
||||
.direnv/
|
||||
resources/vendor/*
|
||||
node_modules
|
||||
.cljs_node_repl
|
||||
build/
|
||||
|
||||
2
bb.edn
2
bb.edn
@@ -3,6 +3,6 @@
|
||||
lock
|
||||
{:doc "Update the clj-nix lockfile"
|
||||
:task (-> (p/sh {:out :inherit :err :inherit}
|
||||
"nix run github:jlesquembre/clj-nix#deps-lock")
|
||||
"nix run github:jlesquembre/clj-nix#deps-lock")
|
||||
:exit
|
||||
System/exit)}}}
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
, doerg-parser
|
||||
, doerg-temml-worker
|
||||
, ibm-plex-web
|
||||
, test-emacs ? callPackage ./test-emacs.nix {}
|
||||
, fake-git
|
||||
, our-tex ? callPackage ./our-tex.nix {}
|
||||
, our-tex
|
||||
, makeWrapper
|
||||
, breakpointHook
|
||||
, writeText
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -16,29 +17,38 @@ let
|
||||
mkCljBin' = args: (mkCljBin args).overrideAttrs (final: prev: {
|
||||
nativeBuildInputs =
|
||||
builtins.filter
|
||||
# A possibly-sketchy predicate, lol.
|
||||
(x: x != fake-git)
|
||||
prev.nativeBuildInputs;
|
||||
# A possibly-sketchy predicate, lol.
|
||||
(x: x != fake-git)
|
||||
prev.nativeBuildInputs;
|
||||
});
|
||||
|
||||
plex = ibm-plex-web.override {
|
||||
families = [ "math" "serif" "sans" "sans-kr" ];
|
||||
};
|
||||
|
||||
bin-path = lib.makeBinPath [
|
||||
doerg-parser
|
||||
our-tex
|
||||
doerg-temml-worker
|
||||
];
|
||||
|
||||
doerg-config = writeText "doerg-extra-config.edn" ''
|
||||
#:net.deertopia.doerg
|
||||
{:ibm-plex-web "${ibm-plex-web}"
|
||||
:latex "${lib.getExe' our-tex "xelatex"}"
|
||||
:dvisvgm "${lib.getExe' our-tex "dvisvgm"}"
|
||||
:doerg-temml-worker "${lib.getExe doerg-temml-worker}"
|
||||
:doerg-parser "${lib.getExe doerg-parser}"}
|
||||
'';
|
||||
in mkCljBin' {
|
||||
name = "net.deertopia/doerg";
|
||||
version = "0.1.0";
|
||||
projectSrc = ./.;
|
||||
lockfile = ../deps-lock.json;
|
||||
projectSrc = lib.cleanSource ./.;
|
||||
lockfile = ./deps-lock.json;
|
||||
main-ns = "net.deertopia.doerg.main";
|
||||
nativeBuildInputs = [
|
||||
plex
|
||||
makeWrapper
|
||||
breakpointHook
|
||||
];
|
||||
buildInputs = [
|
||||
doerg-parser
|
||||
@@ -49,15 +59,19 @@ in mkCljBin' {
|
||||
nativeCheckInputs = [
|
||||
doerg-parser
|
||||
doerg-temml-worker
|
||||
test-emacs
|
||||
plex
|
||||
our-tex
|
||||
];
|
||||
preBuild = ''
|
||||
cp ${doerg-config} resources/net/deertopia/doerg/extra-config.edn
|
||||
'';
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
export \
|
||||
EMACS=test-emacs \
|
||||
XDG_STATE_HOME=$(mktemp -d "state-home-XXXXXX")
|
||||
clojure -M:test
|
||||
'';
|
||||
postInstall = ''
|
||||
wrapProgram $out/bin/doerg \
|
||||
--prefix PATH : ${bin-path}
|
||||
'';
|
||||
passthru = { inherit plex our-tex test-emacs; };
|
||||
}
|
||||
691
deps-lock.json
691
deps-lock.json
@@ -1,14 +1,6 @@
|
||||
{
|
||||
"lock-version": 4,
|
||||
"git-deps": [
|
||||
{
|
||||
"lib": "io.github.msyds/spec-dict",
|
||||
"url": "https://github.com/msyds/spec-dict.git",
|
||||
"rev": "531d629b7f05f37232261cf9e8927a4b5915714f",
|
||||
"git-dir": "https/github.com/msyds/spec-dict",
|
||||
"hash": "sha256-5hMdPsB8OhOCtByPZS+CHXzVLq0H+OBKKnXec21xwmg="
|
||||
}
|
||||
],
|
||||
"git-deps": [],
|
||||
"mvn-deps": [
|
||||
{
|
||||
"mvn-path": "aero/aero/1.1.6/aero-1.1.6.jar",
|
||||
@@ -40,6 +32,26 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-4bSR/Z0g4rXVwv2u6e9rkoL8d1nV5b9iNIs/U2o8l8Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "borkdude/dynaload/0.3.5/dynaload-0.3.5.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-CIfAzbmvzs18SW6iWKMuQ6py52bz8GMuG9D1JFyowkw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "borkdude/dynaload/0.3.5/dynaload-0.3.5.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-XBwijxopsG0KfQNJD15k+vcTo8YWcpi6Fxz/wzz57Rg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "borkdude/edamame/1.5.37/edamame-1.5.37.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-TuYGDVJS0LlKcIOdvQy699fMToHZwnfSs1UvKAuXxag="
|
||||
},
|
||||
{
|
||||
"mvn-path": "borkdude/edamame/1.5.37/edamame-1.5.37.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ALbGpZQfZ2CIRW5VUez5OLBhJ+lSDPY7oxb1UwPhyG4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "camel-snake-kebab/camel-snake-kebab/0.4.3/camel-snake-kebab-0.4.3.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -86,25 +98,70 @@
|
||||
"hash": "sha256-KKpi9U7eZ2YjAyQI14sMgqv91IiMfFagshIrg+Pad+M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "clout/clout/2.2.1/clout-2.2.1.jar",
|
||||
"mvn-path": "com/bhauman/spell-spec/0.1.2/spell-spec-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-nzdGxROb7zUJmjOuuDMQCnWOJXKv1CM+ynAM3XLWhws="
|
||||
"hash": "sha256-ux1waVVJJ2hH61sgWNwXc5LWharNvgky+dWnM+J7/eM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "clout/clout/2.2.1/clout-2.2.1.pom",
|
||||
"mvn-path": "com/bhauman/spell-spec/0.1.2/spell-spec-0.1.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-BNzQl/YWeodReE3AkISRm68YmBfPQcvt4sQs7gSMh6c="
|
||||
"hash": "sha256-CHzQYPxRUXL5tdXVJbSIzE8VJaslGlo3UCtVQV44fP4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.jar",
|
||||
"mvn-path": "com/cognitect/transit-clj/1.0.333/transit-clj-1.0.333.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-vAz0YHWHcgH4QG7n3idBrn32wGb18EV72AYypxjAbnI="
|
||||
"hash": "sha256-jgNSoALPld3rUncLlQweteqWtzUfzjng/uk+Icpjvvs="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/cognitect/transit-clj/1.0.333/transit-clj-1.0.333.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-h2ulOH2EfKM1RH6jSt9UKxfRsHdI7L3JAahwv8x3qDM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/cognitect/transit-java/1.0.371/transit-java-1.0.371.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-kmeszqpryOidXL9l+EeDhkeHbXIa8ggyTjjNAECyNpY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/cognitect/transit-java/1.0.371/transit-java-1.0.371.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Bz9V9PAfwqd7K1G5QD7FYJtLC/CuHbzrxI4iN0TJe78="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-U8oIX0oVD3A/SeGqvZNb0DtD4eo9VdE1Q4KSryLO9Ws="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-annotations/2.21/jackson-annotations-2.21.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ccrFOSFR4qUozJoJF58KM0F58FxS+OWWz1jd8Suyfys="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-XxZVisIjBzpvJHRA8wX1nwXv9QqvHurguq1BKAABb2g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.21.1/jackson-core-2.21.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Ht1fLkncpfjkUZlXwkt7MFC9HH7og5INozz/Ax/x98A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.21.1/jackson-core-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Dz+1656JcESawMuY4vjntRPS1OxbGk8C4id45Pe6uNc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-databind/2.21.1/jackson-databind-2.21.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-sBHrUgLZ7IieJ/HcvfbGPwanbnoWwKGzDGBI1VbJoo4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-databind/2.21.1/jackson-databind-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-vUgX0LkXlK/29LEWtXa/7ckne+LWxlHJVm9VIiLGpVA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.20.0/jackson-dataformat-cbor-2.20.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -130,26 +187,61 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ZJ/OQKV9Qhx82erCP919XPbzwdG5NAbuJ3xFw1Mm5Yg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.1/jackson-datatype-jsr310-2.21.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-TWM3iwprU3M/CG69MBAjuiEbk4fkF71YSlQAMgzQi40="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.21.1/jackson-datatype-jsr310-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-dMXOjKDqCO8xnVps5iQk39nLk9rcAe+YF4c/t/Zpm64="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-base/2.20.0/jackson-base-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-/IgCjRnuqjftpZbmuY03SfIs/IrdGeoZdFq+g2iDzmY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-base/2.21.1/jackson-base-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-YNTrZqAAoz+jfny1HiVQ2r50Z6C4rGCAbX07qXKMzWQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-bom/2.20.0/jackson-bom-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-9ig2R+cB/aHNMS3MIcsTKkD3mPGejkL6/D/jR8WlG7s="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-bom/2.21.1/jackson-bom-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-jXx43eEPTQjnKWzvCEzzC3etzqejbiPRUgeT/exj/yg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-parent/2.20/jackson-parent-2.20.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-tDt/XGLoaxZPrnCuF9aRHF22B5mvAQVzYK/aguSEW+U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-parent/2.21/jackson-parent-2.21.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-OFHfYn+utGiHuVYQRjC3Sou7X33iLpdM8VmC4g4Dc94="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/module/jackson-modules-java8/2.21.1/jackson-modules-java8-2.21.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-gN/cby92+kwGXhHcdFMaAkRyRfFBWzoScCgf/NjJK1o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/oss-parent/70/oss-parent-70.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-JsqO1vgsnS7XzTIpgQW7ZcD52JnbYXV6CXQVhvqTpjk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/oss-parent/75/oss-parent-75.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-/LvxwYyQR+aRfThPIGTiG0Klj8hfsFI6ni4BXv98YZ0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/github/seancorfield/next.jdbc/1.3.1070/next.jdbc-1.3.1070.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -160,6 +252,16 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-dXkdZHooK97QEyeXodFSC942EiB9B8MlHUNZlbH8nvI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-TmlpaJK4i0HFXUmrL9zCHurZK/VKzFiMAFBZbDt1GZw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Zl9jWQ3vtj1irdIdNSU2LPk3z2ocBeSwFFuujailf4M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/nextjournal/beholder/1.0.2/beholder-1.0.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -180,6 +282,11 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2Fv7Xf/j/e+vS9pjGOyCkOyQEqA+0rzjZzo3p4T2WmU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/sun/activation/all/1.2.0/all-1.2.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-HYUY46x1MqEE5Pe+d97zfJguUwcjxr2z1ncIzOKwwsQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/unboundid/unboundid-ldapsdk/5.1.1/unboundid-ldapsdk-5.1.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -201,24 +308,14 @@
|
||||
"hash": "sha256-yG7hmKNaNxVIeGD0Gcv2Qufk2ehxR3eUfb5qTjogq1g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "commons-io/commons-io/2.17.0/commons-io-2.17.0.jar",
|
||||
"mvn-path": "commons-io/commons-io/2.20.0/commons-io-2.20.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-SqTKSPPf0wt4Igt4gdjLk+rECT7JQ2G2vvqUh5mKVQs="
|
||||
"hash": "sha256-35C7oP48tYa38WTnj+j49No/LdXCf6ZF+IgQDMwl3XI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "commons-io/commons-io/2.17.0/commons-io-2.17.0.pom",
|
||||
"mvn-path": "commons-io/commons-io/2.20.0/commons-io-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-SEqTn/9TELjLXGuQKcLc8VXT+TuLjWKF8/VrsroJ/Ek="
|
||||
},
|
||||
{
|
||||
"mvn-path": "compojure/compojure/1.7.1/compojure-1.7.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-CtYPv//W9VUqS0NpBWYADP2bbXq9g22e05zVgm4Ifyk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "compojure/compojure/1.7.1/compojure-1.7.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-wJXfgk0wVcbec4QiDLsCvzmpdc8wE9hGub5Shmi/7wc="
|
||||
"hash": "sha256-vb34EHLBkO6aixgaXFj1vZF6dQ+xOiVt679T9dvTOio="
|
||||
},
|
||||
{
|
||||
"mvn-path": "crypto-equality/crypto-equality/1.0.1/crypto-equality-1.0.1.jar",
|
||||
@@ -251,14 +348,29 @@
|
||||
"hash": "sha256-kJSODD3MvE8aCvaABWue2JizAcvtLd4/9CR5eWmXxdk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.27/fipp-0.6.27.jar",
|
||||
"mvn-path": "fi/metosin/reitit-openapi/0.10.1/reitit-openapi-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-qK1dAlan2r+90UOm6QvnZXURhA/is4MMp9tnK20RDPc="
|
||||
"hash": "sha256-mdWhP6mKwiTjUyah++5keAqxQfDbokB0H7b96pvtXTo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.27/fipp-0.6.27.pom",
|
||||
"mvn-path": "fi/metosin/reitit-openapi/0.10.1/reitit-openapi-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ugagpDW5XBNQMTr+1z3s6r5TXwbF/pw6Ffrcc4Tzlvk="
|
||||
"hash": "sha256-OaawIvv0GgkuZwK6MAFtmuyw3zNcYiZVd66K/IipB2A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.26/fipp-0.6.26.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-p+xjV7gTIRMv0HwvV+/rAhFEFVlDY9g6FDE6GU9fVTU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.29/fipp-0.6.29.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-22eJoDXAE84RqZHrOBiILWjUf6ap7uRiey4NnhvvBfI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.29/fipp-0.6.29.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-OqX0rRj77alJ4fa8hN3RHgnc6rR/JUwJCJY6o4LwCcU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "hawk/hawk/0.2.11/hawk-0.2.11.jar",
|
||||
@@ -310,6 +422,31 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Y/C4zR1No0m2Dfk4kdHgDF0/0sm9M9jlvu0HWijNiFQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Q/3vC1ts6zGwQksgi5MMdKtY+sLO63s/b9OuuLXKQ5M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-2ikm88i+iYZDzBCs3sbeCwNRpX+yc1dw+gF3sGrecbk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "javax/xml/bind/jaxb-api-parent/2.4.0-b180830.0359/jaxb-api-parent-2.4.0-b180830.0359.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ctEy4shY0iMPFdBI8ek6J5xAxOnshLxW+fLz61r0tLg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-VrnpcCdTdjAHQ1Fi6niAVe/P78hquSDwMsBBHcVHuDY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-sck/wwHX9f5M3hPRlTKZJR2jfv/8kfUjg1UEw/+HNwc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/clj-diff/1.4.78/clj-diff-1.4.78.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -321,14 +458,24 @@
|
||||
"hash": "sha256-2QZ6mFjx7+UGI232PUr3CzsQenqd+xcRsbqEpxs32w0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.12.219/deep-diff2-2.12.219.jar",
|
||||
"mvn-path": "lambdaisland/deep-diff/0.0-47/deep-diff-0.0-47.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-BkOq5C/7omo09wyTTg7nkBi6GWBmlayVsPa9mrDvCyU="
|
||||
"hash": "sha256-falL4yyvcE4PHTuanJq/7G2nS1u4BwuU0d+R/Ns9h54="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.12.219/deep-diff2-2.12.219.pom",
|
||||
"mvn-path": "lambdaisland/deep-diff/0.0-47/deep-diff-0.0-47.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-rW/85js2hSWVc36e2BcTRmkahJHc2TjGIEfvForuToY="
|
||||
"hash": "sha256-1PXzUUHstr5hI/+oPIQUGogO744bynAw2Zoo5HSjTbE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.11.216/deep-diff2-2.11.216.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-U2zJZmPIO66EtkgwwfyY41uRyu2DRmXH0ogNfluw5Rg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.11.216/deep-diff2-2.11.216.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ok3nYS+8XCcCTPJIkqaO1SQH6v2ENwK2GZJdH0c4D20="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/kaocha/1.91.1392/kaocha-1.91.1392.jar",
|
||||
@@ -350,16 +497,6 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-n+46BXjy57A8898EXgyplEyyqf/S5qocf140ZbglV64="
|
||||
},
|
||||
{
|
||||
"mvn-path": "medley/medley/1.4.0/medley-1.4.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-TPIRabvctGuZ531Am+63v9GqNmCIUodXQky5l9SW81U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "medley/medley/1.4.0/medley-1.4.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-JhEgB4cMXujVcrvDw4n8a9bMZG1cUAdfbolYQMWGEMA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "meta-merge/meta-merge/1.0.0/meta-merge-1.0.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -370,6 +507,216 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-sAogZY/OzCvRNBAx85T1LWjFP7SAxEVBNMyqwgTqWTE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/jsonista/0.3.14/jsonista-0.3.14.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-X2Q8enVPRd4MZ2e+RWmybKP8RimgPq9CaqhCDAGSusc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/jsonista/0.3.14/jsonista-0.3.14.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-O7ct/9mXDlQyA15IKaKIpd3OONz8EXjiCx76OX3jL10="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/malli/0.20.1/malli-0.20.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-RaaMI4tsXRl2KXUPGmPMWqbQRUVrCpRcjJ1ayAZ9gd4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/malli/0.20.1/malli-0.20.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-B+fEOtVMMuJa8MZjN10cdiwuZE/4Lbb9nCn6LYIaa8g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/muuntaja/0.6.11/muuntaja-0.6.11.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ESyKKT/YetFeFhDVaDaBDGXLzV/9A5xJOAjs6SHQCZI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/muuntaja/0.6.11/muuntaja-0.6.11.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-fEq6j197KE2x1YOr+2EnuOzvgD4nM2KBK1G3GsmSv2E="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-core/0.10.1/reitit-core-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-7gBhQkwe2ZlzVO//GWsSNeq1O9ydlm9aA3l183eqrrU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-core/0.10.1/reitit-core-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-sXrrlJWKnQFn7pKvBRPz3yuqWBpdN2TzhML3hOMioGY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-dev/0.10.1/reitit-dev-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-jfnIj4oC09La0M+oA96yPqt60Jx5XxAAw21/dpFTgmk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-dev/0.10.1/reitit-dev-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LxsZ5EiqWPvmbSdMSlPbEFQrWCUuynZihnk0PUe7E5w="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-frontend/0.10.1/reitit-frontend-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SLNS7KASzrAXoTPljH4AAJK4vKVnpfJxjFDFzM9OTVo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-frontend/0.10.1/reitit-frontend-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-lKSwm77Jj4iUKIQD5uOJBOFZbcMtmvPwfpRM4JrdspE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-http/0.10.1/reitit-http-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-5IbNDHtNHe8PRs1m5EKe28V9N+bPdi991OQgkZQN6As="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-http/0.10.1/reitit-http-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-TgdsRodZjIIALEf6/nPUvhUT9reeaYQOWHpJlxG5Ze8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-interceptors/0.10.1/reitit-interceptors-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-9ET465F/wmbc/1KzbxsiNa/MscQ3HjP6RsQGPtTdlVk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-interceptors/0.10.1/reitit-interceptors-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-IE/2mrKYaGe8oXkhuivDQVbnXpyV85DCHQczcC+mxNM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-malli/0.10.1/reitit-malli-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-TN815aCf2t/vP6PbamBXLHq3jsBmLxg6cz0a5L16CFQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-malli/0.10.1/reitit-malli-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-7MEtlqJTDa9m1Qc4sno8lPgMJvH7WKW7giiuP33S484="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-middleware/0.10.1/reitit-middleware-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-L0lA3bGz2yVGoSgqvbK0UabAYA5DwEz4LIbcu8IN2mo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-middleware/0.10.1/reitit-middleware-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-YmrCRAZJtq0kKhbTVDH8190wNCCaSmcWz+3axCV78dU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-ring/0.10.1/reitit-ring-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-u4SZ3GXuPI8+9YjQpzDTASebKD0XxfNE8TnDZD/7TMQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-ring/0.10.1/reitit-ring-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-TadxOEr0yVP1udbCT6/qso2lKldYgJ9xDFN2HfZiF4Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-schema/0.10.1/reitit-schema-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LYEChqfzN7Ut9uOWy+vqPghd+T110hF/nAUTJkY1iT4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-schema/0.10.1/reitit-schema-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-3G0NVZR5Ufmq5pZcC0CcUC296EKZ9FlwtTu+O4vDX+I="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-sieppari/0.10.1/reitit-sieppari-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-7mdIxfmr6QgeRfFnPKW+dlXnqMeEP+idfqoaR4IfBiA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-sieppari/0.10.1/reitit-sieppari-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-mwE5HM9GFIyVXIkt9k/fDQ/T47fNNctRZW4nvrNiZtc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-spec/0.10.1/reitit-spec-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-RNpOMJ9qA+FxQhArd9ZMewvkYLtte3KCuaphmtsCtQY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-spec/0.10.1/reitit-spec-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-Un79w9ZiucZXQOhiQt3Y4vuXT0aAyhk53OoVptrFZfo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-swagger-ui/0.10.1/reitit-swagger-ui-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-zxTK2IBTB8ImucHXzLDALU4OrChKL4XbAw3xnau3jI4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-swagger-ui/0.10.1/reitit-swagger-ui-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-UJWoNe/PZ+ZfbmphCtly5DRDFTZBAQX3HTHxC6pj0KU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-swagger/0.10.1/reitit-swagger-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-RodPXcikvKTcUzssb6rCydYwqHg+bFDvoIsmAdjMgyA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit-swagger/0.10.1/reitit-swagger-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-UZ1aNIMMdOXM7UVfipabpE5o/tEUgYeTuSPcuvVCOUY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit/0.10.1/reitit-0.10.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-vWARTpMbF9O9c/k6lLuJMZLr4Jxe7LpjmjRAHh52oHo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/reitit/0.10.1/reitit-0.10.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-K9Rj53e3toJSqoH77T3QP3AczGNEfQOhRE3bWe6fqww="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/ring-swagger-ui/5.31.0/ring-swagger-ui-5.31.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-52/nNM6fyGWQ0sZuarTrQBe7yF8NOX92DqDVJlmPQx0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/ring-swagger-ui/5.31.0/ring-swagger-ui-5.31.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-P5s2MdIbtEk50xAgeBajaswZBIC18mdZxiDUJIogt+U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/schema-tools/0.13.1/schema-tools-0.13.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-fGQBvcjQyDRqz64GQ2hKTovprY4lb2JFH/Z4aH8jumI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/schema-tools/0.13.1/schema-tools-0.13.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-J/pYO3QRubM3IBvnGHiIfhcaB41df1LkuLf9CZHwvpA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/sieppari/0.0.0-alpha13/sieppari-0.0.0-alpha13.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LTLkMBx8NyTQNAgrG4nwuNbbil/amMYF/rT6TtBvZTc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/sieppari/0.0.0-alpha13/sieppari-0.0.0-alpha13.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-KtIhqq/oyvTwjLfZ7xmcN77k88lPsfdIrLvgImiXj6Q="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/spec-tools/0.10.8/spec-tools-0.10.8.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2UvmSY29d8pk/drnLDWJLW8Fc669T3NHHRjqtT/m/9E="
|
||||
},
|
||||
{
|
||||
"mvn-path": "metosin/spec-tools/0.10.8/spec-tools-0.10.8.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-NXedlytjHNeGLD+iNGFdjY1qPanzk3VpiLeT7EDCLbY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/arrangement/2.1.0/arrangement-2.1.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -390,6 +737,16 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SzmvI+F2QOnCPH5H6OKH124pbohIazXgPG3PhqH0VZA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/puget/1.1.2/puget-1.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-7i5fjiJhNogHcc2ZaD1NsjU70gSF++gh9re+jOZmRRU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/puget/1.1.2/puget-1.1.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LjYHVXDmCU2iBMeOwiacuvmPvMJ8uOS4n973O47Br7s="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/incongru/watchservice/barbary-watchservice/1.0/barbary-watchservice-1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -410,35 +767,45 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Zf8lhJuthZVUtQMXeS9Wia20UprkAx6aUkYxnLK4U1Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/java/jvnet-parent/1/jvnet-parent-1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-KBRAgRJo5l2eJms8yJgpfiFOBPCXQNA4bO60qJI9Y78="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/java/jvnet-parent/5/jvnet-parent-5.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-GvaZ+Nndq2f5oNIC+9eRXrA2Klpt/V/8VMr6NGXJywo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/apache/23/apache-23.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-vBBiTgYj82V3+sVjnKKTbTJA7RUvttjVM6tNJwVDSRw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/apache/29/apache-29.pom",
|
||||
"mvn-path": "org/apache/apache/34/apache-34.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-PkkDcXSCC70N9jQgqXclWIY5iVTCoGKR+mH3J6w1s3c="
|
||||
"hash": "sha256-NnGunU0GKuO7mFcxx2CIuy9vfXJU4tME7p9pC5dlEyg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/apache/33/apache-33.pom",
|
||||
"mvn-path": "org/apache/apache/35/apache-35.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-14vYUkxfg4ChkKZSVoZimpXf5RLfIRETg6bYwJI6RBU="
|
||||
"hash": "sha256-6il9zRFBNui46LYwIw1Sp2wvxp9sXbJdZysYVwAHKLg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2-core/2.0.0-M1/commons-fileupload2-core-2.0.0-M1.jar",
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2-core/2.0.0-M4/commons-fileupload2-core-2.0.0-M4.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-aPumFRznTMztKyudp8asY5gDFDFmVzBSudlcyURbgh8="
|
||||
"hash": "sha256-0oXNjN3j2UZiCLN8d1BFSwsoDqdzsZsFCuHi3bCeaZE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2-core/2.0.0-M1/commons-fileupload2-core-2.0.0-M1.pom",
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2-core/2.0.0-M4/commons-fileupload2-core-2.0.0-M4.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-P238Oe+/9c1XC1Luqb27XH8VCbCnOzUnB7REXwdWnko="
|
||||
"hash": "sha256-nVr4glJx8ilRBfsNqBBjCO0oCevs9QMIecG2dIXqjc8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2/2.0.0-M1/commons-fileupload2-2.0.0-M1.pom",
|
||||
"mvn-path": "org/apache/commons/commons-fileupload2/2.0.0-M4/commons-fileupload2-2.0.0-M4.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-KVM5MYJNx4Iu09XWp0fCeEcYoxZVo/Ifx9gkWcFvtq8="
|
||||
"hash": "sha256-1OvVB1KVvvXrUL7AnQ6iN8VXDbZd5dfVfGMoJBxNoYY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-parent/52/commons-parent-52.pom",
|
||||
@@ -446,14 +813,14 @@
|
||||
"hash": "sha256-ddvo806Y5MP/QtquSi+etMvNO18QR9VEYKzpBtu0UC4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-parent/58/commons-parent-58.pom",
|
||||
"mvn-path": "org/apache/commons/commons-parent/84/commons-parent-84.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-LUsS4YiZBjq9fHUni1+pejcp2Ah4zuy2pA2UbpwNVZA="
|
||||
"hash": "sha256-kjn7lxAdsnBw5Jg9ENM6DpHPZ2ytkb9TgVQiw1Ye+bE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/commons/commons-parent/74/commons-parent-74.pom",
|
||||
"mvn-path": "org/apache/commons/commons-parent/85/commons-parent-85.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-gOthsMh/3YJqBpMTsotnLaPxiFgy2kR7Uebophl+fss="
|
||||
"hash": "sha256-0Yn/LAAn6Wu2XTHm8iftKvlmFps2rx6XPdW6CJJtx7U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojars/pntblnk/clj-ldap/0.0.17/clj-ldap-0.0.17.jar",
|
||||
@@ -586,14 +953,19 @@
|
||||
"hash": "sha256-NnHYN2UlIwq6Ah8fYmx54g86ELYrXfgXIiWJDsSv4EU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.0/core.rrb-vector-0.2.0.jar",
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ftqNXGlaxVNp3NTHN4YUMhdXuBAoG//KMMss02PRZZQ="
|
||||
"hash": "sha256-juK6yvw4QzWMznZRDXMyQhK7NRn61XgE7Oq9w3rFCR8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.0/core.rrb-vector-0.2.0.pom",
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.1/core.rrb-vector-0.2.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-t+0/8ZfxrdZOHvJS2zRY8wlhPcZXdejY4OkTlx4CRY4="
|
||||
"hash": "sha256-8E3BkBQZq+xGiL0YD1/881QHMXAvDTLk1/L74IRBmQo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.1/core.rrb-vector-0.2.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-HS8j0IAGN08JpOXyX+qxQ/sA5uw4oJhiPCkKtHPUjUo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.jar",
|
||||
@@ -645,11 +1017,6 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-EMRQ3qBnbiNW9J5FhBXH6cNrP5AWlnxlBMErOKQp3rc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/0.1.2/pom.contrib-0.1.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-RoC9g43MuowXwlgXE0fxb1uq5rXft4Grc4K8Y4X/gAY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/0.2.2/pom.contrib-0.2.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -671,9 +1038,9 @@
|
||||
"hash": "sha256-CRbXpBVYuVAKQnyIb6KYJ6zlJZIGvjrTPmTilvwaYRE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/1.3.0/pom.contrib-1.3.0.pom",
|
||||
"mvn-path": "org/clojure/pom.contrib/1.4.0/pom.contrib-1.4.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-g5qUXfrO6lvVB5+CSPM0bdIULesJFGyj9dG/riYxCWc="
|
||||
"hash": "sha256-CZNnaHYIH0kbpa+C+mtaA3o77joSWgLW1eJ6op81Z4c="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar",
|
||||
@@ -706,14 +1073,14 @@
|
||||
"hash": "sha256-PLp+DcwIXEzpLd3/6iJhJP+sF4vnm9A3m1suMKlpy+o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/test.check/1.1.2/test.check-1.1.2.jar",
|
||||
"mvn-path": "org/clojure/test.check/1.1.3/test.check-1.1.3.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-93r5qZJ67LZqNoa282s1Al8kvOZr8/AF3UTcQEvIdgE="
|
||||
"hash": "sha256-iwY3sTmCc0dC+z9NEp8KnZ49dSsa7AxvZc7UVV9ytkk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/test.check/1.1.2/test.check-1.1.2.pom",
|
||||
"mvn-path": "org/clojure/test.check/1.1.3/test.check-1.1.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-UZ45jnJMYvCsnWsZ15+P8QAdqYWD/eAb1wUrB+Ga1ow="
|
||||
"hash": "sha256-pPIf6yOG+/zUKlIgDRTA94u+9omfdIzO/LCkSZ4P3sU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.cli/1.1.230/tools.cli-1.1.230.jar",
|
||||
@@ -735,30 +1102,40 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-E15H98p5wKoYG2kJPML50aYyKt1qgli2aXxQCNIwv00="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-JxTXKUyQ+SaO7vNyj+TZjr+q7fJAoCN02u8rhVhEgkg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-cGCU9H2ljugXofq5uAwxLs0nZHK85uHVRCOfFAcR2zE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-EdGzHyxlwzVbKSu5tEuPyv2lS0TaY+NKuXt5qKs7uOA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-rvXugot8sUocWPRbn4oQ/zQMV2mSXqDvXDXR5J2SC+o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.11.0/junit-bom-5.11.0.pom",
|
||||
"mvn-path": "org/clojure/tools.reader/1.5.2/tools.reader-1.5.2.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-5nRZ1IgkJKxjdPQNscj0ouiJRrNAugcsgL6TKivkZE0="
|
||||
"hash": "sha256-y5btDv3wuLw2JjLLdAZ+8iX2sD8/R4yLpEGC9qF6N7Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.reader/1.5.2/tools.reader-1.5.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-uZlvXJtX4jSGPzlfzmT5fTBQtPWFMKYhWllpsILSFOc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-P7cSMa/QmLsPk/Xrl6qCkcjQVWN5El5Zb5Lsj5RMYWI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-WrGVb+jEXzXUal5H8yB0TZ/E9YV82pMRs3GJxdNT2g8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.12.2/junit-bom-5.12.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-zvgP7IZFT2gGv7DfJGabXG8y4styhTnqhZ9H39ybvBc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.13.1/junit-bom-5.13.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-+mhFHqgwVy7UP/5R11tqBfel5mWmAqUfSda+AgY6ZfM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.13.4/junit-bom-5.13.4.pom",
|
||||
@@ -766,39 +1143,39 @@
|
||||
"hash": "sha256-16CKmbJQLwu2jNTh+YTwv2kySqogi9D3M2bAP8NUikI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.9.3/junit-bom-5.9.3.pom",
|
||||
"mvn-path": "org/junit/junit-bom/5.14.1/junit-bom-5.14.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-TQMpzZ5y8kIOXKFXJMv+b/puX9KIg2FRYnEZD9w0Ltc="
|
||||
"hash": "sha256-AbAd+jZlULQKxXYFSKfXKLYQnRfEUeg4ZNHl4M6GLJQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-core-protocols/1.13.0/ring-core-protocols-1.13.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-CuDZ5U9cQ2xn7/4P09pwsH2DrvoPmZ3AYcdTLk7E61w="
|
||||
"mvn-path": "org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-4JymXYUgSI6ApdxCaEior8z9QPSi6zuWRgQlldO9m14="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-core-protocols/1.13.0/ring-core-protocols-1.13.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-Yk/LF6pMW5Tw5Dp0wTIrr6/Ale2o1QCqqsTYwwlKpKY="
|
||||
"mvn-path": "org/msgpack/msgpack/0.6.12/msgpack-0.6.12.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-lEl9jwL43oFZpbfVE24BD1f12axliGES7O2GlcUFbe4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-middleware/0.2.1/ring-websocket-middleware-0.2.1.jar",
|
||||
"mvn-path": "org/ring-clojure/ring-core-protocols/1.15.3/ring-core-protocols-1.15.3.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2d3B369xBMuJr8imgnRrzIbG/oKZ9DgulVzHf+QD/4c="
|
||||
"hash": "sha256-les1EK5xBCc4p2eSaymVSGXgEtqI8Tu/roI7+9d9Avw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-middleware/0.2.1/ring-websocket-middleware-0.2.1.pom",
|
||||
"mvn-path": "org/ring-clojure/ring-core-protocols/1.15.3/ring-core-protocols-1.15.3.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-geZT2NZSl92xlKe1VGL9vLrWBJZ9EDfxx5ANVN9SHvM="
|
||||
"hash": "sha256-5AT9lCnTs+9UKPXPgw8HlY79V6hVp8nsaAmwPzwvG1M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-protocols/1.13.0/ring-websocket-protocols-1.13.0.jar",
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-protocols/1.15.3/ring-websocket-protocols-1.15.3.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-lzsFA+cR8mxTjJzRYK2XY43z9l08Do9whdKKJhD5l8g="
|
||||
"hash": "sha256-aE4bRgOaRFIp5+kA13+WJ+QK6WUUlbE3PHCEVVoRAeQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-protocols/1.13.0/ring-websocket-protocols-1.13.0.pom",
|
||||
"mvn-path": "org/ring-clojure/ring-websocket-protocols/1.15.3/ring-websocket-protocols-1.15.3.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-oLLU3iXdPWNptThQLeay5UJcKxyOM6GQKZgIS4o4EWs="
|
||||
"hash": "sha256-SK+Ln7xwzgCgM5lFhckR5IND3PkmILZ7Ji9iT6UDm5g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar",
|
||||
@@ -855,6 +1232,16 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Z3XeNvNR9MdFCL/+qtZAIceVhx/ZRIXsdsPhduUwU7g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "prismatic/schema/1.1.12/schema-1.1.12.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-t/uQ9AKwdu5wKracrzn0SiGq+i4TOZFiWLgsiaeXHbg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "prismatic/schema/1.1.12/schema-1.1.12.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-bUkp9AkJtNLYxBjJekPaQnvJQSp5zz61OPFbpxTCJSo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "progrock/progrock/0.1.2/progrock-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -875,70 +1262,30 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-At+3ryDvgcJTZQVfYCjoscwpBdCyaLuJzEKM2nIwo2U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-anti-forgery/1.4.0/ring-anti-forgery-1.4.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-Z0itZOlIfEQ4HwhHU4WoyPzkO3hXWbY/kCygSSaXOz8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-anti-forgery/1.4.0/ring-anti-forgery-1.4.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-guNEM3RUHq9/pMc/GBjrEzTJpVhtWKCXl7uD7ye+g2A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-codec/1.2.0/ring-codec-1.2.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-b9itBQBiBVtXtzgRBnH2j0NXdEQ9GCbmL07GTSxFZcI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-codec/1.2.0/ring-codec-1.2.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-de3pMoKzj49m+yTFILdNGDfQsbtdpUIW+AOglmzp2s4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-core/1.11.0/ring-core-1.11.0.pom",
|
||||
"mvn-path": "ring/ring-codec/1.3.0/ring-codec-1.3.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-4AnoLJdSIHaEyCMqqLHgDAGRG1VLpHTUwiSLGEr47kA="
|
||||
"hash": "sha256-oxdtWPK54uTixsdcBtHfKxYiR+4JupjVJVR+nlnIgO8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-core/1.13.0/ring-core-1.13.0.jar",
|
||||
"mvn-path": "ring/ring-codec/1.3.0/ring-codec-1.3.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-qyDIz0gvmRO2Ech8xmnwsONQB+t2fDCLpYRAl06LgR0="
|
||||
"hash": "sha256-7NTqazbyzHjn3jGoUIS5rmFdWLihb9Gj4GuVT9HVxxQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-core/1.13.0/ring-core-1.13.0.pom",
|
||||
"mvn-path": "ring/ring-core/1.15.3/ring-core-1.15.3.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-QXfegvVoaQ2rDDWprFQFW4tYFjxxm933D/t+VAiJt98="
|
||||
"hash": "sha256-TY2XCYiY4z6Lt40/DyiwscjO3m2IujpOw17ljpdAB7w="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-defaults/0.6.0/ring-defaults-0.6.0.jar",
|
||||
"mvn-path": "ring/ring-core/1.15.3/ring-core-1.15.3.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-HM9l8iRYVXq+segdDDa+Id/C+FmpABE/cqdNvhBc06Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-defaults/0.6.0/ring-defaults-0.6.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-d7DxPmcpVzJf6xjbTHjp5KAS4+UQEEuHFwhDBWAXj1o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-headers/0.4.0/ring-headers-0.4.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-d31Q9COKRgl4mrKQsAcNld5/72UPN0EuhQczwXdENJk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-headers/0.4.0/ring-headers-0.4.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-XNQNCCBJsKSvYgDzPplpfiRAK0xrGhJ6zjnlzpMGyx8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-ssl/0.4.0/ring-ssl-0.4.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-K87le9GjOe01TMt41bkDHlXhly+9jk4DZ/udBls6Mpw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ring/ring-ssl/0.4.0/ring-ssl-0.4.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-HHmMD/cPNu7HwRubeajXYOBDYK1y9x9F9KhRytq2AQw="
|
||||
"hash": "sha256-NPKQlHc3j00ir6LHeUH8RXmAijy6lZsG8euvHtMa1x0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.jar",
|
||||
@@ -950,6 +1297,16 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SrxOK5ppxzvTc+gy0/AOWQZ4Q/+DUe/V7rsfOCTbnFE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tech/droit/clj-diff/1.0.1/clj-diff-1.0.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ZnTq41/jMQHEdHLgs6JGuh2aFwvOzOTuSaxkbcdOpLc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tech/droit/clj-diff/1.0.1/clj-diff-1.0.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-V7Sh1HoKMFlY7HNgBEpuF4nKhGJq4wIRKemo1UJDtgo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -959,26 +1316,6 @@
|
||||
"mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-H9VZA1l1INzUrnbmoz7/XjWmFUIrutKo7ZrDMqr75KA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "vvvvalvalval/scope-capture-nrepl/0.3.1/scope-capture-nrepl-0.3.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-M8lO7sWNJpvTomq/N8utgfGghk742Wd5GYfTDeZc9cM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "vvvvalvalval/scope-capture-nrepl/0.3.1/scope-capture-nrepl-0.3.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-8Fa6X1vBnqcSa5LUa/NWI3NG58sLk13s96NuSqCSt1Q="
|
||||
},
|
||||
{
|
||||
"mvn-path": "vvvvalvalval/scope-capture/0.3.2/scope-capture-0.3.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-w9+kis07e4yX5IrA21Dl0bTffsAoShp1QWvIg5lnfoc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "vvvvalvalval/scope-capture/0.3.2/scope-capture-0.3.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-jhHu+a80ZnzaUTeE+iuQidcK5SF4P2zJQb6fzEpujmQ="
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
24
deps.edn
Normal file
24
deps.edn
Normal file
@@ -0,0 +1,24 @@
|
||||
{:deps {aero/aero #:mvn{:version "1.1.6"}
|
||||
babashka/fs #:mvn{:version "0.5.24"}
|
||||
babashka/process #:mvn{:version "0.6.25"}
|
||||
ch.qos.logback/logback-classic #:mvn{:version "1.1.3"}
|
||||
cheshire/cheshire #:mvn{:version "6.1.0"}
|
||||
com.github.seancorfield/next.jdbc #:mvn{:version "1.3.1070"}
|
||||
com.rpl/specter #:mvn{:version "1.1.6"}
|
||||
hiccup/hiccup #:mvn{:version "2.0.0-RC4"}
|
||||
http-kit/http-kit #:mvn{:version "2.8.0"}
|
||||
instaparse/instaparse #:mvn{:version "1.5.0"}
|
||||
metosin/reitit #:mvn{:version "0.10.1"}
|
||||
mvxcvi/clj-cbor #:mvn{:version "1.1.1"}
|
||||
org.clojars.pntblnk/clj-ldap #:mvn{:version "0.0.17"}
|
||||
org.clojure/clojure #:mvn{:version "1.12.0"}
|
||||
org.clojure/core.match #:mvn{:version "1.1.0"}
|
||||
org.clojure/test.check #:mvn{:version "1.1.3"}
|
||||
org.clojure/tools.logging #:mvn{:version "1.3.0"}
|
||||
org.xerial/sqlite-jdbc #:mvn{:version "3.47.1.0"}}
|
||||
:paths ["src" "resources"]
|
||||
:aliases
|
||||
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
|
||||
:extra-paths ["test"]
|
||||
:main-opts ["-m" "kaocha.runner"]}
|
||||
:dev {:extra-paths ["dev"]}}}
|
||||
@@ -10,4 +10,5 @@ buildNpmPackage {
|
||||
npmDeps = importNpmLock { npmRoot = ./.; };
|
||||
npmConfigHook = importNpmLock.npmConfigHook;
|
||||
dontNpmBuild = true;
|
||||
meta.mainProgram = "doerg-parser";
|
||||
}
|
||||
6
doerg/doerg-parser/index.js → doerg-parser/index.js
Normal file → Executable file
6
doerg/doerg-parser/index.js → doerg-parser/index.js
Normal file → Executable file
@@ -2,13 +2,17 @@
|
||||
|
||||
const { parse } = require ("uniorg-parse/lib/parser.js");
|
||||
|
||||
const opts = {
|
||||
trackPosition: true
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const chunks = []
|
||||
for await (const chunk of process.stdin) {
|
||||
chunks.push (chunk)
|
||||
}
|
||||
const orgText = Buffer.concat (chunks).toString ("utf8")
|
||||
process.stdout.write (JSON.stringify (parse (orgText)))
|
||||
process.stdout.write (JSON.stringify (parse (orgText, opts)))
|
||||
}
|
||||
|
||||
main ()
|
||||
@@ -1,11 +1,17 @@
|
||||
{
|
||||
"name": "doerg-parser",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "doerg-parser",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"uniorg-parse": "^3.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"doerg-parser": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
12
doerg-temml-worker/README.org
Normal file
12
doerg-temml-worker/README.org
Normal file
@@ -0,0 +1,12 @@
|
||||
#+title: doerg-temml-worker
|
||||
|
||||
This is a tiny Node script that is used by doerg. For each CBOR-encoded value on stdin (a "command"), a response value is spit to stdout.
|
||||
|
||||
Currently, the following commands are supported:
|
||||
- Any string: Return the Temml-rendered MathML code as a string (inline).
|
||||
- An array with a single string element: Return the Temml-rendered MathML code as a string (display).
|
||||
If something goes wrong, either of these commands may return an object of form
|
||||
#+begin_src json
|
||||
{"type": "error"
|
||||
,"error": «error object»}
|
||||
#+end_src
|
||||
@@ -8,8 +8,15 @@
|
||||
buildNpmPackage {
|
||||
pname = "doerg-temml-worker";
|
||||
version = "0.1.0";
|
||||
src = ./.;
|
||||
src =
|
||||
builtins.filterSource
|
||||
(name: _file-type: ! builtins.elem name [
|
||||
"deserialise.clj" "deps.edn" "default.nix"
|
||||
"README.org" "serialise.clj" "node_modules"
|
||||
])
|
||||
./.;
|
||||
npmDeps = importNpmLock { npmRoot = ./.; };
|
||||
npmConfigHook = importNpmLock.npmConfigHook;
|
||||
dontNpmBuild = true;
|
||||
meta.mainProgram = "doerg-temml-worker";
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "doerg-tex",
|
||||
"name": "doerg-temml-worker",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "doerg-tex",
|
||||
"name": "doerg-temml-worker",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"cbor-x": "^1.6.0",
|
||||
@@ -13,7 +13,7 @@
|
||||
"temml": "^0.13.1"
|
||||
},
|
||||
"bin": {
|
||||
"doerg-tex": "index.js"
|
||||
"doerg-temml-worker": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@cbor-extract/cbor-extract-darwin-arm64": {
|
||||
@@ -1,6 +0,0 @@
|
||||
#+title: Doerg specification
|
||||
#+author: Guppy
|
||||
|
||||
* Footnotes
|
||||
|
||||
- A bunch of metadata should be read into a node of type =doerg-data=
|
||||
@@ -1,271 +0,0 @@
|
||||
{
|
||||
"lock-version": 4,
|
||||
"git-deps": [],
|
||||
"mvn-deps": [
|
||||
{
|
||||
"mvn-path": "babashka/fs/0.5.24/fs-0.5.24.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-owunNIWFqt6xNGhNV6vFs7GyYEz8z8wHRT7TSw1MDlU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "babashka/fs/0.5.24/fs-0.5.24.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-E1jX6M3DeoTXVU6Vzd6xIpE0s9QAZpZALJl4nSKU8E8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "babashka/process/0.6.25/process-0.6.25.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-XWTJ6kUgLD3/UJGe++Lf0+/Ja9SPViS50v33v3JOf4s="
|
||||
},
|
||||
{
|
||||
"mvn-path": "babashka/process/0.6.25/process-0.6.25.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-4bSR/Z0g4rXVwv2u6e9rkoL8d1nV5b9iNIs/U2o8l8Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "cheshire/cheshire/6.1.0/cheshire-6.1.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ruCrbkSBlaoJXyLEKOINK8YQWRxUwQ7D4YPdOwgWOcI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "cheshire/cheshire/6.1.0/cheshire-6.1.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-KKpi9U7eZ2YjAyQI14sMgqv91IiMfFagshIrg+Pad+M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-vAz0YHWHcgH4QG7n3idBrn32wGb18EV72AYypxjAbnI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-XxZVisIjBzpvJHRA8wX1nwXv9QqvHurguq1BKAABb2g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.20.0/jackson-dataformat-cbor-2.20.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-qwdWFsvWf1Z2+Jgl7JyLx7VMhNvpNLFiFFs0FyNwtdY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.20.0/jackson-dataformat-cbor-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-SYvwMYvqLnY2Wf0r/k8W8pHt8JNaMMnysKKP7jrXz8c="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.20.0/jackson-dataformat-smile-2.20.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-NFwALLesnlQ0Go8ExWoR3CGUVCbqg5n/VuAvuOkSpm4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.20.0/jackson-dataformat-smile-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-IM1JgnnQUcaQMkt6R1+Ee/wQoAcQS6uc371ga1sFhDk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/dataformat/jackson-dataformats-binary/2.20.0/jackson-dataformats-binary-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ZJ/OQKV9Qhx82erCP919XPbzwdG5NAbuJ3xFw1Mm5Yg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-base/2.20.0/jackson-base-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-/IgCjRnuqjftpZbmuY03SfIs/IrdGeoZdFq+g2iDzmY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-bom/2.20.0/jackson-bom-2.20.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-9ig2R+cB/aHNMS3MIcsTKkD3mPGejkL6/D/jR8WlG7s="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/jackson/jackson-parent/2.20/jackson-parent-2.20.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-tDt/XGLoaxZPrnCuF9aRHF22B5mvAQVzYK/aguSEW+U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/fasterxml/oss-parent/70/oss-parent-70.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-JsqO1vgsnS7XzTIpgQW7ZcD52JnbYXV6CXQVhvqTpjk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.10.3/clojure-1.10.3.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-fxJHLa7Y9rUXSYqqKrE6ViR1w+31FHjkWBzHYemJeaM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.10.3/clojure-1.10.3.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-GJwAxDNAdJai+7DsyzeQjJSVXZHq0b5IFWdE7MGBbZQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.0/clojure-1.11.0.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-PiH6daB+yd278bK1A1bPGAcQ0DmN6qT0TpHNYwRVWUc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.0/clojure-1.11.0.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-SQjMS0yeYsmoFJb5PLWsb2lBd8xkXc87jOXkkavOHro="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.1/clojure-1.11.1.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-I4G26UI6tGUVFFWUSQPROlYkPWAGuRlK/Bv0+HEMtN4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.1/clojure-1.11.1.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-IMRaGr7b2L4grvk2BQrjGgjBZ0CzL4dAuIOM3pb/y4o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.2/clojure-1.11.2.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-iPqZkT1pIs+39kn1xGdQOHfLb8yMwW02948mSAhLqZc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.2/clojure-1.11.2.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-FzbP/xCV4dT+/raogrut9ttB7+MV8pbw/aMtt//EExE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.3/clojure-1.11.3.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-nDBUCTKOK5boXdK160t1gQxnt2unCuTQ9t3pvPtVsbc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.3/clojure-1.11.3.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-DA2+Ge4NKpxXMQzr3dNWRD8NFlFMQmBHsGLjpXwNuK0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.4/clojure-1.11.4.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-/H/xtmENDjSUp1zBHvgYEL2kAqwVcBL+TjuJlYbPQTM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.11.4/clojure-1.11.4.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-a6YADmhI+Cw5y5tJqyqmo6Vi9MJNUrMeUZCuZJXwwwk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.0/clojure-1.12.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-xFMzAGRBoFnqn9sTQfxsH0C5IaENzNgmZTEeSKA4R2M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.0/clojure-1.12.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-KfRiqonLl2RXWEGKXwjUwagrc1yW569JgX0WqpuQgVA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.match/1.1.0/core.match-1.1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-10V6tjEIWae9cTmEM4IEX6PN7A0T97qSEpfy8/uZj1M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.match/1.1.0/core.match-1.1.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-NnHYN2UlIwq6Ah8fYmx54g86ELYrXfgXIiWJDsSv4EU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-/PRCveArBKhj8vzFjuaiowxM8Mlw99q4VjTwq3ERZrY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-AarxdIP/HHSCySoHKV1+e8bjszIt9EsptXONAg/wB0A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-Bu6owHC75FwVhWfkQ0OWgbyMRukSNBT4G/oyukLWy8g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-F3i70Ti9GFkLgFS+nZGdG+toCfhbduXGKFtn1Ad9MA4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.4.74/core.specs.alpha-0.4.74.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-63OsCM9JuoQMiLpnvu8RM2ylVDM9lAiAjXiUbg/rnds="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.specs.alpha/0.4.74/core.specs.alpha-0.4.74.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-M0EOuKpz1S2Vez3G4KZfOZisBiPL2BPZDDPm5onEJCk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/0.3.0/pom.contrib-0.3.0.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-fxgrOypUPgV0YL+T/8XpzvasUn3xoTdqfZki6+ee8Rk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/1.1.0/pom.contrib-1.1.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-EOzku1+YKQENwWVh9C67g7ry9HYFtR+RBbkvPKoIlxU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/1.2.0/pom.contrib-1.2.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-CRbXpBVYuVAKQnyIb6KYJ6zlJZIGvjrTPmTilvwaYRE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-z2iZ+YUpjGSxPqEplGrZAo3uja3w6rmuGORVAn04JJw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-WhHw4eizwFLmUcSYxpRbRNs1Nb8sGHGf3PZd8fiLE+Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-Z+yJjrVcZqlXpVJ53YXRN2u5lL2HZosrDeHrO5foquA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"hash": "sha256-bY3hTDrIdXYMX/kJVi/5hzB3AxxquTnxyxOeFp/pB1g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.5.238/spec.alpha-0.5.238.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-lM2ZtupjlkHzevSGCmQ7btOZ7lqL5dcXz/C2Y8jXUHc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.5.238/spec.alpha-0.5.238.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-PLp+DcwIXEzpLd3/6iJhJP+sF4vnm9A3m1suMKlpy+o="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.logging/1.3.0/tools.logging-1.3.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-gmlpt42a2jJ95rfaDxdkV9lWFPo4woAyZhDzGmtRXJE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.logging/1.3.0/tools.logging-1.3.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-E15H98p5wKoYG2kJPML50aYyKt1qgli2aXxQCNIwv00="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/junit/junit-bom/5.13.4/junit-bom-5.13.4.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-16CKmbJQLwu2jNTh+YTwv2kySqogi9D3M2bAP8NUikI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SapkjttsFOVwlaEbOR6u5gZXgyP7eXVfkjMaxjAPl6A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-H9VZA1l1INzUrnbmoz7/XjWmFUIrutKo7ZrDMqr75KA="
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{:deps {org.clojure/tools.logging {:mvn/version "1.3.0"}
|
||||
babashka/fs {:mvn/version "0.5.24"}
|
||||
org.clojure/core.match {:mvn/version "1.1.0"}
|
||||
cheshire/cheshire {:mvn/version "6.1.0"}
|
||||
babashka/process {:mvn/version "0.6.25"}
|
||||
io.github.msyds/spec-dict
|
||||
{:git/sha "531d629b7f05f37232261cf9e8927a4b5915714f"}
|
||||
hiccup/hiccup {:mvn/version "2.0.0-RC4"}
|
||||
com.rpl/specter {:mvn/version "1.1.6"}
|
||||
lambdaisland/deep-diff2 {:mvn/version "2.12.219"}
|
||||
mvxcvi/clj-cbor {:mvn/version "1.1.1"}
|
||||
ch.qos.logback/logback-classic {:mvn/version "1.1.3"}}
|
||||
:paths ["src" "resources" "test"]
|
||||
:aliases
|
||||
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
|
||||
:main-opts ["-m" "kaocha.runner"]}}}
|
||||
@@ -1 +0,0 @@
|
||||
#+title: doerg-temml-worker
|
||||
@@ -1,6 +0,0 @@
|
||||
{:deps {babashka/fs {:mvn/version "0.5.24"}
|
||||
cheshire/cheshire {:mvn/version "6.1.0"}
|
||||
com.rpl/specter {:mvn/version "1.1.6"}
|
||||
mvxcvi/clj-cbor {:mvn/version "1.1.1"}
|
||||
babashka/process {:mvn/version "0.6.25"}}
|
||||
:paths ["." "classes"]}
|
||||
@@ -1,5 +0,0 @@
|
||||
(ns deserialise
|
||||
(:require [clj-cbor.core :as cbor]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(prn (cbor/decode cbor/default-codec System/in :eof))
|
||||
@@ -1,19 +0,0 @@
|
||||
(ns serialise
|
||||
(:require [clj-cbor.core :as cbor]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn w [x]
|
||||
(cbor/encode cbor/default-codec System/out x))
|
||||
|
||||
(defn c [x]
|
||||
(->> x cbor/encode (map #(format "%02x" %)) (str/join " ")))
|
||||
|
||||
#_
|
||||
(w "\\naturalto")
|
||||
|
||||
(w "\\ifxetex blah \\fi")
|
||||
|
||||
#_#_#_
|
||||
(w "c = \\sqrt{a^2 + y^2}")
|
||||
(w "c = \\sqrt{a^ + y^2")
|
||||
(w "\\alpha^\\beta")
|
||||
@@ -1,11 +0,0 @@
|
||||
\documentclass{article}
|
||||
\usepackage{amsmath}
|
||||
\usepackage[active,tightpage,auctex,dvips]{preview}
|
||||
\usepackage{fontspec}
|
||||
\usepackage{ifxetex}
|
||||
\usepackage{syd-plex}
|
||||
|
||||
\begin{document}
|
||||
\setlength\abovedisplayskip{0pt}
|
||||
% {{contents}}
|
||||
\end{document}
|
||||
@@ -1,35 +0,0 @@
|
||||
(ns net.deertopia.doerg.config
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[babashka.fs :as fs]
|
||||
[spec-dict.main :refer [dict]]))
|
||||
|
||||
(s/def ::config
|
||||
(s/keys :req [::ibm-plex-web
|
||||
::latex
|
||||
::dvisvgm]))
|
||||
|
||||
(s/def ::file
|
||||
#(or (instance? java.io.File %)
|
||||
(string? %)))
|
||||
|
||||
(def default
|
||||
{::ibm-plex-web
|
||||
(or (System/getenv "DOERG_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"})
|
||||
|
||||
(def ^:dynamic *cfg* default)
|
||||
|
||||
(s/def ::ibm-plex-web ::file)
|
||||
|
||||
(s/def ::latex ::file)
|
||||
|
||||
(s/def ::dvisvgm ::file)
|
||||
|
||||
(s/def ::doerg-temml-worker ::file)
|
||||
@@ -1,4 +0,0 @@
|
||||
(ns net.deertopia.doerg.tex
|
||||
(:require [net.deertopia.doerg.tex.native :as native]
|
||||
[net.deertopia.doerg.tex.temml :as temml]
|
||||
[babashka.fs :as fs]))
|
||||
@@ -1,68 +0,0 @@
|
||||
(ns net.deertopia.doerg.tex.temml
|
||||
(:require [babashka.process :as p]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[clj-cbor.core :as cbor]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as l]
|
||||
[babashka.fs :as fs])
|
||||
(:import (java.io ByteArrayOutputStream)))
|
||||
|
||||
(def ^:dynamic *worker-timeout-duration*
|
||||
"Number of milliseconds to wait before killing the external Uniorg
|
||||
process."
|
||||
(* 10 1000))
|
||||
|
||||
(def ^:dynamic *worker*)
|
||||
|
||||
(defn worker [& {:keys [preamble]}]
|
||||
(let [doerg-temml-worker (::cfg/doerg-temml-worker cfg/*cfg*)]
|
||||
(p/process
|
||||
{:shutdown p/destroy-tree
|
||||
:err (l/log-stream :info "temml/err")}
|
||||
doerg-temml-worker
|
||||
"--preamble"
|
||||
"resources/net/deertopia/doerg/prelude.tex")))
|
||||
|
||||
(defn close-worker [tw]
|
||||
(.close (:in tw)))
|
||||
|
||||
(defmacro with-worker [tw & body]
|
||||
`(let [~tw (worker)]
|
||||
(try
|
||||
(do ~@body)
|
||||
(finally
|
||||
(close-worker ~tw)
|
||||
(p/destroy-tree ~tw)))))
|
||||
|
||||
(defmacro binding-worker [& body]
|
||||
`(binding [*worker* (worker)]
|
||||
(try
|
||||
~@body
|
||||
(finally
|
||||
(close-worker *worker*)))))
|
||||
|
||||
(defn command-worker [x]
|
||||
(cbor/encode cbor/default-codec (:in *worker*) x)
|
||||
(.flush (:in *worker*))
|
||||
(cbor/decode cbor/default-codec (:out *worker*)))
|
||||
|
||||
(defn render-inline [s]
|
||||
(command-worker s))
|
||||
|
||||
(defn render-display [s]
|
||||
(command-worker [s]))
|
||||
|
||||
(defn render [s]
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\[(.*)\\]" s)]
|
||||
(render-display inner)
|
||||
(if (re-matches #"(?s)\\begin\{.+?}(.*?)\\end\{.+?}" s)
|
||||
(render-display s)
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\\((.*)\\\)" s)]
|
||||
(render-inline inner)
|
||||
(throw (ex-info "weird" {:snippet s}))))))
|
||||
|
||||
;; hackky....
|
||||
(defn erroneous-output? [s]
|
||||
(re-find #"(#b22222|temml-error)" s))
|
||||
@@ -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))))
|
||||
@@ -1,51 +0,0 @@
|
||||
(ns net.deertopia.doerg.element-test
|
||||
(:require [net.deertopia.doerg.element :as sut]
|
||||
[babashka.process :as p]
|
||||
[clojure.test :as t]
|
||||
[clojure.zip :as z]
|
||||
[clojure.java.io :as io]
|
||||
[com.rpl.specter :as sp]))
|
||||
|
||||
(defn- first-child-of-type [parent type]
|
||||
(some #(and (sut/of-type? % type) %) (:children parent)))
|
||||
|
||||
(defn- parse-resource [path]
|
||||
(-> (str "net/deertopia/doerg/element_test/" path)
|
||||
io/resource slurp sut/read-string))
|
||||
|
||||
(t/deftest known-greater-elements
|
||||
(t/testing "known greater elements satisfy `greater-element?`"
|
||||
(let [root (parse-resource "greater-elements.org")
|
||||
section (->> root
|
||||
(sp/select [sut/children-walker
|
||||
#(sut/of-type? % "section")])
|
||||
second)
|
||||
headline (first-child-of-type section "headline")
|
||||
headline-text (first-child-of-type headline "text")
|
||||
paragraph (first-child-of-type section "paragraph")
|
||||
paragraph-text (first-child-of-type paragraph "text")]
|
||||
(t/is (sut/greater-element? root))
|
||||
(t/is (sut/greater-element? section))
|
||||
(t/is (sut/greater-element? headline))
|
||||
(t/is (not (sut/greater-element? headline-text)))
|
||||
(t/is (sut/greater-element? paragraph))
|
||||
(t/is (not (sut/greater-element? paragraph-text))))))
|
||||
|
||||
(defn- first-paragraph-belongs-to-first-section? [doc]
|
||||
(let [first-paragraph (sp/select-first [sut/postorder-walker
|
||||
#(sut/of-type? % "paragraph")]
|
||||
doc)
|
||||
first-section (sp/select-first [sut/postorder-walker
|
||||
#(sut/of-type? % "section")]
|
||||
doc)]
|
||||
(if (and first-paragraph first-section)
|
||||
(boolean (some #(= % first-paragraph)
|
||||
(:children first-section)))
|
||||
true)))
|
||||
|
||||
(t/deftest first-paragraph-under-first-section
|
||||
(t/testing "first paragraph should belong to a section"
|
||||
(t/is (-> (parse-resource "first-paragraph-under-first-section.org")
|
||||
first-paragraph-belongs-to-first-section?))
|
||||
(t/is (not (-> (parse-resource "first-paragraph-under-heading.org")
|
||||
first-paragraph-belongs-to-first-section?)))))
|
||||
40
flake.lock
generated
40
flake.lock
generated
@@ -59,24 +59,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-fetcher-data": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
@@ -129,11 +111,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1760038930,
|
||||
"narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
|
||||
"lastModified": 1774386573,
|
||||
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
|
||||
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -162,7 +144,6 @@
|
||||
"root": {
|
||||
"inputs": {
|
||||
"clj-nix": "clj-nix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"sydpkgs": "sydpkgs"
|
||||
}
|
||||
@@ -184,21 +165,6 @@
|
||||
"repo": "sydpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
||||
80
flake.nix
80
flake.nix
@@ -1,7 +1,6 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
clj-nix.url = "github:jlesquembre/clj-nix";
|
||||
sydpkgs.url = "github:msyds/sydpkgs";
|
||||
};
|
||||
@@ -16,15 +15,15 @@
|
||||
];
|
||||
|
||||
each-system = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec {
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
inputs.sydpkgs.overlays.default
|
||||
clj-nix.overlays.default
|
||||
self.overlays.default
|
||||
];
|
||||
};
|
||||
inherit (pkgs) lib;
|
||||
clj-nix.overlays.default
|
||||
self.overlays.default
|
||||
];
|
||||
};
|
||||
inherit (pkgs) lib;
|
||||
inherit system;
|
||||
});
|
||||
in {
|
||||
@@ -32,48 +31,45 @@
|
||||
_pkgs = each-system ({ pkgs, ... }: pkgs);
|
||||
|
||||
packages = each-system ({ pkgs, ... }: {
|
||||
inherit (pkgs) publisher doerg doerg-parser doerg-temml-worker;
|
||||
default = pkgs.publisher;
|
||||
inherit (pkgs) doerg doerg-parser doerg-temml-worker;
|
||||
default = pkgs.doerg;
|
||||
});
|
||||
|
||||
overlays.default = final: prev:
|
||||
let graal = x: final.mkGraalBin { cljDrv = x; };
|
||||
vendored = final.callPackage ./vendor {};
|
||||
in {
|
||||
inherit (vendored) ibm-plex-web;
|
||||
publisher = final.callPackage ./publisher/package.nix {};
|
||||
doerg = final.callPackage ./doerg/package.nix {};
|
||||
doerg-parser = final.callPackage ./doerg/doerg-parser {};
|
||||
doerg-temml-worker = final.callPackage ./doerg/doerg-temml-worker {};
|
||||
};
|
||||
in {
|
||||
ibm-plex-web = final.callPackage ./ibm-plex-web.nix {};
|
||||
doerg = final.callPackage ./. {};
|
||||
doerg-parser = final.callPackage ./doerg-parser {};
|
||||
doerg-temml-worker = final.callPackage ./doerg-temml-worker {};
|
||||
our-tex = final.callPackage ./our-tex.nix {};
|
||||
};
|
||||
|
||||
checks = each-system ({ pkgs, system, ... }: {
|
||||
build-all =
|
||||
pkgs.linkFarmFromDrvs
|
||||
"all"
|
||||
(pkgs.lib.attrValues self.packages.${system});
|
||||
build-all =
|
||||
pkgs.linkFarmFromDrvs
|
||||
"all"
|
||||
(pkgs.lib.attrValues self.packages.${system});
|
||||
});
|
||||
|
||||
devShells = each-system ({ pkgs, system, ... }: {
|
||||
default = pkgs.mkShell {
|
||||
inputsFrom = [
|
||||
pkgs.doerg
|
||||
pkgs.doerg-parser
|
||||
pkgs.doerg-temml-worker
|
||||
];
|
||||
packages = with pkgs; [
|
||||
clojure-lsp
|
||||
doerg-parser
|
||||
doerg-temml-worker
|
||||
# wahhh ibm-plex-web is a dependency of doerg... why must
|
||||
# i specify it hereeee.
|
||||
# ibm-plex-web
|
||||
zprint
|
||||
clojure
|
||||
babashka
|
||||
sqlite-web
|
||||
];
|
||||
};
|
||||
default = pkgs.mkShell {
|
||||
inputsFrom = [
|
||||
pkgs.doerg
|
||||
pkgs.doerg-parser
|
||||
pkgs.doerg-temml-worker
|
||||
];
|
||||
packages = with pkgs; [
|
||||
clojure-lsp
|
||||
doerg-parser
|
||||
doerg-temml-worker
|
||||
zprint
|
||||
clojure
|
||||
babashka
|
||||
sqlite-web
|
||||
pkgs.doerg.test-emacs
|
||||
];
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -39,5 +39,6 @@ texlive.combine {
|
||||
collection-fontsrecommended # Essential fonts.
|
||||
etoolbox # For Org-mode exports.
|
||||
caption
|
||||
standalone
|
||||
;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
((nil
|
||||
. ((cider-clojure-cli-aliases . ":dev")
|
||||
(eval
|
||||
. (progn
|
||||
(defun start-deertopia-server ()
|
||||
(let ((n (cider-format-connection-params "%j" cider-launch-params)))
|
||||
(when (equal n "net-deertopia")
|
||||
(cider-interactive-eval
|
||||
"(do (require '[net.deertopia.publisher.server :as server])
|
||||
(server/start!))"))))
|
||||
(add-hook 'cider-connected-hook #'start-deertopia-server))))))
|
||||
@@ -1,23 +0,0 @@
|
||||
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}
|
||||
http-kit/http-kit {:mvn/version "2.8.0"}
|
||||
org.clojure/tools.logging {:mvn/version "1.3.0"}
|
||||
hiccup/hiccup {:mvn/version "2.0.0-RC4"}
|
||||
compojure/compojure {:mvn/version "1.7.1"}
|
||||
org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"}
|
||||
ring/ring-defaults {:mvn/version "0.6.0"}
|
||||
babashka/fs {:mvn/version "0.5.24"}
|
||||
org.clojure/core.match {:mvn/version "1.1.0"}
|
||||
com.github.seancorfield/next.jdbc {:mvn/version "1.3.1070"}
|
||||
org.xerial/sqlite-jdbc {:mvn/version "3.47.1.0"}
|
||||
cheshire/cheshire {:mvn/version "6.1.0"}
|
||||
instaparse/instaparse {:mvn/version "1.5.0"}
|
||||
babashka/process {:mvn/version "0.6.25"}
|
||||
org.clojure/test.check {:mvn/version "1.1.2"}
|
||||
#_#_
|
||||
io.github.msyds/spec-dict
|
||||
{:git/sha "531d629b7f05f37232261cf9e8927a4b5915714f"}
|
||||
net.deertopia/doerg {:local/root "../doerg"}}
|
||||
:paths ["src" "resources" "test"]
|
||||
:aliases
|
||||
{:dev
|
||||
{:extra-deps {vvvvalvalval/scope-capture-nrepl {:mvn/version "0.3.1"}}}}}
|
||||
@@ -1,53 +0,0 @@
|
||||
;;; -*- mode:clojure -*-
|
||||
;;;
|
||||
;;; USAGE:
|
||||
;;;
|
||||
;;; bb -cp . -m override-deps -- [DEP-NAME INFO]…
|
||||
;;;
|
||||
;;; This script takes a series of deps substitutions on the command
|
||||
;;; line, applies them to a deps.edn file (read on stdin), and spits
|
||||
;;; the result to stdout.
|
||||
;;;
|
||||
;;; It is used to build the Doerg server with Nix, since Clj-nix does
|
||||
;;; not resolve the local deps itself.
|
||||
|
||||
(ns override-deps
|
||||
(:require [rewrite-clj.zip :as z]
|
||||
[babashka.fs :as fs]
|
||||
[clojure.edn :as edn]))
|
||||
|
||||
(defn apply-overrides [zloc overrides]
|
||||
(loop [os (seq overrides)
|
||||
loc zloc]
|
||||
(if-some [[[k v] & xs] os]
|
||||
(recur xs (z/assoc loc k v))
|
||||
loc)))
|
||||
|
||||
(defn args->overrides [args]
|
||||
(assert (even? (count args)))
|
||||
(->> args (map edn/read-string) (apply hash-map)))
|
||||
|
||||
(defn -main [& args]
|
||||
(let [zloc (-> (slurp *in*) z/of-string)
|
||||
overrides (args->overrides args)]
|
||||
(-> zloc
|
||||
z/down
|
||||
(z/find-value :deps) z/right
|
||||
(apply-overrides overrides)
|
||||
z/root-string
|
||||
print)))
|
||||
|
||||
|
||||
|
||||
(comment
|
||||
"Example overrides"
|
||||
(def overrides '{net.deertopia/doerg "blah!!!!"
|
||||
ring/ring-defaults {:mvn/version "xxxxx"}}))
|
||||
|
||||
(comment
|
||||
"Behaviour of `args->overrides`."
|
||||
(= (args->overrides ["net.deertopia/doerg" "{:mvn/version \"abc\"}"
|
||||
"ring/ring-defaults" "{:local/root \"/path/to/jar\"}"])
|
||||
'{ring/ring-defaults {:local/root "/path/to/jar"}
|
||||
net.deertopia/doerg {:mvn/version "abc"}}))
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{ mkCljBin
|
||||
, doerg
|
||||
, babashka
|
||||
}:
|
||||
|
||||
mkCljBin {
|
||||
name = "net.deertopia/publisher";
|
||||
version = "0.1.0";
|
||||
projectSrc = ./.;
|
||||
lockfile = ../deps-lock.json;
|
||||
main-ns = "net.deertopia.publisher.main";
|
||||
buildInputs = [];
|
||||
nativeBuildInputs = [
|
||||
babashka
|
||||
];
|
||||
postPatch = ''
|
||||
mv deps.edn deps.edn.old
|
||||
bb -cp . -m override-deps < deps.edn.old > deps.edn \
|
||||
net.deertopia/doerg '{:local/root "${doerg.lib}/${doerg.name}.jar"}'
|
||||
'';
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
(ns net.deertopia.publisher.main
|
||||
(:require [net.deertopia.doerg.main :as doerg])
|
||||
(:gen-class))
|
||||
|
||||
(defn -main []
|
||||
(doerg/-main)
|
||||
(println "hi from publisher"))
|
||||
@@ -1,25 +0,0 @@
|
||||
{ fetchzip
|
||||
, fetchurl
|
||||
}:
|
||||
|
||||
{
|
||||
ibm-plex-serif = fetchzip {
|
||||
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-serif%401.1.0/ibm-plex-serif.zip";
|
||||
hash = "sha256-8ygaAeMKygYS4GCub4YUQmkh87pYHfi3s0PQ6AbaeGw=";
|
||||
};
|
||||
|
||||
ibm-plex-math = fetchzip {
|
||||
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-math%401.1.0/ibm-plex-math.zip";
|
||||
hash = "sha256-dJA6uqxa/yb3eLY4l39NeP0yIl2NfrbaRpf6h0/F7Xc=";
|
||||
};
|
||||
|
||||
ibm-plex-sans-kr = fetchzip {
|
||||
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-sans-kr%401.1.0/ibm-plex-sans-kr.zip";
|
||||
hash = "sha256-FsHxMvLlI4yylgG96DOZIdW2DYpk7I+c5QgkVIkNZIE=";
|
||||
};
|
||||
|
||||
"d3.v7.min.js" = fetchurl {
|
||||
url = "https://d3js.org/d3.v7.min.js";
|
||||
hash = "sha256-8glLv2FBs1lyLE/kVOtsSw8OQswQzHr5IfwVj864ZTk=";
|
||||
};
|
||||
}
|
||||
18
resources/net/deertopia/doerg/default-config.edn
Normal file
18
resources/net/deertopia/doerg/default-config.edn
Normal file
@@ -0,0 +1,18 @@
|
||||
#:net.deertopia.doerg.config
|
||||
{:ibm-plex-web #or [#xdg-data-dir "ibm-plex-web"
|
||||
#env IBM_PLEX_WEB]
|
||||
:latex "xelatex"
|
||||
:dvisvgm "dvisvgm"
|
||||
:doerg-temml-worker
|
||||
#profile {:dev #file "../../../../doerg-temml-worker/index.js"
|
||||
:default "doerg-temml-worker"}
|
||||
:doerg-parser
|
||||
#profile {:dev #file "../../../../doerg-parser/index.js"
|
||||
:default "doerg-parser"}
|
||||
:state-directory #join [#or [#env XDG_STATE_HOME
|
||||
#envf ["%s/.local/share" HOME]]
|
||||
"/doerg-server"]
|
||||
:org-roam-db-path
|
||||
#profile {:default #join [#env HOME "/.cache/emacs/org-roam.db"]
|
||||
:test #join [#or [#env TMP "/tmp"] "/doerg-org-roam-test.db"]}
|
||||
:port #profile {:default 8080}}
|
||||
30
resources/net/deertopia/doerg/elisp/grammar
Normal file
30
resources/net/deertopia/doerg/elisp/grammar
Normal file
@@ -0,0 +1,30 @@
|
||||
<file> ::= elements
|
||||
|
||||
<elements> ::= ws? element ws? elements
|
||||
| ws? ε
|
||||
|
||||
<element> ::= string
|
||||
| list
|
||||
| symbol
|
||||
| integer
|
||||
| property-string
|
||||
|
||||
string ::= <'"'> #'([^"\\]|\\.|\\\n)*' <'"'>
|
||||
|
||||
property-string
|
||||
::= <'#('> ws? string text-property* ws? <')'>
|
||||
|
||||
text-property ::= ws? element ws? element ws? element
|
||||
|
||||
list ::= <'('> elements dot-cdr? <')'>
|
||||
|
||||
symbol ::= #'([^?#0-9 \n\s\f()\[\]"\'\\.]|\\.)([^ \n\s\f()\[\]"\'\\]|\\.)*'
|
||||
| #'\.([^ \n\s\f()\[\]"\'\\]|\\.)+'
|
||||
|
||||
integer ::= #'[-+]?[0-9]+' <#'.'>?
|
||||
|
||||
dot-cdr ::= <'.'> ws? element
|
||||
|
||||
<text> ::= ws? (string | property-string) ws?
|
||||
|
||||
<ws> ::= <#'(\s||\n)'>+
|
||||
BIN
resources/net/deertopia/doerg/favicon.ico
Normal file
BIN
resources/net/deertopia/doerg/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
5
resources/net/deertopia/doerg/native-prelude.tex
Normal file
5
resources/net/deertopia/doerg/native-prelude.tex
Normal file
@@ -0,0 +1,5 @@
|
||||
% Default uses arrow glyphs from the active font, which are kinda ugly in the
|
||||
% case of Plex.
|
||||
\tikzcdset{
|
||||
arrow style=tikz
|
||||
}
|
||||
19
resources/net/deertopia/doerg/preview-template.tex
Normal file
19
resources/net/deertopia/doerg/preview-template.tex
Normal file
@@ -0,0 +1,19 @@
|
||||
\documentclass[tikz,dvisvgm]{standalone}
|
||||
\usepackage[active,tightpage,auctex,dvips]{preview}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{ifxetex}
|
||||
\usepackage{syd-plex}
|
||||
\usepackage{quiver}
|
||||
\usepackage{tikz}
|
||||
\usepackage{amscd}
|
||||
\usepackage{metalogo}
|
||||
|
||||
% {{preamble}}
|
||||
|
||||
\begin{document}
|
||||
\setlength\abovedisplayskip{0pt} % Remove padding before equation environments.
|
||||
|
||||
% {{contents}}
|
||||
|
||||
\end{document}
|
||||
1
resources/net/deertopia/doerg/public/Temml-Plex.css
Symbolic link
1
resources/net/deertopia/doerg/public/Temml-Plex.css
Symbolic link
@@ -0,0 +1 @@
|
||||
../Temml-Plex.css
|
||||
1
resources/net/deertopia/doerg/public/deerstar.css
Symbolic link
1
resources/net/deertopia/doerg/public/deerstar.css
Symbolic link
@@ -0,0 +1 @@
|
||||
../deerstar.css
|
||||
1
resources/net/deertopia/doerg/public/tuftesque.css
Symbolic link
1
resources/net/deertopia/doerg/public/tuftesque.css
Symbolic link
@@ -0,0 +1 @@
|
||||
../tuftesque.css
|
||||
@@ -104,6 +104,7 @@ section {
|
||||
p,
|
||||
dl,
|
||||
ol,
|
||||
.latex-fragment,
|
||||
ul {
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.5rem;
|
||||
@@ -114,6 +115,7 @@ p {
|
||||
margin-bottom: 1.4rem;
|
||||
padding-right: 0;
|
||||
vertical-align: baseline;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
/* Chapter Epigraphs */
|
||||
@@ -436,7 +438,7 @@ label.margin-toggle:not(.sidenote-number) {
|
||||
}
|
||||
}
|
||||
|
||||
.link.external::after
|
||||
.org-link.external::after
|
||||
{ content: "↗"
|
||||
; vertical-align: super
|
||||
; font-size: 1rem
|
||||
@@ -444,8 +446,8 @@ label.margin-toggle:not(.sidenote-number) {
|
||||
}
|
||||
|
||||
.center
|
||||
{ align-items: "center"
|
||||
; justify-content: "center"
|
||||
{ align-items: center
|
||||
; justify-content: center
|
||||
; display: flex
|
||||
; max-width: 55%
|
||||
}
|
||||
@@ -549,10 +551,15 @@ figure.fullwidth figcaption {
|
||||
|
||||
.latex-fragment.display-math
|
||||
{ display: block
|
||||
; width: 55%
|
||||
/* Center it — do we want to do that? */
|
||||
; align-items: center
|
||||
; justify-content: center
|
||||
; display: flex
|
||||
; max-width: 55%
|
||||
; width: 55%
|
||||
}
|
||||
|
||||
p > .latex-fragment.display-math
|
||||
{ max-width: 100%
|
||||
; width: 100%
|
||||
}
|
||||
25
src/net/deertopia/doerg/cached_file.clj
Normal file
25
src/net/deertopia/doerg/cached_file.clj
Normal file
@@ -0,0 +1,25 @@
|
||||
(ns net.deertopia.doerg.cached-file
|
||||
(:require [babashka.fs :as fs]))
|
||||
|
||||
(defn newer-than?
|
||||
"Return `true` if fs `file₁` was last modified sooner or at the same
|
||||
time as `file₂`, or if `file₂` does not exist."
|
||||
[file₁ file₂]
|
||||
(or (not (fs/exists? file₂))
|
||||
(<= 0 (compare (fs/last-modified-time file₁)
|
||||
(fs/last-modified-time file₂)))))
|
||||
|
||||
(def ^:dynamic *use-cache?*
|
||||
"Bind to `false` to disable caching for debugging purposes."
|
||||
true)
|
||||
|
||||
(defn cached-file
|
||||
"Return a file path after potentially regenerating the file by
|
||||
calling `compute` with no arguments only if stale? is logical true."
|
||||
[& {:keys [file stale? compute]}]
|
||||
(when (or (not *use-cache?*) stale?)
|
||||
(let [r (compute)]
|
||||
(assert (string? r))
|
||||
(fs/create-dirs (fs/parent file))
|
||||
(spit file r)))
|
||||
file)
|
||||
82
src/net/deertopia/doerg/config.clj
Normal file
82
src/net/deertopia/doerg/config.clj
Normal file
@@ -0,0 +1,82 @@
|
||||
(ns net.deertopia.doerg.config
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[babashka.fs :as fs]
|
||||
[aero.core :as aero]
|
||||
[clojure.java.io :as io]))
|
||||
|
||||
(s/def ::config
|
||||
(s/keys :req [::ibm-plex-web
|
||||
::latex
|
||||
::dvisvgm
|
||||
::doerg-temml-worker
|
||||
::doerg-parser
|
||||
::state-directory
|
||||
::org-roam-db-path]))
|
||||
|
||||
(s/def ::directory
|
||||
(s/conformer #(fs/file %)))
|
||||
|
||||
(s/def ::file
|
||||
(s/conformer #(-> % fs/expand-home fs/file)))
|
||||
|
||||
(s/def ::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 ::ibm-plex-web ::directory)
|
||||
|
||||
(s/def ::latex ::executable)
|
||||
|
||||
(s/def ::dvisvgm ::executable)
|
||||
|
||||
(s/def ::doerg-temml-worker ::executable)
|
||||
|
||||
(s/def ::doerg-parser ::executable)
|
||||
|
||||
(s/def ::state-directory ::file)
|
||||
(s/def ::org-roam-db-path ::file)
|
||||
|
||||
(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"))))
|
||||
|
||||
(defmethod aero/reader 'file
|
||||
[{:keys [source]} tag value]
|
||||
"Aero tag to reference a `java.io.File` relative to the config
|
||||
file."
|
||||
(-> (aero/relative-resolver source value)
|
||||
fs/file))
|
||||
|
||||
(defn read-config [files & {:as opts}]
|
||||
(let [r (->> files
|
||||
(filter identity)
|
||||
(map #(aero/read-config % opts))
|
||||
(apply merge))
|
||||
conformed (s/conform ::config r)]
|
||||
(if-not (s/invalid? conformed)
|
||||
conformed
|
||||
(throw (ex-info "Failed to conform config"
|
||||
(s/explain-data ::config r))))))
|
||||
|
||||
(defn load-config! [var spec files & {:as opts}]
|
||||
(alter-var-root var (constantly (read-config files opts))))
|
||||
|
||||
(def sources
|
||||
[;; 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 default (read-config sources))
|
||||
|
||||
(def ^:dynamic *cfg* default)
|
||||
@@ -1,21 +1,25 @@
|
||||
(ns net.deertopia.doerg.element
|
||||
(:require [babashka.process :as p]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[clojure.string :as str]
|
||||
[clojure.zip]
|
||||
[babashka.fs :as fs]
|
||||
[clojure.java.io :as io]
|
||||
(:refer-clojure :exclude [read-string type])
|
||||
(:require [babashka.fs :as fs]
|
||||
[babashka.process :as p]
|
||||
[cheshire.core :as json]
|
||||
[clojure.spec.alpha :as s]
|
||||
[spec-dict.main :refer [dict]]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[clojure.core.match :refer [match]]
|
||||
[net.deertopia.doerg :as-alias doerg]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as str]
|
||||
[clojure.test.check.generators :as gen]
|
||||
[clojure.tools.logging.readable :as lr]
|
||||
[clojure.zip :as z]
|
||||
[com.rpl.specter :as sp]
|
||||
[clojure.tools.logging.readable :as lr])
|
||||
(:import (java.util UUID))
|
||||
(:refer-clojure :exclude [read-string]))
|
||||
|
||||
[com.rpl.specter.zipper :as sz]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[clojure.tools.logging :as l])
|
||||
(:import
|
||||
(java.util UUID)))
|
||||
|
||||
(defonce ^:private uniorg-script-path-atom (atom nil))
|
||||
|
||||
|
||||
(def ^:dynamic *uniorg-timeout-duration*
|
||||
"Number of milliseconds to wait before killing the external Uniorg
|
||||
@@ -31,19 +35,21 @@
|
||||
:or {in *in*}}]
|
||||
(let [r (-> (p/process
|
||||
{:in in :out :string}
|
||||
"doerg-parser")
|
||||
(-> cfg/*cfg* ::doerg/doerg-parser str))
|
||||
(common/deref-with-timeout *uniorg-timeout-duration*))]
|
||||
(if (zero? (:exit r))
|
||||
(when (zero? (:exit r))
|
||||
(-> r :out (json/parse-string (comp keyword camel->kebab))))))
|
||||
|
||||
(declare gather-first-section)
|
||||
(declare gather-first-section gather-latex-paragraphs element-types)
|
||||
|
||||
(defn read-string [s & {:keys [post-processors]
|
||||
:or {post-processors [gather-first-section]}}]
|
||||
(defn read-string
|
||||
[s & {:keys [post-processors]
|
||||
:or {post-processors [gather-first-section
|
||||
gather-latex-paragraphs]}}]
|
||||
(let [apply-post-processors (apply comp (reverse post-processors))]
|
||||
(with-in-str s
|
||||
(-> (uniorg :in *in*)
|
||||
apply-post-processors))))
|
||||
(-> (uniorg :in *in*)
|
||||
apply-post-processors))))
|
||||
|
||||
|
||||
|
||||
@@ -57,11 +63,12 @@
|
||||
(and (map? e) (contains? e :children)))
|
||||
|
||||
(defn org-element? [element]
|
||||
#_
|
||||
(s/valid? ::org-element element)
|
||||
(and (map? element)
|
||||
(contains? element :type)))
|
||||
|
||||
(defn type [element]
|
||||
(:type element))
|
||||
|
||||
(defn of-type?
|
||||
"Return truthy if the Org node `element` is of type `type`. In the
|
||||
vararg case, return truthy if `element` is of any of the types
|
||||
@@ -88,16 +95,6 @@
|
||||
(and (of-type? element "latex-fragment")
|
||||
(-> element :contents (str/starts-with? "\\[")))))
|
||||
|
||||
|
||||
;;; Spec
|
||||
|
||||
(s/def ::org-element
|
||||
(dict {:type string?}
|
||||
^:opt {:contents-begin nat-int?
|
||||
:contents-end nat-int?
|
||||
:children (s/coll-of ::org-element
|
||||
:kind seq?)}))
|
||||
|
||||
|
||||
;;; Zipper
|
||||
|
||||
@@ -198,6 +195,22 @@
|
||||
:first-section-nodes of-first-section
|
||||
:rest remaining-nodes*}))
|
||||
|
||||
(defn- element-bounds [& nodes]
|
||||
(reduce (fn [acc {:keys [contents-begin contents-end]}]
|
||||
(if (and (nat-int? contents-begin)
|
||||
(nat-int? contents-end))
|
||||
(-> acc
|
||||
(update
|
||||
:contents-begin
|
||||
#(min (or % Integer/MAX_VALUE) contents-begin))
|
||||
(update
|
||||
:contents-end
|
||||
#(max (or % Integer/MIN_VALUE) contents-end)))
|
||||
acc))
|
||||
{:contents-begin nil
|
||||
:contents-end nil}
|
||||
nodes))
|
||||
|
||||
(defn gather-first-section [node]
|
||||
(assert (of-type? node "org-data")
|
||||
"`gather-doerg-data` should be applied to the document root.")
|
||||
@@ -205,8 +218,86 @@
|
||||
(split-sections (:children node))
|
||||
;; TODO: Construct `:contents-begin` and `:contents-end` data
|
||||
;; by spanning the children.
|
||||
new-children (concat top-level-nodes
|
||||
(list {:type "section"
|
||||
:children first-section-nodes})
|
||||
rest)]
|
||||
first-section (merge {:type "section"
|
||||
:children (vec first-section-nodes)}
|
||||
(apply element-bounds first-section-nodes))
|
||||
new-children (vec (concat top-level-nodes
|
||||
(list first-section)
|
||||
rest))]
|
||||
(assoc node :children new-children)))
|
||||
|
||||
(defn- newline-final-paragraph?
|
||||
"Is `e` a paragraph, and does it end with a newline?"
|
||||
[e]
|
||||
(and (of-type? e "paragraph")
|
||||
(some-> (-> e :position :end :column)
|
||||
(= 1))))
|
||||
|
||||
(defn consequtive-elements?
|
||||
"Returh truthy if each successive pair of elements is NOT separated
|
||||
by at least one explicit paragraph break; i.e. a blank line."
|
||||
[& elements]
|
||||
(match elements
|
||||
([(e₁ :guard newline-final-paragraph?) e₂ & es] :seq)
|
||||
(and (= (-> e₁ :position :end :line)
|
||||
(-> e₂ :position :start :line))
|
||||
(recur es))
|
||||
([e₁ e₂ & es] :seq)
|
||||
(and (= (-> e₁ :position :end :line inc)
|
||||
(-> e₂ :position :start :line))
|
||||
(recur es))
|
||||
([_] :seq) true
|
||||
([] :seq) true))
|
||||
|
||||
(defn swallow
|
||||
([predator prey]
|
||||
(assert (greater-element? predator))
|
||||
(-> predator
|
||||
(update :children #(conj % prey))
|
||||
(assoc-in [:position :end] (-> prey :position :end))))
|
||||
([predator prey & more-prey]
|
||||
(reduce swallow predator (cons prey more-prey))))
|
||||
|
||||
(defn- paragraph-followed-by-tex? [children]
|
||||
(match children
|
||||
[(para :guard #(of-type? % "paragraph"))
|
||||
(tex :guard #(of-type? % "latex-environment"))
|
||||
& _]
|
||||
(consequtive-elements? para tex)
|
||||
:else false))
|
||||
|
||||
(defn- paragraph-followed-by-paragraph? [children]
|
||||
(match children
|
||||
[(para₁ :guard #(of-type? % "paragraph"))
|
||||
(para₂ :guard #(of-type? % "paragraph"))
|
||||
& _]
|
||||
(consequtive-elements? para₁ para₂)
|
||||
:else false))
|
||||
|
||||
(defn gather-latex-paragraphs [node]
|
||||
(->> node
|
||||
(sp/transform
|
||||
[postorder-walker (sp/must :children)]
|
||||
(fn [children]
|
||||
(loop [acc []
|
||||
cs (vec children)]
|
||||
(match cs
|
||||
;; CASE: A paragraph followed by a LaTeX environment.
|
||||
;; If there are no blank lines separating the paragraph
|
||||
;; from the LaTeX environment, the LaTeX environment
|
||||
;; shall become a child of the paragraph.
|
||||
([para tex & rest] :guard paragraph-followed-by-tex?)
|
||||
(recur acc (vec (cons (swallow para tex) rest)))
|
||||
;; CASE: Similar to the paragraph-followed-by-tex case,
|
||||
;; but instead of swallowing the entire second element,
|
||||
;; we swallow the /children/ of the second element,
|
||||
;; since paragraphs cannot be nested.
|
||||
([para₁ para₂ & rest]
|
||||
:guard paragraph-followed-by-paragraph?)
|
||||
(recur acc (vec (cons (apply swallow para₁ (:children para₂))
|
||||
rest)))
|
||||
;; CASE: Irrelevant or empty!
|
||||
[c & rest]
|
||||
(recur (conj acc c) rest)
|
||||
[] acc))))))
|
||||
|
||||
119
src/net/deertopia/doerg/elisp.clj
Normal file
119
src/net/deertopia/doerg/elisp.clj
Normal file
@@ -0,0 +1,119 @@
|
||||
(ns net.deertopia.doerg.elisp
|
||||
(:require [clojure.core.match :refer [match]]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.spec.alpha :as s]
|
||||
[instaparse.core :as ip])
|
||||
(:refer-clojure :exclude [print read read-string]))
|
||||
|
||||
(ip/defparser read*
|
||||
(io/resource "net/deertopia/doerg/elisp/grammar"))
|
||||
|
||||
(defn- transform-string [s]
|
||||
(let [s* (loop [s (seq s)
|
||||
acc ""]
|
||||
(match s
|
||||
([\\ c & cs] :seq)
|
||||
(recur
|
||||
cs
|
||||
(str acc
|
||||
(condp = c
|
||||
\n \newline
|
||||
\f \formfeed
|
||||
\\ \\
|
||||
\" \"
|
||||
\newline nil
|
||||
(throw (ex-info "IDK!" {:char c})))))
|
||||
([c & cs] :seq) (recur cs (str acc c))
|
||||
([] :seq) acc))]
|
||||
[:string (apply str s*)]))
|
||||
|
||||
(defn- transform-integer [s]
|
||||
[:integer (parse-long s)])
|
||||
|
||||
(defn- transform-property-string
|
||||
([[_ text]]
|
||||
[:string text])
|
||||
([[_ text] & props]
|
||||
[:string text (->> (for [[_ [_ beg] [_ end] prop] props]
|
||||
{[beg end] prop})
|
||||
(apply merge))]))
|
||||
|
||||
(defn- transform-list [& xs]
|
||||
(match (last xs)
|
||||
[:dot-cdr x] [:cons* (butlast xs) x]
|
||||
_ [:cons* xs]))
|
||||
|
||||
(def transforms {:string transform-string
|
||||
:list transform-list
|
||||
:integer transform-integer
|
||||
:property-string transform-property-string})
|
||||
|
||||
(defn read [s & args]
|
||||
(->> (apply read* s args)
|
||||
(ip/transform transforms)))
|
||||
|
||||
(defn read-string [s]
|
||||
(read s :start :text))
|
||||
|
||||
(defn cons? [x]
|
||||
(= (first x) :cons*))
|
||||
|
||||
(s/def ::alist
|
||||
(s/tuple #{:list}
|
||||
(s/and ::list
|
||||
cons?)))
|
||||
|
||||
(defn car [x]
|
||||
(match x
|
||||
[:cons* xs y] (first xs)
|
||||
[:cons* xs] (first xs)
|
||||
[:symbol "nil"] nil
|
||||
_ nil))
|
||||
|
||||
(defn cdr [x]
|
||||
(match x
|
||||
[:cons* xs y] (if (<= (count xs) 1)
|
||||
y
|
||||
[:cons* (rest xs) y])
|
||||
[:cons* xs] [:cons* (rest xs)]
|
||||
[:symbol "nil"] nil
|
||||
_ nil))
|
||||
|
||||
(defn emacs-list? [x]
|
||||
(match x
|
||||
[:cons* xs] true
|
||||
_ false))
|
||||
|
||||
(defn read-alist [s]
|
||||
(let [r (->> s read*
|
||||
(ip/transform
|
||||
(merge transforms
|
||||
{:symbol (fn [s] (symbol s))
|
||||
:string (fn [s] s)}))
|
||||
first)]
|
||||
(match r
|
||||
[:cons* pairs] (->> (for [pair pairs]
|
||||
(let [x (car pair)
|
||||
y (cdr pair)]
|
||||
{x y}))
|
||||
(apply merge))
|
||||
_ nil)))
|
||||
|
||||
(defn read-string [s]
|
||||
(match (-> s read first)
|
||||
[:string x & props] x
|
||||
:else nil))
|
||||
|
||||
(defn print [x]
|
||||
;; TODO: this is really not how it should be done lol. at the
|
||||
;; moment, `print` is only used in `net.deertopia.doerg.roam`
|
||||
;; and only to serialise uuids, so it's not a /massive/ priority.
|
||||
(cond (or (string? x) (uuid? x)) (str \" x \")
|
||||
:else (throw (ex-info "`print` is unimplemented lol"
|
||||
{:x x}))))
|
||||
|
||||
(comment
|
||||
(do (ip/defparser parse* (io/resource "elisp-grammar"))
|
||||
(read "#(\"blah\" 0 1 (doge))")
|
||||
(read "\"bla\\nh\"")
|
||||
(read-alist "((x . y))")))
|
||||
@@ -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]))
|
||||
|
||||
#_
|
||||
@@ -28,7 +27,7 @@
|
||||
[:meta {:charset "utf-8"}])
|
||||
|
||||
(defn external-stylesheet [href]
|
||||
[:link {:rel "stylesheet" :type "text/css" :href href}])
|
||||
[:link {:rel "stylesheet" :type "text/css" :href (str "/resource/" href)}])
|
||||
|
||||
(def ibm-plex
|
||||
(concat
|
||||
@@ -9,12 +9,11 @@
|
||||
[net.deertopia.doerg.html :as doerg-html]
|
||||
[hiccup2.core :as hiccup]
|
||||
[clojure.pprint]
|
||||
#_
|
||||
[net.deertopia.doerg.tex :as tex]
|
||||
[net.deertopia.doerg.tex.native :as tex-native]
|
||||
[net.deertopia.doerg.tex.temml :as tex-temml]
|
||||
[clojure.zip :as z]
|
||||
[babashka.fs :as fs]))
|
||||
[babashka.fs :as fs]
|
||||
[clojure.edn :as edn]))
|
||||
|
||||
;;; Top-level API
|
||||
|
||||
@@ -41,7 +40,7 @@
|
||||
#(do (assert (element/of-type? % "keyword"))
|
||||
(:key %)))
|
||||
|
||||
(def ^:dynamic ^:private *document-info*)
|
||||
(def ^:dynamic ^:private *opts*)
|
||||
|
||||
(declare ^:private gather-footnotes render-renderer-error
|
||||
view-children-as-seq render-tex-snippets)
|
||||
@@ -58,25 +57,34 @@
|
||||
(lr/error e "Error in renderer" {:node node})
|
||||
(render-renderer-error e)))))))
|
||||
|
||||
(def default-language
|
||||
"Default language, used in the lang attribute of the body tag."
|
||||
"en")
|
||||
|
||||
(defn org-document
|
||||
"Recursively render an Org-mode document to Hiccup."
|
||||
[doc]
|
||||
(tex-temml/binding-worker
|
||||
(let [rendered (-> doc gather-footnotes render-tex-snippets
|
||||
org-element-recursive)]
|
||||
[:html
|
||||
[:head
|
||||
[:title "org document"]
|
||||
doerg-html/head]
|
||||
[:body
|
||||
[:article
|
||||
rendered]]])))
|
||||
[doc & {:as opts :keys [postamble]}]
|
||||
(binding [*opts* opts]
|
||||
(tex-temml/binding-worker
|
||||
(let [rendered (-> doc gather-footnotes render-tex-snippets
|
||||
org-element-recursive)]
|
||||
[:html
|
||||
[:head
|
||||
[:title "org document"]
|
||||
doerg-html/head]
|
||||
[:body {:lang default-language}
|
||||
[:article
|
||||
rendered
|
||||
(when postamble
|
||||
[:footer
|
||||
[:hr]
|
||||
postamble])]]]))))
|
||||
|
||||
(defn to-html
|
||||
"Read `f` with `slurp` as an Org document and return a string of
|
||||
rendered HTML."
|
||||
[f]
|
||||
(str (hiccup/html {} (-> f slurp element/read-string org-document))))
|
||||
rendered HTML. See `org-document` for opts."
|
||||
[f & {:as opts}]
|
||||
(str (hiccup/html {} (-> f slurp element/read-string (org-document opts)))))
|
||||
|
||||
|
||||
;;; Further dispatching on `org-element`
|
||||
@@ -100,6 +108,19 @@
|
||||
(sp/view #(update % :children seq))
|
||||
sp/STAY))
|
||||
|
||||
(defn center [& es]
|
||||
[:div.center es])
|
||||
|
||||
(defn doerg-attrs [e]
|
||||
(->> e :affiliated :attr_doerg (str/join " ")
|
||||
(format "{%s}") edn/read-string))
|
||||
|
||||
(defn em [x]
|
||||
(format "%.4fem" x))
|
||||
|
||||
(defn wrap-if [x c f]
|
||||
(if c (f x) x))
|
||||
|
||||
(defn- contains-footnote-refs? [node]
|
||||
(some #(element/of-type? % "footnote-reference")
|
||||
(:children node)))
|
||||
@@ -143,81 +164,41 @@
|
||||
#(element/of-keyword-type? % "LATEX_HEADER")
|
||||
(sp/view :value)])))
|
||||
|
||||
(defn- read-and-patch-generated-svg [{:keys [file height depth]}]
|
||||
;; dvisvgm writes standalone SVG files, to which we need to make a
|
||||
;; few changes to use them inline within our HTML.
|
||||
;; • XML header: Bad syntax when embedded in an HTML doc. Remove
|
||||
;; it.
|
||||
;; • Width and height: We override these with our own values
|
||||
;; computed by `net.deertopia.doerg.tex` to ensure correct
|
||||
;; positioning relative to the surrounding text. More
|
||||
;; accurately, we remove the height and width attributes from
|
||||
;; the SVG tag, and set the new values for height and
|
||||
;; vertical-align in the style attribute
|
||||
;; • Viewbox: Must be removed entirely for correct positioning.
|
||||
(-> (slurp file)
|
||||
(str/replace-first #"<\?xml version='1.0' encoding='UTF-8'\?>\n?" "")
|
||||
(str/replace-first #" height=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first #" width=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first
|
||||
#"viewBox=['\"][^\"']+[\"']"
|
||||
(fn [s]
|
||||
(format "%s style=\"%s\""
|
||||
s
|
||||
(format "height:%.4fem;vertical-align:%.4fem;display:inline-block"
|
||||
height (- depth)))))))
|
||||
(defn- timeout-snippet-promises [snippet-promises fut]
|
||||
;; Time out after twenty seconds. With all the LaTeX and IPC, there
|
||||
;; are so many opportunities for things to go wrong </3.
|
||||
(let [ms (* 20 1000)
|
||||
fut-res (deref fut ms ::timed-out)]
|
||||
(if (= fut-res ::timed-out)
|
||||
(do (l/warnf "Giving up on rendering TeX snippets after %.3f seconds."
|
||||
(/ ms 1000))
|
||||
(future-cancel fut)
|
||||
(doseq [[_snippet p] snippet-promises]
|
||||
(deliver p ::timed-out)))
|
||||
fut-res)))
|
||||
|
||||
(defn render-tex-snippets
|
||||
"Traverse doc, adorning each LaTeX node with a promise resolving to,
|
||||
optimistically, Hiccup-rendered SVG or MathML code."
|
||||
[doc]
|
||||
(let [promises (atom [])
|
||||
(let [snippet-promises (atom [])
|
||||
r (->> doc (sp/transform
|
||||
[element/postorder-walker
|
||||
#(element/of-type?
|
||||
% "latex-fragment" "latex-environment")]
|
||||
(fn [node]
|
||||
(let [p (promise)]
|
||||
(swap! promises #(conj % {:promise p :node node}))
|
||||
(swap! snippet-promises #(conj % [(:value node) p]))
|
||||
(assoc node ::rendered p)))))
|
||||
f (fn []
|
||||
(fs/with-temp-dir [svg-dir {:prefix "doerg-svg"}]
|
||||
(let [rendered-snippets
|
||||
(delay (->> @promises
|
||||
(map #(-> % :node :value))
|
||||
(apply tex-native/render svg-dir)))]
|
||||
(doseq [{:keys [promise node]} @promises]
|
||||
(try (let [{:keys [value]} node
|
||||
temml (tex-temml/render value)]
|
||||
(if (tex-temml/erroneous-output? temml)
|
||||
(let [tex (get @rendered-snippets value)]
|
||||
(if (:errors tex)
|
||||
(deliver promise (hiccup/raw temml))
|
||||
(->> tex
|
||||
read-and-patch-generated-svg
|
||||
hiccup/raw
|
||||
(deliver promise))))
|
||||
(deliver promise (hiccup/raw temml))))
|
||||
(catch Exception e
|
||||
(lr/error e)
|
||||
(throw e)))))))
|
||||
fut (future-call (bound-fn* f))]
|
||||
;; Time out after eight seconds. With all the LaTeX and IPC, there
|
||||
;; are so many opportunities for things to go wrong </3.
|
||||
(let [fut-res (deref fut (* 10 1000) ::timed-out)]
|
||||
(if (= fut-res ::timed-out)
|
||||
(do (future-cancel fut)
|
||||
(doseq [{:keys [promise]} @promises]
|
||||
(deliver promise ::timed-out)))
|
||||
fut-res))
|
||||
sp @snippet-promises
|
||||
fut (-> #(tex/render-snippets sp)
|
||||
bound-fn* future-call)]
|
||||
(timeout-snippet-promises sp fut)
|
||||
r))
|
||||
|
||||
(comment
|
||||
(render-tex-snippets doc))
|
||||
|
||||
|
||||
|
||||
(defn- render-pprint
|
||||
(defn render-pprint
|
||||
"Render the argument inline as `clojure.pprint/pprint` output."
|
||||
[x & {:keys [text]
|
||||
:or {text "debug!"}}]
|
||||
@@ -367,23 +348,41 @@
|
||||
[:span.latex-fragment.display-math
|
||||
(-> e ::rendered deref)])
|
||||
|
||||
(defmethod org-element "example-block" [{:keys [value]}]
|
||||
[:pre value])
|
||||
(defmethod org-element "example-block" [{:keys [value] :as e}]
|
||||
(let [{:keys [center? alt scale img?]} (doerg-attrs e)]
|
||||
(-> [:pre (merge (and img? {:role "img"
|
||||
:aria-label alt
|
||||
:title alt})
|
||||
(and scale {:style {:font-size (em scale)}}))
|
||||
value]
|
||||
(wrap-if center? center))))
|
||||
|
||||
(defmethod org-element "src-block" [{:keys [value]}]
|
||||
[:pre [:code value]])
|
||||
|
||||
(defmethod org-element "quote-block" [{:keys [children]}]
|
||||
[:blockquote children])
|
||||
(defn- split-quote-block-children [children]
|
||||
(match (split-with #(not= % [:hr]) children)
|
||||
[x ([[:hr] & ys] :seq)] [x (strip-paragraphs ys)]
|
||||
x x))
|
||||
|
||||
(defmethod org-element "quote-block" [{:keys [children] :as e}]
|
||||
(let [{:keys [epigraph?]} (doerg-attrs e)
|
||||
[content footer] (split-quote-block-children children)]
|
||||
(-> [:blockquote
|
||||
content
|
||||
(when footer
|
||||
[:footer footer])]
|
||||
(wrap-if epigraph? (fn [c] [:div.epigraph c])))))
|
||||
|
||||
(defmethod org-element "horizontal-rule" [_]
|
||||
[:hr])
|
||||
|
||||
(defmethod org-element "comment" [_] nil)
|
||||
|
||||
(defmethod org-keyword "TITLE" [{:keys [value]}]
|
||||
[:h1 value])
|
||||
|
||||
;; Completely ignore the LATEX_COMPILER keyword.
|
||||
(defmethod org-keyword "LATEX_COMPILER" [_] nil)
|
||||
|
||||
(defmethod org-keyword "LATEX_HEADER" [_] nil)
|
||||
|
||||
;; Not sure how to deal with this one yet.
|
||||
@@ -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
|
||||
#_
|
||||
@@ -14,11 +15,14 @@
|
||||
"/home/msyds/org/20250919114912-homepage.org"
|
||||
#_
|
||||
"/home/msyds/org/20251111182118-path_induction.org"
|
||||
#_
|
||||
;; #_
|
||||
"/home/msyds/org/20250512144715-natural_transformation_category_theory.org"
|
||||
#_
|
||||
"/home/msyds/org/20251021155921-path_action.org"
|
||||
"test/net/deertopia/doerg/render_test/fallbacks.org")
|
||||
#_
|
||||
"test/net/deertopia/doerg/render_test/fallbacks.org"
|
||||
#_
|
||||
"/home/msyds/org/20250910115311-men_who_would_make_stunning_dykes.org")
|
||||
|
||||
(defn- force-create-sym-link [path target]
|
||||
(fs/delete-if-exists path)
|
||||
@@ -27,17 +31,17 @@
|
||||
(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))
|
||||
(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")
|
||||
(io/resource "net/deertopia/doerg/tuftesque.css"))
|
||||
(force-create-sym-link (fs/file dest "Temml-Plex.css")
|
||||
(io/resource "net/deertopia/doerg/Temml-Plex.css"))
|
||||
(fs/delete-if-exists (fs/file dest "index.html"))
|
||||
(->> src render/to-html str (spit (fs/file dest "index.html"))))
|
||||
(let [resource-dir (fs/file dest "resource")]
|
||||
(fs/create-dirs dest)
|
||||
(fs/create-dirs resource-dir)
|
||||
(force-create-sym-link (fs/file resource-dir "ibm-plex-web")
|
||||
(-> cfg/*cfg* ::doerg/ibm-plex-web))
|
||||
(doseq [x #{"Temml-Plex.css" "tuftesque.css" "deerstar.css"}]
|
||||
(force-create-sym-link
|
||||
(fs/file resource-dir x)
|
||||
(io/resource (str "net/deertopia/doerg/" x))))
|
||||
(fs/delete-if-exists (fs/file dest "index.html"))
|
||||
(->> src render/to-html str (spit (fs/file dest "index.html")))))
|
||||
|
||||
(defn render-edn [& {:keys [src dest]
|
||||
:or {src some-org-file
|
||||
183
src/net/deertopia/doerg/roam.clj
Normal file
183
src/net/deertopia/doerg/roam.clj
Normal file
@@ -0,0 +1,183 @@
|
||||
(ns net.deertopia.doerg.roam
|
||||
(:require [babashka.fs :as fs]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[net.deertopia.doerg.elisp :as elisp]
|
||||
[net.deertopia.doerg.slug :as slug]
|
||||
[next.jdbc :as sql])
|
||||
(:import (java.util UUID)))
|
||||
|
||||
|
||||
;;; Global database
|
||||
|
||||
(defonce ^:dynamic *use-db-cache?* true)
|
||||
|
||||
(defn ds []
|
||||
(sql/get-datasource
|
||||
{:dbtype "sqlite"
|
||||
:dbname (-> cfg/*cfg* ::cfg/org-roam-db-path str)}))
|
||||
|
||||
|
||||
;;; Elisp sexp (de)serialisation
|
||||
|
||||
(defn id [node]
|
||||
(-> node :id))
|
||||
|
||||
(defn slug [node]
|
||||
(-> node :id slug/from-uuid))
|
||||
|
||||
(defn- print-id [node]
|
||||
(-> node id elisp/print))
|
||||
|
||||
|
||||
;;; Node
|
||||
|
||||
(defrecord Node [id cache])
|
||||
|
||||
(defn uuid-exists? [uuid]
|
||||
(sql/execute-one! (ds)
|
||||
["select 1 from nodes where id = ? limit 1"
|
||||
(-> uuid str elisp/print)]))
|
||||
|
||||
(defn make-node
|
||||
([uuid] (make-node uuid {}))
|
||||
([uuid props]
|
||||
(and (uuid-exists? uuid)
|
||||
(->Node uuid (atom props)))))
|
||||
|
||||
(defn- fetch-with-cache [node field fetch]
|
||||
(if *use-db-cache?*
|
||||
(-> (:cache node)
|
||||
(swap! (fn [cache]
|
||||
(update cache field #(or % (fetch node)))))
|
||||
(get field))
|
||||
(fetch node)))
|
||||
|
||||
(defn org-file [node]
|
||||
(fetch-with-cache
|
||||
node :org-file
|
||||
(fn [node]
|
||||
(when-some [r (sql/execute-one!
|
||||
(ds)
|
||||
["select file from nodes where id = ?"
|
||||
(-> node :id str elisp/print)])]
|
||||
(-> r :nodes/file elisp/read-string)))))
|
||||
|
||||
(defn title [node]
|
||||
(fetch-with-cache
|
||||
node :title
|
||||
#(when-some [r (sql/execute-one!
|
||||
(ds)
|
||||
["select title from nodes where id = ?"
|
||||
(print-id %)])]
|
||||
(-> r :nodes/title elisp/read-string))))
|
||||
|
||||
(defprotocol GetNode
|
||||
(get-node [this]
|
||||
"Return the node associated with `this` or nil."))
|
||||
|
||||
(extend-protocol GetNode
|
||||
String
|
||||
(get-node [this]
|
||||
(or (some-> this slug/from-string get-node)
|
||||
(some-> this parse-uuid get-node)
|
||||
(throw (IllegalArgumentException.
|
||||
"Give `get-node` a UUID or slug string plz. }:)"))))
|
||||
java.util.UUID
|
||||
(get-node [this]
|
||||
(make-node this))
|
||||
net.deertopia.doerg.slug.Slug
|
||||
(get-node [this]
|
||||
(-> this slug/to-uuid make-node))
|
||||
Node
|
||||
(get-node [this]
|
||||
this))
|
||||
|
||||
(comment
|
||||
(def node (get-node "68XqhHerTWCbE--RYLEdHw"))
|
||||
(fetch-with-cache
|
||||
node :title
|
||||
#(do (println "fetch")
|
||||
(sql/execute-one! (ds) ["select title from nodes where id = ?"
|
||||
(elisp/print (:id %))]))))
|
||||
|
||||
|
||||
;;; Node operations
|
||||
|
||||
(defn level [node]
|
||||
(fetch-with-cache
|
||||
node :level
|
||||
#(-> (sql/execute-one!
|
||||
(ds) ["select level from nodes where id = ?"
|
||||
(print-id %)])
|
||||
:nodes/level)))
|
||||
|
||||
(defn top-level? [node]
|
||||
(zero? (level node)))
|
||||
|
||||
(defn file [node]
|
||||
(fetch-with-cache
|
||||
node :file
|
||||
#(-> (sql/execute-one!
|
||||
(ds) ["select file from nodes where id = ?"
|
||||
(print-id %)])
|
||||
:nodes/file
|
||||
elisp/read-string)))
|
||||
|
||||
(defn properties [node]
|
||||
(fetch-with-cache
|
||||
node :properties
|
||||
#(-> (sql/execute-one!
|
||||
(ds) ["select properties from nodes where id = ?"
|
||||
(print-id %)])
|
||||
:nodes/properties
|
||||
elisp/read-alist)))
|
||||
|
||||
(defn public? [node]
|
||||
(-> node properties (get "DEERTOPIAVISIBILITY") (= "public")))
|
||||
|
||||
(defn graph-visible? [node]
|
||||
(#{"public" "graphonly"}
|
||||
(-> node properties (get "DEERTOPIAVISIBILITY"))))
|
||||
|
||||
(defn backlinks
|
||||
"Returns a collection of nodes linking to `node`."
|
||||
[node]
|
||||
(for [{id :nodes/id title :nodes/title}
|
||||
(sql/execute! (ds) ["select distinct nodes.id, nodes.title from links
|
||||
inner join nodes
|
||||
on nodes.id = links.source
|
||||
where links.dest = ?"
|
||||
(elisp/print (str (:id node)))])
|
||||
:let [id' (elisp/read-string id)]
|
||||
:when (-> id' parse-uuid get-node public?)]
|
||||
(make-node id' {:title (elisp/read-string title)})))
|
||||
|
||||
|
||||
;;; Graph support
|
||||
|
||||
(defn- read-string-field [n field]
|
||||
(-> n (get field) elisp/read-string))
|
||||
|
||||
(defn- uuid-graph-visible? [uuid]
|
||||
(-> uuid parse-uuid get-node graph-visible?))
|
||||
|
||||
(defn get-graph []
|
||||
(let [nodes (sql/execute! (ds) ["select id, title from nodes"])
|
||||
links (sql/execute!
|
||||
(ds)
|
||||
["select n1.id as source, nodes.id as target from
|
||||
((nodes as n1) join links on n1.id = links.source)
|
||||
join (nodes as n2) on links.dest = nodes.id
|
||||
where links.type = '\"id\"'"])]
|
||||
{:nodes (for [n nodes
|
||||
:let [id (read-string-field n :nodes/id)]
|
||||
:when (uuid-graph-visible? id)]
|
||||
{:id id
|
||||
:title (read-string-field n :nodes/title)})
|
||||
:links (for [l links
|
||||
:let [source (read-string-field l :nodes/source)
|
||||
target (read-string-field l :nodes/target)]
|
||||
:when (and (uuid-graph-visible? source)
|
||||
(uuid-graph-visible? target))]
|
||||
{:source source
|
||||
:target target})}))
|
||||
188
src/net/deertopia/doerg/server.clj
Normal file
188
src/net/deertopia/doerg/server.clj
Normal file
@@ -0,0 +1,188 @@
|
||||
(ns net.deertopia.doerg.server
|
||||
(:require [clojure.pprint :refer [pprint]]
|
||||
[clojure.tools.logging :as l]
|
||||
[hiccup2.core :as hiccup]
|
||||
[net.deertopia.doerg.html :as doerg-html]
|
||||
[net.deertopia.doerg.config :as-alias cfg]
|
||||
[net.deertopia.doerg.slug :as slug]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[net.deertopia.doerg.roam :as roam]
|
||||
[org.httpkit.server :as http]
|
||||
[reitit.coercion]
|
||||
[reitit.coercion.spec]
|
||||
[reitit.ring.coercion]
|
||||
[reitit.core :as r]
|
||||
[reitit.ring]
|
||||
[reitit.ring.middleware.exception :as reitit-exception]
|
||||
[ring.util.response :as response]
|
||||
[spec-tools.spell]
|
||||
[reitit.spec]
|
||||
[reitit.dev.pretty]
|
||||
[clojure.spec.alpha :as s]
|
||||
[net.deertopia.doerg.render :as doerg-render]
|
||||
[net.deertopia.doerg.cached-file :as cached-file]
|
||||
[babashka.fs :as fs]
|
||||
[aero.core :as aero]
|
||||
[clojure.string :as str]
|
||||
[net.deertopia.doerg :as-alias doerg]
|
||||
[net.deertopia.doerg.config :as doerg-config]))
|
||||
|
||||
|
||||
;;; Routes
|
||||
|
||||
(def homepage-slug "68XqhHerTWCbE--RYLEdHw")
|
||||
(def not-found-slug "PGDHTvUzQ62Js1Y5db-A8g")
|
||||
|
||||
(defn hello [req]
|
||||
(-> (hiccup/html {}
|
||||
[:html
|
||||
[:head
|
||||
[:title "hello"]
|
||||
doerg-html/charset
|
||||
doerg-html/viewport]
|
||||
[:body
|
||||
[:pre
|
||||
(with-out-str
|
||||
(pprint req))]]])
|
||||
str
|
||||
response/response
|
||||
(response/content-type "text/html")))
|
||||
|
||||
(defn html-dir []
|
||||
(-> cfg/*cfg* ::cfg/state-directory (fs/file "html")))
|
||||
|
||||
(defn not-found [req]
|
||||
(response/not-found "not found"))
|
||||
|
||||
(defn org-file->html-file [org-file]
|
||||
(fs/file (html-dir)
|
||||
(-> org-file
|
||||
fs/file-name
|
||||
(fs/strip-ext {:ext "org"})
|
||||
(str ".html"))))
|
||||
|
||||
(defn slug-link [slug & contents]
|
||||
[:a {:href (str "/n/" slug)}
|
||||
contents])
|
||||
|
||||
(defmethod doerg-render/org-link "id"
|
||||
[{:keys [path raw-link children]}]
|
||||
[:span.org-link
|
||||
(slug-link (slug/from-uuid path)
|
||||
(or (seq children) raw-link))
|
||||
#_[:a {:href (str "/n/" (slug/from-uuid path))}
|
||||
(or (seq children) raw-link)]])
|
||||
|
||||
(defn backlinks-postamble [node]
|
||||
[:section#backlinks
|
||||
[:h2 "Backlinks"]
|
||||
[:ul
|
||||
(for [n (->> (roam/backlinks node)
|
||||
(sort-by (comp str/lower-case roam/title)))]
|
||||
[:li (slug-link (roam/slug n)
|
||||
(roam/title n))])]])
|
||||
|
||||
(defn node-by-slug [{{:keys [slug]} :path-params :as req}]
|
||||
(if-some [node (some-> slug slug/from-string roam/get-node)]
|
||||
(let [org-file (roam/org-file node)
|
||||
html-file (org-file->html-file org-file)]
|
||||
(cached-file/cached-file
|
||||
:file html-file
|
||||
:stale? (cached-file/newer-than? org-file html-file)
|
||||
:compute #(doerg-render/to-html
|
||||
org-file
|
||||
:postamble (backlinks-postamble node)))
|
||||
(-> (str html-file)
|
||||
response/file-response
|
||||
(response/content-type "text/html")))
|
||||
(not-found req)))
|
||||
|
||||
(defn node-by-id [req]
|
||||
(hello req))
|
||||
|
||||
(def exception-middleware
|
||||
(reitit-exception/create-exception-middleware
|
||||
(merge
|
||||
reitit-exception/default-handlers
|
||||
{::reitit-exception/wrap
|
||||
(fn [handler e request]
|
||||
(l/error e "error in fucking somwhere dude")
|
||||
(handler e request))})))
|
||||
|
||||
(defn handle-homepage [req]
|
||||
(-> req
|
||||
(assoc-in [:path-params :slug] homepage-slug)
|
||||
node-by-slug))
|
||||
|
||||
(defn handle-resource [{:keys [uri]}]
|
||||
(if-some [[_ resource] (re-matches #"^/resource/ibm-plex-web/(.*)" uri)]
|
||||
(-> resource
|
||||
(response/file-response
|
||||
{:root (-> doerg-config/*cfg* ::doerg/ibm-plex-web str)}))
|
||||
(-> uri
|
||||
(str/replace-first #"^/resource/" "")
|
||||
(response/resource-response
|
||||
{:root "net/deertopia/doerg/public"
|
||||
:allow-symlinks? true}))))
|
||||
|
||||
(defn handle-favicon [_]
|
||||
(response/resource-response "net/deertopia/doerg/favicon.ico"))
|
||||
|
||||
(def router
|
||||
(reitit.ring/router
|
||||
#{["/" #'handle-homepage]
|
||||
["/n/:slug" #'node-by-slug]
|
||||
["/id/:id" #'node-by-id]
|
||||
["/resource/*" #'handle-resource]
|
||||
["/myreq" #'hello]
|
||||
["/favicon.ico" #'handle-favicon]}
|
||||
{:validate reitit.spec/validate
|
||||
:exception reitit.dev.pretty/exception
|
||||
:spec :reitit.spec/default-data
|
||||
:data
|
||||
{:coercion reitit.coercion.spec/coercion
|
||||
:middleware [exception-middleware
|
||||
reitit.ring.coercion/coerce-request-middleware
|
||||
reitit.ring.coercion/coerce-response-middleware
|
||||
#_reitit.ring.coercion/coerce-exceptions-middleware]}}))
|
||||
|
||||
|
||||
;;; Server API
|
||||
|
||||
(def app (reitit.ring/ring-handler router))
|
||||
|
||||
(defonce server (atom nil))
|
||||
|
||||
(defn stop! []
|
||||
(when @server
|
||||
(http/server-stop! @server {:timeout 100})
|
||||
(reset! server nil)
|
||||
(l/info "Stopped server")))
|
||||
|
||||
;; For some reason, the log messages from `stop!` are not flushed
|
||||
;; before the JVM shuts dowm. Nevertheless, the server /does/ come to
|
||||
;; a graceful halt.
|
||||
(def ^:private shutdown-hook (Thread. stop!))
|
||||
|
||||
(defn start! []
|
||||
(if @server
|
||||
(throw (IllegalStateException. "Server already started"))
|
||||
(do (reset! server
|
||||
(http/run-server (bound-fn* #'app)
|
||||
{:port (-> cfg/*cfg* ::cfg/port)
|
||||
:legacy-return-value? false}))
|
||||
;; For some reason, the log messages are not flushed before
|
||||
;; the JVM shuts dowm. Nevertheless, the server /does/ come
|
||||
;; to a graceful halt.
|
||||
(try (.addShutdownHook (Runtime/getRuntime) shutdown-hook)
|
||||
(catch IllegalArgumentException e
|
||||
(when (not= "Hook previously registered"
|
||||
(ex-message e))
|
||||
(throw e))))
|
||||
(l/infof "Server started on port %d"
|
||||
(-> cfg/*cfg* ::cfg/port)))))
|
||||
|
||||
(defn status []
|
||||
(if @server
|
||||
(http/server-status @server)
|
||||
:stopped))
|
||||
64
src/net/deertopia/doerg/slug.clj
Normal file
64
src/net/deertopia/doerg/slug.clj
Normal file
@@ -0,0 +1,64 @@
|
||||
(ns net.deertopia.doerg.slug
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[spec-tools.core :as st])
|
||||
(:import (java.nio ByteBuffer)
|
||||
(java.util Base64 UUID)))
|
||||
|
||||
(defrecord Slug [slug-string]
|
||||
Object
|
||||
(toString [this]
|
||||
(:slug-string this)))
|
||||
|
||||
(defn from-string [s]
|
||||
(try (let [decoder (Base64/getUrlDecoder)]
|
||||
(when (= 16 (count (.decode decoder s)))
|
||||
(Slug. s)))
|
||||
;; really stupid
|
||||
(catch IllegalArgumentException _
|
||||
nil)))
|
||||
|
||||
(defn to-string [s]
|
||||
(str s))
|
||||
|
||||
(defn- coerce-to-uuid [string-or-uuid]
|
||||
(cond (string? string-or-uuid) (UUID/fromString string-or-uuid)
|
||||
(uuid? string-or-uuid) string-or-uuid))
|
||||
|
||||
(defn- uuid->bytes [string-or-uuid]
|
||||
(let [uuid (coerce-to-uuid string-or-uuid)]
|
||||
(.array (doto (ByteBuffer/wrap (byte-array 16))
|
||||
(.putLong (.getMostSignificantBits uuid))
|
||||
(.putLong (.getLeastSignificantBits uuid))))))
|
||||
|
||||
(defn- bytes->uuid [bytes]
|
||||
(when (= (count bytes) 16)
|
||||
(let [bb (ByteBuffer/wrap bytes)
|
||||
high (.getLong bb)
|
||||
low (.getLong bb)]
|
||||
(UUID. high low))))
|
||||
|
||||
(defn from-uuid [string-or-uuid]
|
||||
(let [uuid (coerce-to-uuid string-or-uuid)
|
||||
encoder (.withoutPadding (Base64/getUrlEncoder))]
|
||||
(Slug. (.encodeToString encoder (uuid->bytes uuid)))))
|
||||
|
||||
(defn to-uuid [slug]
|
||||
(let [decoder (Base64/getUrlDecoder)]
|
||||
(bytes->uuid (.decode decoder (str slug)))))
|
||||
|
||||
(comment
|
||||
(let [uuid #uuid "f9eab66e-7773-4b87-b854-0bfc8f563809"
|
||||
slug (from-uuid uuid)
|
||||
round-tripped (to-uuid slug)]
|
||||
{:uuid uuid, :slug slug, :round-tripped round-tripped}))
|
||||
|
||||
(defn make-slug [string]
|
||||
(assert (try (to-uuid string)
|
||||
(catch Throwable _
|
||||
nil))
|
||||
"invalid slug")
|
||||
(->Slug string))
|
||||
|
||||
(s/def ::slug
|
||||
(s/conformer #(or (some-> % from-string)
|
||||
::s/invalid)))
|
||||
62
src/net/deertopia/doerg/tex.clj
Normal file
62
src/net/deertopia/doerg/tex.clj
Normal file
@@ -0,0 +1,62 @@
|
||||
(ns net.deertopia.doerg.tex
|
||||
(:require [net.deertopia.doerg.tex.native :as native]
|
||||
[net.deertopia.doerg.tex.temml :as temml]
|
||||
[babashka.fs :as fs]
|
||||
[clojure.string :as str]
|
||||
[hiccup2.core :as hiccup]
|
||||
[clojure.tools.logging :as l]
|
||||
[clojure.tools.logging.readable :as lr]))
|
||||
|
||||
(defn- read-and-patch-generated-svg [{:keys [file height depth]}]
|
||||
;; dvisvgm writes standalone SVG files, to which we need to make a
|
||||
;; few changes to use them inline within our HTML.
|
||||
;; • XML header: Bad syntax when embedded in an HTML doc. Remove
|
||||
;; it.
|
||||
;; • Width and height: We override these with our own values
|
||||
;; computed by `net.deertopia.doerg.tex` to ensure correct
|
||||
;; positioning relative to the surrounding text. More
|
||||
;; accurately, we remove the height and width attributes from
|
||||
;; the SVG tag, and set the new values for height and
|
||||
;; vertical-align in the style attribute
|
||||
;; • Viewbox: Must be removed entirely for correct positioning.
|
||||
(-> (slurp file)
|
||||
(str/replace-first #"<\?xml version='1.0' encoding='UTF-8'\?>\n?" "")
|
||||
(str/replace-first #" height=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first #" width=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first
|
||||
#"viewBox=['\"][^\"']+[\"']"
|
||||
(fn [s]
|
||||
(format "%s style=\"%s\""
|
||||
s
|
||||
(format "height:%.4fem;vertical-align:%.4fem;display:inline-block"
|
||||
height (- depth)))))
|
||||
;; Stupid hack. --currentcolor on dvisvgm should be enough, but
|
||||
;; it doesn't get e.g. TikZ arrows.
|
||||
(str/replace #"stroke=['\"]#000['\"]" "stroke=\"currentColor\"")))
|
||||
|
||||
(defn render-snippets [snippet-promises]
|
||||
(fs/with-temp-dir [svg-dir {:prefix "doerg-svg-"}]
|
||||
(let [rendered-snippets
|
||||
(delay (->> snippet-promises
|
||||
(map first)
|
||||
(apply native/render svg-dir)))]
|
||||
(doseq [[snippet p] snippet-promises]
|
||||
(try (let [temml (temml/render snippet)]
|
||||
(->> (if (temml/erroneous-output? temml)
|
||||
(let [tex (get @rendered-snippets snippet)]
|
||||
(if (:errors tex)
|
||||
temml
|
||||
(read-and-patch-generated-svg tex)))
|
||||
temml)
|
||||
hiccup/raw (deliver p)))
|
||||
(catch Exception e
|
||||
(l/error e "Error in TeX thread")
|
||||
(throw e)))))))
|
||||
|
||||
(comment
|
||||
(let [snippets (for [x ["\\(\\ifxetex blah \\fi\\)"
|
||||
"\\(\\sqrt{x^2 + y^2}\\)"]]
|
||||
[x (promise)])]
|
||||
(temml/binding-worker
|
||||
(render-snippets snippets)
|
||||
(map #(-> % second deref) snippets))))
|
||||
@@ -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,18 +83,18 @@
|
||||
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"
|
||||
"--relative" "--no-fonts" "-v3"
|
||||
"--relative" "--no-fonts" "-v3" "--currentcolor"
|
||||
"--message=processing page {?pageno}: output written to {?svgpath}"
|
||||
"--bbox=preview" "-o" "%9p.svg" file)))
|
||||
|
||||
@@ -107,13 +108,21 @@
|
||||
(format "%09d.svg" i))]
|
||||
(zipmap (reverse snippets) svgs)))
|
||||
|
||||
(defn- read-prelude []
|
||||
(str (-> "net/deertopia/doerg/prelude.tex" io/resource slurp)
|
||||
\newline
|
||||
(-> "net/deertopia/doerg/native-prelude.tex" io/resource slurp)))
|
||||
|
||||
(defn- instantiate-preview-template [snippets]
|
||||
(let [contents (->> (for [s snippets]
|
||||
(format "\\begin{preview}\n%s\n\\end{preview}" s))
|
||||
(str/join "\n"))]
|
||||
(-> (io/resource "net/deertopia/doerg/preview-template.tex")
|
||||
slurp
|
||||
(str/replace-first "% {{contents}}" contents))))
|
||||
(str/replace #"% \{\{(contents|preamble)}}"
|
||||
#(case (second %)
|
||||
"contents" contents
|
||||
"preamble" (read-prelude))))))
|
||||
|
||||
(defn render
|
||||
"Render a collection of `snippets` to SVGs in `output-dir` using a
|
||||
90
src/net/deertopia/doerg/tex/temml.clj
Normal file
90
src/net/deertopia/doerg/tex/temml.clj
Normal file
@@ -0,0 +1,90 @@
|
||||
(ns net.deertopia.doerg.tex.temml
|
||||
(:require [babashka.process :as p]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[clj-cbor.core :as cbor]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as l]
|
||||
[babashka.fs :as fs]
|
||||
[net.deertopia.doerg :as-alias doerg])
|
||||
(:import (java.io ByteArrayOutputStream)))
|
||||
|
||||
(def ^:dynamic *worker-timeout-duration*
|
||||
"Number of milliseconds to wait before killing the external Uniorg
|
||||
process."
|
||||
(* 10 1000))
|
||||
|
||||
(def ^:dynamic *worker*)
|
||||
|
||||
;; 외부의 브로그램이 JVM resource를 사용 위해서 파일 시스템에서 써야
|
||||
;; 합니다.
|
||||
(defonce ^:private prelude-file
|
||||
(-> (fs/create-temp-file {:prefix "doerg-prelude-"
|
||||
:suffix ".tex"})
|
||||
fs/file))
|
||||
|
||||
(defn worker []
|
||||
(let [doerg-temml-worker (-> cfg/*cfg* ::doerg/doerg-temml-worker)]
|
||||
(when (or (not (fs/exists? prelude-file))
|
||||
(zero? (fs/size prelude-file)))
|
||||
(-> "net/deertopia/doerg/prelude.tex"
|
||||
io/resource
|
||||
io/input-stream
|
||||
(io/copy prelude-file)))
|
||||
(p/process
|
||||
{:shutdown p/destroy-tree
|
||||
:err (l/log-stream :info "temml/err")}
|
||||
doerg-temml-worker
|
||||
"--preamble" prelude-file)))
|
||||
|
||||
(defn close-worker [tw]
|
||||
(.close (:in tw)))
|
||||
|
||||
(defmacro with-worker [tw & body]
|
||||
`(let [~tw (worker)]
|
||||
(try
|
||||
(do ~@body)
|
||||
(finally
|
||||
(close-worker ~tw)
|
||||
(p/destroy-tree ~tw)))))
|
||||
|
||||
(defmacro binding-worker [& body]
|
||||
`(binding [*worker* (worker)]
|
||||
(try
|
||||
~@body
|
||||
(finally
|
||||
(close-worker *worker*)))))
|
||||
|
||||
(defn command-worker [x]
|
||||
(cbor/encode cbor/default-codec (:in *worker*) x)
|
||||
(.flush (:in *worker*))
|
||||
(let [r (cbor/decode cbor/default-codec (:out *worker*))]
|
||||
(if (string? r)
|
||||
r
|
||||
(throw (ex-info "bad data from temml worker"
|
||||
{:data r})))))
|
||||
|
||||
(defn render-inline [s]
|
||||
(command-worker s))
|
||||
|
||||
(defn render-display [s]
|
||||
(command-worker [s]))
|
||||
|
||||
(defn render [s]
|
||||
(let [s (str/trim s)]
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\\[(.*)\\]" s)]
|
||||
(render-display inner)
|
||||
(if (re-matches #"(?s)\\begin\{.+?}(.*?)\\end\{.+?}" s)
|
||||
(render-display s)
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\\((.*)\\\)" s)]
|
||||
(render-inline inner)
|
||||
(throw (IllegalArgumentException.
|
||||
(ex-info
|
||||
(str "`net.deertopia.doerg.tex.temml` argument should"
|
||||
" be enclosed in math delimiters.")
|
||||
{:arg s}))))))))
|
||||
|
||||
;; hackky....
|
||||
(defn erroneous-output? [s]
|
||||
(re-find #"(#b22222|temml-error)" s))
|
||||
10
test-emacs.nix
Normal file
10
test-emacs.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ emacsPackages
|
||||
, symlinkJoin
|
||||
, writeScriptBin
|
||||
, lib
|
||||
}:
|
||||
|
||||
let emacs = emacsPackages.emacsWithPackages (epkgs: [ epkgs.org-roam ]);
|
||||
in writeScriptBin "test-emacs" ''
|
||||
exec ${lib.getExe emacs} "$@"
|
||||
''
|
||||
9
test/net/deertopia/doerg/config_test.clj
Normal file
9
test/net/deertopia/doerg/config_test.clj
Normal file
@@ -0,0 +1,9 @@
|
||||
(ns net.deertopia.doerg.config-test
|
||||
(:require [clojure.test :as t]
|
||||
[net.deertopia.doerg.config :as cfg]))
|
||||
|
||||
(defn test-config-fixture
|
||||
"`clojure.test` fixture to run tests with the :test configuration."
|
||||
[f]
|
||||
(binding [cfg/*cfg* (cfg/read-config cfg/sources :profile :test)]
|
||||
(f)))
|
||||
115
test/net/deertopia/doerg/element_test.clj
Normal file
115
test/net/deertopia/doerg/element_test.clj
Normal file
@@ -0,0 +1,115 @@
|
||||
(ns net.deertopia.doerg.element-test
|
||||
(:require [net.deertopia.doerg.element :as sut]
|
||||
[babashka.process :as p]
|
||||
[clojure.test :as t]
|
||||
[clojure.zip :as z]
|
||||
[clojure.java.io :as io]
|
||||
[com.rpl.specter :as sp]))
|
||||
|
||||
(defn- first-child-of-type [parent type]
|
||||
(some #(and (sut/of-type? % type) %) (:children parent)))
|
||||
|
||||
(defn- parse-resource [path]
|
||||
(-> (str "net/deertopia/doerg/element_test/" path)
|
||||
io/resource slurp
|
||||
(sut/read-string)))
|
||||
|
||||
(t/deftest known-greater-elements
|
||||
(t/testing "known greater elements satisfy `greater-element?`"
|
||||
(let [root (parse-resource "greater-elements.org")
|
||||
section (->> root
|
||||
(sp/select [sut/children-walker
|
||||
#(sut/of-type? % "section")])
|
||||
second)
|
||||
headline (first-child-of-type section "headline")
|
||||
headline-text (first-child-of-type headline "text")
|
||||
paragraph (first-child-of-type section "paragraph")
|
||||
paragraph-text (first-child-of-type paragraph "text")]
|
||||
(t/is (sut/greater-element? root))
|
||||
(t/is (sut/greater-element? section))
|
||||
(t/is (sut/greater-element? headline))
|
||||
(t/is (not (sut/greater-element? headline-text)))
|
||||
(t/is (sut/greater-element? paragraph))
|
||||
(t/is (not (sut/greater-element? paragraph-text))))))
|
||||
|
||||
(defn- first-paragraph-belongs-to-first-section? [doc]
|
||||
(let [first-paragraph (sp/select-first [sut/postorder-walker
|
||||
#(sut/of-type? % "paragraph")]
|
||||
doc)
|
||||
first-section (sp/select-first [sut/postorder-walker
|
||||
#(sut/of-type? % "section")]
|
||||
doc)]
|
||||
(if (and first-paragraph first-section)
|
||||
(boolean (some #(= % first-paragraph)
|
||||
(:children first-section)))
|
||||
true)))
|
||||
|
||||
(t/deftest first-paragraph-under-first-section
|
||||
(t/is (-> (parse-resource "first-paragraph-under-first-section.org")
|
||||
first-paragraph-belongs-to-first-section?)))
|
||||
|
||||
(t/deftest first-paragraph-under-heading
|
||||
(t/is (-> (parse-resource "first-paragraph-under-heading.org")
|
||||
first-paragraph-belongs-to-first-section?
|
||||
not)))
|
||||
|
||||
(defn- walk-types [type & types]
|
||||
[sut/postorder-walker #(apply sut/of-type? % type types)])
|
||||
|
||||
(t/deftest paragraph-ending-with-latex
|
||||
(let [doc (parse-resource "paragraph-ending-with-latex.org")
|
||||
type (-> (sp/select-first [(walk-types "paragraph")
|
||||
(sp/must :children)
|
||||
sp/LAST]
|
||||
doc)
|
||||
sut/type)]
|
||||
(t/is (= "latex-environment" type))))
|
||||
|
||||
(t/deftest paragraph-surrounding-latex
|
||||
(let [doc (parse-resource "paragraph-surrounding-latex.org")
|
||||
children (->> doc
|
||||
(sp/select-first [(walk-types "paragraph")])
|
||||
:children
|
||||
(map sut/type))]
|
||||
(t/is (= ["text" "latex-environment" "text"]
|
||||
children))))
|
||||
|
||||
(t/deftest paragraph-ending-in-bold-surrounding-latex
|
||||
(let [doc (parse-resource "paragraph-ending-in-bold-surrounding-latex.org")
|
||||
children (->> doc
|
||||
(sp/select-first [(walk-types "paragraph")])
|
||||
:children
|
||||
(map sut/type))]
|
||||
(t/is (= ["text" "bold" "latex-environment" "text"]
|
||||
children))))
|
||||
|
||||
(t/deftest paragraph-with-multiple-latex
|
||||
(let [doc (parse-resource "paragraph-with-multiple-latex.org")
|
||||
paragraphs (sp/select (walk-types "paragraph") doc)]
|
||||
(t/is (= 2 (count paragraphs)))
|
||||
(let [[p₁ p₂] paragraphs]
|
||||
(doseq [[p ts] [[p₁ ["text" "latex-environment"
|
||||
"text" "latex-environment"]]
|
||||
[p₂ ["text" "latex-environment"
|
||||
"text" "latex-environment" "text"]]]]
|
||||
(t/is (= ts (sp/select [(sp/must :children)
|
||||
sp/ALL (sp/view sut/type)] p)))))))
|
||||
|
||||
(t/deftest paragraph-with-separate-latex
|
||||
(let [doc (parse-resource "paragraph-with-separate-latex.org")
|
||||
cs (sp/select [(walk-types "section")
|
||||
(sp/must :children)
|
||||
sp/ALL
|
||||
(sp/view sut/type)]
|
||||
doc)]
|
||||
(t/is (= ["paragraph" "latex-environment"] cs))))
|
||||
|
||||
(t/deftest paragraph-surrounding-separate-latex
|
||||
(let [doc (parse-resource "paragraph-surrounding-separate-latex.org")
|
||||
cs (sp/select [(walk-types "section")
|
||||
(sp/must :children)
|
||||
sp/ALL
|
||||
(sp/view sut/type)]
|
||||
doc)]
|
||||
(t/is (= ["paragraph" "latex-environment" "paragraph"] cs))))
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#+title: bold-final paragraph surrounding latex
|
||||
|
||||
first part of *paragraph*
|
||||
\begin{equation*}
|
||||
\text{some \LaTeX \}:)}
|
||||
\end{equation*}
|
||||
last part of paragraph
|
||||
@@ -0,0 +1,7 @@
|
||||
#+title: paragraph ending with latex
|
||||
|
||||
here is the paragraph,
|
||||
\begin{align*}
|
||||
\text{and here} &
|
||||
\\ & \text{is the \LaTeX}
|
||||
\end{align*}
|
||||
@@ -0,0 +1,7 @@
|
||||
#+title: paragraph surrounding latex
|
||||
|
||||
first part of paragraph
|
||||
\begin{equation*}
|
||||
\text{some \LaTeX \}:)}
|
||||
\end{equation*}
|
||||
last part of paragraph
|
||||
@@ -0,0 +1,9 @@
|
||||
#+title: paragraphs surrounding separate latex
|
||||
|
||||
a paragraph!
|
||||
|
||||
\begin{gather*}
|
||||
\text{and now, an unrelated latex fragment}
|
||||
\end{gather*}
|
||||
|
||||
more unrelated text
|
||||
@@ -0,0 +1,24 @@
|
||||
#+title: paragraph with multiple latex environments
|
||||
|
||||
* interleaved
|
||||
|
||||
first part of paragraph
|
||||
\begin{equation*}
|
||||
\text{first \LaTeX\ environment}
|
||||
\end{equation*}
|
||||
second part of paragraph
|
||||
\begin{equation*}
|
||||
\text{second \LaTeX\ environment}
|
||||
\end{equation*}
|
||||
|
||||
* fenceposted
|
||||
|
||||
first fencepost
|
||||
\begin{equation*}
|
||||
\text{first fenceposted \LaTeX\ environment}
|
||||
\end{equation*}
|
||||
second fencepost
|
||||
\begin{equation*}
|
||||
\text{second fenceposted \LaTeX\ environment}
|
||||
\end{equation*}
|
||||
third fencepost
|
||||
@@ -0,0 +1,7 @@
|
||||
#+title: paragraph with separate latex
|
||||
|
||||
a paragraph!
|
||||
|
||||
\begin{gather*}
|
||||
\text{and now, an unrelated latex fragment}
|
||||
\end{gather*}
|
||||
8
test/net/deertopia/doerg/org-roam-db-sync.el
Executable file
8
test/net/deertopia/doerg/org-roam-db-sync.el
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/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)
|
||||
@@ -0,0 +1,7 @@
|
||||
:PROPERTIES:
|
||||
:ID: 23ee464d-b13e-4649-826f-622d0edef24e
|
||||
:DeertopiaVisibility: public
|
||||
:END:
|
||||
#+title: awesome file
|
||||
|
||||
wow!
|
||||
23
test/net/deertopia/doerg/roam-test/404.org
Normal file
23
test/net/deertopia/doerg/roam-test/404.org
Normal file
@@ -0,0 +1,23 @@
|
||||
:PROPERTIES:
|
||||
:ID: 3c60c74e-f533-43ad-89b3-563975bf80f2
|
||||
:DeertopiaVisibility: public
|
||||
:END:
|
||||
#+title: page not found
|
||||
|
||||
the page you're looking for doesn't exist, or you lack the permissions necessary to view it........
|
||||
|
||||
#+attr_doerg: :center? true :alt "A doe sitting and sobbing" :scale 1.4
|
||||
#+begin_example
|
||||
\{ / \ }/
|
||||
\/ . . \/
|
||||
.. \Y` `Y/ ..
|
||||
\ `\|~==~|/' /
|
||||
'". T T ."`
|
||||
{`^' }
|
||||
| |
|
||||
/</3 \
|
||||
|| ||
|
||||
_| || |_
|
||||
.,_) ) || ( (_,.
|
||||
|__ /_||_\ __|
|
||||
#+end_example
|
||||
7
test/net/deertopia/doerg/roam-test/categorytheory.org
Normal file
7
test/net/deertopia/doerg/roam-test/categorytheory.org
Normal file
@@ -0,0 +1,7 @@
|
||||
:PROPERTIES:
|
||||
:ID: 90f23e03-f746-42cb-862f-1af2d4bde3cc
|
||||
:DeertopiaVisibility: public
|
||||
:END:
|
||||
#+title: Category theory
|
||||
|
||||
*Category theory* is the mathematical study of categories and functors between them.
|
||||
7
test/net/deertopia/doerg/roam-test/fake-homepage.org
Normal file
7
test/net/deertopia/doerg/roam-test/fake-homepage.org
Normal file
@@ -0,0 +1,7 @@
|
||||
:PROPERTIES:
|
||||
:ID: ebc5ea84-77ab-4d60-9b13-ef9160b11d1f
|
||||
:DeertopiaVisibility: public
|
||||
:END:
|
||||
#+title: deertopia.net!!!!!!!!
|
||||
|
||||
homeee
|
||||
22
test/net/deertopia/doerg/roam-test/monoepi.org
Normal file
22
test/net/deertopia/doerg/roam-test/monoepi.org
Normal file
@@ -0,0 +1,22 @@
|
||||
:PROPERTIES:
|
||||
:ID: 897bfc9d-94ce-4c58-8d21-93f13372b17b
|
||||
:END:
|
||||
#+title: Monomorphisms and epimorphisms
|
||||
|
||||
In [[id:90f23e03-f746-42cb-862f-1af2d4bde3cc][category theory]], *monomorphisms* and *epimorphisms* are types of cancellative morphisms generalising injective and surjective functions, respectively.[fn:1]
|
||||
|
||||
\begin{tikzcd}
|
||||
% https://q.uiver.app/#q=WzAsNixbMCwwLCJYIl0sWzEsMCwiWSJdLFsyLDAsIloiXSxbMSwxLCJZIl0sWzIsMSwiWiJdLFswLDEsIlgiXSxbMCwxLCJnXzEiLDAseyJvZmZzZXQiOi0yfV0sWzAsMSwiZ18yIiwyLHsib2Zmc2V0IjoyfV0sWzEsMiwiZiIsMl0sWzMsNCwiZ18xIiwwLHsib2Zmc2V0IjotMn1dLFszLDQsImdfMiIsMix7Im9mZnNldCI6Mn1dLFs1LDMsImYiLDJdXQ==
|
||||
X & Y & Z \\
|
||||
X & Y & Z
|
||||
\arrow["{g_1}", shift left=2, from=1-1, to=1-2]
|
||||
\arrow["{g_2}"', shift right=2, from=1-1, to=1-2]
|
||||
\arrow["f"', from=1-2, to=1-3]
|
||||
\arrow["f"', from=2-1, to=2-2]
|
||||
\arrow["{g_1}", shift left=2, from=2-2, to=2-3]
|
||||
\arrow["{g_2}"', shift right=2, from=2-2, to=2-3]
|
||||
\end{tikzcd}
|
||||
|
||||
* Footnotes
|
||||
|
||||
[fn:1] blahahahahah blah blah
|
||||
63
test/net/deertopia/doerg/roam_test.clj
Normal file
63
test/net/deertopia/doerg/roam_test.clj
Normal file
@@ -0,0 +1,63 @@
|
||||
(ns net.deertopia.doerg.roam-test
|
||||
(:require [net.deertopia.doerg.roam :as sut]
|
||||
[clojure.test :as t]
|
||||
[clojure.java.io :as io]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[babashka.fs :as fs]
|
||||
[babashka.process :as p]
|
||||
[net.deertopia.doerg.config-test :refer [test-config-fixture]]
|
||||
[next.jdbc :as sql]
|
||||
[clojure.string :as str]
|
||||
[net.deertopia.doerg.elisp :as elisp]
|
||||
[com.rpl.specter :as sp]))
|
||||
|
||||
(def org-roam-directory
|
||||
(fs/file "test/net/deertopia/doerg/roam-test"))
|
||||
|
||||
(defn org-roam-db-sync [db-file]
|
||||
(let [script-file (fs/create-temp-file {:prefix "org-roam-db-sync-"
|
||||
:suffix ".el"})
|
||||
emacs (->> [(System/getenv "EMACS") "test-emacs" "emacs"]
|
||||
(some #(some-> % fs/which)))]
|
||||
(io/copy (-> "net/deertopia/doerg/org-roam-db-sync.el"
|
||||
io/resource io/reader)
|
||||
(fs/file script-file))
|
||||
(p/shell {:out :string :err :string}
|
||||
emacs "-Q" "-x" script-file org-roam-directory db-file)
|
||||
(fs/delete script-file)))
|
||||
|
||||
(defn test-db-fixture [f]
|
||||
(let [db-file (-> cfg/*cfg* ::cfg/org-roam-db-path)]
|
||||
(assert (->> db-file fs/canonicalize str
|
||||
(re-matches #"^/(build|tmp)/.*"))
|
||||
(format "i'm scared to delete a non-test database... %s"
|
||||
(str db-file)))
|
||||
(fs/delete-if-exists db-file)
|
||||
(org-roam-db-sync db-file)
|
||||
(f)
|
||||
(fs/delete db-file)))
|
||||
|
||||
(t/use-fixtures
|
||||
:once (t/join-fixtures [test-config-fixture test-db-fixture]))
|
||||
|
||||
|
||||
|
||||
(t/deftest all-nodes-exist
|
||||
(let [known-node-files (->> (fs/list-dir org-roam-directory)
|
||||
(map (comp str fs/canonicalize))
|
||||
(into #{}))
|
||||
database-nodes
|
||||
(->> (sql/execute!
|
||||
(sut/ds) ["select file, id from nodes"])
|
||||
(map (fn [x]
|
||||
{:file (-> x :nodes/file elisp/read-string)
|
||||
:id (-> x :nodes/id elisp/read-string parse-uuid)}))
|
||||
(into #{}))]
|
||||
(t/testing "database has a node for each file?"
|
||||
(t/is (= known-node-files (sp/transform
|
||||
[sp/ALL]
|
||||
#(:file %)
|
||||
database-nodes))))
|
||||
(t/testing "each uuid exists?"
|
||||
(t/is (every? (comp sut/uuid-exists? :id)
|
||||
database-nodes)))))
|
||||
52
test/net/deertopia/doerg/server_test.clj
Normal file
52
test/net/deertopia/doerg/server_test.clj
Normal file
@@ -0,0 +1,52 @@
|
||||
(ns net.deertopia.doerg.server-test
|
||||
(:require [net.deertopia.doerg.server :as sut]
|
||||
[reitit.ring]
|
||||
[clojure.test :as t]
|
||||
[net.deertopia.doerg.config :as cfg]
|
||||
[net.deertopia.doerg.roam :as roam]
|
||||
[babashka.fs :as fs]
|
||||
[clojure.java.io :as io]
|
||||
[net.deertopia.doerg.roam-test :refer [test-db-fixture]]
|
||||
[net.deertopia.doerg.config-test :refer [test-config-fixture]]))
|
||||
|
||||
(t/use-fixtures
|
||||
:once (t/join-fixtures [test-config-fixture test-db-fixture]))
|
||||
|
||||
(defn with-server [f]
|
||||
(let [was-already-running? (= :running (sut/status))]
|
||||
(when-not was-already-running?
|
||||
(sut/start!))
|
||||
(f)
|
||||
(when-not was-already-running?
|
||||
(sut/stop!))))
|
||||
|
||||
(defn get-sut [uri]
|
||||
(sut/app {:request-method :get
|
||||
:uri uri}))
|
||||
|
||||
|
||||
|
||||
(t/deftest server-is-running
|
||||
;; 서버는 벌써 시작한 다음에 이 테스트 하면 잘못됩니다.
|
||||
;; (assert (not= :running (sut/status)))
|
||||
(with-server
|
||||
(fn []
|
||||
(t/is (= :running (sut/status)))
|
||||
(t/is (->> (format "http://localhost:%d"
|
||||
(::cfg/port cfg/*cfg*))
|
||||
slurp
|
||||
string?)))))
|
||||
|
||||
(t/deftest get-nonexistent-node
|
||||
(let [slug "3Lxvxnb0QrivoU3DX-l_5w"]
|
||||
(assert (nil? (roam/make-node slug)))
|
||||
(t/is (= 404
|
||||
(-> (str "/n/" slug)
|
||||
get-sut :status)))))
|
||||
|
||||
(t/deftest get-homepage
|
||||
(let [resp (-> (str "/n/" sut/homepage-slug)
|
||||
get-sut)]
|
||||
(t/is (= 200 (:status resp)))
|
||||
(t/is (= (-> "/" get-sut :body)
|
||||
(-> resp :body)))))
|
||||
8
vendor/default.nix
vendored
8
vendor/default.nix
vendored
@@ -1,8 +0,0 @@
|
||||
{ fetchzip
|
||||
, fetchurl
|
||||
, callPackage
|
||||
}:
|
||||
|
||||
{
|
||||
ibm-plex-web = callPackage ./ibm-plex-web.nix {};
|
||||
}
|
||||
Reference in New Issue
Block a user