pyrbd 0.2.5__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyrbd/block.py +75 -29
- pyrbd/diagram.py +83 -37
- pyrbd/py.typed +0 -0
- {pyrbd-0.2.5.dist-info → pyrbd-0.3.1.dist-info}/METADATA +11 -4
- pyrbd-0.3.1.dist-info/RECORD +8 -0
- pyrbd-0.2.5.dist-info/RECORD +0 -7
- {pyrbd-0.2.5.dist-info → pyrbd-0.3.1.dist-info}/WHEEL +0 -0
- {pyrbd-0.2.5.dist-info → pyrbd-0.3.1.dist-info}/licenses/LICENSE +0 -0
pyrbd/block.py
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
from typing import Optional
|
4
4
|
from itertools import combinations
|
5
5
|
from copy import deepcopy
|
6
|
+
from collections import namedtuple
|
7
|
+
|
8
|
+
|
9
|
+
Padding = namedtuple("Padding", ["n", "e", "s", "w"])
|
6
10
|
|
7
11
|
|
8
12
|
class Block:
|
@@ -40,7 +44,7 @@ class Block:
|
|
40
44
|
"anchor=west",
|
41
45
|
"align=center",
|
42
46
|
"fill={fill_color}",
|
43
|
-
"draw=black",
|
47
|
+
"draw=black!70!gray",
|
44
48
|
"minimum height=1cm",
|
45
49
|
"rounded corners=0.3mm",
|
46
50
|
"inner sep=4pt",
|
@@ -48,6 +52,9 @@ class Block:
|
|
48
52
|
]
|
49
53
|
)
|
50
54
|
|
55
|
+
arrow_options: str = "arrowcolor, thick"
|
56
|
+
arrow_length: float = 0.5
|
57
|
+
|
51
58
|
def __init__(
|
52
59
|
self,
|
53
60
|
text: str,
|
@@ -68,7 +75,13 @@ class Block:
|
|
68
75
|
if self.parent is None:
|
69
76
|
return ""
|
70
77
|
|
71
|
-
return
|
78
|
+
return " ".join(
|
79
|
+
[
|
80
|
+
f"[right={self.arrow_length + self.shift[0]}cm",
|
81
|
+
f"of {self.parent.id},",
|
82
|
+
f"yshift={self.shift[1]}cm]",
|
83
|
+
]
|
84
|
+
)
|
72
85
|
|
73
86
|
def arrow(self, connector_position: float) -> str:
|
74
87
|
"""Get TikZ arrow string.
|
@@ -90,18 +103,18 @@ class Block:
|
|
90
103
|
|
91
104
|
return "".join(
|
92
105
|
[
|
93
|
-
f"\\draw[
|
106
|
+
f"\\draw[{self.arrow_options}, rectangle connector={connector_position}cm]",
|
94
107
|
f"({self.parent.id}.east) to ({self.id}.west);\n\n",
|
95
108
|
]
|
96
109
|
)
|
97
110
|
|
98
|
-
def get_node(self, connector_position: float =
|
111
|
+
def get_node(self, connector_position: Optional[float] = None) -> str:
|
99
112
|
"""Get TikZ node string.
|
100
113
|
|
101
114
|
Parameters
|
102
115
|
----------
|
103
|
-
connector_position : float
|
104
|
-
distance in cm to right angle bend in connector
|
116
|
+
connector_position : Optional[float]
|
117
|
+
distance in cm to right angle bend in connector. Defaults to `0.5*arrow_length`.
|
105
118
|
|
106
119
|
Returns
|
107
120
|
-------
|
@@ -109,6 +122,9 @@ class Block:
|
|
109
122
|
TikZ string for rendering block
|
110
123
|
"""
|
111
124
|
|
125
|
+
if connector_position is None:
|
126
|
+
connector_position = self.arrow_length / 2
|
127
|
+
|
112
128
|
node = "".join(
|
113
129
|
[
|
114
130
|
"% Block\n",
|
@@ -206,6 +222,10 @@ class Series(Block):
|
|
206
222
|
]
|
207
223
|
)
|
208
224
|
|
225
|
+
internal_arrow_length = 0.3
|
226
|
+
pad = Padding(1, 1, 1, 2.5)
|
227
|
+
label_height = 5
|
228
|
+
|
209
229
|
def __init__(
|
210
230
|
self,
|
211
231
|
blocks: list[Block],
|
@@ -217,11 +237,13 @@ class Series(Block):
|
|
217
237
|
|
218
238
|
self.blocks = blocks
|
219
239
|
self.blocks[0].id = f"{self.id}+0"
|
240
|
+
self.blocks[0].shift = (self.internal_arrow_length, 0)
|
220
241
|
for i, (block, new_parent) in enumerate(
|
221
242
|
zip(self.blocks[1::], self.blocks[0:-1]), start=1
|
222
243
|
):
|
223
244
|
block.parent = new_parent
|
224
245
|
block.id = f"{self.id}+{i}"
|
246
|
+
block.arrow_length = self.internal_arrow_length
|
225
247
|
|
226
248
|
@property
|
227
249
|
def background(self) -> str:
|
@@ -230,11 +252,13 @@ class Series(Block):
|
|
230
252
|
if self.color in ("white", ""):
|
231
253
|
return ""
|
232
254
|
|
255
|
+
pad = self.pad
|
256
|
+
|
233
257
|
return "".join(
|
234
258
|
[
|
235
259
|
"\\begin{pgfonlayer}{background}\n",
|
236
|
-
f"\\coordinate (sw) at ($({self.id}.south west)+(-
|
237
|
-
f"\\coordinate (ne) at ($({self.id}.north east)+(
|
260
|
+
f"\\coordinate (sw) at ($({self.id}.south west)+(-{pad.w}mm, -{pad.s}mm)$);\n",
|
261
|
+
f"\\coordinate (ne) at ($({self.id}.north east)+({pad.e}mm, {pad.n}mm)$);\n",
|
238
262
|
f"\\draw[{self.color}, thick] (sw) rectangle (ne);\n",
|
239
263
|
"\\end{pgfonlayer}\n",
|
240
264
|
]
|
@@ -247,24 +271,27 @@ class Series(Block):
|
|
247
271
|
if len(self.text) == 0:
|
248
272
|
return ""
|
249
273
|
|
274
|
+
pad = self.pad
|
275
|
+
|
250
276
|
return "".join(
|
251
277
|
[
|
252
|
-
f"\\coordinate (nw) at ($({self.id}.north west)+(-
|
253
|
-
f"\\coordinate (ne) at ($({self.id}.north east)+(
|
254
|
-
|
278
|
+
f"\\coordinate (nw) at ($({self.id}.north west)+(-{pad.w}mm, {pad.n}mm)$);\n",
|
279
|
+
f"\\coordinate (ne) at ($({self.id}.north east)+({pad.e}mm, {pad.n}mm)$);\n",
|
280
|
+
"\\coordinate (n) at "
|
281
|
+
f"($({self.id}.north)+(0mm, {self.label_height / 2 + pad.n}mm)$);\n",
|
255
282
|
f"\\draw[{self.color}, fill={self.color}!50, thick] (nw) ",
|
256
|
-
"rectangle ($(ne)+(0,
|
257
|
-
f"\\node[anchor=
|
283
|
+
f"rectangle ($(ne)+(0, {self.label_height}mm)$);\n",
|
284
|
+
f"\\node[anchor=center, inner sep=0pt, outer sep=0pt] at (n) {{{self.text}}};\n",
|
258
285
|
]
|
259
286
|
)
|
260
287
|
|
261
|
-
def get_node(self, connector_position: float =
|
288
|
+
def get_node(self, connector_position: Optional[float] = None) -> str:
|
262
289
|
"""Get TikZ node string.
|
263
290
|
|
264
291
|
Parameters
|
265
292
|
----------
|
266
|
-
connector_position : float
|
267
|
-
distance in cm to right angle bend in connector
|
293
|
+
connector_position : Optional[float]
|
294
|
+
distance in cm to right angle bend in connector. Defaults to `0.5 * arrow_length`
|
268
295
|
|
269
296
|
Returns
|
270
297
|
-------
|
@@ -273,12 +300,15 @@ class Series(Block):
|
|
273
300
|
|
274
301
|
"""
|
275
302
|
|
303
|
+
if connector_position is None:
|
304
|
+
connector_position = self.arrow_length / 2
|
305
|
+
|
276
306
|
block_nodes = "\n".join(
|
277
307
|
block.get_node(connector_position) for block in self.blocks
|
278
308
|
)
|
279
309
|
series_node = "".join(
|
280
310
|
[
|
281
|
-
f"\\node[{self.tikz_options}]",
|
311
|
+
f"%%% Series\n\\node[{self.tikz_options}]",
|
282
312
|
f"({self.id})",
|
283
313
|
self.position,
|
284
314
|
"{\\begin{tikzpicture}\n",
|
@@ -320,6 +350,9 @@ class Group(Block):
|
|
320
350
|
"anchor=west",
|
321
351
|
]
|
322
352
|
)
|
353
|
+
internal_arrow_length = 0.3
|
354
|
+
pad = Padding(1, 1, 1, 1)
|
355
|
+
label_height = 5
|
323
356
|
|
324
357
|
def __init__(
|
325
358
|
self,
|
@@ -335,6 +368,7 @@ class Group(Block):
|
|
335
368
|
block.shift = (0, shift)
|
336
369
|
block.parent = self
|
337
370
|
block.id = f"{self.id}-{i}"
|
371
|
+
block.arrow_length = self.internal_arrow_length
|
338
372
|
|
339
373
|
@property
|
340
374
|
def shifts(self) -> list[float]:
|
@@ -357,11 +391,13 @@ class Group(Block):
|
|
357
391
|
if self.color in ("white", ""):
|
358
392
|
return ""
|
359
393
|
|
394
|
+
pad = self.pad
|
395
|
+
|
360
396
|
return "".join(
|
361
397
|
[
|
362
398
|
"\\begin{pgfonlayer}{background}\n",
|
363
|
-
f"\\coordinate (sw) at ($({self.id}.south west)+(-
|
364
|
-
f"\\coordinate (ne) at ($({self.id}.north east)+(
|
399
|
+
f"\\coordinate (sw) at ($({self.id}.south west)+(-{pad.w}mm, -{pad.s}mm)$);\n",
|
400
|
+
f"\\coordinate (ne) at ($({self.id}.north east)+({pad.e}mm, {pad.n}mm)$);\n",
|
365
401
|
f"\\draw[{self.color}, thick] (sw) rectangle (ne);\n",
|
366
402
|
"\\end{pgfonlayer}\n",
|
367
403
|
]
|
@@ -374,14 +410,17 @@ class Group(Block):
|
|
374
410
|
if len(self.text) == 0:
|
375
411
|
return ""
|
376
412
|
|
413
|
+
pad = self.pad
|
414
|
+
|
377
415
|
return "".join(
|
378
416
|
[
|
379
|
-
f"\\coordinate (nw) at ($({self.id}.north west)+(-
|
380
|
-
f"\\coordinate (ne) at ($({self.id}.north east)+(
|
381
|
-
|
417
|
+
f"\\coordinate (nw) at ($({self.id}.north west)+(-{pad.w}mm, {pad.n}mm)$);\n",
|
418
|
+
f"\\coordinate (ne) at ($({self.id}.north east)+({pad.e}mm, {pad.n}mm)$);\n",
|
419
|
+
"\\coordinate (n) at ",
|
420
|
+
f"($({self.id}.north)+(0mm, {self.label_height / 2 + pad.n}mm)$);\n",
|
382
421
|
f"\\draw[{self.color}, fill={self.color}!50, thick] (nw) ",
|
383
|
-
"rectangle ($(ne)+(0,
|
384
|
-
f"\\node[anchor=
|
422
|
+
f"rectangle ($(ne)+(0, {self.label_height}mm)$);\n",
|
423
|
+
f"\\node[anchor=center, inner sep=0pt, outer sep=0pt] at (n) {{{self.text}}};\n",
|
385
424
|
]
|
386
425
|
)
|
387
426
|
|
@@ -402,17 +441,20 @@ class Group(Block):
|
|
402
441
|
if self.parent is None:
|
403
442
|
return ""
|
404
443
|
|
405
|
-
return f"\\draw[
|
444
|
+
return f"\\draw[{self.arrow_options}] ({self.parent.id}.east) to ({self.id}.west);\n"
|
406
445
|
|
407
446
|
@property
|
408
447
|
def arrows(self) -> str:
|
409
448
|
"""Get TikZ string for arrow connecting stacked blocks."""
|
410
449
|
|
450
|
+
scaling = 0.75
|
451
|
+
|
411
452
|
return "\n".join(
|
412
453
|
[
|
413
454
|
" ".join(
|
414
455
|
[
|
415
|
-
"\\draw[
|
456
|
+
f"\\draw[{self.arrow_options},",
|
457
|
+
f"rectangle line={scaling * self.internal_arrow_length}cm]",
|
416
458
|
f"({block1.id}.east) to ({block2.id}.east);\n",
|
417
459
|
]
|
418
460
|
)
|
@@ -420,13 +462,14 @@ class Group(Block):
|
|
420
462
|
]
|
421
463
|
)
|
422
464
|
|
423
|
-
def get_node(self, connector_position: float =
|
465
|
+
def get_node(self, connector_position: Optional[float] = None) -> str:
|
424
466
|
"""Get TikZ node string.
|
425
467
|
|
426
468
|
Parameters
|
427
469
|
----------
|
428
|
-
connector_position : float
|
429
|
-
distance in cm to right angle bend in connector
|
470
|
+
connector_position : Optional[float]
|
471
|
+
distance in cm to right angle bend in connector.
|
472
|
+
Locked to 0.0 for `Group` class
|
430
473
|
|
431
474
|
Returns
|
432
475
|
-------
|
@@ -434,12 +477,15 @@ class Group(Block):
|
|
434
477
|
TikZ string for rendering group
|
435
478
|
"""
|
436
479
|
|
480
|
+
connector_position = 0.0
|
481
|
+
|
437
482
|
block_nodes = "\n".join(
|
438
483
|
block.get_node(connector_position) for block in self.blocks
|
439
484
|
)
|
440
485
|
|
441
486
|
group_node = "".join(
|
442
487
|
[
|
488
|
+
"%%% Group\n"
|
443
489
|
f"\\node[anchor=west, outer sep=0pt, inner sep=0pt, align=center] ({self.id}) ",
|
444
490
|
self.position,
|
445
491
|
"{\\begin{tikzpicture}\n",
|
pyrbd/diagram.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
"""Module containing Diagram class definition."""
|
2
2
|
|
3
|
+
from typing import Optional
|
3
4
|
import subprocess
|
4
5
|
|
5
6
|
import pymupdf
|
@@ -18,12 +19,24 @@ class Diagram:
|
|
18
19
|
list of `Block` instances
|
19
20
|
hazard : str, optional
|
20
21
|
string defining the `hazard` block text
|
22
|
+
colors : dict[str, str], optional
|
23
|
+
dictionary with custom color definitions in HEX format:
|
24
|
+
`{'color name': '6 digit hex code'}`
|
21
25
|
"""
|
22
26
|
|
23
|
-
|
27
|
+
# Default color definitions
|
28
|
+
colors: dict[str, str] = {"arrowcolor": "4c4d4c", "hazardcolor": "ff6666"}
|
29
|
+
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
name: str,
|
33
|
+
blocks: list[Block],
|
34
|
+
hazard: str = "",
|
35
|
+
colors: Optional[dict[str, str]] = None,
|
36
|
+
) -> None:
|
24
37
|
self.filename = name
|
25
38
|
if hazard:
|
26
|
-
self.head = Block(hazard, "
|
39
|
+
self.head = Block(hazard, "hazardcolor")
|
27
40
|
else:
|
28
41
|
self.head = blocks.pop(0)
|
29
42
|
|
@@ -31,11 +44,14 @@ class Diagram:
|
|
31
44
|
self.blocks = blocks
|
32
45
|
self.blocks[0].parent = self.head
|
33
46
|
|
47
|
+
if colors is not None:
|
48
|
+
self.colors = self.colors | colors
|
49
|
+
|
34
50
|
def write(self) -> None:
|
35
51
|
"""Write diagram to .tex file."""
|
36
52
|
|
37
53
|
with open(f"{self.filename}.tex", mode="w", encoding="utf-8") as file:
|
38
|
-
file.write(
|
54
|
+
file.write(tex_preamble(self.colors))
|
39
55
|
for block in [self.head, *self.blocks]:
|
40
56
|
file.write(block.get_node())
|
41
57
|
file.write(TEX_END)
|
@@ -53,7 +69,19 @@ class Diagram:
|
|
53
69
|
page = pdf_document[0]
|
54
70
|
|
55
71
|
# Get and convert page to svg image
|
56
|
-
svg_content = page.get_svg_image()
|
72
|
+
svg_content = page.get_svg_image().splitlines()
|
73
|
+
svg_content.insert(
|
74
|
+
1,
|
75
|
+
"\n".join(
|
76
|
+
[
|
77
|
+
"<style>",
|
78
|
+
" @media (prefers-color-scheme: light) { :root { --color: #000000; } }",
|
79
|
+
" @media (prefers-color-scheme: dark) { :root { --color: #DDDDDD; } }",
|
80
|
+
"</style>",
|
81
|
+
]
|
82
|
+
),
|
83
|
+
)
|
84
|
+
svg_content = "\n".join(svg_content).replace(r"#4c4d4c", "var(--color)")
|
57
85
|
|
58
86
|
# Save to file
|
59
87
|
with open(output_file := f"{self.filename}.svg", "w", encoding="utf-8") as file:
|
@@ -115,7 +143,9 @@ class Diagram:
|
|
115
143
|
"""
|
116
144
|
|
117
145
|
try:
|
118
|
-
subprocess.check_call(
|
146
|
+
subprocess.check_call(
|
147
|
+
["latexmk", "--lualatex", f"{self.filename}.tex", "--silent"]
|
148
|
+
)
|
119
149
|
subprocess.check_call(["latexmk", "-c", f"{self.filename}.tex"])
|
120
150
|
if clear_source:
|
121
151
|
subprocess.check_call(["rm", f"{self.filename}.tex"])
|
@@ -145,38 +175,54 @@ class Diagram:
|
|
145
175
|
return output_files
|
146
176
|
|
147
177
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
178
|
+
def tex_preamble(custom_colors: dict[str, str] | None = None) -> str:
|
179
|
+
"""LaTeX file preamble file with definition of custom colors given in dictionary."""
|
180
|
+
|
181
|
+
color_defs = []
|
182
|
+
if custom_colors is not None:
|
183
|
+
color_defs = [
|
184
|
+
f"\\definecolor{{{color_name}}}{{HTML}}{{{hex_code}}}"
|
185
|
+
for (color_name, hex_code) in custom_colors.items()
|
186
|
+
]
|
187
|
+
|
188
|
+
return "\n".join(
|
189
|
+
[
|
190
|
+
r"\documentclass{standalone}",
|
191
|
+
r"\usepackage[T1]{fontenc}"
|
192
|
+
r"\usepackage{helvet}",
|
193
|
+
r"\renewcommand{\familydefault}{\sfdefault}",
|
194
|
+
r"\usepackage[dvipsnames,svgnames,x11names]{xcolor}",
|
195
|
+
r"\usepackage{tikz}",
|
196
|
+
r"\usetikzlibrary{shapes,arrows,positioning,calc}",
|
197
|
+
r"\pgfdeclarelayer{background}",
|
198
|
+
r"\pgfsetlayers{background, main}",
|
199
|
+
r"\tikzset{",
|
200
|
+
r"connector/.style={",
|
201
|
+
r"-latex,",
|
202
|
+
r"font=\scriptsize},",
|
203
|
+
r"line/.style={",
|
204
|
+
r"font=\scriptsize},",
|
205
|
+
r"rectangle connector/.style={",
|
206
|
+
r"connector,"
|
207
|
+
r"to path={(\tikztostart) -- ++(#1,0pt) \tikztonodes |- (\tikztotarget) },",
|
208
|
+
r"pos=0.5},"
|
209
|
+
r"rectangle connector/.default=0.5cm,",
|
210
|
+
r"rectangle line/.style={",
|
211
|
+
r"line,"
|
212
|
+
r"to path={(\tikztostart) -- ++(#1,0pt) \tikztonodes |- (\tikztotarget) },",
|
213
|
+
r"pos=0.5},"
|
214
|
+
r"rectangle line/.default=0.5cm,",
|
215
|
+
r"straight connector/.style={",
|
216
|
+
r"connector,",
|
217
|
+
r"to path=--(\tikztotarget) \tikztonodes}",
|
218
|
+
r"}",
|
219
|
+
*color_defs,
|
220
|
+
r"\begin{document}",
|
221
|
+
r"\begin{tikzpicture}",
|
222
|
+
"",
|
223
|
+
]
|
224
|
+
)
|
225
|
+
|
180
226
|
|
181
227
|
TEX_END = "\n".join(
|
182
228
|
[
|
pyrbd/py.typed
ADDED
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pyrbd
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.1
|
4
4
|
Summary: Package for creating simple reliability block diagrams (RBDs) using LaTeX and TikZ.
|
5
5
|
Project-URL: Repository, https://github.com/hghugdal/pyrbd
|
6
6
|
Project-URL: Issues, https://github.com/hghugdal/pyrbd/issues
|
@@ -11,12 +11,17 @@ License-File: LICENSE
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
13
13
|
Requires-Python: >=3.10
|
14
|
+
Requires-Dist: pre-commit>=4.3.0
|
14
15
|
Requires-Dist: pymupdf>=1.26.3
|
15
16
|
Description-Content-Type: text/markdown
|
16
17
|
|
17
|
-
# <img alt="pyRBDlogo" src=docs/images/logo.svg width=40 align=top> pyRBD
|
18
|
+
# <img alt="pyRBDlogo" src="https://raw.githubusercontent.com/hghugdal/pyrbd/23d7f00ca74e8465df3760821488b4bb78df803c/docs/images/logo.svg" width=40 align=top> pyRBD
|
18
19
|
|
19
|
-
|
20
|
+
[](https://pypi.org/project/pyrbd/)
|
21
|
+
<img alt="Python" src="https://img.shields.io/badge/Python->= 3.10-blue?logo=python&link=None">
|
22
|
+
<img alt="Tests" src="https://img.shields.io/badge/Tests-Passing-darkgreen?logo=pytest&link=None">
|
23
|
+
<img alt="Coverage" src="https://img.shields.io/badge/Coverage-100%25-darkgreen?link=None">
|
24
|
+
<img alt="Pylint" src="https://img.shields.io/badge/Pylint-10%2F10-darkgreen?link=None">
|
20
25
|
|
21
26
|
A Python package for creating simple reliability block diagrams (RBDs) using `LaTeX` and [`TikZ`](https://en.wikipedia.org/wiki/PGF/TikZ).
|
22
27
|
|
@@ -25,6 +30,7 @@ A Python package for creating simple reliability block diagrams (RBDs) using `La
|
|
25
30
|
|
26
31
|
## Simple example diagram
|
27
32
|
The blocks of the RBD are defined using `Block`, `Series` and `Group`, and the diagram itself is handled by the `Diagram` class. A simple example is given by the code
|
33
|
+
|
28
34
|
```python linenums="1"
|
29
35
|
from pyrbd import Block, Diagram
|
30
36
|
|
@@ -39,7 +45,8 @@ diagram = Diagram(
|
|
39
45
|
diagram.write()
|
40
46
|
diagram.compile()
|
41
47
|
```
|
48
|
+
|
42
49
|
producing the following diagram
|
43
|
-
<div><img src="docs/examples/simple_RBD.svg" width=500/></div>
|
50
|
+
<div><img src="https://raw.githubusercontent.com/hghugdal/pyrbd/e11808e9a40c902f0e1c2c2b0b42ca0d90170cd1/docs/examples/simple_RBD.svg" width=500/></div>
|
44
51
|
|
45
52
|
For more examples, visit the [documentation](https://hghugdal.github.io/pyrbd/).
|
@@ -0,0 +1,8 @@
|
|
1
|
+
pyrbd/__init__.py,sha256=mpsb022BX9eDGSBhuYIr2gOr4sg_M9sYbPGHLPIdvl0,219
|
2
|
+
pyrbd/block.py,sha256=l44FYLS9zQbyblDsVUb9GwvsFm_sU1IamlpbrjryVbw,13786
|
3
|
+
pyrbd/diagram.py,sha256=YiU2tslUh4HbtuVP2dXSsVQFKpOjLl_ArSYjCSiQoks,6806
|
4
|
+
pyrbd/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
pyrbd-0.3.1.dist-info/METADATA,sha256=_IHhEyyaEaLB7lg1iicfWM4lZWg97I4wskgq3OuDqjc,2402
|
6
|
+
pyrbd-0.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
+
pyrbd-0.3.1.dist-info/licenses/LICENSE,sha256=mxXMgWpFgk71JpEEElFrb9FJxeoaDgvrU8gjUUU9LzA,1069
|
8
|
+
pyrbd-0.3.1.dist-info/RECORD,,
|
pyrbd-0.2.5.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
pyrbd/__init__.py,sha256=mpsb022BX9eDGSBhuYIr2gOr4sg_M9sYbPGHLPIdvl0,219
|
2
|
-
pyrbd/block.py,sha256=ETRZJeEUU4OPk0qGo6zZIsaR1oLkyDPf1kelfuKWNsc,12219
|
3
|
-
pyrbd/diagram.py,sha256=NVAsdfmqAu6-6J2mT5Gp2W_8a9WsI2iMbKjcEI6QFlE,5092
|
4
|
-
pyrbd-0.2.5.dist-info/METADATA,sha256=WN1raYOu5KJtH5wj-7b1P8wH8-1GGHmnnqvwrt5hmZs,2196
|
5
|
-
pyrbd-0.2.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
-
pyrbd-0.2.5.dist-info/licenses/LICENSE,sha256=mxXMgWpFgk71JpEEElFrb9FJxeoaDgvrU8gjUUU9LzA,1069
|
7
|
-
pyrbd-0.2.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|