svg-ultralight 0.25.0__tar.gz → 0.27.0__tar.gz
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.
Potentially problematic release.
This version of svg-ultralight might be problematic. Click here for more details.
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/PKG-INFO +1 -1
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/pyproject.toml +6 -2
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/__init__.py +10 -0
- svg_ultralight-0.27.0/src/svg_ultralight/bounding_boxes/bound_helpers.py +95 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/type_bounding_box.py +0 -7
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/root_elements.py +3 -11
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/string_conversion.py +9 -6
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/PKG-INFO +1 -1
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/SOURCES.txt +1 -1
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_inkscape.py +1 -4
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_queries.py +1 -10
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_root_elements.py +33 -5
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_string_conversion.py +32 -0
- svg-ultralight-0.25.0/dev-requirements.txt +0 -102
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/.pre-commit-config.yaml +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/README.md +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/setup.cfg +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/animate.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/__init__.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/supports_bounds.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/type_bound_element.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/type_padded_text.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/constructors/__init__.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/constructors/new_element.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/inkscape.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/layout.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/main.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/metadata.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/nsmap.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/py.typed +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/query.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/strings/__init__.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/strings/svg_strings.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/unit_conversion.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/dependency_links.txt +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/requires.txt +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/top_level.txt +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/__init__.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/conftest.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_layout.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_metadata.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_new_element.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tests/test_svg_ultralight.py +0 -0
- {svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "svg-ultralight"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.27.0"
|
|
4
4
|
description = "a sensible way to create svg files with Python"
|
|
5
5
|
authors = [{ name = "Shay Hill", email = "shay_public@hotmail.com" }]
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -20,6 +20,10 @@ build-backend = "setuptools.build_meta"
|
|
|
20
20
|
addopts = "--doctest-modules"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
[tool.isort]
|
|
24
|
+
profile = "black"
|
|
25
|
+
|
|
26
|
+
|
|
23
27
|
[tool.tox]
|
|
24
28
|
legacy_tox_ini = """
|
|
25
29
|
[tox]
|
|
@@ -33,7 +37,7 @@ legacy_tox_ini = """
|
|
|
33
37
|
|
|
34
38
|
[tool.commitizen]
|
|
35
39
|
name = "cz_conventional_commits"
|
|
36
|
-
version = "0.
|
|
40
|
+
version = "0.27.0"
|
|
37
41
|
tag_format = "$version"
|
|
38
42
|
version_files = ["pyproject.toml:^version"]
|
|
39
43
|
annotated_tag = true
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
:created: 12/22/2019.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from svg_ultralight.bounding_boxes.bound_helpers import (
|
|
8
|
+
new_bbox_union,
|
|
9
|
+
new_bound_union,
|
|
10
|
+
new_element_union,
|
|
11
|
+
)
|
|
7
12
|
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
8
13
|
from svg_ultralight.bounding_boxes.type_bound_element import BoundElement
|
|
9
14
|
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
@@ -27,6 +32,7 @@ from svg_ultralight.nsmap import NSMAP, new_qname
|
|
|
27
32
|
from svg_ultralight.query import pad_text
|
|
28
33
|
from svg_ultralight.root_elements import new_svg_root_around_bounds
|
|
29
34
|
from svg_ultralight.string_conversion import (
|
|
35
|
+
format_attr_dict,
|
|
30
36
|
format_number,
|
|
31
37
|
format_numbers,
|
|
32
38
|
format_numbers_in_string,
|
|
@@ -39,10 +45,14 @@ __all__ = [
|
|
|
39
45
|
"PaddedText",
|
|
40
46
|
"SupportsBounds",
|
|
41
47
|
"deepcopy_element",
|
|
48
|
+
"format_attr_dict",
|
|
42
49
|
"format_number",
|
|
43
50
|
"format_numbers",
|
|
44
51
|
"format_numbers_in_string",
|
|
52
|
+
"new_bbox_union",
|
|
53
|
+
"new_bound_union",
|
|
45
54
|
"new_element",
|
|
55
|
+
"new_element_union",
|
|
46
56
|
"new_metadata",
|
|
47
57
|
"new_qname",
|
|
48
58
|
"new_sub_element",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Helper functions for dealing with BoundElements.
|
|
2
|
+
|
|
3
|
+
:author: Shay Hill
|
|
4
|
+
:created: 2024-05-03
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from lxml.etree import _Element as EtreeElement # type: ignore
|
|
12
|
+
|
|
13
|
+
from svg_ultralight.bounding_boxes.type_bound_element import BoundElement
|
|
14
|
+
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
15
|
+
from svg_ultralight.bounding_boxes.type_padded_text import PaddedText
|
|
16
|
+
from svg_ultralight.constructors import new_element
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def new_element_union(
|
|
23
|
+
*elems: EtreeElement | SupportsBounds, **attributes: float | str
|
|
24
|
+
) -> EtreeElement:
|
|
25
|
+
"""Get the union of any elements found in the given arguments.
|
|
26
|
+
|
|
27
|
+
:param elems: BoundElements, PaddedTexts, or EtreeElements.
|
|
28
|
+
Other arguments will be ignored.
|
|
29
|
+
:return: a new group element containing all elements.
|
|
30
|
+
|
|
31
|
+
This does not support consolidating attributes. E.g., if all elements have the
|
|
32
|
+
same fill color, this will not be recognized and consilidated into a single
|
|
33
|
+
attribute for the group. Too many attributes change their behavior when applied
|
|
34
|
+
to a group.
|
|
35
|
+
"""
|
|
36
|
+
elements_found: list[EtreeElement] = []
|
|
37
|
+
for elem in elems:
|
|
38
|
+
if isinstance(elem, (BoundElement, PaddedText)):
|
|
39
|
+
elements_found.append(elem.elem)
|
|
40
|
+
elif isinstance(elem, EtreeElement):
|
|
41
|
+
elements_found.append(elem)
|
|
42
|
+
|
|
43
|
+
if not elements_found:
|
|
44
|
+
msg = (
|
|
45
|
+
"Cannot find any elements to union. "
|
|
46
|
+
+ "At least one argument must be a "
|
|
47
|
+
+ "BoundElement, PaddedText, or EtreeElement."
|
|
48
|
+
)
|
|
49
|
+
raise ValueError(msg)
|
|
50
|
+
group = new_element("g", **attributes)
|
|
51
|
+
group.extend(elements_found)
|
|
52
|
+
return group
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def new_bbox_union(*blems: SupportsBounds | EtreeElement) -> BoundingBox:
|
|
56
|
+
"""Get the union of the bounding boxes of the given elements.
|
|
57
|
+
|
|
58
|
+
:param blems: BoundElements, BoundingBoxes, or PaddedTexts.
|
|
59
|
+
Other arguments will be ignored.
|
|
60
|
+
:return: the union of all bounding boxes as a BoundingBox instance.
|
|
61
|
+
|
|
62
|
+
Will used the padded_box attribute of PaddedText instances.
|
|
63
|
+
"""
|
|
64
|
+
bboxes: list[BoundingBox] = []
|
|
65
|
+
for blem in blems:
|
|
66
|
+
if isinstance(blem, BoundingBox):
|
|
67
|
+
bboxes.append(blem)
|
|
68
|
+
elif isinstance(blem, BoundElement):
|
|
69
|
+
bboxes.append(blem.bbox)
|
|
70
|
+
elif isinstance(blem, PaddedText):
|
|
71
|
+
bboxes.append(blem.padded_bbox)
|
|
72
|
+
|
|
73
|
+
if not bboxes:
|
|
74
|
+
msg = (
|
|
75
|
+
"Cannot find any bounding boxes to union. "
|
|
76
|
+
+ "At least one argument must be a "
|
|
77
|
+
+ "BoundElement, BoundingBox, or PaddedText."
|
|
78
|
+
)
|
|
79
|
+
raise ValueError(msg)
|
|
80
|
+
|
|
81
|
+
return BoundingBox.merged(*bboxes)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def new_bound_union(*blems: SupportsBounds | EtreeElement) -> BoundElement:
|
|
85
|
+
"""Get the union of the bounding boxes of the given elements.
|
|
86
|
+
|
|
87
|
+
:param blems: BoundElements or EtreeElements.
|
|
88
|
+
At least one argument must be a BoundElement, BoundingBox, or PaddedText.
|
|
89
|
+
:return: the union of all arguments as a BoundElement instance.
|
|
90
|
+
|
|
91
|
+
Will used the padded_box attribute of PaddedText instances.
|
|
92
|
+
"""
|
|
93
|
+
group = new_element_union(*blems)
|
|
94
|
+
bbox = new_bbox_union(*blems)
|
|
95
|
+
return BoundElement(group, bbox)
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import warnings
|
|
10
9
|
from dataclasses import dataclass
|
|
11
10
|
|
|
12
11
|
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
@@ -286,12 +285,6 @@ class BoundingBox(SupportsBounds):
|
|
|
286
285
|
:return: a bounding box around self and other bounding boxes
|
|
287
286
|
:raises DeprecationWarning:
|
|
288
287
|
"""
|
|
289
|
-
warnings.warn(
|
|
290
|
-
"Method a.merge(b, c) is deprecated. "
|
|
291
|
-
+ "Use classmethod BoundingBox.merged(a, b, c) instead.",
|
|
292
|
-
category=DeprecationWarning,
|
|
293
|
-
stacklevel=1,
|
|
294
|
-
)
|
|
295
288
|
return BoundingBox.merged(self, *others)
|
|
296
289
|
|
|
297
290
|
@classmethod
|
|
@@ -8,9 +8,8 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
|
-
from svg_ultralight.bounding_boxes
|
|
11
|
+
from svg_ultralight.bounding_boxes import bound_helpers as bound
|
|
12
12
|
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
13
|
-
from svg_ultralight.bounding_boxes.type_padded_text import PaddedText
|
|
14
13
|
from svg_ultralight.main import new_svg_root
|
|
15
14
|
|
|
16
15
|
if TYPE_CHECKING:
|
|
@@ -64,15 +63,8 @@ def new_svg_root_around_bounds(
|
|
|
64
63
|
:return: root svg element
|
|
65
64
|
:raise ValueError: if no bounding boxes are found in bounded
|
|
66
65
|
"""
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
bboxes += [x.padded_bbox for x in bounded if isinstance(x, PaddedText)]
|
|
70
|
-
|
|
71
|
-
if not bboxes:
|
|
72
|
-
msg = "no bounding boxes found"
|
|
73
|
-
raise ValueError(msg)
|
|
74
|
-
|
|
75
|
-
viewbox = _viewbox_args_from_bboxes(*bboxes)
|
|
66
|
+
bbox = bound.new_bbox_union(*bounded)
|
|
67
|
+
viewbox = _viewbox_args_from_bboxes(bbox)
|
|
76
68
|
return new_svg_root(
|
|
77
69
|
x_=viewbox["x_"],
|
|
78
70
|
y_=viewbox["y_"],
|
|
@@ -79,15 +79,18 @@ def format_numbers_in_string(data: float | str) -> str:
|
|
|
79
79
|
:return: string with floats formatted to limited precision
|
|
80
80
|
|
|
81
81
|
Works as a more robust version of format_number. Will correctly handle input
|
|
82
|
-
floats in exponential notation. This should work for
|
|
83
|
-
svg except 'text'
|
|
84
|
-
'ice3.14bucket', because 'e3.14' will
|
|
85
|
-
will not have such strings, but the
|
|
86
|
-
not handle that case. Do not attempt
|
|
82
|
+
floats in exponential notation. This should work for any parameter value in an
|
|
83
|
+
svg except 'text', 'id' and for any other value except hex color codes. The
|
|
84
|
+
function will fail with input strings like 'ice3.14bucket', because 'e3.14' will
|
|
85
|
+
be identified as a float. SVG param values will not have such strings, but the
|
|
86
|
+
'text' attribute could. This function will not handle that case. Do not attempt
|
|
87
|
+
to reformat 'text' attribute values.
|
|
87
88
|
"""
|
|
88
89
|
with suppress(ValueError):
|
|
89
90
|
# try as a regular number to strip spaces from simple float strings
|
|
90
91
|
return format_number(data)
|
|
92
|
+
if str(data).startswith("#"):
|
|
93
|
+
return str(data)
|
|
91
94
|
words = re.split(r"([^\d.eE-]+)", str(data))
|
|
92
95
|
words = [format_number(w) if _is_float_or_float_str(w) else w for w in words]
|
|
93
96
|
return "".join(words)
|
|
@@ -123,7 +126,7 @@ def _fix_key_and_format_val(key: str, val: str | float) -> tuple[str, str]:
|
|
|
123
126
|
else:
|
|
124
127
|
key_ = key.rstrip("_").replace("_", "-")
|
|
125
128
|
|
|
126
|
-
if key_
|
|
129
|
+
if key_ in {"id", "text"}:
|
|
127
130
|
return key_, str(val)
|
|
128
131
|
|
|
129
132
|
return key_, format_numbers_in_string(val)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
.pre-commit-config.yaml
|
|
2
2
|
README.md
|
|
3
|
-
dev-requirements.txt
|
|
4
3
|
pyproject.toml
|
|
5
4
|
tox.ini
|
|
6
5
|
src/svg_ultralight/__init__.py
|
|
@@ -21,6 +20,7 @@ src/svg_ultralight.egg-info/dependency_links.txt
|
|
|
21
20
|
src/svg_ultralight.egg-info/requires.txt
|
|
22
21
|
src/svg_ultralight.egg-info/top_level.txt
|
|
23
22
|
src/svg_ultralight/bounding_boxes/__init__.py
|
|
23
|
+
src/svg_ultralight/bounding_boxes/bound_helpers.py
|
|
24
24
|
src/svg_ultralight/bounding_boxes/supports_bounds.py
|
|
25
25
|
src/svg_ultralight/bounding_boxes/type_bound_element.py
|
|
26
26
|
src/svg_ultralight/bounding_boxes/type_bounding_box.py
|
|
@@ -17,10 +17,7 @@ from svg_ultralight.inkscape import convert_text_to_path
|
|
|
17
17
|
from svg_ultralight.main import new_svg_root
|
|
18
18
|
from svg_ultralight.nsmap import NSMAP
|
|
19
19
|
|
|
20
|
-
INKSCAPE = Path(
|
|
21
|
-
r"C:\\Program Files\\WindowsApps\\25415Inkscape.Inkscape_1.3.2.0"
|
|
22
|
-
+ "_x64__9waqn51p1ttv2\\VFS\\ProgramFilesX64\\Inkscape\\bin\\inkscape.exe"
|
|
23
|
-
)
|
|
20
|
+
INKSCAPE = Path(r"C:\Program Files\Inkscape\bin\inkscape")
|
|
24
21
|
|
|
25
22
|
if not INKSCAPE.with_suffix(".exe").exists():
|
|
26
23
|
msg = "Inkscape not found. Please install Inkscape or update the INKSCAPE path var."
|
|
@@ -17,10 +17,7 @@ from svg_ultralight import new_svg_root
|
|
|
17
17
|
from svg_ultralight.constructors import new_sub_element
|
|
18
18
|
from svg_ultralight.query import BoundingBox, map_ids_to_bounding_boxes
|
|
19
19
|
|
|
20
|
-
INKSCAPE = Path(
|
|
21
|
-
r"C:\\Program Files\\WindowsApps\\25415Inkscape.Inkscape_1.3.2.0"
|
|
22
|
-
+ "_x64__9waqn51p1ttv2\\VFS\\ProgramFilesX64\\Inkscape\\bin\\inkscape.exe"
|
|
23
|
-
)
|
|
20
|
+
INKSCAPE = Path(r"C:\Program Files\Inkscape\bin\inkscape")
|
|
24
21
|
|
|
25
22
|
if not INKSCAPE.with_suffix(".exe").exists():
|
|
26
23
|
msg = "Inkscape not found. Please install Inkscape or update the INKSCAPE path var."
|
|
@@ -28,12 +25,6 @@ if not INKSCAPE.with_suffix(".exe").exists():
|
|
|
28
25
|
|
|
29
26
|
|
|
30
27
|
class TestMergeBoundingBoxes:
|
|
31
|
-
def test_merge_deprecation_warning(self):
|
|
32
|
-
bbox_a = BoundingBox(-2, -4, 10, 20)
|
|
33
|
-
bbox_b = BoundingBox(0, 0, 10, 10)
|
|
34
|
-
assert pytest.warns(DeprecationWarning, BoundingBox.merge, bbox_a, bbox_b)
|
|
35
|
-
with pytest.warns(DeprecationWarning):
|
|
36
|
-
assert bbox_a.merge(bbox_b) == BoundingBox.merged(bbox_a, bbox_b)
|
|
37
28
|
|
|
38
29
|
def test_new_merged_bbox(self):
|
|
39
30
|
bbox_a = BoundingBox(-2, -4, 10, 20)
|
|
@@ -6,15 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
-
from svg_ultralight.main import new_svg_root
|
|
10
|
-
from svg_ultralight.bounding_boxes.supports_bounds import SupportsBounds
|
|
11
9
|
from svg_ultralight.bounding_boxes.type_bounding_box import BoundingBox
|
|
12
10
|
from svg_ultralight.bounding_boxes.type_bound_element import BoundElement
|
|
13
11
|
from svg_ultralight.bounding_boxes.type_padded_text import PaddedText
|
|
14
12
|
from svg_ultralight.constructors import new_element
|
|
15
13
|
from svg_ultralight.root_elements import new_svg_root_around_bounds
|
|
14
|
+
from svg_ultralight.bounding_boxes.bound_helpers import new_bound_union
|
|
16
15
|
from lxml.etree import _Element as EtreeElement # type: ignore
|
|
17
|
-
from typing import Union
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
class TestNewSvgRootAroundBounds:
|
|
@@ -23,13 +21,13 @@ class TestNewSvgRootAroundBounds:
|
|
|
23
21
|
"""Raise ValueError if no bounding boxes found."""
|
|
24
22
|
with pytest.raises(ValueError) as excinfo:
|
|
25
23
|
_ = new_svg_root_around_bounds()
|
|
26
|
-
assert "
|
|
24
|
+
assert "At least one argument" in str(excinfo.value)
|
|
27
25
|
|
|
28
26
|
def test_no_bound_elements(self):
|
|
29
27
|
"""Raise ValueError if no BoundElements found."""
|
|
30
28
|
with pytest.raises(ValueError) as excinfo:
|
|
31
29
|
_ = new_svg_root_around_bounds(new_element("g"))
|
|
32
|
-
assert "
|
|
30
|
+
assert "At least one argument" in str(excinfo.value)
|
|
33
31
|
|
|
34
32
|
def test_bounding_boxes(self):
|
|
35
33
|
"""Create svg root element from bounding boxes."""
|
|
@@ -53,3 +51,33 @@ class TestNewSvgRootAroundBounds:
|
|
|
53
51
|
result = new_svg_root_around_bounds(*args)
|
|
54
52
|
assert isinstance(result, EtreeElement)
|
|
55
53
|
assert result.attrib["viewBox"] == "0 0 201 201"
|
|
54
|
+
|
|
55
|
+
class TestNewBoundUnion:
|
|
56
|
+
|
|
57
|
+
def test_bounding_boxes_only(self):
|
|
58
|
+
"""Raise an error if no elements found."""
|
|
59
|
+
bboxes = [BoundingBox(0, 0, 100, 100), BoundingBox(50, 50, 150, 150)]
|
|
60
|
+
with pytest.raises(ValueError) as excinfo:
|
|
61
|
+
_ = new_bound_union(*bboxes)
|
|
62
|
+
assert "must be a BoundElement, PaddedText, or Etree" in str(excinfo.value)
|
|
63
|
+
|
|
64
|
+
def test_elements_only(self):
|
|
65
|
+
"""Raise an error if no elements found."""
|
|
66
|
+
elems = [new_element("g"), new_element("g")]
|
|
67
|
+
with pytest.raises(ValueError) as excinfo:
|
|
68
|
+
_ = new_bound_union(*elems)
|
|
69
|
+
assert "must be a BoundElement, BoundingBox, or Padded" in str(excinfo.value)
|
|
70
|
+
|
|
71
|
+
def test_bound_elements(self):
|
|
72
|
+
"""Create svg root element from BoundElements."""
|
|
73
|
+
bboxes = [BoundingBox(0, 0, 100, 100), BoundingBox(50, 50, 150, 150)]
|
|
74
|
+
args = bboxes[0], BoundElement(new_element("g"), bboxes[1])
|
|
75
|
+
result = new_bound_union(*args)
|
|
76
|
+
assert isinstance(result, BoundElement)
|
|
77
|
+
|
|
78
|
+
def test_padded_text(self):
|
|
79
|
+
"""Create svg root element from BoundElements."""
|
|
80
|
+
bboxes = [BoundingBox(0, 0, 100, 100), BoundingBox(50, 50, 150, 150)]
|
|
81
|
+
args = bboxes[0], PaddedText(new_element("g"), bboxes[1], 1, 1, 1, 1)
|
|
82
|
+
result = new_bound_union(*args)
|
|
83
|
+
assert isinstance(result, BoundElement)
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
:created: 2023-09-23
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
# pyright: reportPrivateUsage=false
|
|
8
|
+
|
|
7
9
|
import svg_ultralight.string_conversion as mod
|
|
8
10
|
|
|
9
11
|
|
|
@@ -27,6 +29,36 @@ class TestFormatNumbers:
|
|
|
27
29
|
assert mod.format_numbers([1, 2, 3]) == ["1", "2", "3"]
|
|
28
30
|
|
|
29
31
|
|
|
32
|
+
class TestFormatNumbersInString:
|
|
33
|
+
def test_empty(self):
|
|
34
|
+
"""Return empty string."""
|
|
35
|
+
assert mod.format_numbers_in_string("") == ""
|
|
36
|
+
|
|
37
|
+
def test_no_numbers(self):
|
|
38
|
+
"""Return string with no changes."""
|
|
39
|
+
assert mod.format_numbers_in_string("hello") == "hello"
|
|
40
|
+
|
|
41
|
+
def test_numbers(self):
|
|
42
|
+
"""Return string with numbers formatted."""
|
|
43
|
+
assert mod.format_numbers_in_string("1.0000000001") == "1"
|
|
44
|
+
|
|
45
|
+
def test_skip_text(self):
|
|
46
|
+
"""Skip text."""
|
|
47
|
+
key = "text"
|
|
48
|
+
val = "1.000000000000000000"
|
|
49
|
+
assert mod._fix_key_and_format_val(key, val) == (key, val)
|
|
50
|
+
|
|
51
|
+
def test_skip_id(self):
|
|
52
|
+
"""Skip text."""
|
|
53
|
+
key = "id"
|
|
54
|
+
val = "1.000000000000000000"
|
|
55
|
+
assert mod._fix_key_and_format_val(key, val) == (key, val)
|
|
56
|
+
|
|
57
|
+
def test_skip_hex_colors(self):
|
|
58
|
+
"""Skip hex colors."""
|
|
59
|
+
assert mod.format_numbers_in_string("#000000") == "#000000"
|
|
60
|
+
|
|
61
|
+
|
|
30
62
|
class TestFormatAttrDict:
|
|
31
63
|
def test_float(self):
|
|
32
64
|
"""Return string of float."""
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# This file is autogenerated by pip-compile with Python 3.12
|
|
3
|
-
# by the following command:
|
|
4
|
-
#
|
|
5
|
-
# pip-compile --extra=dev --output-file=dev-requirements.txt --strip-extras pyproject.toml
|
|
6
|
-
#
|
|
7
|
-
argcomplete==3.2.3
|
|
8
|
-
# via commitizen
|
|
9
|
-
cachetools==5.3.3
|
|
10
|
-
# via tox
|
|
11
|
-
cfgv==3.4.0
|
|
12
|
-
# via pre-commit
|
|
13
|
-
chardet==5.2.0
|
|
14
|
-
# via tox
|
|
15
|
-
charset-normalizer==3.3.2
|
|
16
|
-
# via commitizen
|
|
17
|
-
colorama==0.4.6
|
|
18
|
-
# via
|
|
19
|
-
# commitizen
|
|
20
|
-
# pytest
|
|
21
|
-
# tox
|
|
22
|
-
commitizen==3.20.0
|
|
23
|
-
# via svg-ultralight (pyproject.toml)
|
|
24
|
-
decli==0.6.1
|
|
25
|
-
# via commitizen
|
|
26
|
-
distlib==0.3.8
|
|
27
|
-
# via virtualenv
|
|
28
|
-
filelock==3.13.1
|
|
29
|
-
# via
|
|
30
|
-
# tox
|
|
31
|
-
# virtualenv
|
|
32
|
-
identify==2.5.35
|
|
33
|
-
# via pre-commit
|
|
34
|
-
importlib-metadata==7.0.2
|
|
35
|
-
# via commitizen
|
|
36
|
-
iniconfig==2.0.0
|
|
37
|
-
# via pytest
|
|
38
|
-
jinja2==3.1.3
|
|
39
|
-
# via commitizen
|
|
40
|
-
lxml==5.1.0
|
|
41
|
-
# via svg-ultralight (pyproject.toml)
|
|
42
|
-
markupsafe==2.1.5
|
|
43
|
-
# via jinja2
|
|
44
|
-
nodeenv==1.8.0
|
|
45
|
-
# via pre-commit
|
|
46
|
-
packaging==24.0
|
|
47
|
-
# via
|
|
48
|
-
# commitizen
|
|
49
|
-
# pyproject-api
|
|
50
|
-
# pytest
|
|
51
|
-
# tox
|
|
52
|
-
paragraphs==0.2.0
|
|
53
|
-
# via svg-ultralight (pyproject.toml)
|
|
54
|
-
pillow==10.2.0
|
|
55
|
-
# via svg-ultralight (pyproject.toml)
|
|
56
|
-
platformdirs==4.2.0
|
|
57
|
-
# via
|
|
58
|
-
# tox
|
|
59
|
-
# virtualenv
|
|
60
|
-
pluggy==1.4.0
|
|
61
|
-
# via
|
|
62
|
-
# pytest
|
|
63
|
-
# tox
|
|
64
|
-
pre-commit==3.6.2
|
|
65
|
-
# via svg-ultralight (pyproject.toml)
|
|
66
|
-
prompt-toolkit==3.0.36
|
|
67
|
-
# via questionary
|
|
68
|
-
pyproject-api==1.6.1
|
|
69
|
-
# via tox
|
|
70
|
-
pytest==8.1.1
|
|
71
|
-
# via svg-ultralight (pyproject.toml)
|
|
72
|
-
pyyaml==6.0.1
|
|
73
|
-
# via
|
|
74
|
-
# commitizen
|
|
75
|
-
# pre-commit
|
|
76
|
-
questionary==2.0.1
|
|
77
|
-
# via commitizen
|
|
78
|
-
termcolor==2.4.0
|
|
79
|
-
# via commitizen
|
|
80
|
-
tomlkit==0.12.4
|
|
81
|
-
# via commitizen
|
|
82
|
-
tox==4.14.1
|
|
83
|
-
# via svg-ultralight (pyproject.toml)
|
|
84
|
-
types-beautifulsoup4==4.12.0.20240229
|
|
85
|
-
# via types-lxml
|
|
86
|
-
types-html5lib==1.1.11.20240228
|
|
87
|
-
# via types-beautifulsoup4
|
|
88
|
-
types-lxml==2024.2.9
|
|
89
|
-
# via svg-ultralight (pyproject.toml)
|
|
90
|
-
typing-extensions==4.10.0
|
|
91
|
-
# via types-lxml
|
|
92
|
-
virtualenv==20.25.1
|
|
93
|
-
# via
|
|
94
|
-
# pre-commit
|
|
95
|
-
# tox
|
|
96
|
-
wcwidth==0.2.13
|
|
97
|
-
# via prompt-toolkit
|
|
98
|
-
zipp==3.18.1
|
|
99
|
-
# via importlib-metadata
|
|
100
|
-
|
|
101
|
-
# The following packages are considered to be unsafe in a requirements file:
|
|
102
|
-
# setuptools
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/__init__.py
RENAMED
|
File without changes
|
{svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/bounding_boxes/supports_bounds.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight/constructors/new_element.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{svg-ultralight-0.25.0 → svg_ultralight-0.27.0}/src/svg_ultralight.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|