-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# WSON (Web Simple Object Notation) | ||
|
||
WSON is a simple, readable data interchange format that combines the best features of JSON and YAML while addressing some of their limitations. | ||
|
||
## Features | ||
|
||
- Simple and intuitive syntax | ||
- Supports comments (both // and # styles) | ||
- Preserves the original formatting when possible | ||
- Easy to read and write for humans | ||
- Supports nested objects and arrays | ||
- Handles strings, numbers, booleans, and null values | ||
|
||
## Installation | ||
|
||
You can install WSON using pip: | ||
|
||
``` | ||
pip install wson | ||
``` | ||
|
||
## Usage | ||
|
||
Here's a quick example of how to use WSON in your Python projects: | ||
|
||
```python | ||
import wson | ||
|
||
# Parse WSON string | ||
wson_data = """ | ||
{ | ||
status = "success", | ||
code = 200, | ||
message = "Data retrieved successfully", | ||
user = { | ||
id = 123, | ||
name = "John Doe", | ||
email = "john@example.com", | ||
age = 25 | ||
}, | ||
tasks = [ | ||
{ | ||
task_id = 1, | ||
title = "Complete project report", | ||
status = "in-progress", | ||
due_date = "2024-10-15" | ||
}, | ||
{ | ||
task_id = 2, | ||
title = "Review team feedback", | ||
status = "pending", | ||
due_date = "2024-10-20" | ||
} | ||
] | ||
} | ||
""" | ||
|
||
# Parse WSON to Python dictionary | ||
parsed_data = wson.parse_wson(wson_data) | ||
print(parsed_data) | ||
|
||
# Serialize Python dictionary to WSON | ||
wson_output = wson.serialize_wson(parsed_data) | ||
print(wson_output) | ||
``` | ||
|
||
## Why WSON? | ||
|
||
WSON addresses some limitations of JSON and YAML: | ||
|
||
1. Unlike JSON, WSON supports comments, making it more readable and self-documenting. | ||
2. WSON has a simpler syntax compared to YAML, reducing the chance of indentation errors. | ||
3. WSON preserves the original formatting when possible, unlike JSON which often alters the structure. | ||
4. WSON is more concise than JSON, omitting unnecessary quotation marks for keys. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! Please feel free to submit a Pull Request. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# setup.py | ||
|
||
from setuptools import setup, find_packages | ||
|
||
with open("README.md", "r", encoding="utf-8") as fh: | ||
long_description = fh.read() | ||
|
||
setup( | ||
name="wson", | ||
version="0.1.0", | ||
author="lunastev", | ||
author_email="your.email@example.com", | ||
description="A parser and serializer for WSON (Web Simple Object Notation)", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
url="https://github.com/lunastev/wson", | ||
packages=find_packages(), | ||
classifiers=[ | ||
"Development Status :: 3 - Alpha", | ||
"Intended Audience :: Developers", | ||
"License :: OSI Approved :: MIT License", | ||
"Operating System :: OS Independent", | ||
"Programming Language :: Python :: 3", | ||
"Programming Language :: Python :: 3.6", | ||
"Programming Language :: Python :: 3.7", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.9", | ||
], | ||
python_requires=">=3.6", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import re | ||
|
||
class WSONParseError(Exception): | ||
pass | ||
|
||
def parse_wson(wson_str): | ||
wson_str = remove_comments(wson_str) | ||
return convert_wson_to_dict(wson_str) | ||
|
||
def remove_comments(wson_str): | ||
lines = wson_str.splitlines() | ||
cleaned_lines = [] | ||
for line in lines: | ||
comment_index = line.find('//') | ||
hash_index = line.find('#') | ||
if comment_index != -1: | ||
line = line[:comment_index] | ||
elif hash_index != -1: | ||
line = line[:hash_index] | ||
cleaned_lines.append(line.rstrip()) | ||
return '\n'.join(cleaned_lines) | ||
|
||
def parse_value(value): | ||
value = value.strip() | ||
if not value: | ||
return None | ||
if value.startswith('"') and value.endswith('"'): | ||
return value[1:-1] # 문자열 | ||
elif value.lower() in ['true', 'false']: | ||
return value.lower() == 'true' # 불리언 | ||
elif re.match(r'^-?\d+(\.\d+)?$', value): | ||
return float(value) if '.' in value else int(value) | ||
elif value.startswith('{') and value.endswith('}'): | ||
return convert_wson_to_dict(value) # 중첩 WSON 호출 | ||
elif value.startswith('[') and value.endswith(']'): | ||
return parse_array(value) # 배열 파싱 함수 호출 | ||
raise WSONParseError(f"Invalid value: {value}") | ||
|
||
def parse_array(array_str): | ||
array_str = array_str[1:-1].strip() # [] 제거 | ||
items = [] | ||
current_item = '' | ||
brace_count = 0 | ||
bracket_count = 0 | ||
|
||
for char in array_str: | ||
if char == '{': | ||
brace_count += 1 | ||
elif char == '}': | ||
brace_count -= 1 | ||
elif char == '[': | ||
bracket_count += 1 | ||
elif char == ']': | ||
bracket_count -= 1 | ||
|
||
if char == ',' and brace_count == 0 and bracket_count == 0: | ||
items.append(parse_value(current_item.strip())) | ||
current_item = '' | ||
else: | ||
current_item += char | ||
|
||
if current_item.strip(): | ||
items.append(parse_value(current_item.strip())) | ||
|
||
return items | ||
|
||
def convert_wson_to_dict(wson_str): | ||
wson_str = wson_str.strip() | ||
if not (wson_str.startswith('{') and wson_str.endswith('}')): | ||
raise WSONParseError("WSON format must start and end with curly braces.") | ||
|
||
wson_str = wson_str[1:-1] # {} 제거 | ||
data = {} | ||
key = '' | ||
value = '' | ||
in_key = True | ||
brace_count = 0 | ||
bracket_count = 0 | ||
|
||
for char in wson_str: | ||
if char in ['=', ':'] and in_key and brace_count == 0 and bracket_count == 0: | ||
in_key = False | ||
continue | ||
|
||
if char == '{': | ||
brace_count += 1 | ||
elif char == '}': | ||
brace_count -= 1 | ||
elif char == '[': | ||
bracket_count += 1 | ||
elif char == ']': | ||
bracket_count -= 1 | ||
|
||
if char == ',' and brace_count == 0 and bracket_count == 0: | ||
if key: | ||
data[key.strip()] = parse_value(value.strip()) | ||
key = '' | ||
value = '' | ||
in_key = True | ||
elif in_key: | ||
key += char | ||
else: | ||
value += char | ||
|
||
if key: | ||
data[key.strip()] = parse_value(value.strip()) | ||
|
||
return data | ||
|
||
def serialize_wson(data, indent=''): | ||
return '{\n' + serialize_dict(data, indent + ' ') + '\n' + indent + '}' | ||
|
||
def serialize_dict(data, indent=''): | ||
items = [] | ||
for key, value in data.items(): | ||
if isinstance(value, dict): | ||
items.append(f'{indent}{key} = ' + serialize_wson(value, indent)) | ||
elif isinstance(value, list): | ||
items.append(f'{indent}{key} = [\n' + serialize_list(value, indent + ' ') + f'\n{indent}]') | ||
elif isinstance(value, str): | ||
items.append(f'{indent}{key} = "{value}"') | ||
elif value is None: | ||
items.append(f'{indent}{key} = null') | ||
else: | ||
items.append(f'{indent}{key} = {value}') | ||
return ',\n\n'.join(items) | ||
|
||
def serialize_list(data, indent=''): | ||
items = [] | ||
for item in data: | ||
if isinstance(item, dict): | ||
items.append(indent + serialize_wson(item, indent)) | ||
elif isinstance(item, list): | ||
items.append(indent + '[\n' + serialize_list(item, indent + ' ') + f'\n{indent}]') | ||
elif isinstance(item, str): | ||
items.append(f'{indent}"{item}"') | ||
elif item is None: | ||
items.append(f'{indent}null') | ||
else: | ||
items.append(f'{indent}{item}') | ||
return ',\n'.join(items) | ||
|
||
if __name__ == "__main__": | ||
wson_data = """ | ||
{ | ||
status = "success", | ||
code = 200, | ||
message = "Data retrieved successfully", | ||
user = { | ||
id = 123, | ||
name = "John Doe", | ||
email = "john@example.com", | ||
age = 25 | ||
}, | ||
tasks = [ | ||
{ | ||
task_id = 1, | ||
title = "Complete project report", | ||
status = "in-progress", | ||
due_date = "2024-10-15" | ||
}, | ||
{ | ||
task_id = 2, | ||
title = "Review team feedback", | ||
status = "pending", | ||
due_date = "2024-10-20" | ||
} | ||
] | ||
} | ||
""" | ||
|
||
parsed_data = parse_wson(wson_data) | ||
print("Parsed Data:", parsed_data) | ||
|
||
wson_output = serialize_wson(parsed_data) | ||
print("\nSerialized WSON:\n", wson_output) |