From cc3e5906f6292fe26386ca85fbe1b7709c8ea878 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Wed, 8 Oct 2025 15:39:33 +0200 Subject: [PATCH 1/2] Add caption_is_page option --- README.md | 36 ++++++++++--- examples/docs/configuration.md | 17 ++++-- examples/docs/index.md | 20 +++++-- examples/docs/tests/pagging/index.md | 8 +-- mkdocs_drawio/plugin.py | 80 ++++++++++++++++++++-------- pyproject.toml | 2 + 6 files changed, 123 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index e6e78aa..2af8e07 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [![Publish Badge](https://github.com/tuunit/mkdocs-drawio/workflows/Publish/badge.svg)](https://github.com/tuunit/mkdocs-drawio/actions) [![PyPI](https://img.shields.io/pypi/v/mkdocs-drawio)](https://pypi.org/project/mkdocs-drawio/) -Sergey ([onixpro](https://github.com/onixpro)) is the original creator of this plugin but since his repository isn't maintained anymore we forked it on the 19th December of 2023 and have been keeping it up-to-date and expanding on the features since then. -[Buy Sergey a ☕](https://www.buymeacoffee.com/SergeyLukin) +Sergey ([onixpro](https://github.com/onixpro)) is the original creator of this plugin but since his repository isn't maintained anymore we forked it on the 19th December of 2023 and have been keeping it up-to-date and expanding on the features since then. +[Buy Sergey a ☕](https://www.buymeacoffee.com/SergeyLukin) ## Features @@ -39,6 +39,8 @@ Or use the page attribute: ![Bar Diagram](my-diagram.drawio){ page="my-custom-page-name" } ``` +If you prefer to keep the caption purely descriptive, set `use_page_attribute: true` in your plugin configuration. When enabled, the plugin no longer uses the alt text for page selection and instead expects the `page` attribute provided by the `attr_list` markdown extension. + ## Setup Install plugin using pip: @@ -66,16 +68,34 @@ plugins: viewer_js: "https://viewer.diagrams.net/js/viewer-static.min.js" ``` -Further options are: +Further options are the following, with their default value: ```yaml plugins: - drawio: - toolbar: true # control if hovering on a diagram shows a toolbar for zooming or not (default: true) - tooltips: true # control if tooltips will be shown (default: true) - edit: true # control if edit button will be shown in the lightbox view (default: true) - border: 10 # increase or decrease the border / margin around your diagrams (default: 0) - darkmode: true # support darkmode. allows for automatic switching between dark and lightmode based on the theme toggle. (default: false) + # control if hovering on a diagram shows a + # toolbar for zooming or not + toolbar: true + + # control if tooltips will be shown + tooltips: true + + # control if edit button will be shown in the + # lightbox view + edit: true + + # increase or decrease the border / margin around your diagrams + border: 0 + + # support darkmode. allows for automatic switching + # between dark and lightmode based on the theme toggle. + darkmode: false + + # treat the image caption as the diagram page name. + # Set to true to use the attr_list 'page' attribute instead. + # this option is not enabled by default to maintain backward + # compatibility. + use_page_attribute: false ``` ## Material Integration diff --git a/examples/docs/configuration.md b/examples/docs/configuration.md index 3f0fa6d..c49319a 100644 --- a/examples/docs/configuration.md +++ b/examples/docs/configuration.md @@ -30,12 +30,20 @@ plugins: edit: true # Control if darkmode is supported - # When activated the color scheme for your diagrams is automatically toggled - # based on the selected theme. Supports classic mkdocs and mkdocs-material. - darkmode: true + # When activated the color scheme for your diagrams is automatically + # toggled based on the selected theme. Supports classic mkdocs and + # mkdocs-material. + darkmode: true + + # Control if the image caption is used to select a Drawio page + # Disable to rely on the attr_list 'page' attribute instead + use_page_attribute: true ``` + ## HTML Attributes + For each global configuration option you can also use the attribute in the diagram itself. This will override the global configuration. Here is an example: + ```markdown ![](my-diagram.drawio){ data-toolbar-zoom="false" } ``` @@ -46,6 +54,9 @@ To use these attributes you need to enable the markdown extension `attr_list` in markdown_extensions: - attr_list ``` + +> Note: When `use_page_attribute` is set to `true`, enabling the `attr_list` extension becomes mandatory because page selection is driven exclusively through the `page` attribute. + ## Material Integration If you are using the Material Theme and want to use the [instant-loading](https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/?h=instant#instant-loading) feature. You will have to configure the following: diff --git a/examples/docs/index.md b/examples/docs/index.md index 3b39663..414e529 100644 --- a/examples/docs/index.md +++ b/examples/docs/index.md @@ -2,8 +2,8 @@ This plugin allows you to embed draw.io diagrams in your MkDocs documentation. It is compatible with most MkDocs themes, but specifically tested with the Material theme and the MkDocs default theme. -Sergey ([onixpro](https://github.com/onixpro)) is the original creator of this plugin but since his repository isn't maintained anymore we forked it on the 19th December of 2023 and have been keeping it up-to-date and expanding on the features since then. -[Buy Sergey a ☕](https://www.buymeacoffee.com/SergeyLukin) +Sergey ([onixpro](https://github.com/onixpro)) is the original creator of this plugin but since his repository isn't maintained anymore we forked it on the 19th December of 2023 and have been keeping it up-to-date and expanding on the features since then. +[Buy Sergey a ☕](https://www.buymeacoffee.com/SergeyLukin) ## Installation @@ -57,9 +57,23 @@ Or you can use external urls: ![](https://example.com/diagram.drawio) ``` -Additionally this plugin supports multi page diagrams by using the `alt` text to select the pages by name: +Additionally this plugin supports multi page diagrams by using the `alt` text (caption) to select the pages by name. This behaviour is controlled by the `use_page_attribute` configuration option and is enabled by default: ```markdown ![Page-2](my-diagram.drawio) ![my-custom-page-name](my-diagram.drawio) ``` + +If you prefer to keep the caption descriptive and select pages via attributes instead, disable the option in your `mkdocs.yml`: + +```yaml +plugins: + - drawio: + use_page_attribute: false +``` + +With the option disabled, enable the `attr_list` markdown extension and use the `page` attribute: + +```markdown +![Diagram caption](my-diagram.drawio){ page="Page-2" } +``` diff --git a/examples/docs/tests/pagging/index.md b/examples/docs/tests/pagging/index.md index e81d85d..a5f7e1f 100644 --- a/examples/docs/tests/pagging/index.md +++ b/examples/docs/tests/pagging/index.md @@ -1,9 +1,11 @@ # Pagging You can either use the `alt` text of the image for pagging or use an attribute -page for pagging if you have the `attr_list` markdown extension installed in +page for pagging if you have the `attr_list` markdown extension installed in your `mkdocs.yaml`. +> By default the plugin uses the caption (`alt` text) as the page selector. Set `use_page_attribute: true` in your plugin configuration if you always want to rely on the `page` attribute instead. + ```yaml markdown_extensions: - attr_list @@ -47,9 +49,9 @@ markdown_extensions: === "Diagram" Below you should see Page-1 (default) because the specified Page-3 has not been found: ![Page-3](test.drawio) - + Furthoremore, you should see a warning in your mkdocs server similar to: - + ```bash WARNING - Warning: Found 0 results for page name 'Page-3' for diagram 'test.drawio' on path '/tmp/mkdocs_ce1qjhyn/test2' ``` diff --git a/mkdocs_drawio/plugin.py b/mkdocs_drawio/plugin.py index 216632c..cbdb1c6 100644 --- a/mkdocs_drawio/plugin.py +++ b/mkdocs_drawio/plugin.py @@ -10,6 +10,7 @@ from mkdocs.utils import copy_file from mkdocs.plugins import BasePlugin from mkdocs.config import base, config_options as c +from mkdocs.exceptions import ConfigurationError SUB_TEMPLATE = string.Template( '
' @@ -29,6 +30,7 @@ class DrawioConfig(base.Config): border = c.Type(int, default=0) edit = c.Type(bool, default=True) darkmode = c.Type(bool, default=False) + use_page_attribute = c.Type(bool, default=False) class DrawioPlugin(BasePlugin[DrawioConfig]): @@ -74,10 +76,9 @@ def render_drawio_diagrams(self, output_content, page): "html.parser", ) else: - diagram_page = diagram["alt"] - # Use page attribute instead of alt if it is set - if "page" in diagram: - diagram_page = diagram["page"] + diagram_page = diagram.get( + "page" if self.config.use_page_attribute else "alt" + ) mxgraph = BeautifulSoup( DrawioPlugin.substitute_with_file( diagram_config, path, diagram["src"], diagram_page @@ -96,51 +97,62 @@ def substitute_with_url(config: Dict, url: str) -> str: return SUB_TEMPLATE.substitute(config=escape(json.dumps(config))) @staticmethod - def substitute_with_file(config: Dict, path: Path, src: str, alt: str) -> str: + def substitute_with_file(config: Dict, path: Path, src: str, page: str) -> str: try: diagram_xml = etree.parse(path.joinpath(src).resolve()) except Exception: LOGGER.error( - f"Error: Provided diagram file '{src}' on path '{path}' is not a valid diagram" + f"Error: Provided diagram file '{src}' on path " + f"'{path}' is not a valid diagram" ) diagram_xml = etree.fromstring("") - diagram = DrawioPlugin.parse_diagram(diagram_xml, alt) + diagram = DrawioPlugin.parse_diagram(diagram_xml, page, src, path) config["xml"] = diagram return SUB_TEMPLATE.substitute(config=escape(json.dumps(config))) @staticmethod - def parse_diagram(data, alt, src="", path=None) -> str: - if alt is None or len(alt) == 0: + def parse_diagram(data, page, src="", path=None) -> str: + if page is None or len(page) == 0: return etree.tostring(data, encoding=str) - try: mxfile = data.xpath("//mxfile")[0] - # try to parse for a specific page by using the alt attribute - page = mxfile.xpath(f"//diagram[@name='{alt}']") + # try to parse for a specific page by using the page attribute + pages = mxfile.xpath(f"//diagram[@name='{page}']") - if len(page) == 1: - parser = etree.XMLParser() - result = parser.makeelement(mxfile.tag, mxfile.attrib) - - result.append(page[0]) - return etree.tostring(result, encoding=str) - else: + if len(pages) > 1: LOGGER.warning( - f"Warning: Found {len(page)} results for page name '{alt}' for diagram '{src}' on path '{path}'" + f"Warning: Found multiple ({len(pages)}) pages with " + f"same name '{page}' in diagram '{src}' " + f"on path '{path}', using first one." ) + return etree.tostring(mxfile, encoding=str) + + parser = etree.XMLParser() + result = parser.makeelement(mxfile.tag, mxfile.attrib) + + result.append(pages[0]) + return etree.tostring(result, encoding=str) - return etree.tostring(mxfile, encoding=str) except Exception: LOGGER.error( - f"Error: Could not properly parse page name '{alt}' for diagram '{src}' on path '{path}'" + "Error: Could not properly parse page name " + f"'{page}' for diagram '{src}' on path '{path}'" ) return "" def on_config(self, config: base.Config): """Load embedded files""" + if not self.config.use_page_attribute and not self._has_attr_list_extension( + config.get("markdown_extensions", []) + ): + raise ConfigurationError( + "The markdown extension 'attr_list' must be enabled " + "when 'use_page_attribute' is set to false." + ) + self.base = Path(__file__).parent self.css = [] self.js = [] @@ -154,8 +166,30 @@ def on_config(self, config: base.Config): for path in self.js: config.extra_javascript.append(str(path)) - def on_post_build(self, config: base.Config): + def on_post_build(self, config: base.Config) -> None: """Copy embedded files to the site directory""" site = Path(config["site_dir"]) for path in self.css + self.js: copy_file(self.base / path, site / path) + + @staticmethod + def _has_attr_list_extension(extensions) -> bool: + for extension in extensions: + name = DrawioPlugin._get_extension_name(extension) + normalized = name.lower() + if normalized in { + "attr_list", + "attrlist", + "markdown.extensions.attr_list", + "markdown.extensions.attrlist", + }: + return True + return False + + @staticmethod + def _get_extension_name(extension) -> str: + if isinstance(extension, str): + return extension + if isinstance(extension, dict) and extension: + return next(iter(extension.keys())) + return "" diff --git a/pyproject.toml b/pyproject.toml index 6e7459a..864eee3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,8 @@ black = ">=24.0" ruff = "^0.9.2" mkdocs-print-site-plugin = "^2.6.0" mkdocs-material = "^9.5.50" +mkdocs = "^1.6.1" +lxml = "^6.0.2" [build-system] requires = ["poetry-core>=1.0.0"] From 407c9a2d1afb853e2be20bc3d95ba9073c4f51c3 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Wed, 8 Oct 2025 17:15:24 +0200 Subject: [PATCH 2/2] Fix error in doc of use_page_attribute --- examples/docs/configuration.md | 32 ++++++++++++++++---------------- examples/docs/index.md | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/docs/configuration.md b/examples/docs/configuration.md index c49319a..df71989 100644 --- a/examples/docs/configuration.md +++ b/examples/docs/configuration.md @@ -15,29 +15,29 @@ Further options are the following with their default value: ```yaml plugins: - drawio: - # Control if hovering on a diagram shows a toolbar for zooming or not + # control if hovering on a diagram shows a + # toolbar for zooming or not toolbar: true - # Control if tooltips will be shown (data-tooltips) + # control if tooltips will be shown tooltips: true - # Increase or decrease the padding around your diagrams - # (data-border) - border: 5 - - # Control if edit button will be shown in the lightbox view - # (data-edit) + # control if edit button will be shown in the + # lightbox view edit: true - # Control if darkmode is supported - # When activated the color scheme for your diagrams is automatically - # toggled based on the selected theme. Supports classic mkdocs and - # mkdocs-material. - darkmode: true + # increase or decrease the border / margin around your diagrams + border: 0 + + # support darkmode. allows for automatic switching + # between dark and lightmode based on the theme toggle. + darkmode: false - # Control if the image caption is used to select a Drawio page - # Disable to rely on the attr_list 'page' attribute instead - use_page_attribute: true + # treat the image caption as the diagram page name. + # Set to true to use the attr_list 'page' attribute instead. + # this option is not enabled by default to maintain backward + # compatibility. + use_page_attribute: false ``` ## HTML Attributes diff --git a/examples/docs/index.md b/examples/docs/index.md index 414e529..8adb3ba 100644 --- a/examples/docs/index.md +++ b/examples/docs/index.md @@ -57,7 +57,7 @@ Or you can use external urls: ![](https://example.com/diagram.drawio) ``` -Additionally this plugin supports multi page diagrams by using the `alt` text (caption) to select the pages by name. This behaviour is controlled by the `use_page_attribute` configuration option and is enabled by default: +Additionally this plugin supports multi page diagrams by using the `alt` text (caption) to select the pages by name. This behaviour is controlled by the `use_page_attribute` configuration option, which is set to `false` by default. ```markdown ![Page-2](my-diagram.drawio)