Compare commits
10 Commits
cf225f6bc5
...
f947df6711
| Author | SHA1 | Date | |
|---|---|---|---|
| f947df6711 | |||
| 7aa6e02b9e | |||
| 01d88bb30d | |||
| 7e0826c496 | |||
| 06c20588f2 | |||
| 4b4573ee1d | |||
| 071a15ca51 | |||
| f811a519b5 | |||
| fa42052a6a | |||
| ea3b77619a |
382
deps-lock.json
382
deps-lock.json
@@ -10,6 +10,16 @@
|
||||
}
|
||||
],
|
||||
"mvn-deps": [
|
||||
{
|
||||
"mvn-path": "aero/aero/1.1.6/aero-1.1.6.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-9LCpJy2lDICRxVKcn+NVxHI08e65X+kiluLCP3h/PSI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "aero/aero/1.1.6/aero-1.1.6.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-WUXPjq14D3SX6G8piWPyeGgdUZrpshvpSfrFQg8F01A="
|
||||
},
|
||||
{
|
||||
"mvn-path": "babashka/fs/0.5.24/fs-0.5.24.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -40,6 +50,31 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LVp6g6ymqHa1ZOMHYD0CRaNxZ4osT0xoEH7dC5sLv7s="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-mMPxj10NZCzV8yfMckVmzRlklibH2I9wFDvXBMlBV9U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Ond3RjIf1uIuOMzf1PY0vKNysA7mIAPlJ/aqRkkF8+g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ch/qos/logback/logback-core/1.1.3/logback-core-1.1.3.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-R8D9NCmV0zFbj6zKzDJLKnYUOyfEMNSy1qKeq8MfXBQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ch/qos/logback/logback-core/1.1.3/logback-core-1.1.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ziBX5rWqOWLWyNtAxJ6LzhFQqaobNhXtS6b1I9O5pwA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "ch/qos/logback/logback-parent/1.1.3/logback-parent-1.1.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ag4n7GeP9dkLjMZku0UZifXitbMAamW95Lld7BmHOHE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "cheshire/cheshire/6.1.0/cheshire-6.1.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -125,6 +160,26 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-dXkdZHooK97QEyeXodFSC942EiB9B8MlHUNZlbH8nvI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/nextjournal/beholder/1.0.2/beholder-1.0.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-iQOMTbidIDu1sSpfsa2qkpXgWirEsk+u2ZbJNOqJ0Xo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/nextjournal/beholder/1.0.2/beholder-1.0.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-LRJkSGdQPfLoeGjLwU3deFKoaum2dW/QJ46lCK0d4u4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/rpl/specter/1.1.6/specter-1.1.6.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-vqmD19/KmPN99xUGxINR1L2PzgwiUEoa+da1r39BE9U="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/rpl/specter/1.1.6/specter-1.1.6.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2Fv7Xf/j/e+vS9pjGOyCkOyQEqA+0rzjZzo3p4T2WmU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "com/unboundid/unboundid-ldapsdk/5.1.1/unboundid-ldapsdk-5.1.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -185,6 +240,36 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2OgLA0KFMl6QX1RkmhWYtoe5pKmaOk9LlO7TWXyyEEg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "expound/expound/0.9.0/expound-0.9.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-1qNyYJkY4DUb+mqL1pPRi8GZ6Lp6r67BHola+uAY+Vw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "expound/expound/0.9.0/expound-0.9.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-kJSODD3MvE8aCvaABWue2JizAcvtLd4/9CR5eWmXxdk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.27/fipp-0.6.27.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-qK1dAlan2r+90UOm6QvnZXURhA/is4MMp9tnK20RDPc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "fipp/fipp/0.6.27/fipp-0.6.27.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-ugagpDW5XBNQMTr+1z3s6r5TXwbF/pw6Ffrcc4Tzlvk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "hawk/hawk/0.2.11/hawk-0.2.11.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-6UPy8MSHxsWmsg5wzpHdXzHkBIlXCRe7oT/OpzyaekM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "hawk/hawk/0.2.11/hawk-0.2.11.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-q4PzoWHUY53W2TZWihPpw+qXB4QWWVnS1iW3WlvIxFg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "hiccup/hiccup/2.0.0-RC4/hiccup-2.0.0-RC4.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
@@ -215,6 +300,56 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-7Vh2tzj7zXYdGd03xiyTExP/beuWSi8Nn1NmRKkw9bQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "io/methvin/directory-watcher/0.17.3/directory-watcher-0.17.3.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-BSPdOKOTpjt15DIP9SMDSgrDzqaX9hUaesiok8MiUx4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "io/methvin/directory-watcher/0.17.3/directory-watcher-0.17.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Y/C4zR1No0m2Dfk4kdHgDF0/0sm9M9jlvu0HWijNiFQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/clj-diff/1.4.78/clj-diff-1.4.78.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-oovG5LKVI8wppHLlfm6rlYD6DQNorXvliypH6JGhRZw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/clj-diff/1.4.78/clj-diff-1.4.78.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-2QZ6mFjx7+UGI232PUr3CzsQenqd+xcRsbqEpxs32w0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.12.219/deep-diff2-2.12.219.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-BkOq5C/7omo09wyTTg7nkBi6GWBmlayVsPa9mrDvCyU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/deep-diff2/2.12.219/deep-diff2-2.12.219.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-rW/85js2hSWVc36e2BcTRmkahJHc2TjGIEfvForuToY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/kaocha/1.91.1392/kaocha-1.91.1392.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-W7EV1MqxeIVqyTyt6lV9vpZrLRc+TWQKnmNfiPoieug="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/kaocha/1.91.1392/kaocha-1.91.1392.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-p6+0cuuFYlJU5YlhGIbnuHt1d6yOZXx/FhwAM6wCyzg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/tools.namespace/0.3.256/tools.namespace-0.3.256.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-jt141ljkjv97etTTE995zZnqiZfoFnyt0g2hwmuOU8M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "lambdaisland/tools.namespace/0.3.256/tools.namespace-0.3.256.pom",
|
||||
"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/",
|
||||
@@ -225,6 +360,56 @@
|
||||
"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/",
|
||||
"hash": "sha256-1/7i4+PXBuDlRWLnKqNxIQjXAYahLLwJDhBoBYLrAsc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "meta-merge/meta-merge/1.0.0/meta-merge-1.0.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-sAogZY/OzCvRNBAx85T1LWjFP7SAxEVBNMyqwgTqWTE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/arrangement/2.1.0/arrangement-2.1.0.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-83JROF0iDfiVHmjVJVq7UZetvL2PxrPT/KhyojOfOcg="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/arrangement/2.1.0/arrangement-2.1.0.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-fWiMhmYYFAo78Am00FcK7acJA0h7dlH7VNBHf5TT2Is="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/clj-cbor/1.1.1/clj-cbor-1.1.1.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-XqYtfq4Seg2W6Favuh2Ogm2TrZfFCgEFNvsekCgX4I8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "mvxcvi/clj-cbor/1.1.1/clj-cbor-1.1.1.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SzmvI+F2QOnCPH5H6OKH124pbohIazXgPG3PhqH0VZA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/incongru/watchservice/barbary-watchservice/1.0/barbary-watchservice-1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-VMbKvYIJPIUV9uFOQ9lL/n6fx5XRV4nzlDoUGNgmOrU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/incongru/watchservice/barbary-watchservice/1.0/barbary-watchservice-1.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-k7OxHaltUXiIDfjFBT8Yz8eByv8Nnd9LPGRyRKnRws8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-kagUrE9A1g3ukdhC4aith0xiGXmEQD0OPDDTnlXPU7M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "net/java/dev/jna/jna/5.12.1/jna-5.12.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Zf8lhJuthZVUtQMXeS9Wia20UprkAx6aUkYxnLK4U1Y="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/apache/apache/23/apache-23.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -282,62 +467,62 @@
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.10.3/clojure-1.10.3.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-a6YADmhI+Cw5y5tJqyqmo6Vi9MJNUrMeUZCuZJXwwwk="
|
||||
},
|
||||
{
|
||||
@@ -350,6 +535,46 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-KfRiqonLl2RXWEGKXwjUwagrc1yW569JgX0WqpuQgVA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.1/clojure-1.12.1.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-h+7qnjVdhsBFc4r0lNaD4J6RTLBGeuQNRqZrh6NsctQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.1/clojure-1.12.1.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-JUvpyKuMzDArR9fFaj/KEUl+WcMFvxX6YFTD3/TrkZ0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.2/clojure-1.12.2.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-pYv4B+zv7K6iIri4tH4UNo7o4yy0VAs//v/4yglTSA0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.2/clojure-1.12.2.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-55suCRfnPnPCX7N5PzFV+PD4jYAvUMJf1Sl3l3rDQiA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.3/clojure-1.12.3.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-yyoaPbHCzXbvT6SlRdWmXxCxtIt/dnLwoQn1R28FcWY="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.3/clojure-1.12.3.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-q2CmyyuMxXyG21ECte4p8hWsg8/20wEblV+fxb5dAZ0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.4/clojure-1.12.4.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-S4Hpum2jjEXZzFgCPGdAYrjJ8HFPM/8A3tIuapSdoXc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/clojure/1.12.4/clojure-1.12.4.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-xRh5Bi5B/58hr6DkCbGZ/+nyo8aucizf7F/Z26BeQXI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.match/1.1.0/core.match-1.1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -360,24 +585,34 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-NnHYN2UlIwq6Ah8fYmx54g86ELYrXfgXIiWJDsSv4EU="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.0/core.rrb-vector-0.2.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-ftqNXGlaxVNp3NTHN4YUMhdXuBAoG//KMMss02PRZZQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/core.rrb-vector/0.2.0/core.rrb-vector-0.2.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-t+0/8ZfxrdZOHvJS2zRY8wlhPcZXdejY4OkTlx4CRY4="
|
||||
},
|
||||
{
|
||||
"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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-F3i70Ti9GFkLgFS+nZGdG+toCfhbduXGKFtn1Ad9MA4="
|
||||
},
|
||||
{
|
||||
@@ -390,6 +625,16 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-M0EOuKpz1S2Vez3G4KZfOZisBiPL2BPZDDPm5onEJCk="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/java.classpath/1.0.0/java.classpath-1.0.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-wU4OEDBKXlz9LMdC+976wfUpPuxgcML/6JA/tcf+fW8="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/java.classpath/1.0.0/java.classpath-1.0.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-C+AThRRX/CTENM5FU0ZD8iblwQgASGJT/Tc/LglUXig="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/java.data/1.3.113/java.data-1.3.113.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -405,9 +650,14 @@
|
||||
"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/",
|
||||
"hash": "sha256-4OoifEnFw+MHVM0m/MV75+Telz/kOqXMZmdAHsXBAyM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/pom.contrib/0.3.0/pom.contrib-0.3.0.pom",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-fxgrOypUPgV0YL+T/8XpzvasUn3xoTdqfZki6+ee8Rk="
|
||||
},
|
||||
{
|
||||
@@ -427,22 +677,22 @@
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar",
|
||||
"mvn-repo": "https://repo.maven.apache.org/maven2/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.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/",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-bY3hTDrIdXYMX/kJVi/5hzB3AxxquTnxyxOeFp/pB1g="
|
||||
},
|
||||
{
|
||||
@@ -465,6 +715,16 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-UZ45jnJMYvCsnWsZ15+P8QAdqYWD/eAb1wUrB+Ga1ow="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.cli/1.1.230/tools.cli-1.1.230.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-kWYwtTmkP/RotN0BbGKFfitMtdpmhvEpdYfN1DyhAs0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.cli/1.1.230/tools.cli-1.1.230.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-v7Yh5LAaW4vOEWpgcIQNzdWUnomceEaNgRtuiqqf0cc="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/clojure/tools.logging/1.3.0/tools.logging-1.3.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -485,6 +745,16 @@
|
||||
"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-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -530,11 +800,51 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-oLLU3iXdPWNptThQLeay5UJcKxyOM6GQKZgIS4o4EWs="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-+wRqnCKUN5KLsRwtJ8i113PriiXmDL0lPZhSEN7cJoQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-aZgMA4yhsTGSZWFZFhfZwl+r/Hspgor5FZfKhXDPNf4="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-NTkEp6bCgwTQ3KyA+tMMSM2Jj22wO5PwWtbJDdQtmK0="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-parent/1.7.36/slf4j-parent-1.7.36.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-uziNN/vN083mTDzt4hg4aTIY3EUfBAQMXfNgp47X6BI="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/slf4j/slf4j-parent/1.7.7/slf4j-parent-1.7.7.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Hf+uPOdo0FR+JhyWiYz12dGUv/1WAPWXyXUcxqc9M9Q="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/sonatype/oss/oss-parent/7/oss-parent-7.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-tR+IZ8kranIkmVV/w6H96ne9+e9XRyL+kM5DailVlFQ="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/tcrawley/dynapath/1.1.0/dynapath-1.1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-n8eqO+Y4XaOtIqBlJvFaXTNdnonUDzm/L5oA4Lu9iug="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/tcrawley/dynapath/1.1.0/dynapath-1.1.0.pom",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-5OPOTeIWKm8U9QjB0Nv0s9tsrBk5E+kVeAhcGLesJho="
|
||||
},
|
||||
{
|
||||
"mvn-path": "org/xerial/sqlite-jdbc/3.47.1.0/sqlite-jdbc-3.47.1.0.jar",
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
@@ -545,6 +855,26 @@
|
||||
"mvn-repo": "https://repo1.maven.org/maven2/",
|
||||
"hash": "sha256-Z3XeNvNR9MdFCL/+qtZAIceVhx/ZRIXsdsPhduUwU7g="
|
||||
},
|
||||
{
|
||||
"mvn-path": "progrock/progrock/0.1.2/progrock-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-Aln+tbAkduswC31k5UPrVM5Kw9yuU5gxDxZCdo/VPyo="
|
||||
},
|
||||
{
|
||||
"mvn-path": "progrock/progrock/0.1.2/progrock-0.1.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-6rULcjyeeEkPWDy5n7HUa8KA/xH9X4Ujub7XamTq8CM="
|
||||
},
|
||||
{
|
||||
"mvn-path": "riddley/riddley/0.1.12/riddley-0.1.12.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-OY9h+kgluPhskWrlgMfhM7fEd9C3Kn07KY04EDJ0C64="
|
||||
},
|
||||
{
|
||||
"mvn-path": "riddley/riddley/0.1.12/riddley-0.1.12.pom",
|
||||
"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/",
|
||||
@@ -610,6 +940,16 @@
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-HHmMD/cPNu7HwRubeajXYOBDYK1y9x9F9KhRytq2AQw="
|
||||
},
|
||||
{
|
||||
"mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-porCK/LqPNVM4023D9aYRNYx71SfZFDCeMMOb3nfY/M="
|
||||
},
|
||||
{
|
||||
"mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.pom",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
"hash": "sha256-SrxOK5ppxzvTc+gy0/AOWQZ4Q/+DUe/V7rsfOCTbnFE="
|
||||
},
|
||||
{
|
||||
"mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.jar",
|
||||
"mvn-repo": "https://repo.clojars.org/",
|
||||
|
||||
@@ -8,5 +8,9 @@
|
||||
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"}}
|
||||
:paths ["src" "resources" "test"]}
|
||||
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
doerg/doerg-temml-worker/README.org
Normal file
1
doerg/doerg-temml-worker/README.org
Normal file
@@ -0,0 +1 @@
|
||||
#+title: doerg-temml-worker
|
||||
@@ -3,17 +3,13 @@
|
||||
, makeWrapper
|
||||
, ibm-plex
|
||||
, callPackage
|
||||
, our-tex ? callPackage ./our-tex.nix {}
|
||||
}:
|
||||
|
||||
buildNpmPackage {
|
||||
pname = "doerg-tex";
|
||||
pname = "doerg-temml-worker";
|
||||
version = "0.1.0";
|
||||
src = ./.;
|
||||
npmDeps = importNpmLock { npmRoot = ./.; };
|
||||
npmConfigHook = importNpmLock.npmConfigHook;
|
||||
dontNpmBuild = true;
|
||||
buildInputs = [
|
||||
our-tex
|
||||
];
|
||||
}
|
||||
@@ -34,13 +34,13 @@ function do_command (cmd) {
|
||||
return null
|
||||
}
|
||||
} catch (e) {
|
||||
console.error (e)
|
||||
return {type: "error", error: e}
|
||||
}
|
||||
}
|
||||
|
||||
function main () {
|
||||
const options = commandLineArgs (cli_spec)
|
||||
console.error (options)
|
||||
macros = load_preambles (options.preamble)
|
||||
const decoder = new DecoderStream ()
|
||||
const encoder = new EncoderStream ()
|
||||
@@ -1,6 +1,6 @@
|
||||
{"dependencies":{"temml":"^0.13.1"
|
||||
,"command-line-args":"^6.0.1"
|
||||
,"cbor-x":"^1.6.0"}
|
||||
,"name":"doerg-tex"
|
||||
,"name":"doerg-temml-worker"
|
||||
,"version":"0.1.0"
|
||||
,"bin":{"doerg-tex":"index.js"}}
|
||||
,"bin":{"doerg-temml-worker":"index.js"}}
|
||||
@@ -1 +0,0 @@
|
||||
#+title: doerg-tex
|
||||
@@ -1,12 +1,18 @@
|
||||
{ mkCljBin
|
||||
, callPackage
|
||||
, lib
|
||||
, doerg-parser
|
||||
, doerg-temml-worker
|
||||
, ibm-plex-web
|
||||
, fake-git
|
||||
, our-tex ? callPackage ./our-tex.nix {}
|
||||
, makeWrapper
|
||||
, breakpointHook
|
||||
}:
|
||||
|
||||
let
|
||||
# mkCljBin sans fake-git.
|
||||
# mkCljBin sans fake-git. We don't need it, and I don't want it in
|
||||
# my dev shell.
|
||||
mkCljBin' = args: (mkCljBin args).overrideAttrs (final: prev: {
|
||||
nativeBuildInputs =
|
||||
builtins.filter
|
||||
@@ -18,6 +24,11 @@ let
|
||||
plex = ibm-plex-web.override {
|
||||
families = [ "math" "serif" "sans" "sans-kr" ];
|
||||
};
|
||||
bin-path = lib.makeBinPath [
|
||||
doerg-parser
|
||||
our-tex
|
||||
doerg-temml-worker
|
||||
];
|
||||
in mkCljBin' {
|
||||
name = "net.deertopia/doerg";
|
||||
version = "0.1.0";
|
||||
@@ -26,9 +37,27 @@ in mkCljBin' {
|
||||
main-ns = "net.deertopia.doerg.main";
|
||||
nativeBuildInputs = [
|
||||
plex
|
||||
makeWrapper
|
||||
breakpointHook
|
||||
];
|
||||
buildInputs = [
|
||||
doerg-parser
|
||||
doerg-temml-worker
|
||||
plex
|
||||
our-tex
|
||||
];
|
||||
nativeCheckInputs = [
|
||||
doerg-parser
|
||||
doerg-temml-worker
|
||||
plex
|
||||
our-tex
|
||||
];
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
clojure -M:test
|
||||
'';
|
||||
postInstall = ''
|
||||
wrapProgram $out/bin/doerg \
|
||||
--prefix PATH : ${bin-path}
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -546,3 +546,13 @@ figure.fullwidth figcaption {
|
||||
.latex-fragment
|
||||
{ fill: currentColor
|
||||
}
|
||||
|
||||
.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%
|
||||
}
|
||||
|
||||
@@ -4,16 +4,32 @@
|
||||
[spec-dict.main :refer [dict]]))
|
||||
|
||||
(s/def ::config
|
||||
(s/keys :req [::ibm-plex-web]))
|
||||
(s/keys :req [::ibm-plex-web
|
||||
::latex
|
||||
::dvisvgm]))
|
||||
|
||||
(s/def ::file
|
||||
#(or (instance? java.io.File %)
|
||||
(string? %)))
|
||||
|
||||
(def default
|
||||
{::ibm-plex-web
|
||||
(fs/file
|
||||
(or (System/getenv "IBM_PLEX_WEB")
|
||||
(some #(let [x (fs/path % "ibm-plex-web")]
|
||||
(and (fs/exists? x) x))
|
||||
(fs/split-paths (System/getenv "XDG_DATA_DIRS")))))})
|
||||
(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 string?)
|
||||
(s/def ::ibm-plex-web ::file)
|
||||
|
||||
(s/def ::latex ::file)
|
||||
|
||||
(s/def ::dvisvgm ::file)
|
||||
|
||||
(s/def ::doerg-temml-worker ::file)
|
||||
|
||||
@@ -81,6 +81,13 @@
|
||||
(when-some [footnotes-headline (first (:children element))]
|
||||
(= "Footnotes" (:raw-value footnotes-headline)))))
|
||||
|
||||
(defn display-math?
|
||||
"Return truthy if `element` should be considered display math."
|
||||
[element]
|
||||
(or (of-type? element "latex-environment")
|
||||
(and (of-type? element "latex-fragment")
|
||||
(-> element :contents (str/starts-with? "\\[")))))
|
||||
|
||||
|
||||
;;; Spec
|
||||
|
||||
@@ -180,8 +187,8 @@
|
||||
parser, return a map with the following keys
|
||||
• :top-level-nodes The nodes that /should/ be at the top-level.
|
||||
• :first-section-nodes The nodes that should be wrapped in a new
|
||||
section node
|
||||
• :rest Everything else!"
|
||||
section node.
|
||||
• :rest Everything else."
|
||||
[nodes]
|
||||
(let [[of-top-level remaining-nodes]
|
||||
(->> nodes (split-with #(of-type? % "property-drawer" "keyword")))
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
[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]))
|
||||
|
||||
@@ -58,7 +61,7 @@
|
||||
(defn org-document
|
||||
"Recursively render an Org-mode document to Hiccup."
|
||||
[doc]
|
||||
(tex/binding-temml-worker
|
||||
(tex-temml/binding-worker
|
||||
(let [rendered (-> doc gather-footnotes render-tex-snippets
|
||||
org-element-recursive)]
|
||||
[:html
|
||||
@@ -69,6 +72,12 @@
|
||||
[:article
|
||||
rendered]]])))
|
||||
|
||||
(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))))
|
||||
|
||||
|
||||
;;; Further dispatching on `org-element`
|
||||
|
||||
@@ -147,7 +156,7 @@
|
||||
;; 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'?>" "")
|
||||
(str/replace-first #"<\?xml version='1.0' encoding='UTF-8'\?>\n?" "")
|
||||
(str/replace-first #" height=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first #" width=['\"][^\"']+[\"']" "")
|
||||
(str/replace-first
|
||||
@@ -158,7 +167,10 @@
|
||||
(format "height:%.4fem;vertical-align:%.4fem;display:inline-block"
|
||||
height (- depth)))))))
|
||||
|
||||
(defn- render-tex-snippets [doc]
|
||||
(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 [])
|
||||
r (->> doc (sp/transform
|
||||
[element/postorder-walker
|
||||
@@ -173,11 +185,11 @@
|
||||
(let [rendered-snippets
|
||||
(delay (->> @promises
|
||||
(map #(-> % :node :value))
|
||||
(apply tex/render-xelatex svg-dir)))]
|
||||
(apply tex-native/render svg-dir)))]
|
||||
(doseq [{:keys [promise node]} @promises]
|
||||
(try (let [{:keys [value]} node
|
||||
temml (tex/render-temml value)]
|
||||
(if (tex/erroneous-temml-output? temml)
|
||||
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))
|
||||
@@ -187,13 +199,17 @@
|
||||
(deliver promise))))
|
||||
(deliver promise (hiccup/raw temml))))
|
||||
(catch Exception e
|
||||
(prn e)
|
||||
(flush)
|
||||
(throw e))))
|
||||
(when (fs/exists? "/tmp/doerg-svgs")
|
||||
(fs/delete-tree "/tmp/doerg-svgs"))
|
||||
(fs/copy-tree svg-dir "/tmp/doerg-svgs"))))]
|
||||
(future-call (bound-fn* f))
|
||||
(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))
|
||||
r))
|
||||
|
||||
(comment
|
||||
@@ -342,12 +358,14 @@
|
||||
(str "@" key))
|
||||
|
||||
(defmethod org-element "latex-fragment" [{:keys [contents value] :as e}]
|
||||
[:span.latex-fragment
|
||||
(-> e ::rendered (deref #_#_ 2000 "«timed out»"))])
|
||||
[:span {:class (if (element/display-math? e)
|
||||
"latex-fragment display-math"
|
||||
"latex-fragment")}
|
||||
(-> e ::rendered deref)])
|
||||
|
||||
(defmethod org-element "latex-environment" [{:keys [value] :as e}]
|
||||
[:span.latex-fragment
|
||||
(-> e ::rendered (deref #_#_ 2000 "«timed out»"))])
|
||||
[:span.latex-fragment.display-math
|
||||
(-> e ::rendered deref)])
|
||||
|
||||
(defmethod org-element "example-block" [{:keys [value]}]
|
||||
[:pre value])
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"/home/msyds/org/20250512144715-natural_transformation_category_theory.org"
|
||||
#_
|
||||
"/home/msyds/org/20251021155921-path_action.org"
|
||||
"/tmp/t.org")
|
||||
"test/net/deertopia/doerg/render_test/fallbacks.org")
|
||||
|
||||
(defn- force-create-sym-link [path target]
|
||||
(fs/delete-if-exists path)
|
||||
@@ -37,8 +37,7 @@
|
||||
(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"))
|
||||
(->> (h/html (-> src slurp element/read-string render/org-document))
|
||||
str (spit (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
|
||||
|
||||
@@ -1,220 +1,4 @@
|
||||
(ns net.deertopia.doerg.tex
|
||||
(:require [babashka.process :as p]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[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)))
|
||||
|
||||
;;; XeLaTeX
|
||||
|
||||
(def ^:private scale-divisor 66873.46948423679)
|
||||
|
||||
(def ^:private font-size 10)
|
||||
|
||||
(def ^:private tightpage-regexp
|
||||
#"Preview: Tightpage (-?\d+) *(-?\d+) *(-?\d+) *(-?\d+)")
|
||||
|
||||
(def ^:private preview-start-regexp
|
||||
#"! Preview: Snippet (\d+) started.")
|
||||
|
||||
(def ^:private preview-end-regexp
|
||||
#"(?:^Preview: Tightpage.*$)?\n! Preview: Snippet (\d+) ended.\((\d+)\+(\d+)x(\d+)\)")
|
||||
|
||||
(defn- invoke [extra-opts & args]
|
||||
(let [namespace (or (::ns extra-opts)
|
||||
(first args))
|
||||
out-bytes (ByteArrayOutputStream.)
|
||||
out-stream (common/tee-output-stream
|
||||
out-bytes
|
||||
(l/log-stream :info (str namespace "/out")))
|
||||
err-stream (l/log-stream :info (str namespace "/err"))
|
||||
opts (merge extra-opts
|
||||
{:out out-stream :err err-stream :continue true
|
||||
:shutdown p/destroy-tree
|
||||
:pre-start-fn (fn [{:keys [cmd]}]
|
||||
(l/infof "$ %s"
|
||||
(str/join " " cmd)))
|
||||
:exit-fn (fn [{:keys [cmd exit]}]
|
||||
(l/infof "%s exited w/ status %d"
|
||||
(first cmd) exit))})
|
||||
r (apply p/shell opts args)
|
||||
out (.toString out-bytes)]
|
||||
(-> r
|
||||
(assoc ::out out))))
|
||||
|
||||
(defn- parse-tightpage [xelatex-out]
|
||||
(->> (re-find tightpage-regexp xelatex-out)
|
||||
(drop 1)
|
||||
(map parse-long)))
|
||||
|
||||
(defn- snippet-dimensions [[tp1 tp2 tp3 tp4] [d1 d2 d3]]
|
||||
(let [depth (/ (- d2 tp2) scale-divisor font-size)]
|
||||
{:depth depth
|
||||
:height (+ depth
|
||||
(/ (+ d1 tp4)
|
||||
scale-divisor
|
||||
font-size))
|
||||
:width (/ (+ d3 tp3 (- tp2))
|
||||
scale-divisor
|
||||
font-size)}))
|
||||
|
||||
(defn- parse-xelatex-output [out]
|
||||
(let [tightpage-info (parse-tightpage out)
|
||||
m-start (re-matcher preview-start-regexp out)
|
||||
m-end (re-matcher preview-end-regexp out)]
|
||||
(loop [acc []]
|
||||
(if-some [[_ snippet-ix] (re-find m-start)]
|
||||
(let [r (re-find m-end)
|
||||
[_ snippet-ix* _ _ _] r
|
||||
dimensional-info (->> r (drop 2) (map parse-long))
|
||||
errors (-> out
|
||||
(subs (.end m-start) (.start m-end))
|
||||
(str/replace-first #"[^!]*" "")
|
||||
str/trim)]
|
||||
(assert (= snippet-ix snippet-ix*))
|
||||
(recur (conj acc (-> (snippet-dimensions
|
||||
tightpage-info dimensional-info)
|
||||
(assoc :errors (if (empty? errors)
|
||||
nil
|
||||
errors))))))
|
||||
acc))))
|
||||
|
||||
(defn- invoke-xelatex [& {:keys [file output-dir]}]
|
||||
(invoke
|
||||
{:dir output-dir}
|
||||
"xelatex" "-no-pdf" "-interaction" "nonstopmode"
|
||||
"-output-directory" output-dir file))
|
||||
|
||||
;; dvisvgm --page=1- --optimize --clipjoin --relative --no-fonts -v3 --message='processing page {?pageno}: output written to {?svgpath}' --bbox=preview -o %B-%%9p.svg %f
|
||||
|
||||
(defn- invoke-dvisvgm [& {:keys [file output-dir]}]
|
||||
(invoke
|
||||
{:dir output-dir}
|
||||
"dvisvgm" "--page=1-" "--optimize" "--clipjoin"
|
||||
"--relative" "--no-fonts" "-v3"
|
||||
"--message=processing page {?pageno}: output written to {?svgpath}"
|
||||
"--bbox=preview" "-o" "%9p.svg" file))
|
||||
|
||||
(defn- snippet-file-names
|
||||
"Return a map of TeX snippets (as strings, including the math
|
||||
delimiters) to file names as would be output by
|
||||
`invoke-dvisvgm`. The returned file names are relative to dvisvgm's
|
||||
output directory."
|
||||
[snippets]
|
||||
(let [svgs (for [i (range)]
|
||||
(format "%09d.svg" i))]
|
||||
(zipmap (reverse snippets) svgs)))
|
||||
|
||||
(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))))
|
||||
|
||||
(defn render-xelatex
|
||||
"Render a collection of `snippets` to SVGs in `output-dir` using
|
||||
XeLaTeX and dvisvgm. Returns a map whose keys are `snippets` and
|
||||
whose values are maps containing dimensional info, a string of
|
||||
errors output by XeLaTeX, and the path to the generated SVG
|
||||
file. Math delimiters are *not* implicitly added to each snippet."
|
||||
[output-dir & snippets]
|
||||
(fs/with-temp-dir [dir {:prefix "doerg-xelatex"}]
|
||||
(let [preview-tex (fs/file dir "preview.tex")
|
||||
preview-xdv (fs/file dir "preview.xdv")
|
||||
distinct-snippets (distinct snippets)]
|
||||
(fs/create-dirs output-dir)
|
||||
(->> (instantiate-preview-template distinct-snippets)
|
||||
(spit preview-tex))
|
||||
(let [dimensions (-> (invoke-xelatex :output-dir dir :file preview-tex)
|
||||
::out parse-xelatex-output)
|
||||
_ (invoke-dvisvgm :output-dir output-dir :file preview-xdv)]
|
||||
;; Adorn each snippet with dimensions and errors parsed from
|
||||
;; XeLaTeX's output, and the paths to SVG files generated by
|
||||
;; dvisvgm.
|
||||
(assert (= (count distinct-snippets) (count dimensions)))
|
||||
(->> (map (fn [ix snippet dimensions]
|
||||
{snippet
|
||||
(-> dimensions
|
||||
(assoc
|
||||
:file (fs/file output-dir
|
||||
(format "%09d.svg" (inc ix)))))})
|
||||
(range)
|
||||
distinct-snippets
|
||||
dimensions)
|
||||
(into {})))
|
||||
#_
|
||||
(do (when (fs/exists? "/tmp/doerg-tex-test") ; For debugging
|
||||
(fs/delete-tree "/tmp/doerg-tex-test"))
|
||||
(fs/copy-tree dir "/tmp/doerg-tex-test")))))
|
||||
|
||||
(comment
|
||||
(render-xelatex "/tmp/doerg-tex-svgs"
|
||||
"\\(c = \\sqrt{x^2 + y^2}\\)"
|
||||
"\\(x\\)" "\\(y\\)" "\\(x\\)"
|
||||
"\\(\\undefinedcommandlol\\)"))
|
||||
|
||||
|
||||
;;; Temml
|
||||
|
||||
(def ^:dynamic *temml-worker-timeout-duration*
|
||||
"Number of milliseconds to wait before killing the external Uniorg
|
||||
process."
|
||||
(* 10 1000))
|
||||
|
||||
(def ^:dynamic *temml-worker*)
|
||||
|
||||
(defn temml-worker [& {:keys [preamble]}]
|
||||
(p/process
|
||||
{:shutdown p/destroy-tree
|
||||
:err (l/log-stream :info "temml/err")}
|
||||
#_"doerg-tex"
|
||||
"./doerg-tex/index.js"
|
||||
"--preamble"
|
||||
"resources/net/deertopia/doerg/prelude.tex"))
|
||||
|
||||
(defn close-temml-worker [tw]
|
||||
(.close (:in tw)))
|
||||
|
||||
(defmacro with-temml-worker [tw & body]
|
||||
`(let [~tw (temml-worker)]
|
||||
(try
|
||||
(do ~@body)
|
||||
(finally
|
||||
(close-temml-worker ~tw)
|
||||
(p/destroy-tree ~tw)))))
|
||||
|
||||
(defmacro binding-temml-worker [& body]
|
||||
`(binding [*temml-worker* (temml-worker)]
|
||||
(try
|
||||
~@body
|
||||
(finally
|
||||
(close-temml-worker *temml-worker*)))))
|
||||
|
||||
(defn command-temml-worker [x]
|
||||
(cbor/encode cbor/default-codec (:in *temml-worker*) x)
|
||||
(.flush (:in *temml-worker*))
|
||||
(cbor/decode cbor/default-codec (:out *temml-worker*)))
|
||||
|
||||
(defn render-temml-inline [s]
|
||||
(command-temml-worker s))
|
||||
|
||||
(defn render-temml-display [s]
|
||||
(command-temml-worker [s]))
|
||||
|
||||
(defn render-temml [s]
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\[(.*)\\]" s)]
|
||||
(render-temml-display inner)
|
||||
(if (re-matches #"(?s)\\begin\{.+?}(.*?)\\end\{.+?}" s)
|
||||
(render-temml-display s)
|
||||
(if-let [[_ inner] (re-matches #"(?s)\\\((.*)\\\)" s)]
|
||||
(render-temml-inline s)
|
||||
(throw (ex-info "weird" {:snippet s}))))))
|
||||
|
||||
;; hackky....
|
||||
(defn erroneous-temml-output? [s]
|
||||
(re-find #"(#b22222|temml-error)" s))
|
||||
(:require [net.deertopia.doerg.tex.native :as native]
|
||||
[net.deertopia.doerg.tex.temml :as temml]
|
||||
[babashka.fs :as fs]))
|
||||
|
||||
156
doerg/src/net/deertopia/doerg/tex/native.clj
Normal file
156
doerg/src/net/deertopia/doerg/tex/native.clj
Normal file
@@ -0,0 +1,156 @@
|
||||
(ns net.deertopia.doerg.tex.native
|
||||
"Shelling out to (Xe)LaTeX and dvisvgm. Much magic borrowed from
|
||||
the org-latex-preview package for Emacs."
|
||||
(:require [babashka.process :as p]
|
||||
[net.deertopia.doerg.common :as common]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as l]
|
||||
[babashka.fs :as fs]
|
||||
[net.deertopia.doerg.config :as cfg])
|
||||
(:import (java.io ByteArrayOutputStream)))
|
||||
|
||||
(def ^:private scale-divisor 66873.46948423679)
|
||||
|
||||
(def ^:private font-size 10)
|
||||
|
||||
(def ^:private tightpage-regexp
|
||||
#"Preview: Tightpage (-?\d+) *(-?\d+) *(-?\d+) *(-?\d+)")
|
||||
|
||||
(def ^:private preview-start-regexp
|
||||
#"! Preview: Snippet (\d+) started.")
|
||||
|
||||
(def ^:private preview-end-regexp
|
||||
#"(?:^Preview: Tightpage.*$)?\n! Preview: Snippet (\d+) ended.\((\d+)\+(\d+)x(\d+)\)")
|
||||
|
||||
(defn- invoke [extra-opts & args]
|
||||
(let [namespace (or (::ns extra-opts) (first args))
|
||||
out-bytes (ByteArrayOutputStream.)
|
||||
out-stream (common/tee-output-stream
|
||||
out-bytes
|
||||
(l/log-stream :info (str namespace "/out")))
|
||||
err-stream (l/log-stream :info (str namespace "/err"))
|
||||
opts (merge extra-opts
|
||||
{:out out-stream :err err-stream :continue true
|
||||
:shutdown p/destroy-tree
|
||||
:pre-start-fn (fn [{:keys [cmd]}]
|
||||
(l/infof "$ %s"
|
||||
(str/join " " cmd)))
|
||||
:exit-fn (fn [{:keys [cmd exit]}]
|
||||
(l/infof "%s exited w/ status %d"
|
||||
(first cmd) exit))})
|
||||
r (apply p/shell opts args)
|
||||
out (.toString out-bytes)]
|
||||
(-> r
|
||||
(assoc ::out out))))
|
||||
|
||||
(defn- parse-tightpage [latex-out]
|
||||
(->> (re-find tightpage-regexp latex-out)
|
||||
(drop 1)
|
||||
(map parse-long)))
|
||||
|
||||
(defn- compute-geometry [[tp1 tp2 tp3 tp4] [d1 d2 d3]]
|
||||
(let [depth (/ (- d2 tp2) scale-divisor font-size)]
|
||||
{:depth depth
|
||||
:height (+ depth
|
||||
(/ (+ d1 tp4)
|
||||
scale-divisor
|
||||
font-size))
|
||||
:width (/ (+ d3 tp3 (- tp2))
|
||||
scale-divisor
|
||||
font-size)}))
|
||||
|
||||
(defn- parse-latex-output [out]
|
||||
(let [tightpage-info (parse-tightpage out)
|
||||
m-start (re-matcher preview-start-regexp out)
|
||||
m-end (re-matcher preview-end-regexp out)]
|
||||
(loop [acc []]
|
||||
(if-some [[_ snippet-ix] (re-find m-start)]
|
||||
(let [r (re-find m-end)
|
||||
[_ snippet-ix* _ _ _] r
|
||||
dimensional-info (->> r (drop 2) (map parse-long))
|
||||
errors (-> out
|
||||
(subs (.end m-start) (.start m-end))
|
||||
(str/replace-first #"[^!]*" "")
|
||||
str/trim)]
|
||||
(assert (= snippet-ix snippet-ix*))
|
||||
(recur (conj acc (-> (compute-geometry
|
||||
tightpage-info dimensional-info)
|
||||
(assoc :errors (if (empty? errors)
|
||||
nil
|
||||
errors))))))
|
||||
acc))))
|
||||
|
||||
(defn- invoke-latex [& {:keys [file output-dir]}]
|
||||
(let [latex (::cfg/latex cfg/*cfg*)]
|
||||
(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*)]
|
||||
(invoke
|
||||
{:dir output-dir}
|
||||
dvisvgm "--page=1-" "--optimize" "--clipjoin"
|
||||
"--relative" "--no-fonts" "-v3"
|
||||
"--message=processing page {?pageno}: output written to {?svgpath}"
|
||||
"--bbox=preview" "-o" "%9p.svg" file)))
|
||||
|
||||
(defn- snippet-file-names
|
||||
"Return a map of TeX snippets (as strings, including the math
|
||||
delimiters) to file names as would be output by
|
||||
`invoke-dvisvgm`. The returned file names are relative to dvisvgm's
|
||||
output directory."
|
||||
[snippets]
|
||||
(let [svgs (for [i (range)]
|
||||
(format "%09d.svg" i))]
|
||||
(zipmap (reverse snippets) svgs)))
|
||||
|
||||
(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))))
|
||||
|
||||
(defn render
|
||||
"Render a collection of `snippets` to SVGs in `output-dir` using a
|
||||
LaTeX engine (XeLaTeX at the moment) and dvisvgm. Returns a map
|
||||
whose keys are `snippets` and whose values are maps containing
|
||||
geometry info, a string of errors output by LaTeX, and the path to
|
||||
the generated SVG file. Math delimiters are *not* implicitly added
|
||||
to each snippet."
|
||||
[output-dir & snippets]
|
||||
(fs/with-temp-dir [dir {:prefix "doerg-latex"}]
|
||||
(let [preview-tex (fs/file dir "preview.tex")
|
||||
preview-xdv (fs/file dir "preview.xdv")
|
||||
distinct-snippets (distinct snippets)]
|
||||
(fs/create-dirs output-dir)
|
||||
(->> (instantiate-preview-template distinct-snippets)
|
||||
(spit preview-tex))
|
||||
(let [dimensions (-> (invoke-latex :output-dir dir :file preview-tex)
|
||||
::out parse-latex-output)
|
||||
_ (invoke-dvisvgm :output-dir output-dir :file preview-xdv)]
|
||||
;; Adorn each snippet with dimensions and errors parsed from
|
||||
;; LaTeX's output, and the paths to SVG files generated by
|
||||
;; dvisvgm.
|
||||
(assert (= (count distinct-snippets) (count dimensions)))
|
||||
(->> (map (fn [ix snippet dimensions]
|
||||
{snippet
|
||||
(-> dimensions
|
||||
(assoc
|
||||
:file (fs/file output-dir
|
||||
(format "%09d.svg" (inc ix)))))})
|
||||
(range)
|
||||
distinct-snippets
|
||||
dimensions)
|
||||
(into {}))))))
|
||||
|
||||
(comment
|
||||
(render "/tmp/doerg-tex-svgs"
|
||||
"\\(c = \\sqrt{x^2 + y^2}\\)"
|
||||
"\\(x\\)" "\\(y\\)" "\\(x\\)"
|
||||
"\\(\\undefinedcommandlol\\)"))
|
||||
|
||||
68
doerg/src/net/deertopia/doerg/tex/temml.clj
Normal file
68
doerg/src/net/deertopia/doerg/tex/temml.clj
Normal file
@@ -0,0 +1,68 @@
|
||||
(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))
|
||||
60
doerg/test/net/deertopia/doerg/render_test.clj
Normal file
60
doerg/test/net/deertopia/doerg/render_test.clj
Normal file
@@ -0,0 +1,60 @@
|
||||
(ns net.deertopia.doerg.render-test
|
||||
(:require [net.deertopia.doerg.render :as sut]
|
||||
[net.deertopia.doerg.element :as element]
|
||||
[net.deertopia.doerg.tex.temml :as temml]
|
||||
[net.deertopia.doerg.tex.native :as native]
|
||||
[com.rpl.specter :as sp]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.test :as t]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]))
|
||||
|
||||
;; Stupid and hacky.
|
||||
(defn mathml? [s]
|
||||
(str/starts-with? s "<math"))
|
||||
|
||||
;; Also stupid and hacky. }:)
|
||||
(defn svg? [s]
|
||||
(some? (re-matches #"(?s)(<!--.*?-->\n)<svg.*" s)))
|
||||
|
||||
(defn read-resource [s]
|
||||
(let [p (-> (format "net/deertopia/doerg/render_test/%s" s)
|
||||
io/resource slurp)]
|
||||
(cond (str/ends-with? s ".edn") (edn/read-string p)
|
||||
(str/ends-with? s ".org") (element/read-string p))))
|
||||
|
||||
(t/deftest latex-fallbacks
|
||||
(t/testing "LaTeX fallback behaviour"
|
||||
(let [doc (temml/binding-worker
|
||||
(-> "fallbacks.org" read-resource sut/render-tex-snippets))
|
||||
snippets (->> doc
|
||||
(sp/select
|
||||
[element/postorder-walker
|
||||
#(element/of-type?
|
||||
% "latex-fragment" "latex-environment")
|
||||
(sp/view #(-> % ::sut/rendered deref str))]))
|
||||
expectations (-> "fallbacks.edn" read-resource)]
|
||||
(doall (map (fn [s e]
|
||||
(let [mathml (mathml? s)
|
||||
svg (svg? s)]
|
||||
(assert
|
||||
(not= mathml svg)
|
||||
"`mathml?` and `svg?` should be mutually-exclusive.")
|
||||
(case e
|
||||
:mathml (t/is mathml)
|
||||
:svg (t/is svg))))
|
||||
snippets expectations)))))
|
||||
|
||||
(t/deftest latex-laziness
|
||||
(t/testing "LaTeX laziness"
|
||||
(let [ex (Exception. "you're supposed to be lazy!")
|
||||
bad (fn [& _] (throw ex))
|
||||
doc (read-resource "latexless.org")
|
||||
r (try (with-redefs-fn {#'native/render bad
|
||||
#'temml/render bad}
|
||||
#(sut/render-tex-snippets doc))
|
||||
(catch Exception e
|
||||
(if (= e ex)
|
||||
false
|
||||
(throw e))))]
|
||||
(t/is r))))
|
||||
7
doerg/test/net/deertopia/doerg/render_test/fallbacks.edn
Normal file
7
doerg/test/net/deertopia/doerg/render_test/fallbacks.edn
Normal file
@@ -0,0 +1,7 @@
|
||||
[:mathml
|
||||
:mathml
|
||||
:mathml
|
||||
:mathml
|
||||
:svg
|
||||
:mathml
|
||||
:svg]
|
||||
20
doerg/test/net/deertopia/doerg/render_test/fallbacks.org
Normal file
20
doerg/test/net/deertopia/doerg/render_test/fallbacks.org
Normal file
@@ -0,0 +1,20 @@
|
||||
#+title: aghhh
|
||||
|
||||
- blah blah prose prose prose \(c = \sqrt{x^2 + y^2}\), alal.
|
||||
- this thing is \(x\)
|
||||
- another thing \(y\)
|
||||
- this thing is also \(x\) and uses the same svg
|
||||
- ifxetex: \(\ifxetex alalala\fi \)
|
||||
|
||||
balahahahahahaj
|
||||
\begin{align*}
|
||||
x &= y
|
||||
\\ &= zzz.
|
||||
\end{align*}
|
||||
awawawa
|
||||
|
||||
cool ass tbale
|
||||
\begin{tabular}{|c|c|c|}
|
||||
blah & glah & zlah
|
||||
\\ abdwa & www &dj
|
||||
\end{tabular}
|
||||
3
doerg/test/net/deertopia/doerg/render_test/latexless.org
Normal file
3
doerg/test/net/deertopia/doerg/render_test/latexless.org
Normal file
@@ -0,0 +1,3 @@
|
||||
#+title: 이 파일은 LaTeX 코드가 포함되지 않습니다.
|
||||
|
||||
🦌!
|
||||
1
doerg/tests.edn
Normal file
1
doerg/tests.edn
Normal file
@@ -0,0 +1 @@
|
||||
#kaocha/v1 {}
|
||||
10
flake.nix
10
flake.nix
@@ -32,7 +32,7 @@
|
||||
_pkgs = each-system ({ pkgs, ... }: pkgs);
|
||||
|
||||
packages = each-system ({ pkgs, ... }: {
|
||||
inherit (pkgs) publisher doerg doerg-parser doerg-tex;
|
||||
inherit (pkgs) publisher doerg doerg-parser doerg-temml-worker;
|
||||
default = pkgs.publisher;
|
||||
});
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
publisher = final.callPackage ./publisher/package.nix {};
|
||||
doerg = final.callPackage ./doerg/package.nix {};
|
||||
doerg-parser = final.callPackage ./doerg/doerg-parser {};
|
||||
doerg-tex = final.callPackage ./doerg/doerg-tex {};
|
||||
doerg-temml-worker = final.callPackage ./doerg/doerg-temml-worker {};
|
||||
};
|
||||
|
||||
checks = each-system ({ pkgs, system, ... }: {
|
||||
packages =
|
||||
build-all =
|
||||
pkgs.linkFarmFromDrvs
|
||||
"all"
|
||||
(pkgs.lib.attrValues self.packages.${system});
|
||||
@@ -59,12 +59,12 @@
|
||||
inputsFrom = [
|
||||
pkgs.doerg
|
||||
pkgs.doerg-parser
|
||||
pkgs.doerg-tex
|
||||
pkgs.doerg-temml-worker
|
||||
];
|
||||
packages = with pkgs; [
|
||||
clojure-lsp
|
||||
doerg-parser
|
||||
doerg-tex
|
||||
doerg-temml-worker
|
||||
# wahhh ibm-plex-web is a dependency of doerg... why must
|
||||
# i specify it hereeee.
|
||||
# ibm-plex-web
|
||||
|
||||
Reference in New Issue
Block a user