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

MermaidJS: Suppress using HTML tags in SVG documents #1410

Open
ghost opened this issue Dec 14, 2022 · 7 comments
Open

MermaidJS: Suppress using HTML tags in SVG documents #1410

ghost opened this issue Dec 14, 2022 · 7 comments
Labels
🍩 enhancement New feature or request

Comments

@ghost
Copy link

ghost commented Dec 14, 2022

MermaidJS, by default, uses tags that only render inside of web browsers (foreignObject and div). A number of issues have been logged against MermaidJS to address this problem:

Issue 2688 recommends:

{
    "flowchart": {
        "htmlLabels": "false"
    }
}

What would be involved in revising Kroki to configure MermaidJS to avoid using HTML tags for all diagrams so as to generate more conformant SVG documents?

KeenWrite invokes Kroki using an HTTP GET request, so ideally the server could be configured to set htmlLabels to false, which would then allow KeenWrite to display the SVG files without modification:

https://github.com/DaveJarvis/keenwrite/blob/6fa925d27bbec807fc4419454aa81941524f889f/src/main/java/com/keenwrite/preview/DiagramUrlGenerator.java#L26

Alternatively, it looks like Kroki supports HTTP GET URL parameters for setting options:

https://docs.kroki.io/kroki/setup/usage/#_options

See also:

@ggrossetie
Copy link
Member

Kroki supports diagram options: https://docs.kroki.io/kroki/setup/usage/#_options

Currently, the gateway server calls the mermaid companion container with the diagram options but the mermaid service does not use them.

We are using the following default Mermaid configuration: https://github.com/yuzutech/kroki/blob/main/mermaid/src/task.js

So what we need to do is:

  1. establish a naming convention for Mermaid configuration (since they are using nested name)
  2. establish a convention to infer the type of the value (array, boolean, number...)
  3. get the diagram options from the query parameters in: https://github.com/yuzutech/kroki/blob/main/mermaid/src/index.js#L12
  4. merge the configuration with the default configuration: https://github.com/yuzutech/kroki/blob/main/mermaid/src/task.js

As a workaround, I think you can use a directive:

%%{ init: { "flowchart": { "htmlLabels": false } }%%

https://mermaid-js.github.io/mermaid/#/./directives?id=declaring-directives

As a side note, I'm leaning toward HTTP headers (rather than query parameters) to send diagram options to a companion container:

options.stream().iterator().forEachRemaining(entry -> {
String key = entry.getKey();
String value = entry.getValue() != null ? entry.getValue().toString() : "";
request.addQueryParam(key, value);
});

@ggrossetie ggrossetie added the 🍩 enhancement New feature or request label Dec 14, 2022
@ghost
Copy link
Author

ghost commented Dec 14, 2022

As a side note, I'm leaning toward HTTP headers (rather than query parameters) to send diagram options to a companion container:

Would those get censored by aggressive (corporate) network filters, or possibly trip security traps?

ZScaler can be configured to be pretty restrictive for what it accepts over HTTP(s).

@ghost
Copy link
Author

ghost commented Dec 14, 2022

As a workaround, I think you can use a directive:
%%{ init: { "flowchart": { "htmlLabels": false } }%%

KeenWrite generates diagrams dynamically. Users can write the following in their documents:

``` diagram-blockdiag
...
```

As well as:

``` diagram-graphviz
...
```

And:

``` diagram-mermaid
...
```

What's great about Kroki's API at the moment is that KeenWrite doesn't have to care about parsing and identifying the type of diagram to send to Kroki. By introducing %%{ init: { "flowchart": { "htmlLabels": false } }%%, does that mean KeenWrite not only has to detect the diagram type (mermaid) but also try to identify the type of MermaidJS diagram being used?

Is there any way we can keep the API simple and have diagrams "just work"? (I'm rather loathe to add diagram-specific parsing and configuration on the client side of Kroki.)

@ggrossetie
Copy link
Member

I was referring to the "internal" requests between Kroki containers. We will still support all the options when sending a request to the gateway server.

@ghost
Copy link
Author

ghost commented Dec 14, 2022

Here's a sreenshot showing the issue:

https://user-images.githubusercontent.com/2131950/141664461-033423b6-e9ae-4c23-8828-f760b9dde5f6.png

The Preview panel has missing text. A server-side fix would also mean users wouldn't have to upgrade to get the text fixes, which would be pretty cool for a desktop app.

@ggrossetie
Copy link
Member

The Preview panel has missing text. A server-side fix would also mean users wouldn't have to upgrade to get the text fixes, which would be pretty cool for a desktop app.

I'm not really sure why Mermaid chose to use htmlLabels to true by default but if you strongly believe it should be false by default then you should make your case upstream.

What we can do in Kroki is allow to pass options to change this default configuration. It means that you will need to pass a query parameter (or an HTTP header) to your GET request. Something like:

GET https://kroki.io/mermaid/svg/abcd1234?flowchart-html-labels=false

Since some configurations seem to be global we could use:

GET https://kroki.io/mermaid/svg/abcd1234?global-html-labels=false

@ghost
Copy link
Author

ghost commented Dec 15, 2022

Since some configurations seem to be global we could use:

Does that option get silently ignored for non-Mermaid diagrams? That is, would the following still generate a valid SVG file:

final var server = "kroki.io";
final var diagram = "graphviz";
final var encoded = "...";
final var options = "global-html-labels=false";

http.get( format( "https://%s/%s/svg/%s?%s", server, diagram, encoded, options ) );

If so, then that'd work out quite well. If not, could we add an option to ignore irrelevant/unknown/invalid options? Perhaps:

final var options = "accept-non-applicable=true&global-html-labels=false";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍩 enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant