qsln-py 1.0.0__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.
qsln_py-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,48 @@
1
+ Metadata-Version: 2.4
2
+ Name: qsln-py
3
+ Version: 1.0.0
4
+ Summary: Quick Scratch List Notation
5
+ Author: bddjr
6
+ License-Expression: Unlicense
7
+ Project-URL: Homepage, https://github.com/bddjr/QSLN
8
+ Project-URL: Repository, https://github.com/bddjr/QSLN.git
9
+ Keywords: qsln,scratch
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+
14
+ # QSLN
15
+
16
+ Quick Scratch List Notation (Python implementation)
17
+
18
+ About QSLN specification: https://github.com/bddjr/QSLN
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install qsln-py
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ import qsln
30
+
31
+ # Serialize
32
+ encoded = qsln.stringify([["a", "b"], ["cd", "ef"]])
33
+ print(encoded)
34
+ # => "01a01b;02cd02ef;"
35
+
36
+ # Deserialize
37
+ decoded = qsln.parse("01a01b;02cd02ef;")
38
+ print(decoded)
39
+ # => [["a", "b"], ["cd", "ef"]]
40
+ ```
41
+
42
+ > **Note**: `parse` raises a `SyntaxError` on malformed or truncated inputs.
43
+
44
+ ## 📄 License
45
+
46
+ This project is released into the public domain under [The Unlicense](https://unlicense.org).
47
+
48
+ The "Scratch" name is a trademark of the Scratch Foundation.
@@ -0,0 +1,35 @@
1
+ # QSLN
2
+
3
+ Quick Scratch List Notation (Python implementation)
4
+
5
+ About QSLN specification: https://github.com/bddjr/QSLN
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install qsln-py
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```python
16
+ import qsln
17
+
18
+ # Serialize
19
+ encoded = qsln.stringify([["a", "b"], ["cd", "ef"]])
20
+ print(encoded)
21
+ # => "01a01b;02cd02ef;"
22
+
23
+ # Deserialize
24
+ decoded = qsln.parse("01a01b;02cd02ef;")
25
+ print(decoded)
26
+ # => [["a", "b"], ["cd", "ef"]]
27
+ ```
28
+
29
+ > **Note**: `parse` raises a `SyntaxError` on malformed or truncated inputs.
30
+
31
+ ## 📄 License
32
+
33
+ This project is released into the public domain under [The Unlicense](https://unlicense.org).
34
+
35
+ The "Scratch" name is a trademark of the Scratch Foundation.
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qsln-py"
7
+ version = "1.0.0"
8
+ description = "Quick Scratch List Notation"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = "Unlicense"
12
+ authors = [{ name = "bddjr" }]
13
+ keywords = ["qsln", "scratch"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ ]
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/bddjr/QSLN"
20
+ Repository = "https://github.com/bddjr/QSLN.git"
21
+
22
+ [tool.setuptools]
23
+ py-modules = ["qsln"]
qsln_py-1.0.0/qsln.py ADDED
@@ -0,0 +1,83 @@
1
+ # [QSLN] Quick Scratch List Notation
2
+ # Author: bddjr
3
+ # License: The Unlicense
4
+
5
+ from collections.abc import Iterable
6
+ import sys
7
+ from typing import Any
8
+
9
+ __all__ = ["stringify", "parse"]
10
+
11
+ HEX = "0123456789abcdef"
12
+ ErrUnexpectedEndOfInput = "Unexpected end of input"
13
+ UTF16_CODEC = "utf-16le" if sys.byteorder == "little" else "utf-16be"
14
+
15
+
16
+ def stringify(lists: Iterable[Iterable[Any]]) -> str:
17
+ """Serialize a 2D iterable of strings into a QSLN string."""
18
+ out: list[str] = []
19
+ for l in lists:
20
+ for v in l:
21
+ if not isinstance(v, str):
22
+ v = str(v)
23
+ u16_len = len(v.encode(UTF16_CODEC)) >> 1
24
+ l_str = str(u16_len)
25
+ out.append(HEX[len(l_str) - 1])
26
+ out.append(l_str)
27
+ out.append(v)
28
+ out.append(";")
29
+ return "".join(out)
30
+
31
+
32
+ def parse(qsln: str) -> list[list[str]]:
33
+ """Parse a QSLN string into a 2D list of strings."""
34
+ if not isinstance(qsln, str):
35
+ qsln = str(qsln)
36
+ if not qsln:
37
+ raise SyntaxError(ErrUnexpectedEndOfInput)
38
+
39
+ raw = qsln.encode(UTF16_CODEC)
40
+ u16 = memoryview(raw).cast("H")
41
+ length = len(u16)
42
+ out: list[list[str]] = []
43
+ ls: list[str] = []
44
+ i = 0
45
+ while True:
46
+ n = u16[i]
47
+ # ';'
48
+ if n == 59:
49
+ out.append(ls)
50
+ i += 1
51
+ if i == length:
52
+ return out
53
+ ls = []
54
+ continue
55
+
56
+ j = i + 1
57
+ if 48 <= n <= 57:
58
+ # 0-9
59
+ i += n - 46
60
+ else:
61
+ # [A-Fa-f]
62
+ masked = n & -33
63
+ if 65 <= masked <= 70:
64
+ i += masked - 53
65
+ else:
66
+ raise SyntaxError(f"Unexpected token '{chr(n)}' at position {i}")
67
+
68
+ if i >= length:
69
+ raise SyntaxError(ErrUnexpectedEndOfInput)
70
+
71
+ n = 0
72
+ while j < i:
73
+ c = u16[j] - 48
74
+ if c < 0 or c > 9:
75
+ raise SyntaxError(f"Unexpected token '{chr(u16[j])}' at position {j}")
76
+ n = n * 10 + c
77
+ j += 1
78
+
79
+ i += n
80
+ if i >= length:
81
+ raise SyntaxError(ErrUnexpectedEndOfInput)
82
+
83
+ ls.append(u16[j:i].tobytes().decode(UTF16_CODEC))
@@ -0,0 +1,48 @@
1
+ Metadata-Version: 2.4
2
+ Name: qsln-py
3
+ Version: 1.0.0
4
+ Summary: Quick Scratch List Notation
5
+ Author: bddjr
6
+ License-Expression: Unlicense
7
+ Project-URL: Homepage, https://github.com/bddjr/QSLN
8
+ Project-URL: Repository, https://github.com/bddjr/QSLN.git
9
+ Keywords: qsln,scratch
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+
14
+ # QSLN
15
+
16
+ Quick Scratch List Notation (Python implementation)
17
+
18
+ About QSLN specification: https://github.com/bddjr/QSLN
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install qsln-py
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ import qsln
30
+
31
+ # Serialize
32
+ encoded = qsln.stringify([["a", "b"], ["cd", "ef"]])
33
+ print(encoded)
34
+ # => "01a01b;02cd02ef;"
35
+
36
+ # Deserialize
37
+ decoded = qsln.parse("01a01b;02cd02ef;")
38
+ print(decoded)
39
+ # => [["a", "b"], ["cd", "ef"]]
40
+ ```
41
+
42
+ > **Note**: `parse` raises a `SyntaxError` on malformed or truncated inputs.
43
+
44
+ ## 📄 License
45
+
46
+ This project is released into the public domain under [The Unlicense](https://unlicense.org).
47
+
48
+ The "Scratch" name is a trademark of the Scratch Foundation.
@@ -0,0 +1,7 @@
1
+ README.md
2
+ pyproject.toml
3
+ qsln.py
4
+ qsln_py.egg-info/PKG-INFO
5
+ qsln_py.egg-info/SOURCES.txt
6
+ qsln_py.egg-info/dependency_links.txt
7
+ qsln_py.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ qsln
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+