svg-ultralight 0.50.1__tar.gz → 0.51.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.

Files changed (34) hide show
  1. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/PKG-INFO +1 -1
  2. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/pyproject.toml +2 -2
  3. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/attrib_hints.py +3 -2
  4. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/padded_text_initializers.py +61 -9
  5. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/constructors/new_element.py +8 -3
  6. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/font_tools/font_info.py +5 -2
  7. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/layout.py +2 -1
  8. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/transformations.py +2 -2
  9. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/README.md +0 -0
  10. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/__init__.py +0 -0
  11. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/animate.py +0 -0
  12. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/__init__.py +0 -0
  13. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/bound_helpers.py +0 -0
  14. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/supports_bounds.py +0 -0
  15. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/type_bound_collection.py +0 -0
  16. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/type_bound_element.py +0 -0
  17. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/type_bounding_box.py +0 -0
  18. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/bounding_boxes/type_padded_text.py +0 -0
  19. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/constructors/__init__.py +0 -0
  20. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/font_tools/__init__.py +0 -0
  21. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/font_tools/comp_results.py +0 -0
  22. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/image_ops.py +0 -0
  23. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/inkscape.py +0 -0
  24. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/main.py +0 -0
  25. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/metadata.py +0 -0
  26. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/nsmap.py +0 -0
  27. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/py.typed +0 -0
  28. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/query.py +0 -0
  29. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/read_svg.py +0 -0
  30. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/root_elements.py +0 -0
  31. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/string_conversion.py +0 -0
  32. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/strings/__init__.py +0 -0
  33. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/strings/svg_strings.py +0 -0
  34. {svg_ultralight-0.50.1 → svg_ultralight-0.51.0}/src/svg_ultralight/unit_conversion.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: svg-ultralight
3
- Version: 0.50.1
3
+ Version: 0.51.0
4
4
  Summary: a sensible way to create svg files with Python
5
5
  Author: Shay Hill
6
6
  Author-email: Shay Hill <shay_public@hotmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "svg-ultralight"
3
- version = "0.50.1"
3
+ version = "0.51.0"
4
4
  description = "a sensible way to create svg files with Python"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -33,7 +33,7 @@ dev = [
33
33
 
34
34
  [tool.commitizen]
35
35
  name = "cz_conventional_commits"
36
- version = "0.50.1"
36
+ version = "0.51.0"
37
37
  tag_format = "$version"
38
38
  major-version-zero = true
39
39
  version_files = ["pyproject.toml:^version"]
@@ -5,9 +5,10 @@
5
5
  """
6
6
 
7
7
  from collections.abc import Mapping
8
+ from typing import TypeAlias
8
9
 
9
10
  # Types svg_ultralight can format to pass through to lxml constructors.
10
- ElemAttrib = str | float | None
11
+ ElemAttrib: TypeAlias = str | float | None
11
12
 
12
13
  # Type for an optional dictionary of element attributes.
13
- OptionalElemAttribMapping = Mapping[str, ElemAttrib] | None
14
+ OptionalElemAttribMapping: TypeAlias = Mapping[str, ElemAttrib] | None
@@ -23,11 +23,12 @@ to 16px.
23
23
  from __future__ import annotations
24
24
 
25
25
  from copy import deepcopy
26
- from typing import TYPE_CHECKING
26
+ from typing import TYPE_CHECKING, overload
27
27
 
28
28
  from svg_ultralight.bounding_boxes.type_padded_text import PaddedText
29
29
  from svg_ultralight.constructors import new_element, update_element
30
30
  from svg_ultralight.font_tools.font_info import (
31
+ FTFontInfo,
31
32
  get_padded_text_info,
32
33
  get_svg_font_attributes,
33
34
  )
@@ -99,6 +100,7 @@ def pad_text(
99
100
  return PaddedText(text_elem, bbox, tpad, rpad, bpad, lpad)
100
101
 
101
102
 
103
+ @overload
102
104
  def pad_text_ft(
103
105
  font: str | os.PathLike[str],
104
106
  text: str,
@@ -109,11 +111,38 @@ def pad_text_ft(
109
111
  y_bounds_reference: str | None = None,
110
112
  attrib: OptionalElemAttribMapping = None,
111
113
  **attributes: ElemAttrib,
112
- ) -> PaddedText:
114
+ ) -> PaddedText: ...
115
+
116
+
117
+ @overload
118
+ def pad_text_ft(
119
+ font: str | os.PathLike[str],
120
+ text: list[str],
121
+ font_size: float | None = None,
122
+ ascent: float | None = None,
123
+ descent: float | None = None,
124
+ *,
125
+ y_bounds_reference: str | None = None,
126
+ attrib: OptionalElemAttribMapping = None,
127
+ **attributes: ElemAttrib,
128
+ ) -> list[PaddedText]: ...
129
+
130
+
131
+ def pad_text_ft(
132
+ font: str | os.PathLike[str],
133
+ text: str | list[str],
134
+ font_size: float | None = None,
135
+ ascent: float | None = None,
136
+ descent: float | None = None,
137
+ *,
138
+ y_bounds_reference: str | None = None,
139
+ attrib: OptionalElemAttribMapping = None,
140
+ **attributes: ElemAttrib,
141
+ ) -> PaddedText | list[PaddedText]:
113
142
  """Create a new PaddedText instance using fontTools.
114
143
 
115
144
  :param font: path to a font file.
116
- :param text: the text of the text element.
145
+ :param text: the text of the text element or a list of text strings.
117
146
  :param font_size: the font size to use.
118
147
  :param ascent: the ascent of the font. If not provided, it will be calculated
119
148
  from the font file.
@@ -130,7 +159,8 @@ def pad_text_ft(
130
159
  :param attributes: additional attributes to set on the text element. There is a
131
160
  chance these will cause the font element to exceed the BoundingBox of the
132
161
  PaddedText instance.
133
- :return: a PaddedText instance with a line_gap defined.
162
+ :return: a PaddedText instance with a line_gap defined. If a list of strings is
163
+ given for parameter `text`, a list of PaddedText instances is returned.
134
164
  """
135
165
  attributes.update(attrib or {})
136
166
  attributes_ = format_attr_dict(**attributes)
@@ -142,11 +172,33 @@ def pad_text_ft(
142
172
  _ = attributes_.pop("font-weight", None)
143
173
  _ = attributes_.pop("font-stretch", None)
144
174
 
145
- info = get_padded_text_info(
146
- font, text, font_size, ascent, descent, y_bounds_reference=y_bounds_reference
147
- )
148
- elem = info.new_element(**attributes_)
149
- return PaddedText(elem, info.bbox, *info.padding, info.line_gap)
175
+ font_info = FTFontInfo(font)
176
+
177
+ try:
178
+ input_one_text_item = False
179
+ if isinstance(text, str):
180
+ input_one_text_item = True
181
+ text = [text]
182
+
183
+ elems: list[PaddedText] = []
184
+ for text_item in text:
185
+ text_info = get_padded_text_info(
186
+ font_info,
187
+ text_item,
188
+ font_size,
189
+ ascent,
190
+ descent,
191
+ y_bounds_reference=y_bounds_reference,
192
+ )
193
+ elem = text_info.new_element(**attributes_)
194
+ elems.append(
195
+ PaddedText(elem, text_info.bbox, *text_info.padding, text_info.line_gap)
196
+ )
197
+ finally:
198
+ font_info.font.close()
199
+ if input_one_text_item:
200
+ return elems[0]
201
+ return elems
150
202
 
151
203
 
152
204
  def pad_text_mix(
@@ -13,14 +13,16 @@ from __future__ import annotations
13
13
 
14
14
  import copy
15
15
  import warnings
16
- from typing import TYPE_CHECKING
16
+ from typing import TYPE_CHECKING, cast
17
17
 
18
18
  from lxml import etree
19
19
 
20
20
  from svg_ultralight.string_conversion import set_attributes
21
21
 
22
22
  if TYPE_CHECKING:
23
- from lxml.etree import QName
23
+ from lxml.etree import (
24
+ QName,
25
+ )
24
26
  from lxml.etree import (
25
27
  _Element as EtreeElement, # pyright: ignore[reportPrivateUsage]
26
28
  )
@@ -78,7 +80,10 @@ def new_sub_element(
78
80
  >>> etree.tostring(parent)
79
81
  b'<g><rect/></g>'
80
82
  """
81
- elem = etree.SubElement(parent, tag)
83
+ elem = cast(
84
+ "EtreeElement",
85
+ etree.SubElement(parent, tag), # pyright: ignore[reportUnknownMemberType]
86
+ )
82
87
  set_attributes(elem, **attributes)
83
88
  return elem
84
89
 
@@ -644,7 +644,7 @@ def get_font_size_given_height(font: str | os.PathLike[str], height: float) -> f
644
644
 
645
645
 
646
646
  def get_padded_text_info(
647
- font: str | os.PathLike[str],
647
+ font: str | os.PathLike[str] | FTFontInfo,
648
648
  text: str,
649
649
  font_size: float | None = None,
650
650
  ascent: float | None = None,
@@ -669,7 +669,10 @@ def get_padded_text_info(
669
669
  :return: A FTTextInfo object with the information necessary to create a
670
670
  PaddedText instance: bbox, tpad, rpad, bpad, lpad.
671
671
  """
672
- font_info = FTFontInfo(font)
672
+ if isinstance(font, FTFontInfo):
673
+ font_info = font
674
+ else:
675
+ font_info = FTFontInfo(font)
673
676
  if y_bounds_reference:
674
677
  capline_info = FTTextInfo(font_info, y_bounds_reference, font_size)
675
678
  ascent = -capline_info.bbox.y
@@ -7,11 +7,12 @@
7
7
  from __future__ import annotations
8
8
 
9
9
  from collections.abc import Sequence
10
+ from typing import TypeAlias
10
11
 
11
12
  from svg_ultralight.string_conversion import format_number
12
13
  from svg_ultralight.unit_conversion import Measurement, MeasurementArg
13
14
 
14
- PadArg = float | str | Measurement | Sequence[float | str | Measurement]
15
+ PadArg: TypeAlias = float | str | Measurement | Sequence[float | str | Measurement]
15
16
 
16
17
 
17
18
  def expand_pad_arg(pad: PadArg) -> tuple[float, float, float, float]:
@@ -9,7 +9,7 @@ from __future__ import annotations
9
9
  import numbers
10
10
  import re
11
11
  from contextlib import suppress
12
- from typing import TYPE_CHECKING, cast
12
+ from typing import TYPE_CHECKING, TypeAlias, cast
13
13
 
14
14
  from svg_ultralight.strings import svg_matrix
15
15
 
@@ -21,7 +21,7 @@ if TYPE_CHECKING:
21
21
 
22
22
  RE_MATRIX = re.compile(r"matrix\(([^)]+)\)")
23
23
 
24
- _Matrix = tuple[float, float, float, float, float, float]
24
+ _Matrix: TypeAlias = tuple[float, float, float, float, float, float]
25
25
 
26
26
 
27
27
  def mat_dot(mat1: _Matrix, mat2: _Matrix) -> _Matrix: