ckparser 0.3.2__tar.gz → 0.3.3__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.
- {ckparser-0.3.2/ckparser.egg-info → ckparser-0.3.3}/PKG-INFO +28 -4
- {ckparser-0.3.2 → ckparser-0.3.3}/README.md +27 -3
- {ckparser-0.3.2 → ckparser-0.3.3/ckparser.egg-info}/PKG-INFO +28 -4
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.py +95 -22
- {ckparser-0.3.2 → ckparser-0.3.3}/pyproject.toml +1 -1
- {ckparser-0.3.2 → ckparser-0.3.3}/LICENSE +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/MANIFEST.in +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.egg-info/SOURCES.txt +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.egg-info/dependency_links.txt +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.egg-info/entry_points.txt +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.egg-info/requires.txt +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/ckparser.egg-info/top_level.txt +0 -0
- {ckparser-0.3.2 → ckparser-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ckparser
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Parse Paradox Jomini data files to Python/JSON and revert them back experimentally.
|
|
5
5
|
Author: Marc Debureaux (debnet)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -284,6 +284,29 @@ from ckparser import walk
|
|
|
284
284
|
for value, path in walk(data):
|
|
285
285
|
print(path, value)
|
|
286
286
|
```
|
|
287
|
+
|
|
288
|
+
### `objectify`
|
|
289
|
+
|
|
290
|
+
Transform a dictionary datastructure into an object-like dictionary which allows a better inspection.
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
from ckparser import objectify
|
|
294
|
+
|
|
295
|
+
data = {
|
|
296
|
+
"name": "Louis",
|
|
297
|
+
"traits": [
|
|
298
|
+
"brave",
|
|
299
|
+
"diligent"
|
|
300
|
+
],
|
|
301
|
+
"father": {
|
|
302
|
+
"name": "Charles"
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
obj = objectify(data)
|
|
307
|
+
print(obj.traits[1])
|
|
308
|
+
print(obj.father.name)
|
|
309
|
+
```
|
|
287
310
|
|
|
288
311
|
### `parse_all_locales`
|
|
289
312
|
|
|
@@ -518,9 +541,9 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
518
541
|
|
|
519
542
|
### Parsing
|
|
520
543
|
|
|
521
|
-
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, filename=None, is_global=False)`
|
|
522
|
-
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, is_global=False, patch=None)`
|
|
523
|
-
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, variables_first=True)`
|
|
544
|
+
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, as_object=False, filename=None, is_global=False)`
|
|
545
|
+
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, as_object=False, is_global=False, patch=None)`
|
|
546
|
+
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, as_object=False, variables_first=True)`
|
|
524
547
|
|
|
525
548
|
### Reversion
|
|
526
549
|
|
|
@@ -533,6 +556,7 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
533
556
|
* `convert_date(date, key=None)`
|
|
534
557
|
* `read_file(path, encoding="utf_8_sig")`
|
|
535
558
|
* `walk(obj, *from_keys)`
|
|
559
|
+
* `objectify(item, name="Object", default=None)`
|
|
536
560
|
* `parse_all_locales(path, encoding="utf_8_sig", language="english", save=False)`
|
|
537
561
|
* `load_variables(filepath="_variables.json")`
|
|
538
562
|
* `save_variables(filepath="_variables.json")`
|
|
@@ -253,6 +253,29 @@ from ckparser import walk
|
|
|
253
253
|
for value, path in walk(data):
|
|
254
254
|
print(path, value)
|
|
255
255
|
```
|
|
256
|
+
|
|
257
|
+
### `objectify`
|
|
258
|
+
|
|
259
|
+
Transform a dictionary datastructure into an object-like dictionary which allows a better inspection.
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from ckparser import objectify
|
|
263
|
+
|
|
264
|
+
data = {
|
|
265
|
+
"name": "Louis",
|
|
266
|
+
"traits": [
|
|
267
|
+
"brave",
|
|
268
|
+
"diligent"
|
|
269
|
+
],
|
|
270
|
+
"father": {
|
|
271
|
+
"name": "Charles"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
obj = objectify(data)
|
|
276
|
+
print(obj.traits[1])
|
|
277
|
+
print(obj.father.name)
|
|
278
|
+
```
|
|
256
279
|
|
|
257
280
|
### `parse_all_locales`
|
|
258
281
|
|
|
@@ -487,9 +510,9 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
487
510
|
|
|
488
511
|
### Parsing
|
|
489
512
|
|
|
490
|
-
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, filename=None, is_global=False)`
|
|
491
|
-
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, is_global=False, patch=None)`
|
|
492
|
-
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, variables_first=True)`
|
|
513
|
+
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, as_object=False, filename=None, is_global=False)`
|
|
514
|
+
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, as_object=False, is_global=False, patch=None)`
|
|
515
|
+
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, as_object=False, variables_first=True)`
|
|
493
516
|
|
|
494
517
|
### Reversion
|
|
495
518
|
|
|
@@ -502,6 +525,7 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
502
525
|
* `convert_date(date, key=None)`
|
|
503
526
|
* `read_file(path, encoding="utf_8_sig")`
|
|
504
527
|
* `walk(obj, *from_keys)`
|
|
528
|
+
* `objectify(item, name="Object", default=None)`
|
|
505
529
|
* `parse_all_locales(path, encoding="utf_8_sig", language="english", save=False)`
|
|
506
530
|
* `load_variables(filepath="_variables.json")`
|
|
507
531
|
* `save_variables(filepath="_variables.json")`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ckparser
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Parse Paradox Jomini data files to Python/JSON and revert them back experimentally.
|
|
5
5
|
Author: Marc Debureaux (debnet)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -284,6 +284,29 @@ from ckparser import walk
|
|
|
284
284
|
for value, path in walk(data):
|
|
285
285
|
print(path, value)
|
|
286
286
|
```
|
|
287
|
+
|
|
288
|
+
### `objectify`
|
|
289
|
+
|
|
290
|
+
Transform a dictionary datastructure into an object-like dictionary which allows a better inspection.
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
from ckparser import objectify
|
|
294
|
+
|
|
295
|
+
data = {
|
|
296
|
+
"name": "Louis",
|
|
297
|
+
"traits": [
|
|
298
|
+
"brave",
|
|
299
|
+
"diligent"
|
|
300
|
+
],
|
|
301
|
+
"father": {
|
|
302
|
+
"name": "Charles"
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
obj = objectify(data)
|
|
307
|
+
print(obj.traits[1])
|
|
308
|
+
print(obj.father.name)
|
|
309
|
+
```
|
|
287
310
|
|
|
288
311
|
### `parse_all_locales`
|
|
289
312
|
|
|
@@ -518,9 +541,9 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
518
541
|
|
|
519
542
|
### Parsing
|
|
520
543
|
|
|
521
|
-
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, filename=None, is_global=False)`
|
|
522
|
-
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, is_global=False, patch=None)`
|
|
523
|
-
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, variables_first=True)`
|
|
544
|
+
* `parse_text(text, return_text_on_error=False, comments=False, dates=False, as_object=False, filename=None, is_global=False)`
|
|
545
|
+
* `parse_file(path, output_dir=None, encoding="utf_8_sig", base_dir=None, save=False, comments=False, dates=False, as_object=False, is_global=False, patch=None)`
|
|
546
|
+
* `parse_all_files(path, output_dir=None, encoding="utf_8_sig", keep_data=False, save=False, comments=False, dates=False, as_object=False, variables_first=True)`
|
|
524
547
|
|
|
525
548
|
### Reversion
|
|
526
549
|
|
|
@@ -533,6 +556,7 @@ Paradox scripting languages include many practical exceptions, formatting varian
|
|
|
533
556
|
* `convert_date(date, key=None)`
|
|
534
557
|
* `read_file(path, encoding="utf_8_sig")`
|
|
535
558
|
* `walk(obj, *from_keys)`
|
|
559
|
+
* `objectify(item, name="Object", default=None)`
|
|
536
560
|
* `parse_all_locales(path, encoding="utf_8_sig", language="english", save=False)`
|
|
537
561
|
* `load_variables(filepath="_variables.json")`
|
|
538
562
|
* `save_variables(filepath="_variables.json")`
|
|
@@ -41,7 +41,7 @@ import re
|
|
|
41
41
|
import time
|
|
42
42
|
|
|
43
43
|
# Script version
|
|
44
|
-
__version__ = "0.3.
|
|
44
|
+
__version__ = "0.3.3"
|
|
45
45
|
|
|
46
46
|
# Logger (because logging is awesome)
|
|
47
47
|
logger = logging.getLogger(__name__)
|
|
@@ -120,7 +120,7 @@ regex_line = re.compile(r"\"?(?P<key>[^\s\"]+)\"?\s*(?P<operator>[?!<=>]+)\s*(li
|
|
|
120
120
|
# Regex to parse independent items in a list
|
|
121
121
|
regex_item = re.compile(r"(\"[^\"]+\"|[\d\.]+|[^\s]+)")
|
|
122
122
|
# Regex to parse dates
|
|
123
|
-
regex_date = re.compile(r"^(
|
|
123
|
+
regex_date = re.compile(r"^(?P<year>\d{1,4})\.(?P<month>[1-9]|1[0-2])\.(?P<day>[1-9]|[12]\d|3[01])$")
|
|
124
124
|
# Regex to remove empty lines
|
|
125
125
|
regex_empty = re.compile(r"(\n\s*\n)+", re.MULTILINE)
|
|
126
126
|
# Regex to parse locale files
|
|
@@ -192,14 +192,23 @@ def read_file(path, encoding="utf_8_sig"):
|
|
|
192
192
|
return file.read()
|
|
193
193
|
|
|
194
194
|
|
|
195
|
-
def parse_text(
|
|
195
|
+
def parse_text(
|
|
196
|
+
text,
|
|
197
|
+
return_text_on_error=False,
|
|
198
|
+
comments=False,
|
|
199
|
+
dates=False,
|
|
200
|
+
as_object=False,
|
|
201
|
+
filename=None,
|
|
202
|
+
is_global=False,
|
|
203
|
+
):
|
|
196
204
|
"""
|
|
197
205
|
Parse raw text
|
|
198
206
|
:param text: Text to parse
|
|
199
207
|
:param return_text_on_error: (default false) Return working text document if parsing fails
|
|
200
208
|
:param comments: (default false) Include comments?
|
|
201
209
|
:param dates: (default false) Include dates?
|
|
202
|
-
:param
|
|
210
|
+
:param as_object: (default false) Return data as an object-like instead of dict
|
|
211
|
+
:param filename: (default none) file which is parsed (only for debugging)
|
|
203
212
|
:param is_global: (default false) Are variables global?
|
|
204
213
|
:return: Parsed data as dictionary
|
|
205
214
|
"""
|
|
@@ -503,7 +512,7 @@ def parse_text(text, return_text_on_error=False, comments=False, dates=False, fi
|
|
|
503
512
|
logger.error(f"Parse error: {error}")
|
|
504
513
|
logger.debug("Exception:", exc_info=True)
|
|
505
514
|
return regex_clean.sub("", text) if return_text_on_error else None
|
|
506
|
-
return root
|
|
515
|
+
return objectify(root) if as_object else root
|
|
507
516
|
|
|
508
517
|
|
|
509
518
|
def parse_file(
|
|
@@ -514,6 +523,7 @@ def parse_file(
|
|
|
514
523
|
save=False,
|
|
515
524
|
comments=False,
|
|
516
525
|
dates=False,
|
|
526
|
+
as_object=False,
|
|
517
527
|
is_global=False,
|
|
518
528
|
patch=None,
|
|
519
529
|
):
|
|
@@ -524,12 +534,16 @@ def parse_file(
|
|
|
524
534
|
:param encoding: Encoding used to read file
|
|
525
535
|
:param base_dir: Base directory (for debug)
|
|
526
536
|
:param save: (default false) Save parsed file in output directory
|
|
527
|
-
:param comments: Include comments?
|
|
528
|
-
:param dates: Include dates?
|
|
537
|
+
:param comments: (default false) Include comments?
|
|
538
|
+
:param dates: (default false) Include dates?
|
|
539
|
+
:param as_object: (default false) Return data as an object-like instead of dict
|
|
529
540
|
:param is_global: (default false) Are file's variables global?
|
|
530
541
|
:param patch: String replacement patterns
|
|
531
542
|
:return: Parsed data as dictionary or text if parsing fails
|
|
532
543
|
"""
|
|
544
|
+
if save and as_object:
|
|
545
|
+
logger.warning("`as_object` disabled bacause only dicts can be converted to JSON.")
|
|
546
|
+
as_object = False
|
|
533
547
|
start_time = time.monotonic()
|
|
534
548
|
if base_dir:
|
|
535
549
|
base_dir = os.sep.join(str(base_dir).rstrip(os.sep).split(os.sep)[:-1]) + os.sep
|
|
@@ -543,7 +557,13 @@ def parse_file(
|
|
|
543
557
|
filename = os.path.join(base_dir, os.path.basename(path))
|
|
544
558
|
logger.debug(f"Parsing {filename}")
|
|
545
559
|
data = parse_text(
|
|
546
|
-
text,
|
|
560
|
+
text,
|
|
561
|
+
return_text_on_error=True,
|
|
562
|
+
comments=comments,
|
|
563
|
+
dates=dates,
|
|
564
|
+
as_object=as_object,
|
|
565
|
+
filename=filename,
|
|
566
|
+
is_global=is_global,
|
|
547
567
|
)
|
|
548
568
|
if save:
|
|
549
569
|
filename, _ = os.path.splitext(os.path.basename(path))
|
|
@@ -573,6 +593,7 @@ def parse_all_files(
|
|
|
573
593
|
save=False,
|
|
574
594
|
comments=False,
|
|
575
595
|
dates=False,
|
|
596
|
+
as_object=False,
|
|
576
597
|
variables_first=True,
|
|
577
598
|
_variables_only=False,
|
|
578
599
|
):
|
|
@@ -583,8 +604,9 @@ def parse_all_files(
|
|
|
583
604
|
:param encoding: Encoding used to read files
|
|
584
605
|
:param keep_data: (default false) Return parsed data of all files in a dictionary
|
|
585
606
|
:param save: (default false) Save every parsed data in output directory
|
|
586
|
-
:param comments: Include comments?
|
|
587
|
-
:param dates: Include dates?
|
|
607
|
+
:param comments: (default false) Include comments?
|
|
608
|
+
:param dates: (default false) Include dates?
|
|
609
|
+
:param as_object: (default false) Return data as an object-like instead of dict
|
|
588
610
|
:param variables_first: Try to parse variables first
|
|
589
611
|
:return: Dictionary (key: file, value: parsed data if keep_data=True)
|
|
590
612
|
"""
|
|
@@ -600,6 +622,7 @@ def parse_all_files(
|
|
|
600
622
|
save=save,
|
|
601
623
|
comments=comments,
|
|
602
624
|
dates=dates,
|
|
625
|
+
as_object=as_object,
|
|
603
626
|
variables_first=False,
|
|
604
627
|
_variables_only=True,
|
|
605
628
|
)
|
|
@@ -620,6 +643,7 @@ def parse_all_files(
|
|
|
620
643
|
save=save,
|
|
621
644
|
comments=comments,
|
|
622
645
|
dates=dates,
|
|
646
|
+
as_object=as_object,
|
|
623
647
|
is_global=_variables_only,
|
|
624
648
|
)
|
|
625
649
|
if isinstance(data, str):
|
|
@@ -691,6 +715,48 @@ def walk(obj, *from_keys):
|
|
|
691
715
|
yield obj, from_keys
|
|
692
716
|
|
|
693
717
|
|
|
718
|
+
def objectify(data, name="Object", default=None):
|
|
719
|
+
"""
|
|
720
|
+
Convert a dictionary to an object-like dictionary
|
|
721
|
+
:param data: dictionary
|
|
722
|
+
:param name: name of the object
|
|
723
|
+
:param default: default value for unknown attributes
|
|
724
|
+
:return: object-like dictionary
|
|
725
|
+
"""
|
|
726
|
+
|
|
727
|
+
def _getattr(s, k):
|
|
728
|
+
try:
|
|
729
|
+
object.__getattribute__(s, k)
|
|
730
|
+
except AttributeError:
|
|
731
|
+
return s.get(k, default)
|
|
732
|
+
|
|
733
|
+
if isinstance(data, list):
|
|
734
|
+
return [
|
|
735
|
+
objectify(item)
|
|
736
|
+
for item in data
|
|
737
|
+
if not (isinstance(item, str) and item.startswith("@") and item.endswith("@"))
|
|
738
|
+
]
|
|
739
|
+
elif isinstance(data, dict):
|
|
740
|
+
name = (data.get("@type") or name).title()
|
|
741
|
+
slots = set()
|
|
742
|
+
attrs = dict(__getattr__=lambda s, k: _getattr(s, k), __slots__=slots)
|
|
743
|
+
subdata = {}
|
|
744
|
+
for key, value in data.items():
|
|
745
|
+
if key.startswith("#"):
|
|
746
|
+
continue
|
|
747
|
+
skey = key.replace("@", "_").replace(":", "_")
|
|
748
|
+
if match := regex_date.match(skey):
|
|
749
|
+
skey = "_".join(match.groups())
|
|
750
|
+
skey = f"_{skey}" if key != skey or key[0].isdigit() else skey
|
|
751
|
+
slots.add(skey)
|
|
752
|
+
if isinstance(value, (list, dict)):
|
|
753
|
+
subdata[key] = subdata[skey] = objectify(value)
|
|
754
|
+
continue
|
|
755
|
+
subdata[key] = subdata[skey] = value
|
|
756
|
+
return type(name, (dict,), attrs)(subdata)
|
|
757
|
+
return data
|
|
758
|
+
|
|
759
|
+
|
|
694
760
|
# Tags which are always a list when reverting
|
|
695
761
|
list_keys_rules = [
|
|
696
762
|
# Colors
|
|
@@ -737,6 +803,8 @@ def revert(obj, from_key=None, prev_key=None, depth=-1, sep="\t", sort=False):
|
|
|
737
803
|
elif depth > 0:
|
|
738
804
|
lines.append(f"{tabs}{{")
|
|
739
805
|
for key, value in sorted(obj.items()) if sort else obj.items():
|
|
806
|
+
if key.startswith("_"):
|
|
807
|
+
continue
|
|
740
808
|
lines.extend(revert(value, from_key=key, prev_key=from_key, depth=depth + 1, sep=sep, sort=sort))
|
|
741
809
|
if from_key or depth > 0:
|
|
742
810
|
lines.append(f"{tabs}}}")
|
|
@@ -884,6 +952,22 @@ def save_variables(filepath="_variables.json"):
|
|
|
884
952
|
json_dump(global_variables, file, sort_keys=True)
|
|
885
953
|
|
|
886
954
|
|
|
955
|
+
def enable_logging(debug=False, file=False):
|
|
956
|
+
logger.setLevel(logging.DEBUG)
|
|
957
|
+
formatter = logging.Formatter("[%(asctime)s] %(levelname)s: %(message)s")
|
|
958
|
+
console_handler = logging.StreamHandler()
|
|
959
|
+
console_handler.setLevel(logging.INFO)
|
|
960
|
+
console_handler.setFormatter(formatter)
|
|
961
|
+
logger.addHandler(console_handler)
|
|
962
|
+
if debug:
|
|
963
|
+
console_handler.setLevel(logging.DEBUG)
|
|
964
|
+
if file:
|
|
965
|
+
file_handler = logging.FileHandler("ckparser.log")
|
|
966
|
+
file_handler.setLevel(logging.INFO)
|
|
967
|
+
file_handler.setFormatter(formatter)
|
|
968
|
+
logger.addHandler(file_handler)
|
|
969
|
+
|
|
970
|
+
|
|
887
971
|
def main():
|
|
888
972
|
"""
|
|
889
973
|
Command-line main entrypoint
|
|
@@ -900,18 +984,7 @@ def main():
|
|
|
900
984
|
parser.add_argument("--debug", action="store_true", help="debug mode?")
|
|
901
985
|
args = parser.parse_args()
|
|
902
986
|
|
|
903
|
-
|
|
904
|
-
formatter = logging.Formatter("[%(asctime)s] %(levelname)s: %(message)s")
|
|
905
|
-
console_handler = logging.StreamHandler()
|
|
906
|
-
console_handler.setLevel(logging.INFO)
|
|
907
|
-
console_handler.setFormatter(formatter)
|
|
908
|
-
logger.addHandler(console_handler)
|
|
909
|
-
if args.debug:
|
|
910
|
-
console_handler.setLevel(logging.DEBUG)
|
|
911
|
-
file_handler = logging.FileHandler("ckparser.log")
|
|
912
|
-
file_handler.setLevel(logging.INFO)
|
|
913
|
-
file_handler.setFormatter(formatter)
|
|
914
|
-
logger.addHandler(file_handler)
|
|
987
|
+
enable_logging(debug=args.debug, file=True)
|
|
915
988
|
|
|
916
989
|
if args.revert:
|
|
917
990
|
if os.path.isdir(args.path):
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ckparser"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Parse Paradox Jomini data files to Python/JSON and revert them back experimentally."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|