Skip to content

Commit a4f5265

Browse files
authored
Adding support for aasvg graphics. (#216)
* Adding support for aasvg graphics. Adding support for aasvg graphics/diagrams. Example: ```aasvg +--------+ .-------. +--------+ | Server +-->+ Message +--->+ Client | +--------+ '-------' +--------+ ``` Further: some minor syntax and grammar/text fixes. Signed-off-by: Michael Eckel <[email protected]> * Adding example for aasvg diagrams in guide.tcg. Signed-off-by: Michael Eckel <[email protected]> --------- Signed-off-by: Michael Eckel <[email protected]>
1 parent 693cc21 commit a4f5265

File tree

9 files changed

+170
-15
lines changed

9 files changed

+170
-15
lines changed

.github/workflows/render.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ jobs:
7373
*.upb
7474
*.convert.pdf
7575
*.mermaid.pdf
76+
*.aasvg.pdf
7677
key: latex-${{ inputs.input }}-${{ inputs.container-version }}-${{ github.run_id }}
7778
restore-keys: latex-${{ inputs.input }}-${{ inputs.container-version }}
7879

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,17 @@ RUN tlmgr update --self && tlmgr install \
238238
zref
239239

240240
RUN apt install -y \
241+
aasvg \
241242
dbus \
242243
imagemagick \
244+
librsvg2-bin \
243245
libxss1 \
244246
openbox \
245247
wget \
246248
xorg \
247249
xvfb
248250

249-
ENV DRAWIO_RELEASE=24.7.8
251+
ENV DRAWIO_RELEASE=26.0.16
250252

251253
# TARGETPLATFORM is linux/arm64 or linux/amd64. The release for amd64 is called drawio-amd64-23.1.5.deb.
252254
RUN export DRAWIO_DEB=drawio-${TARGETPLATFORM#linux/}-${DRAWIO_RELEASE}.deb && \

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The interesting dependencies are:
1616
(Pandoc/LaTeX template, with some TCG-specific modifications)
1717
* [Mermaid](https://mermaid-js.github.io/mermaid/#/) /
1818
[mermaid-filter](https://github.com/raghur/mermaid-filter) (for rendering diagrams)
19+
* [aasvg](https://github.com/martinthomson/aasvg) (for rendering ASCII art diagrams)
1920

2021
# How to Use
2122

build.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ do_latex() {
670670
--no-highlight
671671
--template=tcg.tex
672672
--lua-filter=mermaid-filter.lua
673+
--lua-filter=aasvg-filter.lua
673674
--lua-filter=informative-sections.lua
674675
--lua-filter=convert-images.lua
675676
--lua-filter=center-images.lua
@@ -745,6 +746,7 @@ do_pdf() {
745746
# Copy converted images so they can be cached as well.
746747
cp *.convert.pdf "${SOURCE_DIR}" 2>/dev/null
747748
cp *.mermaid.pdf "${SOURCE_DIR}" 2>/dev/null
749+
cp *.aasvg.pdf "${SOURCE_DIR}" 2>/dev/null
748750
echo "Elapsed time: $(($end-$start)) seconds"
749751
# Write any LaTeX errors to stderr.
750752
>&2 grep -A 5 "! " "${logfile}"
@@ -779,6 +781,7 @@ do_docx() {
779781
--embed-resources
780782
--standalone
781783
--lua-filter=mermaid-filter.lua
784+
--lua-filter=aasvg-filter.lua
782785
--lua-filter=convert-images.lua
783786
--lua-filter=parse-html.lua
784787
--lua-filter=apply-classes-to-tables.lua
@@ -819,6 +822,7 @@ do_html() {
819822
--embed-resources
820823
--standalone
821824
--lua-filter=mermaid-filter.lua
825+
--lua-filter=aasvg-filter.lua
822826
--lua-filter=parse-html.lua
823827
--lua-filter=apply-classes-to-tables.lua
824828
--lua-filter=landscape-pages.lua

filter/aasvg-filter.lua

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
-- Turn aasvg-classed code blocks into figures, retaining other classes on the
2+
-- code block as classes on the figure.
3+
4+
function runCommandWithInput(command, input)
5+
local pipe = io.popen(command, "w")
6+
if not pipe then
7+
return false
8+
end
9+
pipe:write(input)
10+
pipe:flush()
11+
pipe:close()
12+
return true
13+
end
14+
15+
function runCommandSuppressOutput(command)
16+
-- N.B.: we are using io.popen so we can suppress the output of the command.
17+
local pipe = io.popen(command)
18+
if not pipe then
19+
return false
20+
end
21+
pipe:flush()
22+
local output = pipe:read("*all")
23+
pipe:close()
24+
return true
25+
end
26+
27+
function getContentsHash(contents)
28+
return pandoc.sha1(contents):sub(1,10)
29+
end
30+
31+
function fileExists(file)
32+
local f = io.open(file)
33+
if f then
34+
f:close()
35+
return true
36+
end
37+
return false
38+
end
39+
40+
function aasvgFigure(code, caption, attrs)
41+
local filename_base = getContentsHash('code=' .. code .. 'caption=' .. pandoc.utils.stringify(caption) .. 'attrs=' .. pandoc.utils.stringify(attrs)) .. '.aasvg'
42+
local filename_svg = filename_base .. '.svg'
43+
local filename_pdf = filename_base .. '.pdf'
44+
45+
if fileExists(filename_pdf) then
46+
print(string.format('%s already exists; not re-rendering it', filename_pdf))
47+
else
48+
print(string.format('rendering %s using aasvg ...', filename_svg))
49+
if not runCommandWithInput(string.format(
50+
"aasvg --fill > %s 2>&1", filename_svg), code) then
51+
print(string.format('failed to convert ASCII art SVG (aasvg) diagram to %s using aasvg, falling back to letting LaTeX try to pick it up', filename_svg))
52+
return false
53+
end
54+
55+
print(string.format('converting %s to %s using rsvg-convert ...', filename_svg, filename_pdf))
56+
if not runCommandSuppressOutput(string.format("rsvg-convert --format=pdf --keep-aspect-ratio --output %s %s 2>&1", filename_pdf, filename_svg)) then
57+
print(string.format('failed to convert %s to %s using rsvg-convert, falling back to letting LaTeX try to pick it up', filename_svg, filename_pdf))
58+
return false
59+
end
60+
end
61+
62+
local img = pandoc.Image(caption, filename_pdf)
63+
return pandoc.Figure(img, caption, attrs)
64+
end
65+
66+
function CodeBlock(el)
67+
local isAasvg = false
68+
local figure_classes = pandoc.List({})
69+
for i, class in ipairs(el.classes) do
70+
if class == 'aasvg' then
71+
isAasvg = true
72+
else
73+
figure_classes:insert(class)
74+
end
75+
end
76+
if isAasvg then
77+
local caption = {long = pandoc.Plain(pandoc.Str(el.attributes.caption))}
78+
local attrs = pandoc.Attr(el.identifier, figure_classes)
79+
el.identifier = nil
80+
el.classes = {'aasvg'}
81+
return aasvgFigure(el.text, caption, attrs)
82+
end
83+
return el
84+
end

filter/convert-images.lua

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,41 +42,51 @@ end
4242
-- Wrap calls to drawio in xvfb-run. Note that --no-sandbox has to be the last argument.
4343
-- https://github.com/jgraph/drawio-desktop/issues/249
4444
function drawio(source, dest)
45-
print(string.format('converting %s using drawio...', source))
45+
print(string.format('converting %s using drawio ...', source))
4646
if not runCommandSuppressOutput(string.format("xvfb-run -a drawio -x -f pdf --crop -o %s %s --no-sandbox 2>&1", dest, source)) then
47-
print(string.format('failed to convert %s to %s using drawio, falling back to letting latex try to pick it up', source, dest))
47+
print(string.format('failed to convert %s to %s using drawio, falling back to letting LaTeX try to pick it up', source, dest))
4848
return false
4949
end
5050
return true
5151
end
5252

5353
function imagemagick(source, dest)
54-
print(string.format('converting %s using imagemagick...', source))
54+
print(string.format('converting %s using ImageMagick ...', source))
5555
if not runCommandSuppressOutput(string.format("convert -density 300 %s %s 2>&1", source, dest)) then
56-
print(string.format('failed to convert %s to %s using imagemagick, falling back to letting latex try to pick it up', source, dest))
56+
print(string.format('failed to convert %s to %s using ImageMagick, falling back to letting LaTeX try to pick it up', source, dest))
57+
return false
58+
end
59+
return true
60+
end
61+
62+
function svg(source, dest)
63+
print(string.format('converting %s using rsvg-convert...', source))
64+
if not runCommandSuppressOutput(string.format("rsvg-convert --format=pdf --keep-aspect-ratio --output %s %s 2>&1", dest, source)) then
65+
print(string.format('failed to convert %s to %s using rsvg-convert, falling back to letting LaTeX try to pick it up', source, dest))
5766
return false
5867
end
5968
return true
6069
end
6170

6271
function string:hassuffix(suffix)
63-
return self:sub(-#suffix) == suffix
72+
return self:sub(-#suffix):lower() == suffix:lower()
6473
end
6574

6675
function converterFor(filename)
6776
if filename:hassuffix('.drawio') or filename:hassuffix('.drawio.svg') then
6877
return drawio
69-
end
70-
if filename:hassuffix('.jpg') or filename:hassuffix('.png') or filename:hassuffix('.svg') then
78+
elseif filename:hassuffix('.jpg') or filename:hassuffix('.png') or filename:hassuffix('.webp') then
7179
return imagemagick
80+
elseif filename:hassuffix('.svg') then
81+
return svg
7282
end
7383
return nil
7484
end
7585

7686
function Image (img)
7787
-- Try to convert anything that is not a pdf, jpg, or png.
78-
-- This allows us to support file types that latex doesn't (e.g., SVG),
79-
-- as well as speed up the latex render iterations.
88+
-- This allows us to support file types that LaTeX doesn't (e.g., SVG),
89+
-- as well as speed up the LaTeX render iterations.
8090
local converter = converterFor(img.src)
8191
if converter then
8292
local new_filename = img.src .. '.' .. getFileHash(img.src) .. '.convert.pdf'
@@ -96,4 +106,4 @@ function Image (img)
96106
print(string.format(" not converting %s", img.src))
97107
end
98108
return img
99-
end
109+
end

filter/informative-quote-blocks.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ function BlockQuote(el)
1313
pandoc.RawBlock('latex', '\\end{mdframed}')
1414
}))
1515
return result
16-
end
16+
end

filter/mermaid-filter.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ function mermaidFigure(code, caption, attrs)
3030
if fileExists(filename) then
3131
print(string.format('%s already exists; not re-rendering it', filename))
3232
else
33-
print(string.format('rendering %s using Mermaid...', filename))
33+
print(string.format('rendering %s using Mermaid ...', filename))
3434
if not runCommandWithInput(string.format(
3535
"mmdc --configFile /resources/filters/mermaid-config.json --puppeteerConfigFile ./.puppeteer.json --width 2000 --height 2000 --backgroundColor transparent --pdfFit --input - --output %s 2>&1", filename), code) then
36-
print(string.format('failed to convert %s to %s using drawio, falling back to letting latex try to pick it up', source, dest))
36+
print(string.format('failed to convert Mermaid diagram to %s using mmdc, falling back to letting LaTeX try to pick it up', filename))
3737
return false
3838
end
3939
end

guide.tcg

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ Users are encouraged to use AES instead.
562562

563563
# Figures {#sec:figures}
564564

565-
There are two ways to include a figure in a document: as an image file checked into the repository, and as a [Mermaid](http://mermaid.js.org) diagram.
565+
There are various ways to include a figure in a document: as an image file checked into the repository, as a [Mermaid](http://mermaid.js.org) diagram, and as an [aasvg](https://github.com/martinthomson/aasvg) diagram.
566566

567567
## Images
568568

@@ -670,6 +670,59 @@ graph TD;
670670
Crossreferences to Mermaid diagrams are supported by providing both `caption`
671671
and `#fig:xxxxx` classes in curly braces.
672672

673+
674+
## aasvg diagrams
675+
676+
[aasvg](https://github.com/martinthomson/aasvg) converts ASCII art diagrams into SVG.
677+
It is inspired by [goat](https://github.com/blampe/goat) but rather than a
678+
reimplementation, the code uses the original
679+
[markdeep](https://casual-effects.com/markdeep/) code.
680+
681+
Here is an example aasvg diagram:
682+
683+
````md
684+
```aasvg {caption="(v)TPM Key Management" #fig:tpm-key-management}
685+
.---------------------. .----.
686+
| Virtual Environment | | vTPM +--------------.-----------------.----------------.
687+
'---------------------' '----' | | |
688+
+----------)-----------------)----------------)--------+
689+
.-------------------------------. /| | | | |
690+
| Virtual Platform | / | |handle |handle |handle |
691+
'-------------------------------' / | v v v |
692+
/ | +--------+--------+ +------+-------+ +------+------+ |
693+
.---------------------. +------+ | | vTPM | | vTPM | | vTPM | |
694+
| Virtualization System | | pTPM | | | Endorsement Key | | Platform Key | | Storage Key | |
695+
'---------------------' +------+ | +--------+--------+ +------+-------+ +------+------+ |
696+
\ | '-----------------'---------. .--' |
697+
+---------------------------------+ \ | +-----------------+ +--------------+ +-+-----------+ |
698+
| Physical Machine | \ | | Endorsement | | Platform | | ◌ Storage | |
699+
+---------------------------------+ \| +-----------------+ +--------------+ +-------------+ |
700+
+------------------------------------------------------+
701+
```
702+
````
703+
704+
```aasvg {caption="(v)TPM Key Management" #fig:tpm-key-management}
705+
.---------------------. .----.
706+
| Virtual Environment | | vTPM +--------------.-----------------.----------------.
707+
'---------------------' '----' | | |
708+
+----------)-----------------)----------------)--------+
709+
.-------------------------------. /| | | | |
710+
| Virtual Platform | / | |handle |handle |handle |
711+
'-------------------------------' / | v v v |
712+
/ | +--------+--------+ +------+-------+ +------+------+ |
713+
.---------------------. +------+ | | vTPM | | vTPM | | vTPM | |
714+
| Virtualization System | | pTPM | | | Endorsement Key | | Platform Key | | Storage Key | |
715+
'---------------------' +------+ | +--------+--------+ +------+-------+ +------+------+ |
716+
\ | '-----------------'---------. .--' |
717+
+---------------------------------+ \ | +-----------------+ +--------------+ +-+-----------+ |
718+
| Physical Machine | \ | | Endorsement | | Platform | | ◌ Storage | |
719+
+---------------------------------+ \| +-----------------+ +--------------+ +-------------+ |
720+
+------------------------------------------------------+
721+
```
722+
723+
See the [aasvg website](https://github.com/martinthomson/aasvg) for more examples.
724+
725+
673726
## DrawIO Diagrams
674727

675728
Some diagrams can't easily be represented in (human-maintained) code.

0 commit comments

Comments
 (0)