kerykeion 4.26.0rc1__tar.gz → 4.26.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 kerykeion might be problematic. Click here for more details.
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/PKG-INFO +81 -26
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/README.md +80 -25
- kerykeion-4.26.1/kerykeion/.DS_Store +0 -0
- kerykeion-4.26.1/kerykeion/charts/.DS_Store +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/kerykeion_chart_svg.py +235 -48
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/utilities.py +55 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/pyproject.toml +1 -1
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/LICENSE +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/aspects/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/aspects/aspects_utils.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/aspects/natal_aspects.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/aspects/synastry_aspects.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/aspects/transits_time_range.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/astrological_subject.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/charts_utils.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/draw_planets.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/templates/aspect_grid_only.xml +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/templates/chart.xml +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/templates/wheel_only.xml +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/themes/classic.css +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/themes/dark-high-contrast.css +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/themes/dark.css +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/charts/themes/light.css +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/composite_subject_factory.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/enums.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/ephemeris_data.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/fetch_geonames.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/chart_types.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/kerykeion_exception.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/kr_literals.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/kr_models.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/kr_types/settings_models.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/relationship_score/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/relationship_score/relationship_score.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/relationship_score/relationship_score_factory.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/report.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/settings/__init__.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/settings/config_constants.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/settings/kerykeion_settings.py +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/settings/kr.config.json +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/sweph/README.md +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/sweph/seas_18.se1 +0 -0
- {kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/transits_time_range.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kerykeion
|
|
3
|
-
Version: 4.26.
|
|
3
|
+
Version: 4.26.1
|
|
4
4
|
Summary: A python library for astrology.
|
|
5
5
|
Home-page: https://www.kerykeion.net/
|
|
6
6
|
License: AGPL-3.0
|
|
@@ -53,17 +53,18 @@ Description-Content-Type: text/markdown
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects
|
|
56
|
+
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects, and generates SVG charts—including birth, synastry, transit, and composite charts. You can also customize which planets to include in your calculations.
|
|
57
57
|
|
|
58
58
|
The main goal of this project is to offer a clean, data-driven approach to astrology, making it accessible and programmable.
|
|
59
59
|
|
|
60
|
-
Kerykeion also integrates seamlessly with AI applications.
|
|
60
|
+
Kerykeion also integrates seamlessly with LLM and AI applications.
|
|
61
61
|
|
|
62
62
|
Here is an example of a birthchart:
|
|
63
63
|
|
|
64
64
|

|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
**Web API**
|
|
67
|
+
---
|
|
67
68
|
|
|
68
69
|
If you want to use Kerykeion in a web application, you can try the dedicated web API:
|
|
69
70
|
|
|
@@ -71,12 +72,40 @@ If you want to use Kerykeion in a web application, you can try the dedicated web
|
|
|
71
72
|
|
|
72
73
|
It is [open source](https://github.com/g-battaglia/Astrologer-API) and directly supports this project.
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
**Donate**
|
|
76
|
+
--
|
|
75
77
|
|
|
76
78
|
Maintaining this project requires substantial time and effort. The Astrologer API alone cannot cover the costs of full-time development. If you find Kerykeion valuable and would like to support further development, please consider donating:
|
|
77
79
|
|
|
78
80
|
[](https://ko-fi.com/kerykeion)
|
|
79
81
|
|
|
82
|
+
|
|
83
|
+
## Table of Contents
|
|
84
|
+
- [Installation](#installation)
|
|
85
|
+
- [Basic Usage](#basic-usage)
|
|
86
|
+
- [Generate a SVG Chart](#generate-a-svg-chart)
|
|
87
|
+
- [Birth Chart](#birth-chart)
|
|
88
|
+
- [Synastry Chart](#synastry-chart)
|
|
89
|
+
- [Transit Chart](#transit-chart)
|
|
90
|
+
- [Composite Chart](#composite-chart)
|
|
91
|
+
- [Change the Output Directory](#change-the-output-directory)
|
|
92
|
+
- [Change Language](#change-language)
|
|
93
|
+
- [Report](#report)
|
|
94
|
+
- [Example: Retrieving Aspects](#example-retrieving-aspects)
|
|
95
|
+
- [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
|
|
96
|
+
- [House Systems](#house-systems)
|
|
97
|
+
- [Perspective Type](#perspective-type)
|
|
98
|
+
- [Themes](#themes)
|
|
99
|
+
- [Alternative Initialization](#alternative-initialization)
|
|
100
|
+
- [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
|
|
101
|
+
- [JSON Support](#json-support)
|
|
102
|
+
- [Auto Generated Documentation](#auto-generated-documentation)
|
|
103
|
+
- [Development](#development)
|
|
104
|
+
- [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
|
|
105
|
+
- [License](#license)
|
|
106
|
+
- [Contributing](#contributing)
|
|
107
|
+
- [Citations](#citations)
|
|
108
|
+
|
|
80
109
|
## Installation
|
|
81
110
|
|
|
82
111
|
Kerykeion requires **Python 3.9** or higher.
|
|
@@ -382,34 +411,49 @@ subject = AstrologicalSubject.get_from_iso_utc_time(
|
|
|
382
411
|
|
|
383
412
|
## Lunar Nodes (Rahu & Ketu)
|
|
384
413
|
|
|
385
|
-
|
|
414
|
+
Kerykeion supports both **True** and **Mean** Lunar Nodes:
|
|
386
415
|
|
|
387
|
-
- True North Lunar Node
|
|
388
|
-
- True South Lunar Node
|
|
389
|
-
- Mean North Lunar Node
|
|
390
|
-
- Mean South Lunar Node
|
|
416
|
+
- **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
|
|
417
|
+
- **True South Lunar Node**: `"true_south_node"`.
|
|
418
|
+
- **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
|
|
419
|
+
- **Mean South Lunar Node**: `"mean_south_node"`.
|
|
391
420
|
|
|
392
421
|
In instances of the AstrologicalSubject class, all of them are active by default.
|
|
393
422
|
|
|
394
|
-
In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to
|
|
423
|
+
In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to pass the `active_points` parameter to the `KerykeionChartSVG` class.
|
|
424
|
+
|
|
395
425
|
Example:
|
|
396
426
|
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
"name": "True_South_Node",
|
|
402
|
-
"color": "var(--kerykeion-chart-color-true-node)",
|
|
403
|
-
"is_active": true, // Set to true to activate the true node
|
|
404
|
-
"element_points": 0,
|
|
405
|
-
"related_zodiac_signs": [],
|
|
406
|
-
"label": "True_South_Node"
|
|
407
|
-
}
|
|
408
|
-
...
|
|
409
|
-
```
|
|
427
|
+
```python
|
|
428
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
429
|
+
|
|
430
|
+
subject = AstrologicalSubject("John Lennon", 1940, 10, 9, 18, 30, "Liverpool", "GB")
|
|
410
431
|
|
|
411
|
-
|
|
412
|
-
|
|
432
|
+
chart = KerykeionChartSVG(
|
|
433
|
+
subject,
|
|
434
|
+
active_points=[
|
|
435
|
+
"Sun",
|
|
436
|
+
"Moon",
|
|
437
|
+
"Mercury",
|
|
438
|
+
"Venus",
|
|
439
|
+
"Mars",
|
|
440
|
+
"Jupiter",
|
|
441
|
+
"Saturn",
|
|
442
|
+
"Uranus",
|
|
443
|
+
"Neptune",
|
|
444
|
+
"Pluto",
|
|
445
|
+
"Mean_Node",
|
|
446
|
+
"Mean_South_Node",
|
|
447
|
+
"True_Node", # Activates True North Node
|
|
448
|
+
"True_South_Node", # Activates True South Node
|
|
449
|
+
"Ascendant",
|
|
450
|
+
"Medium_Coeli",
|
|
451
|
+
"Descendant",
|
|
452
|
+
"Imum_Coeli"
|
|
453
|
+
]
|
|
454
|
+
)
|
|
455
|
+
chart.makeSVG()
|
|
456
|
+
```
|
|
413
457
|
|
|
414
458
|
## JSON Support
|
|
415
459
|
|
|
@@ -441,7 +485,18 @@ This project is covered under the AGPL-3.0 License. For detailed information, pl
|
|
|
441
485
|
|
|
442
486
|
As a rule of thumb, if you use this library in a project, you should open-source that project under a compatible license. Alternatively, if you wish to keep your source closed, consider using the [AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/), which is AGPL-3.0 compliant and also helps support the project.
|
|
443
487
|
|
|
488
|
+
Since the AstrologerAPI is an external third-party service, using it does *not* require your code to be open-source.
|
|
489
|
+
|
|
444
490
|
## Contributing
|
|
445
491
|
|
|
446
492
|
Contributions are welcome! Feel free to submit pull requests or report issues.
|
|
447
493
|
|
|
494
|
+
## Citations
|
|
495
|
+
|
|
496
|
+
If using Kerykeion in published or academic work, please cite as follows:
|
|
497
|
+
|
|
498
|
+
```
|
|
499
|
+
Battaglia, G. (2025). Kerykeion: A Python Library for Astrological Calculations and Chart Generation.
|
|
500
|
+
https://github.com/g-battaglia/kerykeion
|
|
501
|
+
```
|
|
502
|
+
|
|
@@ -14,17 +14,18 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects
|
|
17
|
+
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects, and generates SVG charts—including birth, synastry, transit, and composite charts. You can also customize which planets to include in your calculations.
|
|
18
18
|
|
|
19
19
|
The main goal of this project is to offer a clean, data-driven approach to astrology, making it accessible and programmable.
|
|
20
20
|
|
|
21
|
-
Kerykeion also integrates seamlessly with AI applications.
|
|
21
|
+
Kerykeion also integrates seamlessly with LLM and AI applications.
|
|
22
22
|
|
|
23
23
|
Here is an example of a birthchart:
|
|
24
24
|
|
|
25
25
|

|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
**Web API**
|
|
28
|
+
---
|
|
28
29
|
|
|
29
30
|
If you want to use Kerykeion in a web application, you can try the dedicated web API:
|
|
30
31
|
|
|
@@ -32,12 +33,40 @@ If you want to use Kerykeion in a web application, you can try the dedicated web
|
|
|
32
33
|
|
|
33
34
|
It is [open source](https://github.com/g-battaglia/Astrologer-API) and directly supports this project.
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
**Donate**
|
|
37
|
+
--
|
|
36
38
|
|
|
37
39
|
Maintaining this project requires substantial time and effort. The Astrologer API alone cannot cover the costs of full-time development. If you find Kerykeion valuable and would like to support further development, please consider donating:
|
|
38
40
|
|
|
39
41
|
[](https://ko-fi.com/kerykeion)
|
|
40
42
|
|
|
43
|
+
|
|
44
|
+
## Table of Contents
|
|
45
|
+
- [Installation](#installation)
|
|
46
|
+
- [Basic Usage](#basic-usage)
|
|
47
|
+
- [Generate a SVG Chart](#generate-a-svg-chart)
|
|
48
|
+
- [Birth Chart](#birth-chart)
|
|
49
|
+
- [Synastry Chart](#synastry-chart)
|
|
50
|
+
- [Transit Chart](#transit-chart)
|
|
51
|
+
- [Composite Chart](#composite-chart)
|
|
52
|
+
- [Change the Output Directory](#change-the-output-directory)
|
|
53
|
+
- [Change Language](#change-language)
|
|
54
|
+
- [Report](#report)
|
|
55
|
+
- [Example: Retrieving Aspects](#example-retrieving-aspects)
|
|
56
|
+
- [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
|
|
57
|
+
- [House Systems](#house-systems)
|
|
58
|
+
- [Perspective Type](#perspective-type)
|
|
59
|
+
- [Themes](#themes)
|
|
60
|
+
- [Alternative Initialization](#alternative-initialization)
|
|
61
|
+
- [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
|
|
62
|
+
- [JSON Support](#json-support)
|
|
63
|
+
- [Auto Generated Documentation](#auto-generated-documentation)
|
|
64
|
+
- [Development](#development)
|
|
65
|
+
- [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
|
|
66
|
+
- [License](#license)
|
|
67
|
+
- [Contributing](#contributing)
|
|
68
|
+
- [Citations](#citations)
|
|
69
|
+
|
|
41
70
|
## Installation
|
|
42
71
|
|
|
43
72
|
Kerykeion requires **Python 3.9** or higher.
|
|
@@ -343,34 +372,49 @@ subject = AstrologicalSubject.get_from_iso_utc_time(
|
|
|
343
372
|
|
|
344
373
|
## Lunar Nodes (Rahu & Ketu)
|
|
345
374
|
|
|
346
|
-
|
|
375
|
+
Kerykeion supports both **True** and **Mean** Lunar Nodes:
|
|
347
376
|
|
|
348
|
-
- True North Lunar Node
|
|
349
|
-
- True South Lunar Node
|
|
350
|
-
- Mean North Lunar Node
|
|
351
|
-
- Mean South Lunar Node
|
|
377
|
+
- **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
|
|
378
|
+
- **True South Lunar Node**: `"true_south_node"`.
|
|
379
|
+
- **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
|
|
380
|
+
- **Mean South Lunar Node**: `"mean_south_node"`.
|
|
352
381
|
|
|
353
382
|
In instances of the AstrologicalSubject class, all of them are active by default.
|
|
354
383
|
|
|
355
|
-
In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to
|
|
384
|
+
In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to pass the `active_points` parameter to the `KerykeionChartSVG` class.
|
|
385
|
+
|
|
356
386
|
Example:
|
|
357
387
|
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
"name": "True_South_Node",
|
|
363
|
-
"color": "var(--kerykeion-chart-color-true-node)",
|
|
364
|
-
"is_active": true, // Set to true to activate the true node
|
|
365
|
-
"element_points": 0,
|
|
366
|
-
"related_zodiac_signs": [],
|
|
367
|
-
"label": "True_South_Node"
|
|
368
|
-
}
|
|
369
|
-
...
|
|
370
|
-
```
|
|
388
|
+
```python
|
|
389
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
390
|
+
|
|
391
|
+
subject = AstrologicalSubject("John Lennon", 1940, 10, 9, 18, 30, "Liverpool", "GB")
|
|
371
392
|
|
|
372
|
-
|
|
373
|
-
|
|
393
|
+
chart = KerykeionChartSVG(
|
|
394
|
+
subject,
|
|
395
|
+
active_points=[
|
|
396
|
+
"Sun",
|
|
397
|
+
"Moon",
|
|
398
|
+
"Mercury",
|
|
399
|
+
"Venus",
|
|
400
|
+
"Mars",
|
|
401
|
+
"Jupiter",
|
|
402
|
+
"Saturn",
|
|
403
|
+
"Uranus",
|
|
404
|
+
"Neptune",
|
|
405
|
+
"Pluto",
|
|
406
|
+
"Mean_Node",
|
|
407
|
+
"Mean_South_Node",
|
|
408
|
+
"True_Node", # Activates True North Node
|
|
409
|
+
"True_South_Node", # Activates True South Node
|
|
410
|
+
"Ascendant",
|
|
411
|
+
"Medium_Coeli",
|
|
412
|
+
"Descendant",
|
|
413
|
+
"Imum_Coeli"
|
|
414
|
+
]
|
|
415
|
+
)
|
|
416
|
+
chart.makeSVG()
|
|
417
|
+
```
|
|
374
418
|
|
|
375
419
|
## JSON Support
|
|
376
420
|
|
|
@@ -402,6 +446,17 @@ This project is covered under the AGPL-3.0 License. For detailed information, pl
|
|
|
402
446
|
|
|
403
447
|
As a rule of thumb, if you use this library in a project, you should open-source that project under a compatible license. Alternatively, if you wish to keep your source closed, consider using the [AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/), which is AGPL-3.0 compliant and also helps support the project.
|
|
404
448
|
|
|
449
|
+
Since the AstrologerAPI is an external third-party service, using it does *not* require your code to be open-source.
|
|
450
|
+
|
|
405
451
|
## Contributing
|
|
406
452
|
|
|
407
453
|
Contributions are welcome! Feel free to submit pull requests or report issues.
|
|
454
|
+
|
|
455
|
+
## Citations
|
|
456
|
+
|
|
457
|
+
If using Kerykeion in published or academic work, please cite as follows:
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
Battaglia, G. (2025). Kerykeion: A Python Library for Astrological Calculations and Chart Generation.
|
|
461
|
+
https://github.com/g-battaglia/kerykeion
|
|
462
|
+
```
|
|
Binary file
|
|
Binary file
|
|
@@ -37,7 +37,7 @@ from kerykeion.charts.charts_utils import (
|
|
|
37
37
|
draw_planet_grid,
|
|
38
38
|
)
|
|
39
39
|
from kerykeion.charts.draw_planets import draw_planets # type: ignore
|
|
40
|
-
from kerykeion.utilities import get_houses_list
|
|
40
|
+
from kerykeion.utilities import get_houses_list, inline_css_variables_in_svg
|
|
41
41
|
from kerykeion.settings.config_constants import DEFAULT_ACTIVE_POINTS, DEFAULT_ACTIVE_ASPECTS
|
|
42
42
|
from pathlib import Path
|
|
43
43
|
from scour.scour import scourString
|
|
@@ -47,23 +47,44 @@ from datetime import datetime
|
|
|
47
47
|
|
|
48
48
|
class KerykeionChartSVG:
|
|
49
49
|
"""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
KerykeionChartSVG generates astrological chart visualizations as SVG files.
|
|
51
|
+
|
|
52
|
+
This class supports creating full chart SVGs, wheel-only SVGs, and aspect-grid-only SVGs
|
|
53
|
+
for various chart types including Natal, ExternalNatal, Transit, Synastry, and Composite.
|
|
54
|
+
Charts are rendered using XML templates and drawing utilities, with customizable themes,
|
|
55
|
+
language, active points, and aspects.
|
|
56
|
+
The rendered SVGs can be saved to a specified output directory or, by default, to the user's home directory.
|
|
57
|
+
|
|
58
|
+
NOTE:
|
|
59
|
+
The generated SVG files are optimized for web use, opening in browsers. If you want to
|
|
60
|
+
use them in other applications, you might need to adjust the SVG settings or styles.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
first_obj (AstrologicalSubject | AstrologicalSubjectModel | CompositeSubjectModel):
|
|
64
|
+
The primary astrological subject for the chart.
|
|
65
|
+
chart_type (ChartType, optional):
|
|
66
|
+
The type of chart to generate ('Natal', 'ExternalNatal', 'Transit', 'Synastry', 'Composite').
|
|
67
|
+
Defaults to 'Natal'.
|
|
68
|
+
second_obj (AstrologicalSubject | AstrologicalSubjectModel, optional):
|
|
69
|
+
The secondary subject for Transit or Synastry charts. Not required for Natal or Composite.
|
|
70
|
+
new_output_directory (str | Path, optional):
|
|
71
|
+
Directory to write generated SVG files. Defaults to the user's home directory.
|
|
72
|
+
new_settings_file (Path | dict | KerykeionSettingsModel, optional):
|
|
73
|
+
Path or settings object to override default chart configuration (colors, fonts, aspects).
|
|
74
|
+
theme (KerykeionChartTheme, optional):
|
|
75
|
+
CSS theme for the chart. If None, no default styles are applied. Defaults to 'classic'.
|
|
76
|
+
double_chart_aspect_grid_type (Literal['list', 'table'], optional):
|
|
77
|
+
Specifies rendering style for double-chart aspect grids. Defaults to 'list'.
|
|
78
|
+
chart_language (KerykeionChartLanguage, optional):
|
|
79
|
+
Language code for chart labels. Defaults to 'EN'.
|
|
80
|
+
active_points (list[Planet | AxialCusps], optional):
|
|
81
|
+
List of celestial points and angles to include. Defaults to DEFAULT_ACTIVE_POINTS.
|
|
82
|
+
Example:
|
|
83
|
+
["Sun", "Moon", "Mercury", "Venus"]
|
|
84
|
+
|
|
85
|
+
active_aspects (list[ActiveAspect], optional):
|
|
86
|
+
List of aspects (name and orb) to calculate. Defaults to DEFAULT_ACTIVE_ASPECTS.
|
|
87
|
+
Example:
|
|
67
88
|
[
|
|
68
89
|
{"name": "conjunction", "orb": 10},
|
|
69
90
|
{"name": "opposition", "orb": 10},
|
|
@@ -72,6 +93,30 @@ class KerykeionChartSVG:
|
|
|
72
93
|
{"name": "square", "orb": 5},
|
|
73
94
|
{"name": "quintile", "orb": 1},
|
|
74
95
|
]
|
|
96
|
+
|
|
97
|
+
Public Methods:
|
|
98
|
+
makeTemplate(minify=False, remove_css_variables=False) -> str:
|
|
99
|
+
Render the full chart SVG as a string without writing to disk. Use `minify=True`
|
|
100
|
+
to remove whitespace and quotes, and `remove_css_variables=True` to embed CSS vars.
|
|
101
|
+
|
|
102
|
+
makeSVG(minify=False, remove_css_variables=False) -> None:
|
|
103
|
+
Generate and write the full chart SVG file to the output directory.
|
|
104
|
+
Filenames follow the pattern:
|
|
105
|
+
'{subject.name} - {chart_type} Chart.svg'.
|
|
106
|
+
|
|
107
|
+
makeWheelOnlyTemplate(minify=False, remove_css_variables=False) -> str:
|
|
108
|
+
Render only the chart wheel (no aspect grid) as an SVG string.
|
|
109
|
+
|
|
110
|
+
makeWheelOnlySVG(minify=False, remove_css_variables=False) -> None:
|
|
111
|
+
Generate and write the wheel-only SVG file:
|
|
112
|
+
'{subject.name} - {chart_type} Chart - Wheel Only.svg'.
|
|
113
|
+
|
|
114
|
+
makeAspectGridOnlyTemplate(minify=False, remove_css_variables=False) -> str:
|
|
115
|
+
Render only the aspect grid as an SVG string.
|
|
116
|
+
|
|
117
|
+
makeAspectGridOnlySVG(minify=False, remove_css_variables=False) -> None:
|
|
118
|
+
Generate and write the aspect-grid-only SVG file:
|
|
119
|
+
'{subject.name} - {chart_type} Chart - Aspect Grid Only.svg'.
|
|
75
120
|
"""
|
|
76
121
|
|
|
77
122
|
# Constants
|
|
@@ -131,8 +176,33 @@ class KerykeionChartSVG:
|
|
|
131
176
|
double_chart_aspect_grid_type: Literal["list", "table"] = "list",
|
|
132
177
|
chart_language: KerykeionChartLanguage = "EN",
|
|
133
178
|
active_points: List[Union[Planet, AxialCusps]] = DEFAULT_ACTIVE_POINTS,
|
|
134
|
-
|
|
179
|
+
active_aspects: List[ActiveAspect] = DEFAULT_ACTIVE_ASPECTS,
|
|
135
180
|
):
|
|
181
|
+
"""
|
|
182
|
+
Initialize the chart generator with subject data and configuration options.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
first_obj (AstrologicalSubject, AstrologicalSubjectModel, or CompositeSubjectModel):
|
|
186
|
+
Primary astrological subject instance.
|
|
187
|
+
chart_type (ChartType, optional):
|
|
188
|
+
Type of chart to generate (e.g., 'Natal', 'Transit').
|
|
189
|
+
second_obj (AstrologicalSubject or AstrologicalSubjectModel, optional):
|
|
190
|
+
Secondary subject for Transit or Synastry charts.
|
|
191
|
+
new_output_directory (str or Path, optional):
|
|
192
|
+
Base directory to save generated SVG files.
|
|
193
|
+
new_settings_file (Path, dict, or KerykeionSettingsModel, optional):
|
|
194
|
+
Custom settings source for chart colors, fonts, and aspects.
|
|
195
|
+
theme (KerykeionChartTheme or None, optional):
|
|
196
|
+
CSS theme to apply; None for default styling.
|
|
197
|
+
double_chart_aspect_grid_type (Literal['list','table'], optional):
|
|
198
|
+
Layout style for double-chart aspect grids ('list' or 'table').
|
|
199
|
+
chart_language (KerykeionChartLanguage, optional):
|
|
200
|
+
Language code for chart labels (e.g., 'EN', 'IT').
|
|
201
|
+
active_points (List[Planet or AxialCusps], optional):
|
|
202
|
+
Celestial points to include in the chart visualization.
|
|
203
|
+
active_aspects (List[ActiveAspect], optional):
|
|
204
|
+
Aspects to calculate, each defined by name and orb.
|
|
205
|
+
"""
|
|
136
206
|
home_directory = Path.home()
|
|
137
207
|
self.new_settings_file = new_settings_file
|
|
138
208
|
self.chart_language = chart_language
|
|
@@ -269,7 +339,10 @@ class KerykeionChartSVG:
|
|
|
269
339
|
|
|
270
340
|
def set_up_theme(self, theme: Union[KerykeionChartTheme, None] = None) -> None:
|
|
271
341
|
"""
|
|
272
|
-
|
|
342
|
+
Load and apply a CSS theme for the chart visualization.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
theme (KerykeionChartTheme or None): Name of the theme to apply. If None, no CSS is applied.
|
|
273
346
|
"""
|
|
274
347
|
if theme is None:
|
|
275
348
|
self.color_style_tag = ""
|
|
@@ -282,14 +355,21 @@ class KerykeionChartSVG:
|
|
|
282
355
|
|
|
283
356
|
def set_output_directory(self, dir_path: Path) -> None:
|
|
284
357
|
"""
|
|
285
|
-
|
|
358
|
+
Set the directory where generated SVG files will be saved.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
dir_path (Path): Target directory for SVG output.
|
|
286
362
|
"""
|
|
287
363
|
self.output_directory = dir_path
|
|
288
364
|
logging.info(f"Output direcotry set to: {self.output_directory}")
|
|
289
365
|
|
|
290
366
|
def parse_json_settings(self, settings_file_or_dict: Union[Path, dict, KerykeionSettingsModel, None]) -> None:
|
|
291
367
|
"""
|
|
292
|
-
|
|
368
|
+
Load and parse chart configuration settings.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
settings_file_or_dict (Path, dict, or KerykeionSettingsModel):
|
|
372
|
+
Source for custom chart settings.
|
|
293
373
|
"""
|
|
294
374
|
settings = get_settings(settings_file_or_dict)
|
|
295
375
|
|
|
@@ -300,14 +380,13 @@ class KerykeionChartSVG:
|
|
|
300
380
|
|
|
301
381
|
def _draw_zodiac_circle_slices(self, r):
|
|
302
382
|
"""
|
|
303
|
-
|
|
304
|
-
with the 12 slices for each zodiac sign.
|
|
383
|
+
Draw zodiac circle slices for each sign.
|
|
305
384
|
|
|
306
385
|
Args:
|
|
307
|
-
r (float):
|
|
386
|
+
r (float): Outer radius of the zodiac ring.
|
|
308
387
|
|
|
309
388
|
Returns:
|
|
310
|
-
str:
|
|
389
|
+
str: Concatenated SVG elements for zodiac slices.
|
|
311
390
|
"""
|
|
312
391
|
sings = get_args(Sign)
|
|
313
392
|
output = ""
|
|
@@ -326,10 +405,13 @@ class KerykeionChartSVG:
|
|
|
326
405
|
|
|
327
406
|
def _calculate_elements_points_from_planets(self):
|
|
328
407
|
"""
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
408
|
+
Compute elemental point totals based on active planetary positions.
|
|
409
|
+
|
|
410
|
+
Iterates over each active planet to determine its zodiac element and adds extra points
|
|
411
|
+
if the planet is in a related sign. Updates self.fire, self.earth, self.air, and self.water.
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
None
|
|
333
415
|
"""
|
|
334
416
|
|
|
335
417
|
ZODIAC = (
|
|
@@ -381,6 +463,16 @@ class KerykeionChartSVG:
|
|
|
381
463
|
self.water = self.water + self.available_planets_setting[i]["element_points"] + extra_points
|
|
382
464
|
|
|
383
465
|
def _draw_all_aspects_lines(self, r, ar):
|
|
466
|
+
"""
|
|
467
|
+
Render SVG lines for all aspects in the chart.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
r (float): Radius at which aspect lines originate.
|
|
471
|
+
ar (float): Radius at which aspect lines terminate.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
str: SVG markup for all aspect lines.
|
|
475
|
+
"""
|
|
384
476
|
out = ""
|
|
385
477
|
for aspect in self.aspects_list:
|
|
386
478
|
aspect_name = aspect["aspect"]
|
|
@@ -396,6 +488,16 @@ class KerykeionChartSVG:
|
|
|
396
488
|
return out
|
|
397
489
|
|
|
398
490
|
def _draw_all_transit_aspects_lines(self, r, ar):
|
|
491
|
+
"""
|
|
492
|
+
Render SVG lines for all transit aspects in the chart.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
r (float): Radius at which transit aspect lines originate.
|
|
496
|
+
ar (float): Radius at which transit aspect lines terminate.
|
|
497
|
+
|
|
498
|
+
Returns:
|
|
499
|
+
str: SVG markup for all transit aspect lines.
|
|
500
|
+
"""
|
|
399
501
|
out = ""
|
|
400
502
|
for aspect in self.aspects_list:
|
|
401
503
|
aspect_name = aspect["aspect"]
|
|
@@ -412,10 +514,13 @@ class KerykeionChartSVG:
|
|
|
412
514
|
|
|
413
515
|
def _create_template_dictionary(self) -> ChartTemplateDictionary:
|
|
414
516
|
"""
|
|
415
|
-
|
|
517
|
+
Assemble chart data and rendering instructions into a template dictionary.
|
|
518
|
+
|
|
519
|
+
Gathers styling, dimensions, and SVG fragments for chart components based on
|
|
520
|
+
chart type and subjects.
|
|
416
521
|
|
|
417
522
|
Returns:
|
|
418
|
-
ChartTemplateDictionary:
|
|
523
|
+
ChartTemplateDictionary: Populated structure of template variables.
|
|
419
524
|
"""
|
|
420
525
|
# Initialize template dictionary
|
|
421
526
|
template_dict: dict = {}
|
|
@@ -702,8 +807,20 @@ class KerykeionChartSVG:
|
|
|
702
807
|
|
|
703
808
|
return ChartTemplateDictionary(**template_dict)
|
|
704
809
|
|
|
705
|
-
def makeTemplate(self, minify: bool = False) -> str:
|
|
706
|
-
"""
|
|
810
|
+
def makeTemplate(self, minify: bool = False, remove_css_variables = False) -> str:
|
|
811
|
+
"""
|
|
812
|
+
Render the full chart SVG as a string.
|
|
813
|
+
|
|
814
|
+
Reads the XML template, substitutes variables, and optionally inlines CSS
|
|
815
|
+
variables and minifies the output.
|
|
816
|
+
|
|
817
|
+
Args:
|
|
818
|
+
minify (bool): Remove whitespace and quotes for compactness.
|
|
819
|
+
remove_css_variables (bool): Embed CSS variable definitions.
|
|
820
|
+
|
|
821
|
+
Returns:
|
|
822
|
+
str: SVG markup as a string.
|
|
823
|
+
"""
|
|
707
824
|
td = self._create_template_dictionary()
|
|
708
825
|
|
|
709
826
|
DATA_DIR = Path(__file__).parent
|
|
@@ -719,6 +836,9 @@ class KerykeionChartSVG:
|
|
|
719
836
|
|
|
720
837
|
self._create_template_dictionary()
|
|
721
838
|
|
|
839
|
+
if remove_css_variables:
|
|
840
|
+
template = inline_css_variables_in_svg(template)
|
|
841
|
+
|
|
722
842
|
if minify:
|
|
723
843
|
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
724
844
|
|
|
@@ -727,11 +847,22 @@ class KerykeionChartSVG:
|
|
|
727
847
|
|
|
728
848
|
return template
|
|
729
849
|
|
|
730
|
-
def makeSVG(self, minify: bool = False):
|
|
731
|
-
"""
|
|
850
|
+
def makeSVG(self, minify: bool = False, remove_css_variables = False):
|
|
851
|
+
"""
|
|
852
|
+
Generate and save the full chart SVG to disk.
|
|
853
|
+
|
|
854
|
+
Calls makeTemplate to render the SVG, then writes a file named
|
|
855
|
+
"{subject.name} - {chart_type} Chart.svg" in the output directory.
|
|
856
|
+
|
|
857
|
+
Args:
|
|
858
|
+
minify (bool): Pass-through to makeTemplate for compact output.
|
|
859
|
+
remove_css_variables (bool): Pass-through to makeTemplate to embed CSS variables.
|
|
860
|
+
|
|
861
|
+
Returns:
|
|
862
|
+
None
|
|
863
|
+
"""
|
|
732
864
|
|
|
733
|
-
|
|
734
|
-
self.template = self.makeTemplate(minify)
|
|
865
|
+
self.template = self.makeTemplate(minify, remove_css_variables)
|
|
735
866
|
|
|
736
867
|
chartname = self.output_directory / f"{self.user.name} - {self.chart_type} Chart.svg"
|
|
737
868
|
|
|
@@ -739,8 +870,21 @@ class KerykeionChartSVG:
|
|
|
739
870
|
output_file.write(self.template)
|
|
740
871
|
|
|
741
872
|
print(f"SVG Generated Correctly in: {chartname}")
|
|
742
|
-
|
|
743
|
-
|
|
873
|
+
|
|
874
|
+
def makeWheelOnlyTemplate(self, minify: bool = False, remove_css_variables = False):
|
|
875
|
+
"""
|
|
876
|
+
Render the wheel-only chart SVG as a string.
|
|
877
|
+
|
|
878
|
+
Reads the wheel-only XML template, substitutes chart data, and applies optional
|
|
879
|
+
CSS inlining and minification.
|
|
880
|
+
|
|
881
|
+
Args:
|
|
882
|
+
minify (bool): Remove whitespace and quotes for compactness.
|
|
883
|
+
remove_css_variables (bool): Embed CSS variable definitions.
|
|
884
|
+
|
|
885
|
+
Returns:
|
|
886
|
+
str: SVG markup for the chart wheel only.
|
|
887
|
+
"""
|
|
744
888
|
|
|
745
889
|
with open(Path(__file__).parent / "templates" / "wheel_only.xml", "r", encoding="utf-8", errors="ignore") as f:
|
|
746
890
|
template = f.read()
|
|
@@ -748,6 +892,9 @@ class KerykeionChartSVG:
|
|
|
748
892
|
template_dict = self._create_template_dictionary()
|
|
749
893
|
template = Template(template).substitute(template_dict)
|
|
750
894
|
|
|
895
|
+
if remove_css_variables:
|
|
896
|
+
template = inline_css_variables_in_svg(template)
|
|
897
|
+
|
|
751
898
|
if minify:
|
|
752
899
|
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
753
900
|
|
|
@@ -756,18 +903,43 @@ class KerykeionChartSVG:
|
|
|
756
903
|
|
|
757
904
|
return template
|
|
758
905
|
|
|
759
|
-
def makeWheelOnlySVG(self, minify: bool = False):
|
|
760
|
-
"""
|
|
906
|
+
def makeWheelOnlySVG(self, minify: bool = False, remove_css_variables = False):
|
|
907
|
+
"""
|
|
908
|
+
Generate and save wheel-only chart SVG to disk.
|
|
909
|
+
|
|
910
|
+
Calls makeWheelOnlyTemplate and writes a file named
|
|
911
|
+
"{subject.name} - {chart_type} Chart - Wheel Only.svg" in the output directory.
|
|
912
|
+
|
|
913
|
+
Args:
|
|
914
|
+
minify (bool): Pass-through to makeWheelOnlyTemplate for compact output.
|
|
915
|
+
remove_css_variables (bool): Pass-through to makeWheelOnlyTemplate to embed CSS variables.
|
|
761
916
|
|
|
762
|
-
|
|
917
|
+
Returns:
|
|
918
|
+
None
|
|
919
|
+
"""
|
|
920
|
+
|
|
921
|
+
template = self.makeWheelOnlyTemplate(minify, remove_css_variables)
|
|
763
922
|
chartname = self.output_directory / f"{self.user.name} - {self.chart_type} Chart - Wheel Only.svg"
|
|
764
923
|
|
|
765
924
|
with open(chartname, "w", encoding="utf-8", errors="ignore") as output_file:
|
|
766
925
|
output_file.write(template)
|
|
767
926
|
|
|
768
927
|
print(f"SVG Generated Correctly in: {chartname}")
|
|
769
|
-
|
|
770
|
-
|
|
928
|
+
|
|
929
|
+
def makeAspectGridOnlyTemplate(self, minify: bool = False, remove_css_variables = False):
|
|
930
|
+
"""
|
|
931
|
+
Render the aspect-grid-only chart SVG as a string.
|
|
932
|
+
|
|
933
|
+
Reads the aspect-grid XML template, generates the aspect grid based on chart type,
|
|
934
|
+
and applies optional CSS inlining and minification.
|
|
935
|
+
|
|
936
|
+
Args:
|
|
937
|
+
minify (bool): Remove whitespace and quotes for compactness.
|
|
938
|
+
remove_css_variables (bool): Embed CSS variable definitions.
|
|
939
|
+
|
|
940
|
+
Returns:
|
|
941
|
+
str: SVG markup for the aspect grid only.
|
|
942
|
+
"""
|
|
771
943
|
|
|
772
944
|
with open(Path(__file__).parent / "templates" / "aspect_grid_only.xml", "r", encoding="utf-8", errors="ignore") as f:
|
|
773
945
|
template = f.read()
|
|
@@ -781,6 +953,9 @@ class KerykeionChartSVG:
|
|
|
781
953
|
|
|
782
954
|
template = Template(template).substitute({**template_dict, "makeAspectGrid": aspects_grid})
|
|
783
955
|
|
|
956
|
+
if remove_css_variables:
|
|
957
|
+
template = inline_css_variables_in_svg(template)
|
|
958
|
+
|
|
784
959
|
if minify:
|
|
785
960
|
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
786
961
|
|
|
@@ -789,10 +964,22 @@ class KerykeionChartSVG:
|
|
|
789
964
|
|
|
790
965
|
return template
|
|
791
966
|
|
|
792
|
-
def makeAspectGridOnlySVG(self, minify: bool = False):
|
|
793
|
-
"""
|
|
967
|
+
def makeAspectGridOnlySVG(self, minify: bool = False, remove_css_variables = False):
|
|
968
|
+
"""
|
|
969
|
+
Generate and save aspect-grid-only chart SVG to disk.
|
|
970
|
+
|
|
971
|
+
Calls makeAspectGridOnlyTemplate and writes a file named
|
|
972
|
+
"{subject.name} - {chart_type} Chart - Aspect Grid Only.svg" in the output directory.
|
|
973
|
+
|
|
974
|
+
Args:
|
|
975
|
+
minify (bool): Pass-through to makeAspectGridOnlyTemplate for compact output.
|
|
976
|
+
remove_css_variables (bool): Pass-through to makeAspectGridOnlyTemplate to embed CSS variables.
|
|
977
|
+
|
|
978
|
+
Returns:
|
|
979
|
+
None
|
|
980
|
+
"""
|
|
794
981
|
|
|
795
|
-
template = self.makeAspectGridOnlyTemplate(minify)
|
|
982
|
+
template = self.makeAspectGridOnlyTemplate(minify, remove_css_variables)
|
|
796
983
|
chartname = self.output_directory / f"{self.user.name} - {self.chart_type} Chart - Aspect Grid Only.svg"
|
|
797
984
|
|
|
798
985
|
with open(chartname, "w", encoding="utf-8", errors="ignore") as output_file:
|
|
@@ -3,6 +3,7 @@ from kerykeion.kr_types.kr_literals import LunarPhaseEmoji, LunarPhaseName, Poin
|
|
|
3
3
|
from typing import Union, get_args, TYPE_CHECKING
|
|
4
4
|
import logging
|
|
5
5
|
import math
|
|
6
|
+
import re
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from kerykeion import AstrologicalSubject
|
|
@@ -440,3 +441,57 @@ def circular_sort(degrees: list[Union[int, float]]) -> list[Union[int, float]]:
|
|
|
440
441
|
|
|
441
442
|
# Return the reference followed by the sorted remaining elements
|
|
442
443
|
return [reference] + sorted_remaining
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def inline_css_variables_in_svg(svg_content: str) -> str:
|
|
447
|
+
"""
|
|
448
|
+
Process an SVG string to inline all CSS custom properties.
|
|
449
|
+
|
|
450
|
+
Args:
|
|
451
|
+
svg_content (str): The original SVG string with CSS variables
|
|
452
|
+
|
|
453
|
+
Returns:
|
|
454
|
+
str: The modified SVG with all CSS variables replaced by their values
|
|
455
|
+
and all style blocks removed
|
|
456
|
+
"""
|
|
457
|
+
# Find and extract CSS custom properties from style tags
|
|
458
|
+
css_variable_map = {}
|
|
459
|
+
style_tag_pattern = re.compile(r"<style.*?>(.*?)</style>", re.DOTALL)
|
|
460
|
+
style_blocks = style_tag_pattern.findall(svg_content)
|
|
461
|
+
|
|
462
|
+
# Parse all CSS custom properties from style blocks
|
|
463
|
+
for style_block in style_blocks:
|
|
464
|
+
# Match patterns like --color-primary: #ff0000;
|
|
465
|
+
css_variable_pattern = re.compile(r"--([a-zA-Z0-9_-]+)\s*:\s*([^;]+);")
|
|
466
|
+
for match in css_variable_pattern.finditer(style_block):
|
|
467
|
+
variable_name = match.group(1)
|
|
468
|
+
variable_value = match.group(2).strip()
|
|
469
|
+
css_variable_map[f"--{variable_name}"] = variable_value
|
|
470
|
+
|
|
471
|
+
# Remove all style blocks from the SVG
|
|
472
|
+
svg_without_style_blocks = style_tag_pattern.sub("", svg_content)
|
|
473
|
+
|
|
474
|
+
# Function to replace var() references with their actual values
|
|
475
|
+
def replace_css_variable_reference(match):
|
|
476
|
+
variable_name = match.group(1).strip()
|
|
477
|
+
fallback_value = match.group(2) if match.group(2) else None
|
|
478
|
+
|
|
479
|
+
if variable_name in css_variable_map:
|
|
480
|
+
return css_variable_map[variable_name]
|
|
481
|
+
elif fallback_value:
|
|
482
|
+
return fallback_value.strip(", ")
|
|
483
|
+
else:
|
|
484
|
+
return "" # If variable not found and no fallback provided
|
|
485
|
+
|
|
486
|
+
# Pattern to match var(--name) or var(--name, fallback)
|
|
487
|
+
variable_usage_pattern = re.compile(r"var\(\s*(--([\w-]+))\s*(,\s*([^)]+))?\s*\)")
|
|
488
|
+
|
|
489
|
+
# Repeatedly replace all var() references until none remain
|
|
490
|
+
# This handles nested variables or variables that reference other variables
|
|
491
|
+
processed_svg = svg_without_style_blocks
|
|
492
|
+
while variable_usage_pattern.search(processed_svg):
|
|
493
|
+
processed_svg = variable_usage_pattern.sub(
|
|
494
|
+
lambda m: replace_css_variable_reference(m), processed_svg
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
return processed_svg
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kerykeion-4.26.0rc1 → kerykeion-4.26.1}/kerykeion/relationship_score/relationship_score_factory.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
|