Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolves #397 generate data-uri elements for images downloaded from Kroki at build time #454

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<br/>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:<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` |
| `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.<br/>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:<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` |
| `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.
Expand Down
8 changes: 5 additions & 3 deletions dist/browser/asciidoctor-kroki.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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'
Expand Down
11 changes: 10 additions & 1 deletion src/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
Expand All @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/http/http-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
18 changes: 15 additions & 3 deletions test/test.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<div class="imageblock sequence kroki-format-svg kroki">')
})
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('<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2l')
})
it('should create diagrams in imagesdir if kroki-fetch-diagram is set', async () => {
const registry = asciidoctor.Extensions.create()
asciidoctorKroki.register(registry)
Expand Down Expand Up @@ -427,7 +439,7 @@ Bob->Alice : hello
http.get.restore()
}
})
it('should embed an SVG image with built-in allow-uri-read and data-uri (available in Asciidoctor.js 2+)', () => {
it('should embed an SVG image with built-in allow-uri-read and data-uri', () => {
const input = `
:imagesdir: .asciidoctor/kroki

Expand Down Expand Up @@ -1276,7 +1288,7 @@ paragraph
}
]
for (const { location, pageAttr, blockAttr } of inlineOptionsFixtures) {
it(`should inline (via ${location}) an SVG image with built-in allow-uri-read (available in Asciidoctor.js 2+)`, () => {
it(`should inline (via ${location}) an SVG image with built-in allow-uri-read`, () => {
const input = `
:imagesdir: .asciidoctor/kroki
${pageAttr}
Expand Down Expand Up @@ -1333,7 +1345,7 @@ bytefield::test/fixtures/simple.bytefield[svg,role=bytefield${blockAttr}]
}
]
for (const { location, pageAttr, blockAttr } of interactiveOptionsFixtures) {
it(`should include an interactive (via ${location}) SVG image with built-in allow-uri-read and data-uri (available in Asciidoctor.js 2+)`, () => {
it(`should include an interactive (via ${location}) SVG image with built-in allow-uri-read and data-uri`, () => {
const input = `
:imagesdir: .asciidoctor/kroki
${pageAttr}
Expand Down
Loading