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 +48 -0
- qsln_py-1.0.0/README.md +35 -0
- qsln_py-1.0.0/pyproject.toml +23 -0
- qsln_py-1.0.0/qsln.py +83 -0
- qsln_py-1.0.0/qsln_py.egg-info/PKG-INFO +48 -0
- qsln_py-1.0.0/qsln_py.egg-info/SOURCES.txt +7 -0
- qsln_py-1.0.0/qsln_py.egg-info/dependency_links.txt +1 -0
- qsln_py-1.0.0/qsln_py.egg-info/top_level.txt +1 -0
- qsln_py-1.0.0/setup.cfg +4 -0
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.
|
qsln_py-1.0.0/README.md
ADDED
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qsln
|
qsln_py-1.0.0/setup.cfg
ADDED