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

dot, tex, and mermaid blocks #8

Merged
merged 4 commits into from
Nov 7, 2023
Merged

dot, tex, and mermaid blocks #8

merged 4 commits into from
Nov 7, 2023

Conversation

mbostock
Copy link
Member

Adds support for dot (Graphviz) and tex (KaTex) blocks. For Graphviz, I used a newer version and added some hacks to make it work in dark mode out of the box. I’d like to update KaTeX to use ES modules instead of require, too.

Note that adding a dot block with incremental update doesn’t work because the library won’t be in the import map (which has to be set on load). We’ll need to detect this case and trigger a reload instead of an incremental update, or some other solution I haven’t thought of yet.

public/client.js Outdated
e.setAttribute("fill", "currentColor");
e.removeAttribute("fill-opacity");
}
svg.remove();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this is needed? Does renderSVGElement add the element to a virtual DOM somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It creates a standalone XML document (using DOMParser, I believe). So we need to remove it from that document before we can add it to the page.

public/client.js Outdated
bgcolor: "none"
},
nodeAttributes: {
color: "#00000101",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why you need to set both the color and opacity here, or is that required by the package?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphviz don’t understand proper CSS colors, so I can’t set this to currentColor. So this is a hack to set a color that no one should use in practice, and then replace it after rendering which currentColor. I wanted to set the opacity to exactly zero, but then Graphviz ignores the RGB parts.

@mbostock
Copy link
Member Author

HTML code blocks would also help with #32, maybe.

```js
const link = "https://example.com";
```
```html
This is a <a href=${link}>link</a>.
```

@mbostock mbostock mentioned this pull request Oct 23, 2023
@Fil Fil force-pushed the mbostock/tagged-templates branch from b7c352c to 333a052 Compare November 7, 2023 08:25
Copy link
Contributor

@Fil Fil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rebased this PR which had diverged a bit, and added unit tests. LGTM!

Copy link
Contributor

@wiltsecarpenter wiltsecarpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would also be good add mermaid too since other systems have that.

src/markdown.ts Outdated
@@ -77,26 +78,36 @@ function uniqueCodeId(context: ParseContext, content: string): string {
return id;
}

function isLive(language) {
return language === "js" || language === "dot" || language === "tex";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What really determines this set of languages and how we can determine it algorithmically so we don't need this hard-coded list here? Maybe this could be pulled into an array at a higher scope? Or should it be part of the parse context?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracking this suggestion in #113

Copy link
Member Author

@mbostock mbostock Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The set of languages is determined by getSource below:

https://github.com/observablehq/cli/blob/333a0527294886e14e5d4f2ffdab518c2a988caf/src/markdown.ts#L85-L91

Maybe I could rewrite this code to avoid duplication. 🤔 In the case of tagged languages, we could if desired implement it a bit more declaratively by enumerating a list of tags and raw flags. (Note that the language tag can be different than the implementation tag, as is the case with tex and tex.block.)

const template = TemplateParser.parse(input, options);
const source = new Sourcemap(input);
escapeTemplateElements(source, template, raw);
source.insertLeft(template.start, tag + "`");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To pass attributes to the tag function, this might need to be something like new Function(make${tag}(JSON.stringify(attrs) )) or maybe tag + ".bind(" + JSON.stringify(attrs) + ")"

@mbostock
Copy link
Member Author

mbostock commented Nov 7, 2023

I added Mermaid blocks in the latest commit.

@mbostock mbostock changed the title dot & tex blocks dot, tex, and mermaid blocks Nov 7, 2023
@mbostock mbostock merged commit 1c7402a into main Nov 7, 2023
1 check passed
@mbostock mbostock deleted the mbostock/tagged-templates branch November 7, 2023 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants