ckparser 0.3__tar.gz → 0.3.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ckparser
3
- Version: 0.3
3
+ Version: 0.3.2
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ckparser
3
- Version: 0.3
3
+ Version: 0.3.2
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
@@ -41,7 +41,7 @@ import re
41
41
  import time
42
42
 
43
43
  # Script version
44
- __version__ = "0.3"
44
+ __version__ = "0.3.2"
45
45
 
46
46
  # Logger (because logging is awesome)
47
47
  logger = logging.getLogger(__name__)
@@ -102,17 +102,19 @@ regex_string_multiline = re.compile(r"\"[^\"]*\"", re.MULTILINE)
102
102
  # Regex for quoted strings inside quoted strings
103
103
  regex_inner_string = re.compile(r"\|(?P<index>\d+)\|")
104
104
  # Regex to remove comments in files
105
- regex_comment = re.compile(r"(?P<space>\s*)(?P<comment>#.*)")
105
+ regex_comment = re.compile(r"(?P<space>\s*)(?P<comment>#.*)", re.MULTILINE)
106
106
  # Regex to fix blocks with no equal sign
107
- regex_block = re.compile(r"^([^\s\{\=]+)\s*\{\s*$", re.MULTILINE)
107
+ regex_missing = re.compile(r"^(\s*)([\w\.]+)\s+([{])", re.MULTILINE)
108
108
  # Regex to remove "list" prefix
109
109
  regex_list = re.compile(r"\s*=\s*list\s+([\{\"\|])", re.MULTILINE)
110
+ # Regex to split brackets on new lines
111
+ regex_jump = re.compile(r"(\s*)([{}])")
110
112
  # Regex for color blocks (color = [rgb|hsv] { x y z })
111
- regex_color = re.compile(r"=\s*(?P<type>\w+)\s*{")
113
+ regex_color = re.compile(r"=\s*(?P<type>\w+)\s*{", re.MULTILINE)
112
114
  # Regex to parse items with format key=value
113
115
  regex_inline = re.compile(r"([^\s\"]+\s*[?!<=>]+\s*(([^@\"]\[?[^\s]+\]?)|(\"[^\"]+\")|(@\[[^\]]+\]))|(@\w+))")
114
116
  # Regex to parse blocks with bracket below the key/operator
115
- regex_values = re.compile(r"(\s*([?!<=>]+)\s+\{)|(\s+\s*([?!<=>])+\s*\{)")
117
+ regex_block = re.compile(r"(\s*([?!<=>]+)\s+\{)|(\s+\s*([?!<=>])+\s*\{)", re.MULTILINE)
116
118
  # Regex to parse lines with format key=value
117
119
  regex_line = re.compile(r"\"?(?P<key>[^\s\"]+)\"?\s*(?P<operator>[?!<=>]+)\s*(list\s*)?(?P<value>.*)")
118
120
  # Regex to parse independent items in a list
@@ -126,9 +128,11 @@ regex_locale = re.compile(r"^\s*(?P<key>[^\:#]+)\:(\d+)?\s\"(?P<value>.+)\".*$")
126
128
  # Regex for keywords
127
129
  regex_keyword = re.compile(r"(" + "|".join(map(re.escape, sorted(keywords, key=len, reverse=True))) + r") ")
128
130
  # Regex for fixing line count when bracket is below the key/operator
129
- regex_count = re.compile(r"([?!<=>]+)\s*§\n+\s*\{")
131
+ regex_count = re.compile(r"([?!<=>]+)\s*([§\n]+)\s*\{")
130
132
  # Regex for string indexes
131
133
  regex_index = re.compile(r"\|(\d+)\|")
134
+ # Regex to clean line numbers
135
+ regex_clean = re.compile(r"^§+\n", re.MULTILINE)
132
136
  # Regex for variables
133
137
  regex_variables = re.compile(r"\b([\w]+)\b")
134
138
 
@@ -234,15 +238,21 @@ def parse_text(text, return_text_on_error=False, comments=False, dates=False, fi
234
238
  text = regex_comment.sub(replace_comment, text)
235
239
  else:
236
240
  text = regex_comment.sub("", text)
237
- text = text.replace("{", "\n{\n").replace("}", "\n}\n")
238
241
  text = regex_string_multiline.sub(replace, text)
239
- text = regex_list.sub(r"|list=\g<1>", text)
242
+ if missings := regex_missing.findall(text):
243
+ if filename:
244
+ logger.warning(f"Filename: {filename}")
245
+ for _, key, val in missings:
246
+ logger.warning(f"Potential missing `=` operator between `{key}` and `{val}` needs to be fixed.")
247
+ text = regex_missing.sub(r"\g<1>\g<2>=\g<3>", text)
240
248
  text = regex_color.sub(r"={\n\g<1>", text)
249
+ text = regex_list.sub(r"|list=\g<1>", text)
250
+ text = regex_jump.sub(r"\n\g<1>\g<2>\n", text)
241
251
  text = regex_inline.sub(r"\g<1>\n", text)
242
- text = regex_values.sub(r"\g<2>\g<4>{", text)
252
+ text = regex_block.sub(r"\g<2>\g<4>{", text)
243
253
  text = regex_empty.sub(r"\n", text)
244
254
  text = regex_keyword.sub(r"\1|", text)
245
- text = regex_count.sub(r"\g<1>{\n§", text)
255
+ text = regex_count.sub(r"\g<1>{\n\g<2>", text)
246
256
  text = regex_index.sub(lambda match: strings[match.group(1)], text)
247
257
 
248
258
  # Parsing document line by line
@@ -412,10 +422,14 @@ def parse_text(text, return_text_on_error=False, comments=False, dates=False, fi
412
422
  nodes.pop()
413
423
  # If line is a list or list item
414
424
  else:
425
+ # Assuming the parsed file is just an array
426
+ if len(nodes) == 1 and not node:
427
+ root = node = []
428
+ nodes = [("", root)]
415
429
  # Ensure previous data are treated as list
416
430
  if not isinstance(node, list):
417
431
  if len(nodes) < 2:
418
- raise SyntaxError("Incorrect file format or syntax!")
432
+ raise SyntaxError("Incorrect file format or unknown syntax error!")
419
433
  _, prev = nodes[-2]
420
434
  if node_name:
421
435
  if node and isinstance(node, dict):
@@ -466,12 +480,12 @@ def parse_text(text, return_text_on_error=False, comments=False, dates=False, fi
466
480
  result = None
467
481
  if isinstance(result, float):
468
482
  result = round(result, 5)
469
- node.append({"@type": "formula", "@value": value, "@result": result})
483
+ node.append({"@type": "formula", "@value": item, "@result": result})
470
484
  elif item.startswith("@"):
471
485
  if (result := variables.get(item)) is None:
472
486
  if filename:
473
487
  logger.warning(f"Filename: {filename}")
474
- logger.warning(f'Value for "{value}" cannot be found (line: {line_number})')
488
+ logger.warning(f'Value for "{item}" cannot be found (line: {line_number})')
475
489
  node.append({"@type": "variable", "@value": item, "@result": result})
476
490
  elif dates and regex_date.fullmatch(item):
477
491
  item = convert_date(item) or item
@@ -488,7 +502,7 @@ def parse_text(text, return_text_on_error=False, comments=False, dates=False, fi
488
502
  logger.error(f"Line {line_number}: {line_text}")
489
503
  logger.error(f"Parse error: {error}")
490
504
  logger.debug("Exception:", exc_info=True)
491
- return text if return_text_on_error else None
505
+ return regex_clean.sub("", text) if return_text_on_error else None
492
506
  return root
493
507
 
494
508
 
@@ -730,11 +744,13 @@ def revert(obj, from_key=None, prev_key=None, depth=-1, sep="\t", sort=False):
730
744
  if from_key and (from_key.lower() == "this" or not any(regex.match(from_key) for regex in list_keys_rules)):
731
745
  for value in sorted(obj) if sort else obj:
732
746
  lines.extend(revert(value, from_key=from_key, prev_key=prev_key, depth=depth, sep=sep, sort=sort))
733
- elif not any(isinstance(o, (dict, list)) for o in obj):
747
+ elif not any(isinstance(o, (dict, list)) for o in obj) and not any(
748
+ o.startswith("#") and o.endswith("#") for o in obj if isinstance(o, str)
749
+ ):
734
750
  prefix = f"{tabs}{from_key} = {{"
735
751
  # Only for color modes
736
752
  if from_key == "color" and len(obj) == 4 and isinstance(obj[0], str):
737
- prefix = f"{tabs}{from_key} {obj[0]} = {{"
753
+ prefix = f"{tabs}{from_key} = {obj[0]} {{"
738
754
  obj = obj[1:]
739
755
  func = functools.partial(revert_value, from_key=from_key, prev_key=prev_key, sep=sep, sort=sort)
740
756
  values = " ".join(map(str, map(func, obj)))
@@ -777,7 +793,7 @@ def revert_value(value, from_key=None, prev_key=None, **kwargs):
777
793
  return "yes" if value else "no"
778
794
  elif isinstance(value, str):
779
795
  if value.startswith("#") and value.endswith("#"):
780
- return f"#{value}"
796
+ return f"#{value.strip("#")}"
781
797
  elif (
782
798
  " " in value
783
799
  or (value.startswith("$") and value.endswith("$"))
@@ -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.2"
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