Compare commits

...

9 Commits

Author SHA1 Message Date
26410655d9 fix: tikz svgs
All checks were successful
build / build (push) Successful in 43s
Fixes #9
2026-03-05 15:09:37 -07:00
faa84f986d doc: doerg-temml-worker
All checks were successful
build / build (push) Successful in 1m24s
2026-03-05 11:47:59 -07:00
9ec8bca383 feat: warning message on timeout
All checks were successful
build / build (push) Successful in 40s
2026-03-05 09:52:29 -07:00
d946c57bff Merge pull request 'fix: namespace error lol' (#8) from ns-error into main
All checks were successful
build / build (push) Successful in 4s
Reviewed-on: #8
2026-03-05 09:49:24 -07:00
7c4ad64d58 fix: increase snippet timeout to 20s
All checks were successful
build / build (push) Successful in 5s
2026-03-05 09:49:04 -07:00
56742cf72d fix: namespace error lol
Some checks failed
build / build (push) Failing after 1m1s
2026-03-05 09:36:49 -07:00
a92b387e63 refactor: more.
Some checks failed
build / build (push) Failing after 3h13m17s
2026-03-02 15:18:35 -07:00
98c106b3cf fix: trim temml/render input 2026-03-02 15:17:57 -07:00
b336aa873e refactor: more cleanup >_<
Some checks failed
build / build (push) Has been cancelled
2026-03-02 14:59:11 -07:00
9 changed files with 128 additions and 52 deletions

View File

@@ -7,7 +7,6 @@
, fake-git
, our-tex ? callPackage ./our-tex.nix {}
, makeWrapper
, breakpointHook
}:
let
@@ -38,7 +37,6 @@ in mkCljBin' {
nativeBuildInputs = [
plex
makeWrapper
breakpointHook
];
buildInputs = [
doerg-parser

View File

@@ -1 +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

View File

@@ -39,5 +39,6 @@ texlive.combine {
collection-fontsrecommended # Essential fonts.
etoolbox # For Org-mode exports.
caption
standalone
;
}

View File

@@ -1,11 +1,56 @@
\documentclass{article}
\usepackage{amsmath}
\documentclass[tikz,dvisvgm]{standalone}
\usepackage[active,tightpage,auctex,dvips]{preview}
\usepackage{fontspec}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{ifxetex}
\usepackage{syd-plex}
\usepackage{quiver}
\usepackage{tikz}
\usepackage{amscd}
\newcommand{\catname}[1]{\textbf{#1}}
\newcommand{\C}[1]{\catname{#1}}
% Specific categories
\newcommand{\Set}{\catname{Set}}
\newcommand{\Cat}{\catname{Cat}}
\newcommand{\CAT}{\catname{CAT}}
\newcommand{\Grp}{\catname{Grp}}
% Common objects and functions
\newcommand{\Ob}{\operatorname{Ob}}
\newcommand{\op}{\text{op}}
\newcommand{\opof}[1]{{#1}^{\text{op}}}
% \id{x} is the identity morphism on x.
\newcommand{\id}[1]{1_{#1}}
% \Id{C} is the identity functor on C.
\newcommand{\Id}[1]{1_{#1}}
\newcommand{\Mor}{\operatorname{Mor}}
\newcommand{\homset}[3]{{{#1} \left[ {#2} \to {#3} \right]}}
% Constructions of categories.
\newcommand{\FunctorCategory}[2]{\left[#1, #2\right]}
\newcommand{\Funct}[2]{\FunctorCategory{#1}{#2}} % Deprecated.
\newcommand{\ArrowCategory}[1]{{#1}^\to}
% Semantic aliases
\newcommand{\monicto}{\rightarrowtail}
\newcommand{\epicto}{\twoheadrightarrow}
\newcommand{\naturalto}{\Rightarrow}
\newcommand{\isoto}{\cong}
\newcommand{\equivto}{\simeq}
\newcommand{\naturaltrans}[2]{#1 \naturalto #2} % Deprecated.
\newcommand{\horizontalcompose}{\ast}
% Optics
\newcommand{\opticname}[1]{\textbf{#1}}
\newcommand{\optic}[3]{\opticname{#1}^\prime\;#2\;#3}
\newcommand{\Optic}[5]{\opticname{#1}\;#2\;#3\;#4\;#5}
\begin{document}
\setlength\abovedisplayskip{0pt}
\setlength\abovedisplayskip{0pt} % Remove padding before equation environments.
%% \color[rgb]{0.000,0.000,0.004}\special{dvisvgm:currentcolor on}\setcounter{equation}{0}%
% {{contents}}
\end{document}

View File

@@ -12,7 +12,7 @@
;; #_
[net.deertopia.doerg.tex :as tex]
;; [net.deertopia.doerg.tex.native :as tex-native]
;; [net.deertopia.doerg.tex.temml :as tex-temml]
[net.deertopia.doerg.tex.temml :as tex-temml]
[clojure.zip :as z]
[babashka.fs :as fs]))
@@ -143,6 +143,19 @@
#(element/of-keyword-type? % "LATEX_HEADER")
(sp/view :value)])))
(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."
@@ -156,21 +169,12 @@
(let [p (promise)]
(swap! snippet-promises #(conj % [(:value node) p]))
(assoc node ::rendered p)))))
fut (-> #(tex/render-snippets @snippet-promises)
sp @snippet-promises
fut (-> #(tex/render-snippets sp)
bound-fn* future-call)]
;; 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 [[_snippet p] @snippet-promises]
(deliver p ::timed-out)))
fut-res))
(timeout-snippet-promises sp fut)
r))
(comment
(render-tex-snippets doc))
(defn- render-pprint

View File

@@ -14,11 +14,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)

View File

@@ -4,7 +4,8 @@
[babashka.fs :as fs]
[clojure.string :as str]
[hiccup2.core :as hiccup]
[clojure.tools.logging :as l]))
[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
@@ -28,28 +29,38 @@
(format "%s style=\"%s\""
s
(format "height:%.4fem;vertical-align:%.4fem;display:inline-block"
height (- depth)))))))
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\"")))
(def ^:dynamic *save-snippets?* false)
(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)
(deliver p (hiccup/raw temml))
(->> tex
read-and-patch-generated-svg
hiccup/raw
(deliver p))))
(deliver p (hiccup/raw temml))))
(catch Exception e
(l/error e "Error in TeX thread")
(throw e)))))))
(with-redefs [fs/delete-tree
(fn
([path]
(l/warnf "refusing to delete %s" path))
([path opts]
(lr/warnf "refusing to delete %s with opts %s"
path opts)))]
(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\\)"

View File

@@ -93,7 +93,7 @@
(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)))

View File

@@ -55,15 +55,18 @@
(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 (IllegalArgumentException.
(str "`net.deertopia.doerg.tex.temml` argument should"
" be enclosed in math delimiters.")))))))
(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]