asciidoctor-kroki 0.10.2 → 1.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +17 -438
- data/asciidoctor-kroki.gemspec +3 -3
- data/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb +73 -21
- data/lib/asciidoctor/extensions/asciidoctor_kroki/version.rb +1 -1
- data/spec/asciidoctor_kroki_diagram_spec.rb +24 -1
- data/spec/asciidoctor_kroki_processor_spec.rb +20 -0
- data/spec/rspec_helper.rb +2 -2
- metadata +6 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f28746df322330460df07cafca210d9705c1bb5f1f6d97d6217ba0948d43f909
|
|
4
|
+
data.tar.gz: 1ee9e56a3c4982c2f2d8cb71fbba4f88d9e3b1e8b04d9b101ada7500d7b2148d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fbba1d5c16f1cb59a6cfe5f3a992e752592bcb123f7fa73c2a63fb62c0f93f773280fc86ed5afab1f819c0392d5fd94bfdfe70c11bb6a7d1d3dd099f629c171
|
|
7
|
+
data.tar.gz: 918ccffc3ef558cd389bf6d4f27724404e59f23c2f995ba11bf7ca25a482222d404b0310efd2c39f0d457e01a0428aa8512c9c71ec5b53848b7b429cfe99e2ec
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
asciidoctor-kroki (0.
|
|
4
|
+
asciidoctor-kroki (1.0.0.beta.1)
|
|
5
5
|
asciidoctor (~> 2.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
asciidoctor (2.0.
|
|
10
|
+
asciidoctor (2.0.26)
|
|
11
11
|
ast (2.4.3)
|
|
12
12
|
diff-lcs (1.6.2)
|
|
13
13
|
json (2.13.0)
|
data/README.md
CHANGED
|
@@ -1,456 +1,34 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Asciidoctor Kroki Extension
|
|
2
2
|
|
|
3
|
-
[](https://github.com/asciidoctor/asciidoctor-kroki/actions/workflows/build-js.yml)
|
|
4
|
+
[](https://github.com/asciidoctor/asciidoctor-kroki/actions/workflows/build-ruby.yml)
|
|
5
5
|
[](https://www.npmjs.com/package/asciidoctor-kroki)
|
|
6
6
|
[](https://rubygems.org/gems/asciidoctor-kroki)
|
|
7
7
|
[](https://kroki.zulipchat.com/)
|
|
8
8
|
|
|
9
|
-
An extension for [Asciidoctor.js](https://github.com/asciidoctor/asciidoctor.js) to convert diagrams to images using [Kroki](https://kroki.io)
|
|
9
|
+
An extension for [Asciidoctor.js](https://github.com/asciidoctor/asciidoctor.js) and [Asciidoctor](https://github.com/asciidoctor/asciidoctor) to convert diagrams to images using [Kroki](https://kroki.io).
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Documentation
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Full documentation is available at **https://docs.asciidoctor.org/kroki-extension/latest**.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
npm i asciidoctor asciidoctor-kroki
|
|
18
|
-
|
|
19
|
-
Create a file named `kroki.js` with following content and run it:
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
const asciidoctor = require('@asciidoctor/core')()
|
|
23
|
-
const kroki = require('asciidoctor-kroki')
|
|
24
|
-
|
|
25
|
-
const input = 'plantuml::hello.puml[svg,role=sequence]'
|
|
26
|
-
|
|
27
|
-
kroki.register(asciidoctor.Extensions) // 1️⃣
|
|
28
|
-
console.log(asciidoctor.convert(input, { safe: 'safe' }))
|
|
29
|
-
|
|
30
|
-
const registry = asciidoctor.Extensions.create()
|
|
31
|
-
kroki.register(registry) // 2️⃣
|
|
32
|
-
console.log(asciidoctor.convert(input, { safe: 'safe', extension_registry: registry }))
|
|
33
|
-
```
|
|
34
|
-
1️⃣ Register the extension in the global registry <br/>
|
|
35
|
-
2️⃣ Register the extension in a dedicated registry
|
|
36
|
-
|
|
37
|
-
### Browser
|
|
15
|
+
## Quick start
|
|
38
16
|
|
|
39
17
|
Install the dependencies:
|
|
40
18
|
|
|
41
19
|
npm i asciidoctor asciidoctor-kroki
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```html
|
|
46
|
-
<html lang="en">
|
|
47
|
-
<head>
|
|
48
|
-
<title>Asciidoctor x Kroki</title>
|
|
49
|
-
<meta charset="utf-8">
|
|
50
|
-
<script src="node_modules/@asciidoctor/core/dist/browser/asciidoctor.js"></script>
|
|
51
|
-
<script src="node_modules/asciidoctor-kroki/dist/browser/asciidoctor-kroki.js"></script>
|
|
52
|
-
</head>
|
|
53
|
-
<body>
|
|
54
|
-
<div id="content"></div>
|
|
55
|
-
<script>
|
|
56
|
-
const input = `Let's take an example with a _GraphViz_ "Hello World":
|
|
57
|
-
|
|
58
|
-
[graphviz]
|
|
59
|
-
....
|
|
60
|
-
digraph G {
|
|
61
|
-
Hello->World
|
|
62
|
-
}
|
|
63
|
-
....`
|
|
64
|
-
|
|
65
|
-
const asciidoctor = Asciidoctor()
|
|
66
|
-
|
|
67
|
-
const registry = asciidoctor.Extensions.create()
|
|
68
|
-
AsciidoctorKroki.register(registry) // 1️⃣
|
|
69
|
-
const result = asciidoctor.convert(input, { safe: 'safe', extension_registry: registry })
|
|
70
|
-
document.getElementById('content').innerHTML = result
|
|
71
|
-
</script>
|
|
72
|
-
</body>
|
|
73
|
-
</html>
|
|
74
|
-
```
|
|
75
|
-
1️⃣ Register the extension in a dedicated registry
|
|
76
|
-
|
|
77
|
-
> [!IMPORTANT]
|
|
78
|
-
> If you want to reference a diagram file in a browser environment, you will need to define the base directory using the `base_dir` option.
|
|
79
|
-
> In addition, you will also need to provide an implementation to read a binary file **synchronously** for a given path.
|
|
80
|
-
> You can find an implementation based on `XMLHttpRequest` in the source code: https://github.com/ggrossetie/asciidoctor-kroki/blob/9585b969014a1894d0c9fb76df10e1e8c66ce2b2/test/browser/test.js#L2-L34.
|
|
81
|
-
> Once `httpGet` is defined, here's how we should configure the extension:
|
|
21
|
+
Register and use the extension:
|
|
82
22
|
|
|
83
23
|
```js
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
vfs: {
|
|
87
|
-
read: (path, encoding = 'utf8') => httpGet(path, encoding),
|
|
88
|
-
exists: (_) => false,
|
|
89
|
-
add: (_) => { /* no-op */ },
|
|
90
|
-
parse: (path) => ({
|
|
91
|
-
dir: path.substring(0, path.lastIndexOf('/') - 1),
|
|
92
|
-
path
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
const input = 'plantuml::hello.puml[svg,role=sequence]'
|
|
97
|
-
asciidoctor.convert(input, { safe: 'safe', base_dir: window.location.origin, extension_registry: registry })
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Ruby
|
|
24
|
+
import { convert, Extensions } from '@asciidoctor/core'
|
|
25
|
+
import asciidoctorKroki from 'asciidoctor-kroki'
|
|
101
26
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
gem install asciidoctor-kroki
|
|
105
|
-
|
|
106
|
-
Require the library using the `--require` (or `-r`) option from the Asciidoctor CLI:
|
|
107
|
-
|
|
108
|
-
asciidoctor -r asciidoctor-kroki doc.adoc
|
|
109
|
-
|
|
110
|
-
### Antora Integration
|
|
111
|
-
|
|
112
|
-
If you are using [Antora](https://antora.org/), you can integrate Kroki in your documentation site.
|
|
113
|
-
|
|
114
|
-
1. Install the extension in your playbook project:
|
|
115
|
-
|
|
116
|
-
npm i asciidoctor-kroki
|
|
117
|
-
|
|
118
|
-
2. Register the extension in your playbook file:
|
|
119
|
-
|
|
120
|
-
```yaml
|
|
121
|
-
asciidoc:
|
|
122
|
-
extensions:
|
|
123
|
-
- asciidoctor-kroki
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
https://docs.antora.org/antora/latest/playbook/asciidoc-extensions/
|
|
127
|
-
|
|
128
|
-
3. Enjoy!
|
|
129
|
-
|
|
130
|
-
> [!TIP]
|
|
131
|
-
> You can use the `kroki-fetch-diagram` option to download the images from Kroki at build time.
|
|
132
|
-
> In other words, while viewing pages you won't rely on Kroki anymore.
|
|
133
|
-
|
|
134
|
-
```yaml
|
|
135
|
-
asciidoc:
|
|
136
|
-
attributes:
|
|
137
|
-
kroki-fetch-diagram: true
|
|
27
|
+
asciidoctorKroki.register(Extensions)
|
|
28
|
+
console.log(await convert('[graphviz]\n....\ndigraph G { Hello->World }\n....'))
|
|
138
29
|
```
|
|
139
30
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
In your AsciiDoc document, you can either write your diagram inline or, alternatively, you can make a reference to the diagram file using macro form or with the `include` directive.
|
|
143
|
-
|
|
144
|
-
Here's an example where we declare a GraphViz diagram directly in our AsciiDoc document using the block syntax:
|
|
145
|
-
|
|
146
|
-
```adoc
|
|
147
|
-
[graphviz]
|
|
148
|
-
....
|
|
149
|
-
digraph foo {
|
|
150
|
-
node [style=rounded]
|
|
151
|
-
node1 [shape=box]
|
|
152
|
-
node2 [fillcolor=yellow, style="rounded,filled", shape=diamond]
|
|
153
|
-
node3 [shape=record, label="{ a | b | c }"]
|
|
154
|
-
|
|
155
|
-
node1 -> node2 -> node3
|
|
156
|
-
}
|
|
157
|
-
....
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-

|
|
161
|
-
|
|
162
|
-
In the example below, we are using the `vegalite` macro to reference a file named *chart.vlite*:
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
vegalite::chart.vlite[svg,role=chart,opts=interactive]
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-

|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
Finally, we can use the `include` directive to reference a diagram file:
|
|
172
|
-
|
|
173
|
-
```
|
|
174
|
-
[plantuml,alice-bob,svg,role=sequence]
|
|
175
|
-
....
|
|
176
|
-
include::alice-bob.puml[]
|
|
177
|
-
....
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-

|
|
181
|
-
|
|
182
|
-
### References and includes with Antora
|
|
183
|
-
|
|
184
|
-
If you use this Asciidoctor Kroki Extension in combination with Antora, all references and includes MUST use [Antora Resource IDs](https://docs.antora.org/antora/latest/page/resource-id/). The `.puml`-files are best placed in the [_partials_-directory](https://docs.antora.org/antora/latest/page/partials/) of the modules.
|
|
185
|
-
|
|
186
|
-
#### Block macros
|
|
187
|
-
|
|
188
|
-
```adoc
|
|
189
|
-
vegalite::partial$chart.vlite[svg,role=chart,opts=interactive]
|
|
190
|
-
```
|
|
191
|
-
#### Includes
|
|
192
|
-
|
|
193
|
-
```adoc
|
|
194
|
-
[plantuml,alice-bob,svg,role=sequence]
|
|
195
|
-
....
|
|
196
|
-
include::partial$alice-bob.puml[]
|
|
197
|
-
....
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
### Syntax
|
|
202
|
-
|
|
203
|
-
You can declare positional and named attributes when using the block or the macro form.
|
|
204
|
-
|
|
205
|
-
**Positional attributes**
|
|
206
|
-
|
|
207
|
-
When using the block form:
|
|
208
|
-
|
|
209
|
-
1. The first positional attribute specifies the diagram type (see below for a complete list).
|
|
210
|
-
2. The second optional positional attribute assigns a file name (i.e. target) to the generated diagram. *Currently, the value of this attribute is ignored, and an auto-generated hash will be used as file name for caching purposes (see #48)*.
|
|
211
|
-
3. The third optional positional attribute specifies the image format.
|
|
212
|
-
|
|
213
|
-
Example:
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
[mermaid,abcd-flowchart,svg]
|
|
217
|
-
....
|
|
218
|
-
graph TD;
|
|
219
|
-
A-->B;
|
|
220
|
-
A-->C;
|
|
221
|
-
B-->D;
|
|
222
|
-
C-->D;
|
|
223
|
-
....
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
In the above example,
|
|
227
|
-
the diagram type is `mermaid`,
|
|
228
|
-
the file name (i.e., target) is `abcd-flowchart`,
|
|
229
|
-
and the image format is `svg`.
|
|
230
|
-
|
|
231
|
-
When using the macro form:
|
|
232
|
-
|
|
233
|
-
1. The first optional positional attribute specifies the image format.
|
|
234
|
-
|
|
235
|
-
Example:
|
|
236
|
-
|
|
237
|
-
```
|
|
238
|
-
vegalite::chart.vlite[svg]
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
In the above example,
|
|
242
|
-
the diagram type is `vegalite`,
|
|
243
|
-
the target is `chart.vlite`,
|
|
244
|
-
and the image format is `svg`.
|
|
245
|
-
|
|
246
|
-
**Named attributes**
|
|
247
|
-
|
|
248
|
-
You can also use both positional and named attributes. Here's an example:
|
|
249
|
-
|
|
250
|
-
```adoc
|
|
251
|
-
.PlantUML example
|
|
252
|
-
[plantuml#diagAliceBob,alice-and-bob,svg,role=sequence]
|
|
253
|
-
....
|
|
254
|
-
alice -> bob
|
|
255
|
-
....
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
As you can see, we specified an id using the syntax `#diagAliceBob` just after the diagram type, and we are also using a named attribute to assign a role using `role=sequence`.
|
|
259
|
-
|
|
260
|
-
Here's another example using the macro form:
|
|
261
|
-
|
|
262
|
-
```
|
|
263
|
-
vegalite::chart.vlite[svg,role=chart,opts=interactive]
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
We are using a positional attribute to declare the image format and two named attributes to define the `role` and `options`.
|
|
267
|
-
|
|
268
|
-
**Attributes**
|
|
269
|
-
|
|
270
|
-
It's important to note that not all attributes are used in all converters.
|
|
271
|
-
Here's a list of all attributes used in the built-in HTML 5 converter:
|
|
272
|
-
|
|
273
|
-
- `target`
|
|
274
|
-
- `width`
|
|
275
|
-
- `height`
|
|
276
|
-
- `format` (default `svg`)
|
|
277
|
-
- `fallback`
|
|
278
|
-
- `link`
|
|
279
|
-
- `float`
|
|
280
|
-
- `align`
|
|
281
|
-
- `role`
|
|
282
|
-
- `title` (used to define an alternative text description of the diagram)
|
|
283
|
-
|
|
284
|
-
**Options**
|
|
285
|
-
|
|
286
|
-
In addition, the following options are available when using the SVG format:
|
|
287
|
-
|
|
288
|
-
- `inline`
|
|
289
|
-
- `interactive`
|
|
290
|
-
- `none` (used for cancelling defaults)
|
|
291
|
-
|
|
292
|
-
Options can be defined using `options` attribute (or `opts` for short):
|
|
293
|
-
|
|
294
|
-
```adoc
|
|
295
|
-
[blockdiag,opts=inline]
|
|
296
|
-
....
|
|
297
|
-
blockdiag {
|
|
298
|
-
Kroki -> generates -> "Block diagrams";
|
|
299
|
-
|
|
300
|
-
Kroki [color = "greenyellow"];
|
|
301
|
-
"Block diagrams" [color = "pink"];
|
|
302
|
-
}
|
|
303
|
-
....
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Supported diagram types
|
|
307
|
-
|
|
308
|
-
Kroki currently supports the following diagram libraries:
|
|
309
|
-
|
|
310
|
-
* [ActDiag](https://github.com/blockdiag/actdiag): `actdiag`
|
|
311
|
-
* [BlockDiag](https://github.com/blockdiag/blockdiag): `blockdiag`
|
|
312
|
-
* [BPMN](https://github.com/bpmn-io/bpmn-js): `bpmn`
|
|
313
|
-
* [Bytefield](https://github.com/Deep-Symmetry/bytefield-svg/): `bytefield`
|
|
314
|
-
* [C4 (PlantUML)](https://github.com/RicardoNiepel/C4-PlantUML): `c4plantuml`
|
|
315
|
-
* [D2](https://d2lang.com/tour/intro/): `d2`
|
|
316
|
-
* [DBML](https://www.dbml.org/home/): `dbml`
|
|
317
|
-
* [Ditaa](http://ditaa.sourceforge.net): `ditaa`
|
|
318
|
-
* [ERD](https://github.com/BurntSushi/erd): `erd`
|
|
319
|
-
* [Excalidraw](https://github.com/excalidraw/excalidraw): `excalidraw`
|
|
320
|
-
* [GraphViz](https://www.graphviz.org/): `graphviz`
|
|
321
|
-
* [Mermaid](https://github.com/knsv/mermaid): `mermaid`
|
|
322
|
-
* [Nomnoml](https://github.com/skanaar/nomnoml): `nomnoml`
|
|
323
|
-
* [NwDiag](https://github.com/blockdiag/nwdiag): `nwdiag`
|
|
324
|
-
* [PacketDiag](https://github.com/blockdiag/nwdiag): `packetdiag`
|
|
325
|
-
* [Pikchr](https://github.com/drhsqlite/pikchr): `pikchr`
|
|
326
|
-
* [PlantUML](https://github.com/plantuml/plantuml): `plantuml`
|
|
327
|
-
* [RackDiag](https://github.com/blockdiag/nwdiag): `rackdiag`
|
|
328
|
-
* [SeqDiag](https://github.com/blockdiag/seqdiag): `seqdiag`
|
|
329
|
-
* [SVGBob](https://github.com/ivanceras/svgbob): `svgbob`
|
|
330
|
-
* [Symbolator](https://github.com/zebreus/symbolator): `symbolator`
|
|
331
|
-
* [UMLet](https://github.com/umlet/umlet): `umlet`
|
|
332
|
-
* [Vega](https://github.com/vega/vega): `vega`
|
|
333
|
-
* [Vega-Lite](https://github.com/vega/vega-lite): `vegalite`
|
|
334
|
-
* [WaveDrom](https://github.com/wavedrom/wavedrom): `wavedrom`
|
|
335
|
-
* [Structurizr](https://github.com/structurizr/dsl): `structurizr`
|
|
336
|
-
* [Diagrams.net](https://github.com/jgraph/drawio): `diagramsnet` _(only available via [Using Your Own Kroki](#using-your-own-kroki "Using Your Own Kroki"))_
|
|
337
|
-
|
|
338
|
-
Each diagram library supports one or more output formats.
|
|
339
|
-
Consult the [Kroki documentation](https://kroki.io/#support) to find out which formats are supported.
|
|
340
|
-
|
|
341
|
-
## Configuration
|
|
342
|
-
|
|
343
|
-
| Attribute name | Description | Default value |
|
|
344
|
-
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
|
|
345
|
-
| `kroki-server-url` | The URL of the Kroki server (see "Using Your Own Kroki") | `https://kroki.io` |
|
|
346
|
-
| `kroki-data-uri` | Embed images as data-uri elements in HTML elements so file is completely self-contained. | `false` |
|
|
347
|
-
| `kroki-fetch-diagram` | Define if we should download (and save on the disk) the images from the Kroki server.<br/>This feature is not available when running in the browser. | `false` |
|
|
348
|
-
| `kroki-http-method` | Define how we should get the image from the Kroki server. Possible values:<br/><ul><li>`get`: always use GET requests</li><li>`post`: always use POST requests</li><li>`adaptive`: use a POST request if the URI length is longer than `kroki-max-uri-length` (default 4000) characters, otherwise use a GET request</li></ul> | `adaptive` |
|
|
349
|
-
| `kroki-plantuml-include` | A file that will be included at the top of all PlantUML diagrams as if `!include file` was used. This can be useful when you want to define a common skin for all your diagrams. The value can be a path or a URL. | |
|
|
350
|
-
| `kroki-plantuml-include-paths` | Search path(s) that will be used to resolve `!include file` additionally to current diagram directory, similar to PlantUML property [plantuml.include.path](https://plantuml.com/de/preprocessing). Please use directory delimiter `;` (Windows) or `:` (Unix) for multiple paths, e.g.: `"c:/docu/styles;c:/docu/library"` or `"~/docu/styles:~/docu/library"` | |
|
|
351
|
-
| `kroki-max-uri-length` | Define the max URI length before using a POST request when using `adaptive` HTTP method (`kroki-http-method`) | `4000` |
|
|
352
|
-
|
|
353
|
-
> [!IMPORTANT]
|
|
354
|
-
> `kroki-fetch-diagram` and `kroki-plantuml-include` are only available when safe mode is `server` or lower.
|
|
355
|
-
> If you want to learn more about Asciidoctor safe modes: https://docs.asciidoctor.org/asciidoctor/latest/safe-modes/
|
|
356
|
-
|
|
357
|
-
### Default configuration
|
|
358
|
-
|
|
359
|
-
By default, images are generated as SVG when possible.
|
|
360
|
-
To alter this, set the `kroki-default-format` attribute:
|
|
361
|
-
|
|
362
|
-
```adoc
|
|
363
|
-
:kroki-default-format: png
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
You can unset this with `:kroki-default-format!:` or `:kroki-default-format: svg`.
|
|
367
|
-
|
|
368
|
-
> [!NOTE]
|
|
369
|
-
> An AsciiDoc attribute can be defined through the CLI or API, in the document’s header or in the document’s body.
|
|
370
|
-
> In addition, if you are using Antora, you can define AsciiDoc attributes in your playbook and/or in your component descriptor.
|
|
371
|
-
|
|
372
|
-
References:
|
|
373
|
-
|
|
374
|
-
- https://asciidoctor.org/docs/user-manual/#setting-attributes-on-a-document
|
|
375
|
-
- https://docs.antora.org/antora/2.3/page/attributes/#custom-attributes
|
|
376
|
-
|
|
377
|
-
For instance, in an Antora playbook or component descriptor:
|
|
378
|
-
|
|
379
|
-
```yaml
|
|
380
|
-
asciidoc:
|
|
381
|
-
attributes:
|
|
382
|
-
kroki-default-format: png@
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
(the `@` allows the attribute value to be reset in documents)
|
|
386
|
-
|
|
387
|
-
By default, Asciidoctor Kroki generates a link, to a Kroki server or a local file.
|
|
388
|
-
To change the default for SVG diagrams, set the `kroki-default-options` attribute.
|
|
389
|
-
|
|
390
|
-
```adoc
|
|
391
|
-
:kroki-default-options: inline
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
You can unset this with `:kroki-default-options: none` or `:kroki-default-options!:` or specify `opts=none` in a block or macro.
|
|
395
|
-
|
|
396
|
-
## Preprocessing
|
|
397
|
-
|
|
398
|
-
Some diagram libraries allow referencing external entities by URL or accessing resources from the filesystem.
|
|
399
|
-
For example, PlantUML allows the `!import` directive to pull fragments from the filesystem or a remote URL or the standard library.
|
|
400
|
-
Similarly, Vega-Lite can load data from a URL using the `url` property.
|
|
401
|
-
|
|
402
|
-
By default, the Kroki server is running in `SECURE` mode which restrict access to files on the file system and on the network.
|
|
403
|
-
|
|
404
|
-
For ease of use and convenience, Asciidoctor Kroki will try to resolve and load external resources before sending a request to the Kroki server.
|
|
405
|
-
This feature is only available when Asciidoctor safe mode is `server` or lower.
|
|
406
|
-
|
|
407
|
-
## Troubleshooting
|
|
408
|
-
|
|
409
|
-
### 414 URI Too Long
|
|
410
|
-
|
|
411
|
-
By default, the extension retrieves images from the Kroki server using a GET request.
|
|
412
|
-
Be aware that the Kroki server will return a 414 (Request-URI Too Long) response if the requested URI exceeds the maximum length the server can process.
|
|
413
|
-
The default maximum URI length is 4096 characters.
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
To work around this limitation, you can:
|
|
417
|
-
- **Increase the max URI length** if you are using a self-hosted instance of Kroki. For more information, see the Kroki documentation: https://docs.kroki.io/kroki/setup/configuration/#_max_uri_length.
|
|
418
|
-
- **Use POST requests** by enabling `kroki-fetch-diagram` and setting `kroki-http-method` to `adaptive` or `post`.
|
|
419
|
-
|
|
420
|
-
> [!NOTE]
|
|
421
|
-
> If you switch to POST requests, the extension will download the images from the server.
|
|
422
|
-
> In fact, it is no longer possible to retrieve images via GET requests, so the images need to be downloaded and displayed using a relative path.
|
|
423
|
-
|
|
424
|
-
## Using Your Own Kroki
|
|
425
|
-
|
|
426
|
-
By default, this extension sends information and receives diagrams back from https://kroki.io.
|
|
427
|
-
|
|
428
|
-
You may choose to use your own server due to:
|
|
429
|
-
|
|
430
|
-
* Network restrictions — if Kroki is not available behind your corporate firewall
|
|
431
|
-
* Network latency — you are far from the European public instance
|
|
432
|
-
* Privacy — you don't want to send your diagrams to a remote server on the internet
|
|
433
|
-
|
|
434
|
-
This is done using the `kroki-server-url` attribute.
|
|
435
|
-
Typically, this is at the top of the document (under the title):
|
|
436
|
-
|
|
437
|
-
```adoc
|
|
438
|
-
:kroki-server-url: http://my-server-url:port
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
For instance, if you have followed [the instructions](https://docs.kroki.io/kroki/setup/install/#_using_docker) to set up a self-managed server using Docker you can use the following:
|
|
442
|
-
|
|
443
|
-
```adoc
|
|
444
|
-
:kroki-server-url: http://localhost:8080
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
Note that either the `http://` or `https://` prefix _is_ required (the default Docker image only uses `http`).
|
|
448
|
-
|
|
449
|
-
You can also set this attribute using the Javascript API, for instance:
|
|
450
|
-
|
|
451
|
-
```js
|
|
452
|
-
asciidoctor.convertFile('file.adoc', { safe: 'safe', attributes: { 'kroki-server-url': 'http://my-server-url:port' } })
|
|
453
|
-
```
|
|
31
|
+
For installation instructions for Node.js, Browser, Ruby, and Antora, as well as the full configuration reference, see the [documentation](https://docs.asciidoctor.org/kroki-extension/latest).
|
|
454
32
|
|
|
455
33
|
## Contributing
|
|
456
34
|
|
|
@@ -465,11 +43,12 @@ We recommend [`volta`](https://volta.sh/) to manage multiple active Node.js vers
|
|
|
465
43
|
|
|
466
44
|
npm i
|
|
467
45
|
|
|
468
|
-
2.
|
|
46
|
+
2. Build the project:
|
|
469
47
|
|
|
470
|
-
npm run
|
|
48
|
+
npm run build
|
|
471
49
|
|
|
472
|
-
When working on a new feature or when fixing a bug, make sure to run the linter and the test suite:
|
|
50
|
+
When working on a new feature or when fixing a bug, make sure to run the formatter, the linter and the test suite:
|
|
473
51
|
|
|
52
|
+
npm run format
|
|
474
53
|
npm run lint
|
|
475
54
|
npm run test
|
data/asciidoctor-kroki.gemspec
CHANGED
|
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
|
|
11
11
|
s.authors = ['Guillaume Grossetie']
|
|
12
12
|
s.email = ['ggrossetie@yuzutech.fr']
|
|
13
|
-
s.homepage = 'https://github.com/
|
|
13
|
+
s.homepage = 'https://github.com/asciidoctor/asciidoctor-kroki'
|
|
14
14
|
s.license = 'MIT'
|
|
15
15
|
s.metadata = {
|
|
16
|
-
'bug_tracker_uri' => 'https://github.com/
|
|
17
|
-
'source_code_uri' => 'https://github.com/
|
|
16
|
+
'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor-kroki/issues',
|
|
17
|
+
'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor-kroki',
|
|
18
18
|
'rubygems_mfa_required' => 'true'
|
|
19
19
|
}
|
|
20
20
|
# NOTE: the logic to build the list of files is designed to produce a usable package even when the git command is not available
|
|
@@ -124,6 +124,7 @@ module AsciidoctorExtensions
|
|
|
124
124
|
ditaa
|
|
125
125
|
erd
|
|
126
126
|
excalidraw
|
|
127
|
+
goat
|
|
127
128
|
graphviz
|
|
128
129
|
mermaid
|
|
129
130
|
nomnoml
|
|
@@ -155,7 +156,7 @@ module AsciidoctorExtensions
|
|
|
155
156
|
BUILTIN_ATTRIBUTES = %w[target width height format fallback link float align role caption title cloaked-context subs].freeze
|
|
156
157
|
|
|
157
158
|
class << self
|
|
158
|
-
# rubocop:disable Metrics/AbcSize
|
|
159
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
159
160
|
def process(processor, parent, attrs, diagram_type, diagram_text, logger)
|
|
160
161
|
doc = parent.document
|
|
161
162
|
diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
|
|
@@ -165,6 +166,10 @@ module AsciidoctorExtensions
|
|
|
165
166
|
diagram_text = parent.apply_subs(diagram_text, parent.resolve_subs(subs))
|
|
166
167
|
end
|
|
167
168
|
attrs.delete('opts')
|
|
169
|
+
# Apply the option defined on the block/macro or, as a fallback, the document-wide kroki-default-options.
|
|
170
|
+
if (option = get_option(attrs, doc)) && option != 'none'
|
|
171
|
+
attrs["#{option}-option"] = ''
|
|
172
|
+
end
|
|
168
173
|
format = get_format(doc, attrs, diagram_type)
|
|
169
174
|
attrs['role'] = get_role(format, attrs['role'])
|
|
170
175
|
attrs['format'] = format
|
|
@@ -185,14 +190,14 @@ module AsciidoctorExtensions
|
|
|
185
190
|
block = processor.create_block(parent, 'literal', text_content, attrs)
|
|
186
191
|
else
|
|
187
192
|
attrs['alt'] = alt
|
|
188
|
-
attrs['target'] = create_image_src(doc, kroki_diagram, kroki_client)
|
|
193
|
+
attrs['target'] = create_image_src(doc, kroki_diagram, kroki_client, logger)
|
|
189
194
|
block = processor.create_image_block(parent, attrs)
|
|
190
195
|
end
|
|
191
196
|
block.title = title if title
|
|
192
197
|
block.assign_caption(caption, 'figure')
|
|
193
198
|
block
|
|
194
199
|
end
|
|
195
|
-
# rubocop:enable Metrics/AbcSize
|
|
200
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
196
201
|
|
|
197
202
|
private
|
|
198
203
|
|
|
@@ -234,26 +239,48 @@ module AsciidoctorExtensions
|
|
|
234
239
|
end
|
|
235
240
|
end
|
|
236
241
|
|
|
242
|
+
# Get the option defined on the block or macro.
|
|
243
|
+
#
|
|
244
|
+
# First, check if an option is defined as an attribute (e.g. opts=inline).
|
|
245
|
+
# If there is no match, fall back to the document-wide kroki-default-options attribute.
|
|
246
|
+
#
|
|
247
|
+
# @param attrs [Hash] the block or macro attributes
|
|
248
|
+
# @param doc [Asciidoctor::Document] the Asciidoctor document
|
|
249
|
+
# @return [String, nil] the option name (inline, interactive or none) or nil
|
|
250
|
+
def get_option(attrs, doc)
|
|
251
|
+
available_options = %w[inline interactive none]
|
|
252
|
+
available_options.find { |option| attrs["#{option}-option"] == '' } ||
|
|
253
|
+
available_options.find { |option| doc.attr('kroki-default-options') == option }
|
|
254
|
+
end
|
|
255
|
+
|
|
237
256
|
def get_format(doc, attrs, diagram_type)
|
|
238
257
|
format = attrs['format'] || doc.attr('kroki-default-format') || 'svg'
|
|
239
258
|
if format == 'png'
|
|
240
259
|
# redirect PNG format to SVG if the diagram library only supports SVG as output format.
|
|
241
260
|
# this is useful when the default format has been set to PNG
|
|
242
|
-
# Currently, nomnoml, svgbob, wavedrom only support SVG as output format.
|
|
243
|
-
svg_only_diagram_types = %i[nomnoml svgbob wavedrom]
|
|
261
|
+
# Currently, goat, nomnoml, svgbob, wavedrom only support SVG as output format.
|
|
262
|
+
svg_only_diagram_types = %i[goat nomnoml svgbob wavedrom]
|
|
244
263
|
format = 'svg' if svg_only_diagram_types.include?(diagram_type)
|
|
245
264
|
end
|
|
246
265
|
format
|
|
247
266
|
end
|
|
248
267
|
|
|
249
|
-
def create_image_src(doc, kroki_diagram, kroki_client)
|
|
268
|
+
def create_image_src(doc, kroki_diagram, kroki_client, logger)
|
|
250
269
|
if doc.attr('kroki-fetch-diagram') && doc.safe < ::Asciidoctor::SafeMode::SECURE
|
|
251
|
-
kroki_diagram.save(output_dir_path(doc), kroki_client)
|
|
270
|
+
kroki_diagram.save(output_dir_path(doc), kroki_client, generated_files(doc), logger)
|
|
252
271
|
else
|
|
253
272
|
kroki_diagram.get_diagram_uri(server_url(doc))
|
|
254
273
|
end
|
|
255
274
|
end
|
|
256
275
|
|
|
276
|
+
# Returns the per-document registry of generated file names, mapping each name
|
|
277
|
+
# to the diagram URI it was generated from. Used to detect name clashes within
|
|
278
|
+
# a single conversion.
|
|
279
|
+
def generated_files(doc)
|
|
280
|
+
doc.instance_variable_get(:@kroki_generated_files) ||
|
|
281
|
+
doc.instance_variable_set(:@kroki_generated_files, {})
|
|
282
|
+
end
|
|
283
|
+
|
|
257
284
|
def server_url(doc)
|
|
258
285
|
doc.attr('kroki-server-url', 'https://kroki.io')
|
|
259
286
|
end
|
|
@@ -306,28 +333,53 @@ module AsciidoctorExtensions
|
|
|
306
333
|
([Zlib::Deflate.deflate(@text, 9)].pack 'm0').tr '+/', '-_'
|
|
307
334
|
end
|
|
308
335
|
|
|
309
|
-
def save(output_dir_path, kroki_client)
|
|
336
|
+
def save(output_dir_path, kroki_client, generated_files = nil, logger = nil)
|
|
310
337
|
diagram_url = get_diagram_uri(kroki_client.server_url)
|
|
311
|
-
|
|
338
|
+
# An explicit name is used verbatim so links stay stable across content changes;
|
|
339
|
+
# otherwise the name is content-addressed so anonymous diagrams don't collide (see #451).
|
|
340
|
+
named = @target.is_a?(::String) && !@target.empty?
|
|
341
|
+
diagram_name = named ? "#{@target}.#{@format}" : "diag-#{Digest::SHA256.hexdigest diagram_url}.#{@format}"
|
|
312
342
|
file_path = File.join(output_dir_path, diagram_name)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
FileUtils.mkdir_p(output_dir_path)
|
|
323
|
-
File.write(file_path, contents, mode: 'wb')
|
|
343
|
+
if named
|
|
344
|
+
# A stable file may exist from a previous build with stale content, so always
|
|
345
|
+
# re-fetch and overwrite. Warn when the same name is reused for a different diagram.
|
|
346
|
+
warn_on_name_clash(generated_files, diagram_name, diagram_url, logger)
|
|
347
|
+
generated_files[diagram_name] = diagram_url if generated_files
|
|
348
|
+
fetch_and_write(output_dir_path, file_path, kroki_client)
|
|
349
|
+
elsif !File.exist?(file_path)
|
|
350
|
+
# Content-addressed name: an existing file necessarily has identical content.
|
|
351
|
+
fetch_and_write(output_dir_path, file_path, kroki_client)
|
|
324
352
|
end
|
|
325
|
-
|
|
326
353
|
diagram_name
|
|
327
354
|
end
|
|
328
355
|
|
|
329
356
|
private
|
|
330
357
|
|
|
358
|
+
def fetch_and_write(output_dir_path, file_path, kroki_client)
|
|
359
|
+
contents = kroki_client.get_image(self, image_encoding)
|
|
360
|
+
FileUtils.mkdir_p(output_dir_path)
|
|
361
|
+
File.write(file_path, contents, mode: 'wb')
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def warn_on_name_clash(generated_files, diagram_name, diagram_url, logger)
|
|
365
|
+
return unless generated_files && logger
|
|
366
|
+
|
|
367
|
+
previous_url = generated_files[diagram_name]
|
|
368
|
+
return if previous_url.nil? || previous_url == diagram_url
|
|
369
|
+
|
|
370
|
+
logger.warn "kroki: the diagram file name '#{diagram_name}' is generated by more than one diagram with different content; " \
|
|
371
|
+
'the file will be overwritten. Use unique names to keep stable links.'
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def image_encoding
|
|
375
|
+
case @format
|
|
376
|
+
when 'txt', 'atxt', 'utxt', 'svg'
|
|
377
|
+
'utf8'
|
|
378
|
+
else
|
|
379
|
+
'binary'
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
331
383
|
def _url_encode(text)
|
|
332
384
|
CGI.escape(text).gsub('+', '%20')
|
|
333
385
|
end
|
|
@@ -70,7 +70,7 @@ describe AsciidoctorExtensions::KrokiDiagram do
|
|
|
70
70
|
output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
|
|
71
71
|
diagram_name = kroki_diagram.save(output_dir_path, kroki_client)
|
|
72
72
|
diagram_path = File.join(output_dir_path, diagram_name)
|
|
73
|
-
expect(diagram_name).to
|
|
73
|
+
expect(diagram_name).to eq('hello-world.txt'), "diagram name should be the target name without a checksum, got: #{diagram_name}"
|
|
74
74
|
expect(File.exist?(diagram_path)).to be_truthy, "diagram should be saved at: #{diagram_path}"
|
|
75
75
|
content = <<-TXT.chomp
|
|
76
76
|
,-----. ,---.
|
|
@@ -99,4 +99,27 @@ describe AsciidoctorExtensions::KrokiDiagram do
|
|
|
99
99
|
kroki_diagram.save(output_dir_path, kroki_client)
|
|
100
100
|
expect(File.size(diagram_path)).to be_eql(diagram_contents.length), 'diagram should be fully saved on disk'
|
|
101
101
|
end
|
|
102
|
+
it 'should warn when the same target name is reused for diagrams with different content' do
|
|
103
|
+
generated_files = {}
|
|
104
|
+
logger = double('logger', warn: nil)
|
|
105
|
+
kroki_http_client = AsciidoctorExtensions::KrokiHttpClient
|
|
106
|
+
kroki_client = AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client)
|
|
107
|
+
output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
|
|
108
|
+
allow(kroki_http_client).to receive(:get).and_return('content')
|
|
109
|
+
AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'svg', 'alice -> bob', 'shared').save(output_dir_path, kroki_client, generated_files, logger)
|
|
110
|
+
AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'svg', 'carol -> dave', 'shared').save(output_dir_path, kroki_client, generated_files, logger)
|
|
111
|
+
expect(logger).to have_received(:warn).once
|
|
112
|
+
end
|
|
113
|
+
it 'should not warn when the same target name maps to the same diagram' do
|
|
114
|
+
generated_files = {}
|
|
115
|
+
logger = double('logger', warn: nil)
|
|
116
|
+
kroki_http_client = AsciidoctorExtensions::KrokiHttpClient
|
|
117
|
+
kroki_client = AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client)
|
|
118
|
+
output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
|
|
119
|
+
allow(kroki_http_client).to receive(:get).and_return('content')
|
|
120
|
+
2.times do
|
|
121
|
+
AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'svg', 'alice -> bob', 'shared').save(output_dir_path, kroki_client, generated_files, logger)
|
|
122
|
+
end
|
|
123
|
+
expect(logger).not_to have_received(:warn)
|
|
124
|
+
end
|
|
102
125
|
end
|
|
@@ -30,4 +30,24 @@ describe '::AsciidoctorExtensions::KrokiProcessor' do
|
|
|
30
30
|
output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
|
|
31
31
|
expect(output_dir_path).to eq "#{Dir.pwd}/img"
|
|
32
32
|
end
|
|
33
|
+
it 'should return the option defined on the block' do
|
|
34
|
+
doc = Asciidoctor.load('hello')
|
|
35
|
+
option = AsciidoctorExtensions::KrokiProcessor.send(:get_option, { 'inline-option' => '' }, doc)
|
|
36
|
+
expect(option).to eq 'inline'
|
|
37
|
+
end
|
|
38
|
+
it 'should fall back to the kroki-default-options document attribute' do
|
|
39
|
+
doc = Asciidoctor.load('hello', attributes: { 'kroki-default-options' => 'inline' })
|
|
40
|
+
option = AsciidoctorExtensions::KrokiProcessor.send(:get_option, {}, doc)
|
|
41
|
+
expect(option).to eq 'inline'
|
|
42
|
+
end
|
|
43
|
+
it 'should let the block option override the kroki-default-options document attribute' do
|
|
44
|
+
doc = Asciidoctor.load('hello', attributes: { 'kroki-default-options' => 'inline' })
|
|
45
|
+
option = AsciidoctorExtensions::KrokiProcessor.send(:get_option, { 'none-option' => '' }, doc)
|
|
46
|
+
expect(option).to eq 'none'
|
|
47
|
+
end
|
|
48
|
+
it 'should return nil when no option is defined' do
|
|
49
|
+
doc = Asciidoctor.load('hello')
|
|
50
|
+
option = AsciidoctorExtensions::KrokiProcessor.send(:get_option, {}, doc)
|
|
51
|
+
expect(option).to be_nil
|
|
52
|
+
end
|
|
33
53
|
end
|
data/spec/rspec_helper.rb
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
RSpec.configure do |config|
|
|
4
4
|
config.before(:suite) do
|
|
5
|
-
FileUtils.rm(Dir.glob("#{__dir__}/../.asciidoctor/kroki/diag
|
|
5
|
+
FileUtils.rm(Dir.glob("#{__dir__}/../.asciidoctor/kroki/{diag-*,hello-world.*,shared.*}"))
|
|
6
6
|
end
|
|
7
7
|
config.after(:suite) do
|
|
8
|
-
FileUtils.rm(Dir.glob("#{__dir__}/../.asciidoctor/kroki/diag
|
|
8
|
+
FileUtils.rm(Dir.glob("#{__dir__}/../.asciidoctor/kroki/{diag-*,hello-world.*,shared.*}")) unless ENV['DEBUG']
|
|
9
9
|
end
|
|
10
10
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciidoctor-kroki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0.beta.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Guillaume Grossetie
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: asciidoctor
|
|
@@ -100,14 +99,13 @@ files:
|
|
|
100
99
|
- tasks/bundler.rake
|
|
101
100
|
- tasks/lint.rake
|
|
102
101
|
- tasks/rspec.rake
|
|
103
|
-
homepage: https://github.com/
|
|
102
|
+
homepage: https://github.com/asciidoctor/asciidoctor-kroki
|
|
104
103
|
licenses:
|
|
105
104
|
- MIT
|
|
106
105
|
metadata:
|
|
107
|
-
bug_tracker_uri: https://github.com/
|
|
108
|
-
source_code_uri: https://github.com/
|
|
106
|
+
bug_tracker_uri: https://github.com/asciidoctor/asciidoctor-kroki/issues
|
|
107
|
+
source_code_uri: https://github.com/asciidoctor/asciidoctor-kroki
|
|
109
108
|
rubygems_mfa_required: 'true'
|
|
110
|
-
post_install_message:
|
|
111
109
|
rdoc_options: []
|
|
112
110
|
require_paths:
|
|
113
111
|
- lib
|
|
@@ -122,8 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
122
120
|
- !ruby/object:Gem::Version
|
|
123
121
|
version: '0'
|
|
124
122
|
requirements: []
|
|
125
|
-
rubygems_version: 3.
|
|
126
|
-
signing_key:
|
|
123
|
+
rubygems_version: 3.6.9
|
|
127
124
|
specification_version: 4
|
|
128
125
|
summary: Asciidoctor extension to convert diagrams to images using Kroki
|
|
129
126
|
test_files: []
|