svg-ultralight 0.31.0__tar.gz → 0.32.1__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.

Files changed (51) hide show
  1. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/.pre-commit-config.yaml +7 -7
  2. {svg_ultralight-0.31.0/src/svg_ultralight.egg-info → svg_ultralight-0.32.1}/PKG-INFO +1 -1
  3. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/pyproject.toml +2 -2
  4. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/__init__.py +2 -0
  5. svg_ultralight-0.32.1/src/svg_ultralight/import_svg.py +50 -0
  6. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/layout.py +1 -1
  7. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1/src/svg_ultralight.egg-info}/PKG-INFO +1 -1
  8. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight.egg-info/SOURCES.txt +4 -1
  9. svg_ultralight-0.32.1/tests/resources/arrow.svg +21 -0
  10. svg_ultralight-0.32.1/tests/test_import_svg.py +32 -0
  11. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/.gitignore +0 -0
  12. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/README.md +0 -0
  13. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/setup.cfg +0 -0
  14. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/animate.py +0 -0
  15. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/__init__.py +0 -0
  16. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/bound_helpers.py +0 -0
  17. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/supports_bounds.py +0 -0
  18. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/type_bound_collection.py +0 -0
  19. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/type_bound_element.py +0 -0
  20. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/type_bounding_box.py +0 -0
  21. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/bounding_boxes/type_padded_text.py +0 -0
  22. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/constructors/__init__.py +0 -0
  23. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/constructors/new_element.py +0 -0
  24. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/inkscape.py +0 -0
  25. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/main.py +0 -0
  26. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/metadata.py +0 -0
  27. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/nsmap.py +0 -0
  28. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/py.typed +0 -0
  29. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/query.py +0 -0
  30. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/root_elements.py +0 -0
  31. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/string_conversion.py +0 -0
  32. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/strings/__init__.py +0 -0
  33. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/strings/svg_strings.py +0 -0
  34. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/transformations.py +0 -0
  35. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight/unit_conversion.py +0 -0
  36. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight.egg-info/dependency_links.txt +0 -0
  37. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight.egg-info/requires.txt +0 -0
  38. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/src/svg_ultralight.egg-info/top_level.txt +0 -0
  39. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/__init__.py +0 -0
  40. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/conftest.py +0 -0
  41. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_bounding.py +0 -0
  42. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_inkscape.py +0 -0
  43. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_layout.py +0 -0
  44. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_matrices.py +0 -0
  45. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_metadata.py +0 -0
  46. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_new_element.py +0 -0
  47. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_queries.py +0 -0
  48. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_root_elements.py +0 -0
  49. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_string_conversion.py +0 -0
  50. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tests/test_svg_ultralight.py +0 -0
  51. {svg_ultralight-0.31.0 → svg_ultralight-0.32.1}/tox.ini +0 -0
@@ -6,7 +6,7 @@ exclude: "tests"
6
6
  repos:
7
7
 
8
8
  - repo: https://github.com/pre-commit/pre-commit-hooks
9
- rev: v4.5.0
9
+ rev: v4.6.0
10
10
  hooks:
11
11
  - id: check-added-large-files
12
12
  - id: check-ast
@@ -42,7 +42,7 @@ repos:
42
42
  # files: .pre-commit-config.yaml
43
43
 
44
44
  - repo: https://github.com/pre-commit/mirrors-mypy
45
- rev: v1.8.0
45
+ rev: v1.10.0
46
46
  hooks:
47
47
  - id: mypy
48
48
  name: mypy
@@ -64,21 +64,21 @@ repos:
64
64
  args: ["--profile", "black", "--filter-files", "--combine-as"]
65
65
 
66
66
  - repo: https://github.com/psf/black
67
- rev: 24.1.1
67
+ rev: 24.4.2
68
68
  hooks:
69
69
  - id: black
70
70
  language_version: python3.9
71
71
  args: ["--skip-magic-trailing-comma"]
72
72
 
73
73
  - repo: https://github.com/asottile/pyupgrade
74
- rev: v3.15.0
74
+ rev: v3.15.2
75
75
  hooks:
76
76
  - args:
77
77
  - --py39-plus
78
78
  id: pyupgrade
79
79
 
80
80
  - repo: https://github.com/Lucas-C/pre-commit-hooks
81
- rev: v1.5.4
81
+ rev: v1.5.5
82
82
  hooks:
83
83
  - id: remove-tabs
84
84
 
@@ -134,7 +134,7 @@ repos:
134
134
  # D407 [*] Missing dashed underline after section ("Attributes")
135
135
  # D406 [*] Section name should end with a newline ("Attributes")
136
136
  # S320 Using `lxml` to parse untrusted data is known to be vulnerable to XML attacks
137
- rev: 'v0.1.15'
137
+ rev: 'v0.4.6'
138
138
  hooks:
139
139
  - id: ruff
140
140
  exclude: "tests"
@@ -146,6 +146,6 @@ repos:
146
146
 
147
147
  # reads pyproject.toml for additional config
148
148
  - repo: https://github.com/RobertCraigie/pyright-python
149
- rev: v1.1.349
149
+ rev: v1.1.365
150
150
  hooks:
151
151
  - id: pyright
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: svg-ultralight
3
- Version: 0.31.0
3
+ Version: 0.32.1
4
4
  Summary: a sensible way to create svg files with Python
5
5
  Author-email: Shay Hill <shay_public@hotmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "svg-ultralight"
3
- version = "0.31.0"
3
+ version = "0.32.1"
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" }
@@ -37,7 +37,7 @@ legacy_tox_ini = """
37
37
 
38
38
  [tool.commitizen]
39
39
  name = "cz_conventional_commits"
40
- version = "0.31.0"
40
+ version = "0.32.1"
41
41
  tag_format = "$version"
42
42
  version_files = ["pyproject.toml:^version"]
43
43
  annotated_tag = true
@@ -20,6 +20,7 @@ from svg_ultralight.constructors.new_element import (
20
20
  new_sub_element,
21
21
  update_element,
22
22
  )
23
+ from svg_ultralight.import_svg import import_svg
23
24
  from svg_ultralight.inkscape import (
24
25
  write_pdf,
25
26
  write_pdf_from_svg,
@@ -57,6 +58,7 @@ __all__ = [
57
58
  "format_number",
58
59
  "format_numbers",
59
60
  "format_numbers_in_string",
61
+ "import_svg",
60
62
  "mat_apply",
61
63
  "mat_dot",
62
64
  "mat_invert",
@@ -0,0 +1,50 @@
1
+ """Import an svg file as a BoundElement.
2
+
3
+ :author: Shay Hill
4
+ :created: 2024-05-28
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ from lxml import etree
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.constructors import new_element
16
+
17
+ if TYPE_CHECKING:
18
+ import os
19
+
20
+ from lxml.etree import _Element as EtreeElement # type: ignore
21
+
22
+
23
+ def _get_bounds_from_viewbox(root: EtreeElement) -> BoundingBox:
24
+ """Get the BoundingBox from the viewbox attribute of the root element.
25
+
26
+ :param root: The root element of the svg.
27
+ :return: The BoundingBox of the svg.
28
+ """
29
+ viewbox = root.attrib.get("viewBox")
30
+ if viewbox is None:
31
+ msg = "SVG file has no viewBox attribute. Failed to create BoundingBox."
32
+ raise ValueError(msg)
33
+ x, y, width, height = map(float, viewbox.split())
34
+ return BoundingBox(x, y, width, height)
35
+
36
+
37
+ def import_svg(svg: str | os.PathLike[str]) -> BoundElement:
38
+ """Import an svg file as a BoundElement.
39
+
40
+ :param svg: The path to the svg file.
41
+ :return: The BoundElement representation of the svg.
42
+
43
+ The viewbox of the svg is used to create the BoundingBox of the BoundElement.
44
+ """
45
+ tree = etree.parse(svg)
46
+ root = tree.getroot()
47
+ bbox = _get_bounds_from_viewbox(root)
48
+ root_as_elem = new_element("g")
49
+ root_as_elem.extend(root)
50
+ return BoundElement(root_as_elem, bbox)
@@ -99,7 +99,7 @@ def _infer_scale(
99
99
  * print_h == 0 / viewbox_h > 0
100
100
 
101
101
  The print area is invalid, but there is special handling for this. Interpret
102
- viewbox units as print_w.native_unit and determe print area from viewbox area 1
102
+ viewbox units as print_w.native_unit and determine print area from viewbox area 1
103
103
  to 1.
104
104
 
105
105
  >>> _infer_scale(Measurement("in"), Measurement("in"), 1, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: svg-ultralight
3
- Version: 0.31.0
3
+ Version: 0.32.1
4
4
  Summary: a sensible way to create svg files with Python
5
5
  Author-email: Shay Hill <shay_public@hotmail.com>
6
6
  License: MIT
@@ -5,6 +5,7 @@ pyproject.toml
5
5
  tox.ini
6
6
  src/svg_ultralight/__init__.py
7
7
  src/svg_ultralight/animate.py
8
+ src/svg_ultralight/import_svg.py
8
9
  src/svg_ultralight/inkscape.py
9
10
  src/svg_ultralight/layout.py
10
11
  src/svg_ultralight/main.py
@@ -35,6 +36,7 @@ src/svg_ultralight/strings/svg_strings.py
35
36
  tests/__init__.py
36
37
  tests/conftest.py
37
38
  tests/test_bounding.py
39
+ tests/test_import_svg.py
38
40
  tests/test_inkscape.py
39
41
  tests/test_layout.py
40
42
  tests/test_matrices.py
@@ -43,4 +45,5 @@ tests/test_new_element.py
43
45
  tests/test_queries.py
44
46
  tests/test_root_elements.py
45
47
  tests/test_string_conversion.py
46
- tests/test_svg_ultralight.py
48
+ tests/test_svg_ultralight.py
49
+ tests/resources/arrow.svg
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" viewBox="-3 -3 128 128">
2
+ <defs>
3
+ <clipPath id="clip">
4
+ <path d="M0,122L0,103.7L40.666667,73.2L81.333333,79.3L99.556877,49.231152L122,12.2L122,122Z"/>
5
+ </clipPath>
6
+ <mask id="mask">
7
+ <g>
8
+ <rect x="0" y="0" width="122" height="122" fill="#FFFFFF"/>
9
+ <path d="M0,91.45Q0,91.2 0.2,91.05L37.845867,62.8156Q38.013194,62.690105 38.220037,62.721131L75.903051,68.373583Q76.232274,68.422967 76.40482,68.138266L90.745748,44.475734Q91.004899,44.048135 90.5773,43.788984L78.917555,36.722472Q78.176932,36.273609 78.935969,35.856642L121.240962,12.616967Q122,12.2 121.981585,13.06583L120.955238,61.322866Q120.936823,62.188695 120.1962,61.739833L108.536455,54.67332Q108.108856,54.41417 107.849705,54.841768L86.606939,89.892332Q86.434393,90.177033 86.10517,90.12765L43.526984,83.740922Q43.32014,83.709895 43.152813,83.83539L0.8,115.6Q0,116.2 0,115.2Z" fill="#000000" stroke="#000000" stroke-width="3.1"/>
10
+ </g>
11
+ </mask>
12
+ </defs>
13
+ <g clip-path="url(#clip)" mask="url(#mask)">
14
+ <rect x="0" y="0" width="23.6" height="122" fill="orange"/>
15
+ <rect x="24.6" y="0" width="23.6" height="122" fill="orange"/>
16
+ <rect x="49.2" y="0" width="23.6" height="122" fill="orange"/>
17
+ <rect x="73.8" y="0" width="23.6" height="122" fill="orange"/>
18
+ <rect x="98.4" y="0" width="23.6" height="122" fill="orange"/>
19
+ </g>
20
+ <path d="M0,91.45Q0,91.2 0.2,91.05L37.845867,62.8156Q38.013194,62.690105 38.220037,62.721131L75.903051,68.373583Q76.232274,68.422967 76.40482,68.138266L90.745748,44.475734Q91.004899,44.048135 90.5773,43.788984L78.917555,36.722472Q78.176932,36.273609 78.935969,35.856642L121.240962,12.616967Q122,12.2 121.981585,13.06583L120.955238,61.322866Q120.936823,62.188695 120.1962,61.739833L108.536455,54.67332Q108.108856,54.41417 107.849705,54.841768L86.606939,89.892332Q86.434393,90.177033 86.10517,90.12765L43.526984,83.740922Q43.32014,83.709895 43.152813,83.83539L0.8,115.6Q0,116.2 0,115.2Z" fill="#00bfff" stroke="none"/>
21
+ </svg>
@@ -0,0 +1,32 @@
1
+ """Test importing an SVG file.
2
+
3
+ :author: Shay Hill
4
+ :created: 2024-05-28
5
+ """
6
+
7
+ from pathlib import Path
8
+ from svg_ultralight.import_svg import import_svg
9
+ from lxml import etree
10
+
11
+ _TEST_RESOURCES = Path(__file__).parent / "resources"
12
+ _TEST_FILE = _TEST_RESOURCES / "arrow.svg"
13
+
14
+
15
+
16
+ class TestImportSvg:
17
+ def test_get_bbox(self):
18
+ """Import an svg file as a BoundElement instance."""
19
+ blem = import_svg(_TEST_FILE)
20
+ assert blem.bbox.x == -3
21
+ assert blem.bbox.y == -3
22
+ assert blem.bbox.width == 128
23
+ assert blem.bbox.height == 128
24
+
25
+ def test_get_geometry(self):
26
+ tree = etree.parse(_TEST_FILE)
27
+ root = tree.getroot()
28
+ blem = import_svg(_TEST_FILE)
29
+ assert [x.tag for x in blem.elem] == [x.tag for x in root]
30
+
31
+
32
+
File without changes