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.
- {ckparser-0.3/ckparser.egg-info → ckparser-0.3.2}/PKG-INFO +1 -1
- {ckparser-0.3 → ckparser-0.3.2/ckparser.egg-info}/PKG-INFO +1 -1
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.py +33 -17
- {ckparser-0.3 → ckparser-0.3.2}/pyproject.toml +1 -1
- {ckparser-0.3 → ckparser-0.3.2}/LICENSE +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/MANIFEST.in +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/README.md +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.egg-info/SOURCES.txt +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.egg-info/dependency_links.txt +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.egg-info/entry_points.txt +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.egg-info/requires.txt +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/ckparser.egg-info/top_level.txt +0 -0
- {ckparser-0.3 → ckparser-0.3.2}/setup.cfg +0 -0
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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":
|
|
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 "{
|
|
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("$"))
|
|
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
|