From 9eb59c3832d09febbb8928e6bac8357ab63b1be6 Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Thu, 13 Jun 2024 11:35:14 +0200 Subject: [PATCH] resolves #397 generate data-uri elements for images downloaded from Kroki at build time Based on @enrikb and @AshkanV work. --- README.md | 17 +++++++++-------- dist/browser/asciidoctor-kroki.js | 8 +++++--- src/fetch.js | 11 ++++++++++- src/http/http-client.js | 6 ++++-- test/test.spec.js | 18 +++++++++++++++--- 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b7a579b..96e0819 100644 --- a/README.md +++ b/README.md @@ -350,14 +350,15 @@ Consult the [Kroki documentation](https://kroki.io/#support) to find out which f ## Configuration -| Attribute name | Description | Default value | -| ---- | ---- | ---- | -| `kroki-server-url` | The URL of the Kroki server (see "Using Your Own Kroki") | `https://kroki.io` -| `kroki-fetch-diagram` | Define if we should download (and save on the disk) the images from the Kroki server.
This feature is not available when running in the browser. | `false` -| `kroki-http-method` | Define how we should get the image from the Kroki server. Possible values:
| `adaptive` | -| `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. | | -| `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"` | | -| `kroki-max-uri-length` | Define the max URI length before using a POST request when using `adaptive` HTTP method (`kroki-http-method`) | `4000` +| Attribute name | Description | Default value | +|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------| +| `kroki-server-url` | The URL of the Kroki server (see "Using Your Own Kroki") | `https://kroki.io` | +| `kroki-data-uri` | Embed images as data-uri elements in HTML elements so file is completely self-contained. | `false` | +| `kroki-fetch-diagram` | Define if we should download (and save on the disk) the images from the Kroki server.
This feature is not available when running in the browser. | `false` | +| `kroki-http-method` | Define how we should get the image from the Kroki server. Possible values:
| `adaptive` | +| `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. | | +| `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"` | | +| `kroki-max-uri-length` | Define the max URI length before using a POST request when using `adaptive` HTTP method (`kroki-http-method`) | `4000` | **❗ IMPORTANT:** `kroki-fetch-diagram` and `kroki-plantuml-include` are only available when safe mode is `server` or lower. diff --git a/dist/browser/asciidoctor-kroki.js b/dist/browser/asciidoctor-kroki.js index d312624..aab5e38 100644 --- a/dist/browser/asciidoctor-kroki.js +++ b/dist/browser/asciidoctor-kroki.js @@ -20057,7 +20057,7 @@ function extend() { },{}],70:[function(require,module,exports){ module.exports={ "name": "asciidoctor-kroki", - "version": "0.17.0", + "version": "0.18.1", "description": "Asciidoctor extension to convert diagrams to images using Kroki", "type": "commonjs", "main": "./src/asciidoctor-kroki.js", @@ -20440,8 +20440,10 @@ const httpRequest = (XMLHttpRequest, uri, method, headers, encoding = 'utf8', bo try { const xhr = new XMLHttpRequest() xhr.open(method, uri, false) - for (const [name, value] in Object.entries(headers)) { - xhr.setRequestHeader(name, value) + if (headers) { + for (const [name, value] in Object.entries(headers)) { + xhr.setRequestHeader(name, value) + } } if (encoding === 'binary') { xhr.responseType = 'arraybuffer' diff --git a/src/fetch.js b/src/fetch.js index 861d7e7..84f7354 100644 --- a/src/fetch.js +++ b/src/fetch.js @@ -27,6 +27,7 @@ module.exports.save = function (krokiDiagram, doc, target, vfs, krokiClient) { const add = typeof vfs !== 'undefined' && typeof vfs.add === 'function' ? vfs.add : require('./node-fs.js').add const imagesOutputDirectory = getImagesOutputDirectory(doc) + const dataUri = doc.isAttribute('data-uri') || doc.isAttribute('kroki-data-uri') const diagramUrl = krokiDiagram.getDiagramUri(krokiClient.getServerUrl()) const format = krokiDiagram.format const diagramName = `${target || 'diag'}-${rusha.createHash().update(diagramUrl).digest('hex')}.${format}` @@ -44,7 +45,15 @@ module.exports.save = function (krokiDiagram, doc, target, vfs, krokiClient) { encoding = 'binary' } // file is either (already) on the file system or we should read it from Kroki - const contents = exists(filePath) ? read(filePath, encoding) : krokiClient.getImage(krokiDiagram, encoding) + let contents + if (exists(filePath)) { + contents = read(filePath, encoding) + } else { + contents = krokiClient.getImage(krokiDiagram, encoding) + } + if (dataUri) { + return 'data:' + mediaType + ';base64,' + Buffer.from(contents, encoding).toString('base64') + } add({ relative: imagesOutputDirectory, basename: diagramName, diff --git a/src/http/http-client.js b/src/http/http-client.js index d7f50dd..76c71d1 100644 --- a/src/http/http-client.js +++ b/src/http/http-client.js @@ -4,8 +4,10 @@ const httpRequest = (XMLHttpRequest, uri, method, headers, encoding = 'utf8', bo try { const xhr = new XMLHttpRequest() xhr.open(method, uri, false) - for (const [name, value] in Object.entries(headers)) { - xhr.setRequestHeader(name, value) + if (headers) { + for (const [name, value] in Object.entries(headers)) { + xhr.setRequestHeader(name, value) + } } if (encoding === 'binary') { xhr.responseType = 'arraybuffer' diff --git a/test/test.spec.js b/test/test.spec.js index 72f3268..e1a78a4 100644 --- a/test/test.spec.js +++ b/test/test.spec.js @@ -209,6 +209,18 @@ plantuml::test/fixtures/alice.puml[png,role=sequence] expect(html).to.contain(`https://kroki.io/plantuml/svg/${encode(macroFile)}`) expect(html).to.contain('
') }) + it('should download and embed an SVG image with kroki-fetch-diagram and kroki-data-uri', () => { + const registry = asciidoctor.Extensions.create() + asciidoctorKroki.register(registry) + const html = asciidoctor.convert(fs.readFileSync(fixturePath('fetch', 'doc.adoc')), { + attributes: { + 'kroki-data-uri': '' + }, + extension_registry: registry, + safe: 'unsafe' + }) + expect(html).to.contain('