From 80b74f79dfbfa9afb845172a5ea84110d75f1bc8 Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Thu, 13 Mar 2025 01:01:20 +0800 Subject: refactor(project)!: first implementation of the Conventional Role Play SDK with core components, renderers, extractors, and example usage. --- docs/source/api.md | 94 +++++++++++++++++++++++ docs/source/usage.md | 58 ++++++++++++++ examples/basic_usage.py | 31 ++++++++ examples/custom_plugin.py | 25 ++++++ pyproject.toml | 20 ++--- src/conventionalrp/__init__.py | 1 + src/conventionalrp/__main__.py | 7 ++ src/conventionalrp/_core.pyi | 3 + src/conventionalrp/base.py | 0 src/conventionalrp/core/__init__.py | 4 + src/conventionalrp/core/parser.py | 15 ++++ src/conventionalrp/core/processor.py | 39 ++++++++++ src/conventionalrp/extractors/__init__.py | 4 + src/conventionalrp/extractors/base.py | 9 +++ src/conventionalrp/extractors/rule_extractor.py | 24 ++++++ src/conventionalrp/html_renderer.py | 0 src/conventionalrp/json_renderer.py | 0 src/conventionalrp/markdown_renderer.py | 0 src/conventionalrp/plugins/__init__.py | 4 + src/conventionalrp/plugins/plugin_manager.py | 0 src/conventionalrp/renderers/__init__.py | 4 + src/conventionalrp/renderers/base.py | 6 ++ src/conventionalrp/renderers/html_renderer.py | 21 +++++ src/conventionalrp/renderers/json_renderer.py | 9 +++ src/conventionalrp/renderers/markdown_renderer.py | 26 +++++++ src/conventionalrp/tokenizer.py | 0 src/conventionalrp/utils/__init__.py | 2 + src/conventionalrp/utils/text_processing.py | 0 src/pyo3_template/__init__.py | 0 src/pyo3_template/__main__.py | 8 -- src/pyo3_template/_core.pyi | 3 - tests/test_pyo3.py | 2 +- uv.lock | 69 +++++++++-------- 33 files changed, 430 insertions(+), 58 deletions(-) create mode 100644 docs/source/api.md create mode 100644 docs/source/usage.md create mode 100644 examples/basic_usage.py create mode 100644 examples/custom_plugin.py create mode 100644 src/conventionalrp/__init__.py create mode 100644 src/conventionalrp/__main__.py create mode 100644 src/conventionalrp/_core.pyi create mode 100644 src/conventionalrp/base.py create mode 100644 src/conventionalrp/core/__init__.py create mode 100644 src/conventionalrp/core/parser.py create mode 100644 src/conventionalrp/core/processor.py create mode 100644 src/conventionalrp/extractors/__init__.py create mode 100644 src/conventionalrp/extractors/base.py create mode 100644 src/conventionalrp/extractors/rule_extractor.py create mode 100644 src/conventionalrp/html_renderer.py create mode 100644 src/conventionalrp/json_renderer.py create mode 100644 src/conventionalrp/markdown_renderer.py create mode 100644 src/conventionalrp/plugins/__init__.py create mode 100644 src/conventionalrp/plugins/plugin_manager.py create mode 100644 src/conventionalrp/renderers/__init__.py create mode 100644 src/conventionalrp/renderers/base.py create mode 100644 src/conventionalrp/renderers/html_renderer.py create mode 100644 src/conventionalrp/renderers/json_renderer.py create mode 100644 src/conventionalrp/renderers/markdown_renderer.py create mode 100644 src/conventionalrp/tokenizer.py create mode 100644 src/conventionalrp/utils/__init__.py create mode 100644 src/conventionalrp/utils/text_processing.py delete mode 100644 src/pyo3_template/__init__.py delete mode 100644 src/pyo3_template/__main__.py delete mode 100644 src/pyo3_template/_core.pyi diff --git a/docs/source/api.md b/docs/source/api.md new file mode 100644 index 0000000..d1c381b --- /dev/null +++ b/docs/source/api.md @@ -0,0 +1,94 @@ +# API Documentation for TRPG Log Processor + +## Overview + +The TRPG Log Processor SDK provides a structured way to parse, extract, and render logs from tabletop role-playing games (TRPGs). This document outlines the key components of the SDK, including classes, methods, and their functionalities. + +## Core Components + +### Parser + +- **Class**: `Parser` +- **Module**: `src/conventionalrp/core/parser.py` +- **Methods**: + - `parse_log(log: str) -> List[Token]`: Parses a TRPG log string and returns a list of tokens. + - `load_rules(rules_file: str) -> None`: Loads parsing rules from a specified file. + +### Processor + +- **Class**: `Processor` +- **Module**: `src/conventionalrp/core/processor.py` +- **Methods**: + - `process_tokens(tokens: List[Token]) -> None`: Processes a list of tokens. + - `generate_output(format: str) -> str`: Generates output in the specified format (e.g., HTML, Markdown, JSON). + +## Extractors + +### BaseExtractor + +- **Class**: `BaseExtractor` +- **Module**: `src/conventionalrp/extractors/base.py` +- **Methods**: + - `extract(data: Any) -> Any`: Extracts relevant data based on defined rules. + - `load_rules(rules_file: str) -> None`: Loads extraction rules from a specified file. + +### RuleExtractor + +- **Class**: `RuleExtractor` +- **Module**: `src/conventionalrp/extractors/rule_extractor.py` +- **Methods**: + - `extract(data: Any) -> List[Rule]`: Extracts rules from JSON configuration files. + +## Renderers + +### BaseRenderer + +- **Class**: `BaseRenderer` +- **Module**: `src/conventionalrp/renderers/base.py` +- **Methods**: + - `render(data: Any) -> str`: Renders data into a specific format. + - `set_style(style: str) -> None`: Sets the rendering style. + +### HTMLRenderer + +- **Class**: `HTMLRenderer` +- **Module**: `src/conventionalrp/renderers/html_renderer.py` +- **Methods**: + - `render(data: Any) -> str`: Renders data into HTML format. + +### MarkdownRenderer + +- **Class**: `MarkdownRenderer` +- **Module**: `src/conventionalrp/renderers/markdown_renderer.py` +- **Methods**: + - `render(data: Any) -> str`: Renders data into Markdown format. + +### JSONRenderer + +- **Class**: `JSONRenderer` +- **Module**: `src/conventionalrp/renderers/json_renderer.py` +- **Methods**: + - `render(data: Any) -> str`: Renders data into JSON format. + +## Plugins + +### PluginManager + +- **Class**: `PluginManager` +- **Module**: `src/conventionalrp/plugins/plugin_manager.py` +- **Methods**: + - `load_plugins() -> None`: Loads available plugins. + - `execute_plugin(name: str, data: Any) -> Any`: Executes a specified plugin with the provided data. + +## Utilities + +### Text Processing + +- **Module**: `src/conventionalrp/utils/text_processing.py` +- **Functions**: + - `tokenize(text: str) -> List[str]`: Tokenizes input text into a list of tokens. + - `match_regex(pattern: str, text: str) -> List[str]`: Matches a regex pattern against the input text. + +## Conclusion + +This API documentation provides a comprehensive overview of the TRPG Log Processor SDK. For detailed usage instructions and examples, please refer to the `usage.md` file in the `docs` directory. diff --git a/docs/source/usage.md b/docs/source/usage.md new file mode 100644 index 0000000..33481ca --- /dev/null +++ b/docs/source/usage.md @@ -0,0 +1,58 @@ +# Usage Instructions for TRPG Log Processor + +## Overview + +The TRPG Log Processor is a Python SDK designed for structured processing of tabletop role-playing game (TRPG) logs. It provides functionalities for parsing logs, extracting rules, and rendering outputs in multiple formats. + +## Installation + +To install the TRPG Log Processor, you can use pip: + +```bash +pip install conventionalrp +``` + +## Basic Usage + +Here is a simple example of how to use the TRPG Log Processor: + +```python +from conventionalrp.core.parser import Parser +from conventionalrp.core.processor import Processor +from conventionalrp.extractors.rule_extractor import RuleExtractor +from conventionalrp.renderers.html_renderer import HTMLRenderer + +# Step 1: Load rules +rule_extractor = RuleExtractor() +rules = rule_extractor.load_rules('path/to/rules.json') + +# Step 2: Parse the log +parser = Parser(rules) +parsed_log = parser.parse_log('path/to/log.txt') + +# Step 3: Process the parsed tokens +processor = Processor() +output = processor.process_tokens(parsed_log) + +# Step 4: Render the output +renderer = HTMLRenderer() +html_output = renderer.render(output) + +# Save or display the output +with open('output.html', 'w') as f: + f.write(html_output) +``` + +## Features + +- **Rule Extraction**: Easily extract rules from JSON configuration files using the `RuleExtractor`. +- **Multi-format Rendering**: Render outputs in various formats such as HTML, Markdown, and JSON using the respective renderer classes. +- **Extensibility**: Create custom plugins to extend the functionality of the SDK. + +## Custom Plugins + +To create a custom plugin, you can follow the example provided in `examples/custom_plugin.py`. This allows you to add additional processing or rendering capabilities tailored to your needs. + +## Documentation + +For more detailed information on the API and available classes, please refer to the [API documentation](api.md). diff --git a/examples/basic_usage.py b/examples/basic_usage.py new file mode 100644 index 0000000..e2209da --- /dev/null +++ b/examples/basic_usage.py @@ -0,0 +1,31 @@ +from trpg_log_processor.core.parser import Parser +from trpg_log_processor.core.processor import Processor +from trpg_log_processor.extractors.rule_extractor import RuleExtractor +from trpg_log_processor.renderers.html_renderer import HTMLRenderer + +def main(): + # Initialize the parser and load rules + parser = Parser() + parser.load_rules('path/to/rules.json') + + # Parse the TRPG log + log_data = "Your TRPG log data here" + parsed_tokens = parser.parse_log(log_data) + + # Initialize the rule extractor + extractor = RuleExtractor() + rules = extractor.extract('path/to/rules.json') + + # Process the parsed tokens + processor = Processor() + processed_data = processor.process_tokens(parsed_tokens, rules) + + # Render the output in HTML format + renderer = HTMLRenderer() + output = renderer.render(processed_data) + + # Print or save the output + print(output) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/custom_plugin.py b/examples/custom_plugin.py new file mode 100644 index 0000000..74a0bcc --- /dev/null +++ b/examples/custom_plugin.py @@ -0,0 +1,25 @@ +from trpg_log_processor.plugins.plugin_manager import PluginManager + +class CustomPlugin: + def __init__(self): + self.name = "Custom Plugin" + + def process(self, data): + # Custom processing logic + processed_data = data.upper() # Example transformation + return processed_data + +def main(): + plugin_manager = PluginManager() + custom_plugin = CustomPlugin() + + plugin_manager.register_plugin(custom_plugin) + + # Example data to process + data = "This is a sample TRPG log." + result = custom_plugin.process(data) + + print(f"Processed Data: {result}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 6081a51..e8f26b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,16 +3,16 @@ requires = ["maturin>=1.4,<2.0"] build-backend = "maturin" [project] -name = "pyo3_template" +name = "conventionalrp" dynamic = ["version"] -description = "HydroRoll Pyo3 Project Template" -authors = [{ name = "yourname", email = "you@hydroroll.team" }] +description = "HydroRoll Conventional Role Play SDK" +authors = [{ name = "HsiangNianian", email = "leader@hydroroll.team" }] dependencies = [] requires-python = ">=3.9" readme.content-type = "text/x-rst" readme.text = """ """ -license = { text = "MIT" } +license = { text = "AGPLv3.0" } keywords = ["hydroroll"] classifiers = [ "Development Status :: 5 - Production/Stable", @@ -27,17 +27,13 @@ classifiers = [ [project.urls] homepage = "https://hydroroll.team/" -repository = "https://github.com/HydroRoll-Team/{project}" -documentation = "https://{project}.hydroroll.team/" - -[project.scripts] -pyo3_template = "pyo3_template.__main__:main" -pyo3t = "pyo3_template.__main__:main" +repository = "https://github.com/HydroRoll-Team/conventional_role_play" +documentation = "https://crp.hydroroll.team/" [tool.maturin] features = ["pyo3/extension-module"] -module-name = "pyo3_template._core" -python-package = "pyo3_template" +module-name = "conventionalrp._core" +python-package = "conventionalrp" python-source = "src" [tool.ruff] diff --git a/src/conventionalrp/__init__.py b/src/conventionalrp/__init__.py new file mode 100644 index 0000000..4522950 --- /dev/null +++ b/src/conventionalrp/__init__.py @@ -0,0 +1 @@ +from . import _core \ No newline at end of file diff --git a/src/conventionalrp/__main__.py b/src/conventionalrp/__main__.py new file mode 100644 index 0000000..01b510d --- /dev/null +++ b/src/conventionalrp/__main__.py @@ -0,0 +1,7 @@ +from ._core import sum_as_string + +def main(): + print(sum_as_string(1, 2)) + +if __name__ == "__main__": + main() diff --git a/src/conventionalrp/_core.pyi b/src/conventionalrp/_core.pyi new file mode 100644 index 0000000..4945a82 --- /dev/null +++ b/src/conventionalrp/_core.pyi @@ -0,0 +1,3 @@ +def sum_as_string(self, a: int, b: int) -> str: ... + +class Base: ... \ No newline at end of file diff --git a/src/conventionalrp/base.py b/src/conventionalrp/base.py new file mode 100644 index 0000000..e69de29 diff --git a/src/conventionalrp/core/__init__.py b/src/conventionalrp/core/__init__.py new file mode 100644 index 0000000..7097e41 --- /dev/null +++ b/src/conventionalrp/core/__init__.py @@ -0,0 +1,4 @@ +# FILE: /trpg-log-processor/trpg-log-processor/src/trpg_log_processor/core/__init__.py +""" +This file initializes the core module of the trpg_log_processor SDK. +""" \ No newline at end of file diff --git a/src/conventionalrp/core/parser.py b/src/conventionalrp/core/parser.py new file mode 100644 index 0000000..32b1b9f --- /dev/null +++ b/src/conventionalrp/core/parser.py @@ -0,0 +1,15 @@ +class Parser: + def __init__(self): + self.rules = [] + + def load_rules(self, rules): + """Load parsing rules.""" + self.rules = rules + + def parse_log(self, log): + """Parse the TRPG log based on loaded rules.""" + parsed_data = [] + for rule in self.rules: + # Implement rule-based parsing logic here + pass + return parsed_data \ No newline at end of file diff --git a/src/conventionalrp/core/processor.py b/src/conventionalrp/core/processor.py new file mode 100644 index 0000000..40033cf --- /dev/null +++ b/src/conventionalrp/core/processor.py @@ -0,0 +1,39 @@ +class Processor: + def __init__(self, rules): + self.rules = rules + + def process_tokens(self, tokens): + processed_data = [] + for token in tokens: + processed_data.append(self.apply_rules(token)) + return processed_data + + def apply_rules(self, token): + # Implement rule application logic here + for rule in self.rules: + if rule.matches(token): + return rule.apply(token) + return token + + def generate_output(self, processed_data, format_type): + # Implement output generation logic based on format_type + if format_type == 'json': + return self.generate_json_output(processed_data) + elif format_type == 'html': + return self.generate_html_output(processed_data) + elif format_type == 'markdown': + return self.generate_markdown_output(processed_data) + else: + raise ValueError("Unsupported format type") + + def generate_json_output(self, processed_data): + import json + return json.dumps(processed_data) + + def generate_html_output(self, processed_data): + # Implement HTML output generation + return "" + "".join(f"
{data}
" for data in processed_data) + "" + + def generate_markdown_output(self, processed_data): + # Implement Markdown output generation + return "\n".join(f"- {data}" for data in processed_data) \ No newline at end of file diff --git a/src/conventionalrp/extractors/__init__.py b/src/conventionalrp/extractors/__init__.py new file mode 100644 index 0000000..d27a5eb --- /dev/null +++ b/src/conventionalrp/extractors/__init__.py @@ -0,0 +1,4 @@ +# FILE: /trpg-log-processor/trpg-log-processor/src/trpg_log_processor/extractors/__init__.py +""" +This file initializes the extractors module. +""" \ No newline at end of file diff --git a/src/conventionalrp/extractors/base.py b/src/conventionalrp/extractors/base.py new file mode 100644 index 0000000..fc42f29 --- /dev/null +++ b/src/conventionalrp/extractors/base.py @@ -0,0 +1,9 @@ +class BaseExtractor: + def __init__(self): + self.rules = [] + + def extract(self, log_data): + raise NotImplementedError("Subclasses should implement this method.") + + def load_rules(self, rules_source): + raise NotImplementedError("Subclasses should implement this method.") \ No newline at end of file diff --git a/src/conventionalrp/extractors/rule_extractor.py b/src/conventionalrp/extractors/rule_extractor.py new file mode 100644 index 0000000..78e8505 --- /dev/null +++ b/src/conventionalrp/extractors/rule_extractor.py @@ -0,0 +1,24 @@ +class BaseExtractor: + def extract(self): + raise NotImplementedError("This method should be overridden by subclasses.") + + def load_rules(self, rules): + raise NotImplementedError("This method should be overridden by subclasses.") + + +class RuleExtractor(BaseExtractor): + def __init__(self, config_file): + self.config_file = config_file + self.rules = self.load_rules_from_file() + + def load_rules_from_file(self): + import json + with open(self.config_file, 'r') as file: + return json.load(file) + + def extract(self): + # Implement rule extraction logic here + extracted_rules = [] + for rule in self.rules: + extracted_rules.append(rule) # Placeholder for actual extraction logic + return extracted_rules \ No newline at end of file diff --git a/src/conventionalrp/html_renderer.py b/src/conventionalrp/html_renderer.py new file mode 100644 index 0000000..e69de29 diff --git a/src/conventionalrp/json_renderer.py b/src/conventionalrp/json_renderer.py new file mode 100644 index 0000000..e69de29 diff --git a/src/conventionalrp/markdown_renderer.py b/src/conventionalrp/markdown_renderer.py new file mode 100644 index 0000000..e69de29 diff --git a/src/conventionalrp/plugins/__init__.py b/src/conventionalrp/plugins/__init__.py new file mode 100644 index 0000000..32fa8a0 --- /dev/null +++ b/src/conventionalrp/plugins/__init__.py @@ -0,0 +1,4 @@ +# FILE: /trpg-log-processor/trpg-log-processor/src/trpg_log_processor/plugins/__init__.py +""" +This file initializes the plugins module. +""" \ No newline at end of file diff --git a/src/conventionalrp/plugins/plugin_manager.py b/src/conventionalrp/plugins/plugin_manager.py new file mode 100644 index 0000000..e69de29 diff --git a/src/conventionalrp/renderers/__init__.py b/src/conventionalrp/renderers/__init__.py new file mode 100644 index 0000000..ce04364 --- /dev/null +++ b/src/conventionalrp/renderers/__init__.py @@ -0,0 +1,4 @@ +# FILE: /trpg-log-processor/trpg-log-processor/src/trpg_log_processor/renderers/__init__.py +""" +This file initializes the renderers module. +""" \ No newline at end of file diff --git a/src/conventionalrp/renderers/base.py b/src/conventionalrp/renderers/base.py new file mode 100644 index 0000000..498adec --- /dev/null +++ b/src/conventionalrp/renderers/base.py @@ -0,0 +1,6 @@ +class BaseRenderer: + def render(self, data): + raise NotImplementedError("Render method must be implemented by subclasses.") + + def set_style(self, style): + self.style = style \ No newline at end of file diff --git a/src/conventionalrp/renderers/html_renderer.py b/src/conventionalrp/renderers/html_renderer.py new file mode 100644 index 0000000..3c30549 --- /dev/null +++ b/src/conventionalrp/renderers/html_renderer.py @@ -0,0 +1,21 @@ +from .base import BaseRenderer + +class HTMLRenderer(BaseRenderer): + def __init__(self): + super().__init__() + self.title = "TRPG Log Output" + + def render(self, data): + html_content = f"