From de8f0dab67a5c37e0752e89c1a9fe102ec773a75 Mon Sep 17 00:00:00 2001 From: Benjamin Abel Date: Sun, 29 Sep 2024 08:20:57 +0200 Subject: [PATCH] Implement CeTZ diagrams (#38) Closes: #37 --- .github/workflows/ci.yaml | 14 ++++++++ Makefile | 2 +- README.md | 2 ++ _extensions/diagram/diagram.lua | 37 +++++++++++++++++-- test/expected-cetz.html | 11 ++++++ test/input-cetz.md | 63 +++++++++++++++++++++++++++++++++ test/test-cetz.yaml | 9 +++++ 7 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 test/expected-cetz.html create mode 100644 test/input-cetz.md create mode 100644 test/test-cetz.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f20e8cc..58941f3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -153,6 +153,20 @@ jobs: - name: Test run: 'make test-tikz' + Cetz: + runs-on: ubuntu-latest + strategy: + fail-fast: true + container: + image: ghcr.io/quarto-dev/quarto:latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Render + run: make PANDOC=/opt/quarto/bin/tools/x86_64/pandoc test-cetz + Quarto: runs-on: ubuntu-latest strategy: diff --git a/Makefile b/Makefile index a1965d9..2a3604d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ DIFF ?= diff .PHONY: test test: test-asymptote test-dot test-mermaid test-plantuml test-tikz \ - test-no-alt-or-caption + test-no-alt-or-caption test-cetz test-%: test/test-%.yaml test/input-%.md $(FILTER_FILE) @$(PANDOC) --defaults test/test-$*.yaml | \ diff --git a/README.md b/README.md index 6af6e47..3b18348 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ that can be used to specify a specific executable. | [Mermaid] | `mermaid` | `mmdc` | `MERMAID_BIN` | | [PlantUML] | `plantuml` | `plantuml` | `PLANTUML_BIN` | | [Ti*k*Z] | `tikz` | `pdflatex` | `PDFLATEX_BIN` | +| [cetz] | `cetz` | `typst` | `TYPST_BIN` | ### Other diagram engines @@ -113,6 +114,7 @@ The filter can be extended with local packages; see [Mermaid]: https://mermaid.js.org/ [PlantUML]: https://plantuml.com/ [Ti*k*Z]: https://github.com/pgf-tikz/pgf +[Cetz]: https://github.com/cetz-package/cetz Figure options -------------- diff --git a/_extensions/diagram/diagram.lua b/_extensions/diagram/diagram.lua index ea3547d..46df24e 100644 --- a/_extensions/diagram/diagram.lua +++ b/_extensions/diagram/diagram.lua @@ -99,7 +99,8 @@ local function pipe (command, args, input) if pandoc.utils.type(command) == 'List' then command = command:map(stringify) cmd = command:remove(1) - args = command:extend(args) + command:extend(args) + args = command else cmd = stringify(command) end @@ -253,12 +254,45 @@ local asymptote = { end, } +--- Cetz diagram engine +local cetz = { + line_comment_start = '%%', + mime_types = mime_types_set{'jpg', 'pdf', 'png', 'svg'}, + mime_type = 'image/svg+xml', + compile = function (self, code) + local mime_type = self.mime_type + local format = extension_for_mimetype[mime_type] + if not format then + format, mime_type = 'svg', 'image/svg+xml' + end + local preamble = [[ +#import "@preview/cetz:0.2.2" +#set page(width: auto, height: auto, margin: .5cm) +]] + + local typst_code = preamble .. code + + return with_temporary_directory("diagram", function (tmpdir) + return with_working_directory(tmpdir, function () + local outfile = 'diagram.' .. format + pipe( + self.execpath or 'typst', + {"compile", "-f", format, "-", outfile}, + typst_code + ) + return read_file(outfile), mime_type + end) + end) + end, +} + local default_engines = { asymptote = asymptote, dot = graphviz, mermaid = mermaid, plantuml = plantuml, tikz = tikz, + cetz = cetz, } -- @@ -365,7 +399,6 @@ local function configure (meta, format_name) } end - -- -- Format conversion -- diff --git a/test/expected-cetz.html b/test/expected-cetz.html new file mode 100644 index 0000000..9d2c0a3 --- /dev/null +++ b/test/expected-cetz.html @@ -0,0 +1,11 @@ +

Cetz

+

The image code +comes from the cetz docs licensed under LGPLv3.

+
+ + +
diff --git a/test/input-cetz.md b/test/input-cetz.md new file mode 100644 index 0000000..692c238 --- /dev/null +++ b/test/input-cetz.md @@ -0,0 +1,63 @@ +# Cetz + +The image +[code](https://github.com/cetz-package/cetz/blob/master/gallery/karls-picture.typ) +comes from the cetz docs licensed under +[LGPLv3](https://github.com/cetz-package/cetz/blob/master/LICENSE). + +```{.cetz caption="This is an image, created with cetz" width=90% filename=karls} +//| label: fig-auth +//| class: important +#show math.equation: block.with(fill: white, inset: 1pt) + +#cetz.canvas(length: 5cm, { + import cetz.draw: * + + set-style( + mark: (fill: black, scale: 2), + stroke: (thickness: 0.4pt, cap: "round"), + angle: ( + radius: 0.3, + label-radius: .22, + fill: green.lighten(80%), + stroke: (paint: green.darken(50%)) + ), + content: (padding: 1pt) + ) + + grid((-1.5, -1.5), (1.4, 1.4), step: 0.5, stroke: gray + 0.2pt) + + circle((0,0), radius: 1) + + line((-1.5, 0), (1.5, 0), mark: (end: "stealth")) + content((), $ x $, anchor: "west") + line((0, -1.5), (0, 1.5), mark: (end: "stealth")) + content((), $ y $, anchor: "south") + + for (x, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (1, $ 1 $)) { + line((x, 3pt), (x, -3pt)) + content((), anchor: "north", ct) + } + + for (y, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (0.5, $ 1/2 $), (1, $ 1 $)) { + line((3pt, y), (-3pt, y)) + content((), anchor: "east", ct) + } + + // Draw the green angle + cetz.angle.angle((0,0), (1,0), (1, calc.tan(30deg)), + label: text(green, [#sym.alpha])) + + line((0,0), (1, calc.tan(30deg))) + + set-style(stroke: (thickness: 1.2pt)) + + line((30deg, 1), ((), "|-", (0,0)), stroke: (paint: red), name: "sin") + content(("sin.start", 50%, "sin.end"), text(red)[$ sin alpha $]) + line("sin.end", (0,0), stroke: (paint: blue), name: "cos") + content(("cos.start", 50%, "cos.end"), text(blue)[$ cos alpha $], anchor: "north") + line((1, 0), (1, calc.tan(30deg)), name: "tan", stroke: (paint: orange)) + content("tan.end", $ text(#orange, tan alpha) = text(#red, sin alpha) / text(#blue, cos alpha) $, anchor: "west") +}) + +``` diff --git a/test/test-cetz.yaml b/test/test-cetz.yaml new file mode 100644 index 0000000..cca62db --- /dev/null +++ b/test/test-cetz.yaml @@ -0,0 +1,9 @@ +input-files: ['test/input-cetz.md'] +filters: + - diagram.lua +to: html +metadata: + diagram: + engine: + cetz: + execpath: ['quarto', 'typst'] \ No newline at end of file