decksmith 0.1.6__py3-none-any.whl → 0.1.8__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.
decksmith/card_builder.py CHANGED
@@ -7,7 +7,7 @@ import operator
7
7
  import pandas as pd
8
8
  from PIL import Image, ImageDraw, ImageFont
9
9
  from .utils import get_wrapped_text, apply_anchor
10
- from .validate import validate_card
10
+ from .validate import validate_card, transform_card
11
11
 
12
12
 
13
13
  class CardBuilder:
@@ -32,6 +32,9 @@ class CardBuilder:
32
32
  self.card = Image.new("RGBA", (width, height), bg_color)
33
33
  self.draw = ImageDraw.Draw(self.card, "RGBA")
34
34
  self.element_positions = {}
35
+ # Store position if id is provided
36
+ if "id" in spec:
37
+ self.element_positions[self.spec["id"]] = (0, 0, width, height)
35
38
 
36
39
  def _calculate_absolute_position(self, element: dict) -> tuple:
37
40
  """
@@ -585,6 +588,7 @@ class CardBuilder:
585
588
  Args:
586
589
  output_path (str): The path where the card image will be saved.
587
590
  """
591
+ self.spec = transform_card(self.spec)
588
592
  validate_card(self.spec)
589
593
 
590
594
  for el in self.spec.get("elements", []):
decksmith/validate.py CHANGED
@@ -5,79 +5,80 @@ Python module for validating a dictionar
5
5
  from jval import validate
6
6
 
7
7
  ELEMENT_SPEC = {
8
- "?*id": "<str>",
9
- "*type": "<str>",
10
- "?*position": ["<float>"],
11
- "?*relative_to": ["<str>"],
12
- "?*anchor": "<str>",
8
+ "?*id": "<?str>",
9
+ "*type": "<?str>",
10
+ "?*position": ["<?float>"],
11
+ "?*relative_to": ["<?str>"],
12
+ "?*anchor": "<?str>",
13
13
  }
14
14
 
15
15
  SPECS_FOR_TYPE = {
16
16
  "text": {
17
- "*text": "<str>",
18
- "?*color": ["<int>"],
19
- "?*font_path": "<str>",
20
- "?*font_size": "<int>",
21
- "?*font_variant": "<str>",
22
- "?*line_spacing": "<int>",
23
- "?*width": "<int>",
24
- "?*align": "<str>",
25
- "?*stroke_width": "<int>",
26
- "?*stroke_color": ["<int>"],
17
+ "*text": "<?str>",
18
+ "?*color": ["<?int>"],
19
+ "?*font_path": "<?str>",
20
+ "?*font_size": "<?int>",
21
+ "?*font_variant": "<?str>",
22
+ "?*line_spacing": "<?int>",
23
+ "?*width": "<?int>",
24
+ "?*align": "<?str>",
25
+ "?*stroke_width": "<?int>",
26
+ "?*stroke_color": ["<?int>"],
27
27
  },
28
28
  "image": {
29
- "*path": "<str>",
29
+ "*path": "<?str>",
30
30
  "?*filters": {
31
- "?*crop_top": "<int>",
32
- "?*crop_bottom": "<int>",
33
- "?*crop_left": "<int>",
34
- "?*crop_right": "<int>",
35
- "?*crop_box": ["<int>"],
36
- "?*rotate": "<int>",
37
- "?*flip": "<str>",
31
+ "?*crop_top": "<?int>",
32
+ "?*crop_bottom": "<?int>",
33
+ "?*crop_left": "<?int>",
34
+ "?*crop_right": "<?int>",
35
+ "?*crop_box": ["<?int>"],
36
+ "?*rotate": "<?int>",
37
+ "?*flip": "<?str>",
38
38
  "?*resize": ["<?int>"],
39
39
  },
40
40
  },
41
41
  "circle": {
42
- "*radius": "<int>",
43
- "?*color": ["<int>"],
44
- "?*outline_color": ["<int>"],
45
- "?*outline_width": "<int>",
42
+ "*radius": "<?int>",
43
+ "?*color": ["<?int>"],
44
+ "?*outline_color": ["<?int>"],
45
+ "?*outline_width": "<?int>",
46
46
  },
47
47
  "ellipse": {
48
- "*size": ["<int>"],
49
- "?*color": ["<int>"],
50
- "?*outline_color": ["<int>"],
51
- "?*outline_width": "<int>",
48
+ "*size": ["<?int>"],
49
+ "?*color": ["<?int>"],
50
+ "?*outline_color": ["<?int>"],
51
+ "?*outline_width": "<?int>",
52
52
  },
53
53
  "polygon": {
54
- "*points": [["<int>"]],
55
- "?*color": ["<int>"],
56
- "?*outline_color": ["<int>"],
57
- "?*outline_width": "<int>",
54
+ "*points": [["<?int>"]],
55
+ "?*color": ["<?int>"],
56
+ "?*outline_color": ["<?int>"],
57
+ "?*outline_width": "<?int>",
58
58
  },
59
59
  "regular-polygon": {
60
- "*radius": "<int>",
61
- "*sides": "<int>",
62
- "?*rotation": "<int>",
63
- "?*color": ["<int>"],
64
- "?*outline_color": ["<int>"],
65
- "?*outline_width": "<int>",
60
+ "*radius": "<?int>",
61
+ "*sides": "<?int>",
62
+ "?*rotation": "<?int>",
63
+ "?*color": ["<?int>"],
64
+ "?*outline_color": ["<?int>"],
65
+ "?*outline_width": "<?int>",
66
66
  },
67
67
  "rectangle": {
68
- "*size": ["<int>"],
69
- "?*corners": ["<bool>"],
70
- "?*corner_radius": "<int>",
71
- "?*color": ["<int>"],
72
- "?*outline_color": ["<int>"],
73
- "?*outline_width": "<int>",
68
+ "*size": ["<?int>"],
69
+ "?*corners": ["<?bool>"],
70
+ "?*corner_radius": "<?int>",
71
+ "?*color": ["<?int>"],
72
+ "?*outline_color": ["<?int>"],
73
+ "?*outline_width": "<?int>",
74
74
  },
75
75
  }
76
76
 
77
77
  CARD_SPEC = {
78
- "*width": "<int>",
79
- "*height": "<int>",
80
- "?*background_color": ["<int>"],
78
+ "?*id": "<?str>",
79
+ "*width": "<?int>",
80
+ "*height": "<?int>",
81
+ "?*background_color": ["<?int>"],
81
82
  "*elements": [],
82
83
  }
83
84
 
@@ -106,3 +107,19 @@ def validate_card(card):
106
107
  for element in card["elements"]:
107
108
  # print(f"DEBUG: {element['type']}")
108
109
  validate_element(element, element["type"])
110
+
111
+
112
+ def transform_card(card):
113
+ """
114
+ Perform certain automatic type casts on the card and its
115
+ elements. For example, cast the "text" property of elements
116
+ of type "text" to str, to support painting numbers as text.
117
+ Args:
118
+ card (dict): The card.
119
+ Return:
120
+ dict: The transformed card with all automatic casts applied.
121
+ """
122
+ for element in card.get("elements", []):
123
+ if element.get("type") == "text" and "text" in element:
124
+ element["text"] = str(element["text"])
125
+ return card
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: decksmith
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: A command-line application to dynamically generate decks of cards from a JSON specification and a CSV data file, inspired by nandeck.
5
5
  License: GPL-2.0-only
6
6
  Author: Julio Cabria
@@ -1,13 +1,13 @@
1
1
  decksmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- decksmith/card_builder.py,sha256=rAUPKvto3no9BRxaBoWvaPl7lAbUd93q7yYCJqIx84g,25311
2
+ decksmith/card_builder.py,sha256=oXD6XvtbNaUW-WF47v6y7GjIyg_g2giu4SEEEqq8D_c,25521
3
3
  decksmith/deck_builder.py,sha256=8YK4ds51-z9f-BUyQ8jyh15BY9f16UQBYFI6Z87yFfU,3415
4
4
  decksmith/export.py,sha256=aMMoGdBDQ-Gr4QJ_ziiV3F673kEyXzM0phVq14uDDJg,6225
5
5
  decksmith/main.py,sha256=AzDq1aXziQmYz2IWdWSoBFskUeAXfOmcfYnIQUNIYp0,3357
6
6
  decksmith/templates/deck.csv,sha256=pNJebNxoDIfM8m0-aj05YrANHih1BTKOMry1kspIpPI,462
7
7
  decksmith/templates/deck.json,sha256=BTTnmaFP5AkbbC_B7uMF6R4bOM7JizW6EATcsjjJrT4,695
8
8
  decksmith/utils.py,sha256=XKSapVB1_zZvYcl3LgZcHAob4Pk5HUT9AnlAQBAdeTs,2833
9
- decksmith/validate.py,sha256=mvWQd2c6SvoIe4r8z04SMdCqa0WyZKPq6lT_qZNUTbU,2830
10
- decksmith-0.1.6.dist-info/entry_points.txt,sha256=-usRztjj2gnfmPubb8nFYHD22drzThAmSfM6geWI98Y,48
11
- decksmith-0.1.6.dist-info/METADATA,sha256=lVO53XymZRHeZ0y097Gxwz0-913Z-2nPrJpjBns6h0U,2419
12
- decksmith-0.1.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
13
- decksmith-0.1.6.dist-info/RECORD,,
9
+ decksmith/validate.py,sha256=W7BzB2LEw6WojJX7DGPQiqEiMCz7r0TIi5NJU3Wym6s,3450
10
+ decksmith-0.1.8.dist-info/entry_points.txt,sha256=-usRztjj2gnfmPubb8nFYHD22drzThAmSfM6geWI98Y,48
11
+ decksmith-0.1.8.dist-info/METADATA,sha256=SIlCh-pJy-d2hZi-lNrLd-KaNeqeelYXp159FSC3MEM,2419
12
+ decksmith-0.1.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
13
+ decksmith-0.1.8.dist-info/RECORD,,