prefig 0.4.3.dev20250823053253__tar.gz → 0.4.5__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.
Files changed (67) hide show
  1. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/PKG-INFO +2 -2
  2. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/README.md +1 -1
  3. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/circle.py +13 -4
  4. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/diagram.py +16 -0
  5. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/label.py +14 -4
  6. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/point.py +7 -1
  7. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/polygon.py +4 -1
  8. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/rectangle.py +5 -2
  9. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/pyproject.toml +1 -1
  10. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/LICENSE +0 -0
  11. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/__init__.py +0 -0
  12. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/cli.py +0 -0
  13. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/CTM.py +0 -0
  14. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/__init__.py +0 -0
  15. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/annotations.py +0 -0
  16. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/area.py +0 -0
  17. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/arrow.py +0 -0
  18. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/axes.py +0 -0
  19. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/calculus.py +0 -0
  20. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/clip.py +0 -0
  21. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/compat.py +0 -0
  22. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/coordinates.py +0 -0
  23. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/definition.py +0 -0
  24. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/diffeqs.py +0 -0
  25. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/graph.py +0 -0
  26. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/grid_axes.py +0 -0
  27. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/group.py +0 -0
  28. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/image.py +0 -0
  29. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/implicit.py +0 -0
  30. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/label_tools.py +0 -0
  31. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/legend.py +0 -0
  32. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/line.py +0 -0
  33. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/math_utilities.py +0 -0
  34. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/network.py +0 -0
  35. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/parametric_curve.py +0 -0
  36. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/parse.py +0 -0
  37. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/path.py +0 -0
  38. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/read.py +0 -0
  39. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/repeat.py +0 -0
  40. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/riemann_sum.py +0 -0
  41. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/shape.py +0 -0
  42. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/slope_field.py +0 -0
  43. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/statistics.py +0 -0
  44. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/tags.py +0 -0
  45. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/tangent_line.py +0 -0
  46. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/user_namespace.py +0 -0
  47. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/utilities.py +0 -0
  48. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/core/vector.py +0 -0
  49. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/engine.py +0 -0
  50. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/diagcess/diagcess.html +0 -0
  51. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/diagcess/diagcess.js +0 -0
  52. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/de-system.xml +0 -0
  53. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/derivatives.xml +0 -0
  54. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/diffeqs.xml +0 -0
  55. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/implicit.xml +0 -0
  56. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/projection.xml +0 -0
  57. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/riemann.xml +0 -0
  58. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/roots_of_unity.xml +0 -0
  59. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/examples/tangent.xml +0 -0
  60. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/fonts/Braille29.ttf +0 -0
  61. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/js/mj-sre-page.js +0 -0
  62. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/js/package.json +0 -0
  63. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/schema/pf_schema.rnc +0 -0
  64. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/schema/pf_schema.rng +0 -0
  65. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/resources/template/pf_publication.xml +0 -0
  66. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/scripts/__init__.py +0 -0
  67. {prefig-0.4.3.dev20250823053253 → prefig-0.4.5}/prefig/scripts/install_mj.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefig
3
- Version: 0.4.3.dev20250823053253
3
+ Version: 0.4.5
4
4
  Summary: An authoring system for mathematical diagrams
5
5
  Home-page: https://prefigure.org
6
6
  License: GPL-3.0-or-later
@@ -92,7 +92,7 @@ PreFigure may be installed locally as a Python package in the usual way using `p
92
92
  apt install nodejs
93
93
  ```
94
94
 
95
- 6. For creating tactile graphics to be embossed, you are encouraged to install `rsvg-convert`, which PreFigure uses to convert SVGs into PDFs. On Ubuntu, you can say
95
+ 6. For building PDF versions of diagrams, you will need to install `rsvg-convert`, which PreFigure uses to convert SVGs into PDFs. On Ubuntu, you can say
96
96
 
97
97
  ```
98
98
  apt install librsvg2-bin
@@ -64,7 +64,7 @@ PreFigure may be installed locally as a Python package in the usual way using `p
64
64
  apt install nodejs
65
65
  ```
66
66
 
67
- 6. For creating tactile graphics to be embossed, you are encouraged to install `rsvg-convert`, which PreFigure uses to convert SVGs into PDFs. On Ubuntu, you can say
67
+ 6. For building PDF versions of diagrams, you will need to install `rsvg-convert`, which PreFigure uses to convert SVGs into PDFs. On Ubuntu, you can say
68
68
 
69
69
  ```
70
70
  apt install librsvg2-bin
@@ -47,9 +47,12 @@ def circle(element, diagram, parent, outline_status):
47
47
  if element.get('stroke') is not None:
48
48
  element.set('stroke', 'black')
49
49
  if element.get('fill') is not None:
50
- element.set('fill', 'lightgray')
50
+ if element.get('fill').strip().lower() != 'none':
51
+ element.set('fill', 'lightgray')
52
+ else:
53
+ element.set('fill', 'none')
51
54
  else:
52
- element.set('stroke', element.get('stroke', 'none'))
55
+ element.set('stroke', element.get('stroke', 'black'))
53
56
  element.set('fill', element.get('fill', 'none'))
54
57
  element.set('thickness', element.get('thickness', '2'))
55
58
  util.add_attr(circle, util.get_2d_attr(element))
@@ -120,7 +123,10 @@ def ellipse(element, diagram, parent, outline_status):
120
123
  if element.get('stroke') is not None:
121
124
  element.set('stroke', 'black')
122
125
  if element.get('fill') is not None:
123
- element.set('fill', 'lightgray')
126
+ if elementl.get('fill').strip().lower() != 'none':
127
+ element.set('fill', 'lightgray')
128
+ else:
129
+ element.set('fill', 'none')
124
130
  else:
125
131
  element.set('stroke', element.get('stroke', 'none'))
126
132
  element.set('fill', element.get('fill', 'none'))
@@ -283,7 +289,10 @@ def angle(element, diagram, parent, outline_status):
283
289
  element.set('stroke', element.get('stroke', 'black'))
284
290
  if diagram.output_format() == 'tactile':
285
291
  if element.get('fill') is not None:
286
- element.set('fill', 'lightgray')
292
+ if element.get('fill').strip().lower() != 'none':
293
+ element.set('fill', 'lightgray')
294
+ else:
295
+ element.set('fill', 'none')
287
296
  else:
288
297
  element.set('fill', element.get('fill', 'none'))
289
298
  element.set('thickness', element.get('thickness','2'))
@@ -109,6 +109,15 @@ class Diagram:
109
109
  if data_directory is not None:
110
110
  self.external = data_directory
111
111
 
112
+ templates = self.diagram_element.xpath('.//templates')
113
+ if len(templates) > 0:
114
+ templates_element = templates[0]
115
+ for template in templates:
116
+ templates_parent = template.getparent()
117
+ templates_parent.remove(template)
118
+ for child in templates_element:
119
+ self.defaults[child.tag] = child
120
+
112
121
  if self.defaults.get('macros', None) is not None:
113
122
  label.add_macros(self.defaults.get('macros').text)
114
123
 
@@ -487,6 +496,13 @@ class Diagram:
487
496
  def get_root(self):
488
497
  return self.root
489
498
 
499
+ def apply_defaults(self, tag, element):
500
+ default = self.defaults.get(tag, None)
501
+ if default is not None:
502
+ for attr, value in default.attrib.items():
503
+ if element.get(attr, None) is None:
504
+ element.set(attr, value)
505
+
490
506
  # when a graphical component is outlined, we first add the component's path
491
507
  # to <defs> so that it can be reused, then we stroke it with a thick white
492
508
  def add_outline(self, element, path, parent, outline_width = None):
@@ -15,6 +15,8 @@ import tempfile
15
15
 
16
16
  log = logging.getLogger('prefigure')
17
17
 
18
+ allowed_fonts = {'serif','sans-serif','monospace'}
19
+
18
20
  def init(format, environment):
19
21
  global math_labels
20
22
  global text_measurements
@@ -465,10 +467,18 @@ def position_svg_label(element, diagram, ctm, group):
465
467
  # These lists contain: font, size, italics, bold, color
466
468
  label_color = element.get("color", None)
467
469
 
468
- std_font_face = ['sans', 14, False, False, label_color]
469
- it_font_face = ['sans', 14, True, False, label_color]
470
- b_font_face = ['sans', 14, False, True, label_color]
471
- it_b_font_face = ['sans', 14, True, True, label_color]
470
+ diagram.apply_defaults('label', element)
471
+
472
+ font_family = element.get('font', 'sans-serif').lower().strip()
473
+ if font_family not in allowed_fonts:
474
+ font_family = 'sans-serif'
475
+
476
+ font_size = un.valid_eval(element.get('font-size', '14'))
477
+
478
+ std_font_face = [font_family, font_size, False, False, label_color]
479
+ it_font_face = [font_family, font_size, True, False, label_color]
480
+ b_font_face = [font_family, font_size, False, True, label_color]
481
+ it_b_font_face = [font_family, font_size, True, True, label_color]
472
482
 
473
483
  label = element
474
484
 
@@ -34,7 +34,13 @@ def point(element, diagram, parent, outline_status = None):
34
34
  return
35
35
 
36
36
  if diagram.output_format() == 'tactile':
37
- element.set('size', element.get('size', '9'))
37
+ if element.get('size', None) is not None:
38
+ size = un.valid_eval(element.get('size'))
39
+ size = max(size, 9)
40
+ size = str(size)
41
+ else:
42
+ size = '9'
43
+ element.set('size', size)
38
44
  else:
39
45
  element.set('size', element.get('size', '4'))
40
46
  size = util.get_attr(element, 'size', '1')
@@ -53,7 +53,10 @@ def polygon(element, diagram, parent,
53
53
  if element.get('stroke') is not None:
54
54
  element.set('stroke', 'black')
55
55
  if element.get('fill') is not None:
56
- element.set('fill', 'lightgray')
56
+ if element.get('fill').strip().lower() != 'none':
57
+ element.set('fill', 'lightgray')
58
+ else:
59
+ element.set('fill', 'none')
57
60
  util.set_attr(element, 'stroke', 'none')
58
61
  util.set_attr(element, 'fill', 'none')
59
62
  util.set_attr(element, 'thickness', '2')
@@ -75,8 +75,11 @@ def rectangle(element, diagram, parent, outline_status):
75
75
  fill = element.get('fill')
76
76
  if stroke is not None and stroke != 'none':
77
77
  element.set('stroke', 'black')
78
- if fill is not None and fill != 'none':
79
- element.set('fill', 'lightgray')
78
+ if fill is not None:
79
+ if fill.strip().lower() != 'none':
80
+ element.set('fill', 'lightgray')
81
+ else:
82
+ element.set('fill', 'none')
80
83
  else:
81
84
  util.set_attr(element, 'stroke', 'none')
82
85
  util.set_attr(element, 'fill', 'none')
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "prefig"
3
- version = "0.4.3.dev20250823053253"
3
+ version = "0.4.5"
4
4
  description = "An authoring system for mathematical diagrams"
5
5
  readme = "README.md"
6
6
  homepage = "https://prefigure.org"
File without changes