Skip to content

Commit

Permalink
wson
Browse files Browse the repository at this point in the history
  • Loading branch information
LunaStev authored Oct 8, 2024
1 parent dbdb1fe commit c44c963
Show file tree
Hide file tree
Showing 3 changed files with 292 additions and 0 deletions.
84 changes: 84 additions & 0 deletions README.md
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.
30 changes: 30 additions & 0 deletions setup.py
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",
)
178 changes: 178 additions & 0 deletions wson.py
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)

0 comments on commit c44c963

Please sign in to comment.