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

open diagram in new tab #25

Closed
wants to merge 1 commit into from
Closed
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: 17 additions & 0 deletions d2/css/mkdocs_d2_plugin.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
.d2,
.d2-light,
.d2-dark {
display: flex;
flex-direction: column;
}

.d2 a:hover {
text-decoration: underline
}

.d2-button {
margin: 10px 0;
padding: 5px 10px;
cursor: pointer;
}

.d2-button:hover {
text-decoration: underline;
}

[data-md-color-scheme="default"] div.d2-dark {
display: none;
}
Expand Down
41 changes: 32 additions & 9 deletions d2/fence.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import xml.etree.ElementTree as etree
from typing import Any, Dict

from markdown import Markdown
Expand Down Expand Up @@ -56,17 +57,29 @@ def formatter(
source, language, class_name, options, md, **kwargs
)

result, _, ok = self.renderer(source.encode(), options["opts"], options["alt"])
result, svg, ok = self.renderer(
source.encode(), options["opts"], options["alt"]
)
if not ok:
error(result)
return fence_code_format(
source, language, class_name, options, md, **kwargs
)

elem = etree.Element("div")
elem.set("class", "d2")

new_tab_button = etree.Element("button")
new_tab_button.set("class", "d2-button")
new_tab_button.set("onclick", f'd2OpenInNewTab("{result}")')
new_tab_button.text = "Open diagram in new tab"

if "opts_dark" not in options:
return f'<div class="d2">{result}</div>'
elem.append(svg.root)
elem.append(new_tab_button)
return etree.tostring(elem, encoding="utf-8", method="html").decode()

dark_result, _, ok = self.renderer(
dark_result, dark_svg, ok = self.renderer(
source.encode(), options["opts_dark"], options["alt"]
)
if not ok:
Expand All @@ -75,12 +88,22 @@ def formatter(
source, language, class_name, options, md, **kwargs
)

return (
'<div class="d2">'
f'<div class="d2-light">{result}</div>'
f'<div class="d2-dark">{dark_result}</div>'
"</div>"
)
light = etree.Element("div", {"class": "d2-light"})
light.append(svg.root)
light.append(new_tab_button)
elem.append(light)

dark_new_tab_button = etree.Element("button")
dark_new_tab_button.set("class", "d2-button")
dark_new_tab_button.set("onclick", f'd2OpenInNewTab("{dark_result}")')
dark_new_tab_button.text = "Open diagram in new tab"

dark = etree.Element("div", {"class": "d2-dark"})
dark.append(dark_svg.root)
dark.append(dark_new_tab_button)
elem.append(dark)

return etree.tostring(elem, encoding="utf-8", method="html").decode()


def falsy(value: str) -> bool:
Expand Down
13 changes: 13 additions & 0 deletions d2/img.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,14 @@ def run(self, root: etree.Element) -> Optional[etree.Element]:
elem.clear()
elem.set("class", "d2")

new_tab_button = etree.Element("button")
new_tab_button.set("class", "d2-button")
new_tab_button.set("onclick", f'd2OpenInNewTab("{result}")')
new_tab_button.text = "Open diagram in new tab"

if not cfg.has_dark_theme():
elem.append(svg.root)
elem.append(new_tab_button)
continue

dark_result, dark_svg, ok = self.renderer(
Expand All @@ -65,10 +71,17 @@ def run(self, root: etree.Element) -> Optional[etree.Element]:

light = etree.Element("div", {"class": "d2-light"})
light.append(svg.root)
light.append(new_tab_button)
elem.append(light)

dark_new_tab_button = etree.Element("button")
dark_new_tab_button.set("class", "d2-button")
dark_new_tab_button.set("onclick", f'd2OpenInNewTab("{dark_result}")')
dark_new_tab_button.text = "Open diagram in new tab"

dark = etree.Element("div", {"class": "d2-dark"})
dark.append(dark_svg.root)
dark.append(dark_new_tab_button)
elem.append(dark)


Expand Down
Empty file added d2/js/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions d2/js/mkdocs_d2_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function d2OpenInNewTab(svgID) {
const container = document.getElementById(svgID);
const svg = container ? container.querySelector('svg') : null;
if (!svg) return;

const tempDiv = document.createElement('div');
tempDiv.innerHTML = svg.outerHTML;

const links = tempDiv.querySelectorAll('a');
links.forEach(link => {
link.setAttribute('onmouseover', 'this.style.textDecoration="underline"');
link.setAttribute('onmouseout', 'this.style.textDecoration="none"');
link.setAttribute('target', '_blank');
});

const blob = new Blob([tempDiv.innerHTML], { type: "text/html" });
const url = URL.createObjectURL(blob);
const win = window.open(url);

if (win) {
win.onload = () => URL.revokeObjectURL(url);
}
}
29 changes: 24 additions & 5 deletions d2/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def on_config(self, config: MkDocsConfig) -> Optional[MkDocsConfig]:
}

config["extra_css"].append("assets/stylesheets/mkdocs_d2_plugin.css")
config["extra_javascript"].append("assets/javascript/mkdocs_d2_plugin.js")

return config

Expand All @@ -92,16 +93,31 @@ def on_post_build(self, config: MkDocsConfig) -> None:
self.cache.close()

def on_files(self, files: Files, config):
content = importlib_files("d2.css").joinpath("mkdocs_d2_plugin.css").read_text()
file = File(
# CSS
css_content = (
importlib_files("d2.css").joinpath("mkdocs_d2_plugin.css").read_text()
)
css_file = File(
"assets/stylesheets/mkdocs_d2_plugin.css",
None,
config["site_dir"],
config["use_directory_urls"],
)
file.content_string = content
css_file.content_string = css_content
files.append(css_file)

files.append(file)
# JS
js_content = (
importlib_files("d2.js").joinpath("mkdocs_d2_plugin.js").read_text()
)
js_file = File(
"assets/javascript/mkdocs_d2_plugin.js",
None,
config["site_dir"],
config["use_directory_urls"],
)
js_file.content_string = js_content
files.append(js_file)


def render(
Expand Down Expand Up @@ -166,4 +182,7 @@ def render(
svg.root.set("role", "img")
svg.root.set("aria-label", alt)

return etree.tostring(svg.root, encoding="unicode"), svg, True
svg_id = uuid4().hex
svg.root.set("id", svg_id)

return svg_id, svg, True
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
"Programming Language :: Python :: 3.12",
],
packages=find_packages(),
package_data={"d2.css": ["mkdocs_d2_plugin.css"]},
package_data={
"d2.css": ["mkdocs_d2_plugin.css"],
"d2.js": ["mkdocs_d2_plugin.js"],
},
include_package_data=True,
entry_points={
"mkdocs.plugins": ["d2 = d2.plugin:Plugin"],
Expand Down
Loading