Skip to content

Commit

Permalink
feat: add markdown/code shape support
Browse files Browse the repository at this point in the history
  • Loading branch information
MrBlenny committed Dec 29, 2022
1 parent 1a613bd commit 4ee2a6c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ See the [tests](/tests/test_py_d2) for more detailed usage examples.
- [x] Containers (nodes/links in nodes)
- [x] Shapes in shapes
- [x] Arrow directions
- [ ] Markdown / block strings / code in shapes
- [x] Markdown / block strings / code in shapes
- [ ] Icons in shapes
- [ ] SQL table shapes
- [ ] Class shapes
Expand Down
2 changes: 1 addition & 1 deletion graph.d2
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ shape_name2: {
fill: blue
}
}
shape_name1 -> shape_name2
shape_name1 -> shape_name2
37 changes: 36 additions & 1 deletion src/py_d2/D2Shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from py_d2.D2Style import D2Style
from py_d2.helpers import add_label_and_properties
from py_d2.helpers import flatten
from py_d2.helpers import indent


class Shape(Enum):
Expand Down Expand Up @@ -37,6 +38,28 @@ class Shape(Enum):
sequence_diagram = "sequence_diagram"


class D2Text:
def __init__(
self,
# The actual text body (multiline is fine)
text: str,
# The format, eg) md, tex, html, css etc
format: str,
# The number of pipes to use
pipes: int = 1,
):
self.text = text
self.format = format
self.pipes = pipes

def lines(self) -> List[str]:
sep = "|" * self.pipes
return [f"{sep}{self.format}", *self.text.split("\n"), sep]

def __repr__(self) -> str:
return "\n".join(self.lines())


class D2Shape:
def __init__(
self,
Expand All @@ -53,6 +76,7 @@ def __init__(
connections: Optional[List[D2Connection]] = None,
# A shape this is near
near: Optional[str] = None,
**kwargs: D2Text,
):
self.name = name
self.label = label
Expand All @@ -61,6 +85,7 @@ def __init__(
self.style = style
self.connections = connections or []
self.near = near
self.kwargs = kwargs

def add_shape(self, shape: D2Shape):
self.shapes.append(shape)
Expand All @@ -82,11 +107,21 @@ def lines(self) -> List[str]:
if self.style:
properties += self.style.lines()

for key, value in self.kwargs.items():
other_property = value.lines()
other_property_line_1 = other_property[0]
other_property_lines_other = other_property[1:-1]
other_property_line_end = other_property[-1]
properties += [
f"{key}: {other_property_line_1}",
*indent(other_property_lines_other),
other_property_line_end,
]

lines = add_label_and_properties(self.name, self.label, properties)

return lines

def __repr__(self) -> str:
lines = self.lines()
return "\n".join(lines)
return "\n".join(lines)
56 changes: 55 additions & 1 deletion tests/test_py_d2/test_d2_shape.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from py_d2.D2Connection import D2Connection
from py_d2.D2Shape import D2Shape
from py_d2.D2Shape import D2Text
from py_d2.D2Shape import Shape
from py_d2.D2Style import D2Style

Expand Down Expand Up @@ -137,6 +138,59 @@ def test_d2_shape_shapes():
assert str(shape_classs) == "shape_name: {\n shape: class\n}"
assert str(shape_sequence_diagram) == "shape_name: {\n shape: sequence_diagram\n}"


def test_d2_shape_near():
shape = D2Shape(name="shape_name", near="some_other_shape")
assert str(shape) == "shape_name: {\n near: some_other_shape\n}"
assert str(shape) == "shape_name: {\n near: some_other_shape\n}"


def test_d2_shape_other_properties():
text = "Some text"
shape = D2Shape(name="shape_name", thing=D2Text(text=text, format="md"))
assert str(shape) == "\n".join(["shape_name: {", " thing: |md", " Some text", " |", "}"])


def test_d2_shape_other_properties_multi_line():
text = "\n".join(["multiline text", "like this", "works too"])
shape = D2Shape(name="shape_name", thing=D2Text(text=text, format="md"))
assert str(shape) == "\n".join(
["shape_name: {", " thing: |md", " multiline text", " like this", " works too", " |", "}"]
)


def test_d2_shape_other_properties_can_be_anything():
text = "\n".join(["multiline text", "like this", "works too"])
shape = D2Shape(
name="shape_name", description=D2Text(text=text, format="md"), other_thing=D2Text(text=text, format="md")
)
assert str(shape) == "\n".join(
[
"shape_name: {",
" description: |md",
" multiline text",
" like this",
" works too",
" |",
" other_thing: |md",
" multiline text",
" like this",
" works too",
" |",
"}",
]
)


def test_d2_shape_text_can_specify_pipe_count():
text = "const iLoveTypescript = 1 || true;\nconst really = () => iLoveTypescript"
shape = D2Shape(name="shape_name", code=D2Text(text=text, format="ts", pipes=3))
assert str(shape) == "\n".join(
[
"shape_name: {",
" code: |||ts",
" const iLoveTypescript = 1 || true;",
" const really = () => iLoveTypescript",
" |||",
"}",
]
)

0 comments on commit 4ee2a6c

Please sign in to comment.