From d593e09f3d0332e60f3ce954468d3847612322d3 Mon Sep 17 00:00:00 2001 From: Diego Carrasco G <557703+dacog@users.noreply.github.com> Date: Fri, 22 Nov 2024 19:10:03 +0100 Subject: [PATCH] add missing options from the d2 bin. Update Readme, add CHANGELOG.md, increase package version. --- CHANGELOG.md | 43 +++++++++++++++++++++ README.md | 33 +++++++++++++--- d2_python/__init__.py | 88 +++++++++++++++++++++++++++++++++++++++---- pyproject.toml | 8 +++- setup.py | 2 +- 5 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d399985 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,43 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project tries to adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.2.0] - 2024-11-22 + +### Added + +- Dark theme support with `dark_theme` parameter +- Sketch mode rendering with `sketch` parameter +- SVG centering with `center` parameter +- Output scaling with `scale` parameter +- SVG asset bundling control with `bundle` parameter +- Tooltip appendix forcing with `force_appendix` parameter +- Execution timeout control with `timeout` parameter +- Board animation with `animate_interval` parameter +- Target board specification with `target` parameter +- Custom font support: + - Regular font with `font_regular` + - Italic font with `font_italic` + - Bold font with `font_bold` + - Semibold font with `font_semibold` + +### Changed + +- Improved type hints using `Union` and `Literal` types + +### Fixed + +- + +## [0.1.0] - Initial Release + +### Added + +- Basic D2 diagram rendering support +- Multiple output formats (svg, png, pdf) +- Theme customization +- Layout engine options +- Platform detection and binary management diff --git a/README.md b/README.md index 820b845..49189a4 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,14 @@ pytest test_d2.py -v - Automatic platform detection and binary management - Support for multiple output formats (svg, png, pdf) -- Theme customization -- Layout engine options +- Theme customization with dark mode support +- Layout engine options (dagre, elk) +- Hand-drawn sketch mode +- SVG enhancements: + - Asset bundling + - Center alignment + - Custom scaling + - Animation support ## Local Development Setup @@ -76,16 +82,33 @@ d2.render("test.d2", "output.svg") ## API Reference +## API Reference + ### D2 Class -#### render(input_file, output_file, **options) -- `input_file`: Path to D2 source file +#### render(input_source, output_file, **options) + +- `input_source`: Path to D2 source file or string content - `output_file`: Path for output file - Options: - `format`: Output format ('svg', 'png', 'pdf'). Default: 'svg' - - `theme`: Theme name ('dark', 'light', etc.). Default: system theme + - `theme`: Theme ID (0-11) or name. Default: system theme + - `dark_theme`: Theme ID for dark mode. Default: None (uses same as light) - `layout`: Layout engine ('dagre', 'elk'). Default: 'dagre' - `pad`: Padding in pixels. Default: 100 + - `sketch`: Render in hand-drawn style. Default: False + - `center`: Center SVG in viewbox. Default: False + - `scale`: Output scaling (-1 for auto). Default: -1 + - `bundle`: Bundle SVG assets. Default: True + - `force_appendix`: Force tooltip appendix. Default: False + - `timeout`: Execution timeout in seconds. Default: 120 + - `animate_interval`: Animation interval in ms. Default: 0 + - `target`: Target board to render. Default: "*" + - Font customization: + - `font_regular`: Path to regular .ttf + - `font_italic`: Path to italic .ttf + - `font_bold`: Path to bold .ttf + - `font_semibold`: Path to semibold .ttf ## License diff --git a/d2_python/__init__.py b/d2_python/__init__.py index 5aa9631..5379182 100644 --- a/d2_python/__init__.py +++ b/d2_python/__init__.py @@ -2,11 +2,21 @@ import platform import subprocess from pathlib import Path -from typing import Optional +from typing import Optional, Union +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal + import tempfile class D2: + """ + Python wrapper for the D2 diagram scripting language. + Supports multiple output formats, themes, and layout options. + """ + def __init__(self): system = platform.system().lower() if system == "linux": @@ -31,10 +41,23 @@ def __init__(self): def render(self, input_source: str, output_file: str, - format: str = "svg", - theme: Optional[str] = None, - layout: str = "dagre", - pad: int = 100) -> None: + format: Literal["svg", "png", "pdf"] = "svg", + theme: Optional[Union[int, str]] = None, + layout: Literal["dagre", "elk"] = "dagre", + pad: int = 100, + dark_theme: Optional[int] = None, + sketch: bool = False, + center: bool = False, + scale: float = -1, + bundle: bool = True, + force_appendix: bool = False, + timeout: int = 120, + animate_interval: int = 0, + target: str = "*", + font_regular: Optional[str] = None, + font_italic: Optional[str] = None, + font_bold: Optional[str] = None, + font_semibold: Optional[str] = None) -> None: """ Render D2 diagram to specified format. @@ -42,18 +65,67 @@ def render(self, input_source: Input D2 file path or string content output_file: Output file path format: Output format (svg, png, pdf) - theme: Theme name (dark, light) + theme: Theme ID (0-11) or name. See https://github.com/terrastruct/d2/tree/master/d2themes + dark_theme: Theme ID to use when in dark mode. -1 uses the same theme as light mode layout: Layout engine (dagre, elk) pad: Padding in pixels + sketch: Render the diagram to look like it was sketched by hand + center: Center the SVG in the containing viewbox + scale: Scale the output. -1 means SVGs fit to screen, others use default size + bundle: When outputting SVG, bundle all assets and layers into the output file + force_appendix: Force addition of appendix for tooltips and links in SVG exports + timeout: Maximum number of seconds D2 runs before timing out + animate_interval: Milliseconds between transitions when using multiple boards (SVG only) + target: Target board to render. Use '*' for all scenarios, '' for root only + font_regular: Path to .ttf file for regular font + font_italic: Path to .ttf file for italic font + font_bold: Path to .ttf file for bold font + font_semibold: Path to .ttf file for semibold font """ cmd = [self.binary_path] - if theme: - cmd.extend(["--theme", theme]) + if theme is not None: + cmd.extend(["--theme", str(theme)]) + + if dark_theme is not None: + cmd.extend(["--dark-theme", str(dark_theme)]) cmd.extend(["--layout", layout]) cmd.extend(["--pad", str(pad)]) + if sketch: + cmd.append("--sketch") + + if center: + cmd.append("--center") + + if scale != -1: + cmd.extend(["--scale", str(scale)]) + + if not bundle: + cmd.extend(["--bundle", "false"]) + + if force_appendix: + cmd.append("--force-appendix") + + if timeout != 120: + cmd.extend(["--timeout", str(timeout)]) + + if animate_interval > 0: + cmd.extend(["--animate-interval", str(animate_interval)]) + + if target != "*": + cmd.extend(["--target", target]) + + for font_type, font_path in [ + ("regular", font_regular), + ("italic", font_italic), + ("bold", font_bold), + ("semibold", font_semibold) + ]: + if font_path: + cmd.extend([f"--font-{font_type}", str(font_path)]) + if format != "svg": cmd.extend(["--format", format]) diff --git a/pyproject.toml b/pyproject.toml index cf929dd..6989b8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "d2-python-wrapper" -version = "0.1.0" +version = "0.2.0" description = "Python wrapper for D2 diagram tool" authors = [{ name = "Diego Carrasco G." }] readme = "README.md" @@ -14,4 +14,8 @@ requires-python = ">=3.7" include = ["d2_python*"] [tool.setuptools.package-data] -d2_python = ["bin/linux/*", "bin/win32/*", "bin/darwin/*"] \ No newline at end of file +d2_python = ["bin/linux/*", "bin/win32/*", "bin/darwin/*"] + +[tool.d2] +# Track D2 binary version separately +binary_version = "v0.6.8" diff --git a/setup.py b/setup.py index 894e973..9ad98c5 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="d2-python", - version="0.1.0", + version="0.2.0", packages=find_packages(), package_data={ "d2_python": [