commit dda306aa4373c6ecca716b6ac930e7f1c6e48224 Author: PedroEdiaz Date: Tue May 20 01:54:43 2025 -0600 First commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..76c8fea --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +1-Clause BSD NON-AI License + +Copyright (c) 2025 +NVIAM. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. The source code and any modifications made to it may not be used for the purpose of training or improving machine learning algorithms, +including but not limited to artificial intelligence, natural language processing, or data mining. This condition applies to any derivatives, +modifications, or updates based on the Software code. Any usage of the source code in an AI-training dataset is considered a breach of this License. + +THIS SOFTWARE IS PROVIDED BY NVIAM “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL NVIAM BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..93d7efc --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Templateless + +A lightweight, logicless templating library for the +[Odin programming language](https://odin-lang.org/). This library allows you to +define templates using placeholder variables within strings and replace them +with values from a provided dictionary. + +## Features +- Simple template substitution using `{{key}}` syntax +- Clean and minimal interface +- Designed to integrate easily into Odin projects +- No errors returns + +## Limitations + +- No support for nested templates or conditionals. +- Only basic string replacement — not a full-featured template engine. + +## Usage + +```odin +import "template" + +main :: proc() { + fmt := "Hello, {{name}}! Welcome to {{place}}." + values := map[string]string{ + "name": "Alice", + "place": "Odinland", + } + + result := template.template(fmt, values) + fmt.println(result) // Output: Hello, Alice! Welcome to Odinland. +} +``` + +## Installation +Clone or copy the template module into your Odin project directory: + +```bash +git clone https://github.com/yourusername/odin-template.git +```` + +Or copy `template.odin` into your source tree. + +## Interface + +```odin +template :: proc(fmt: string, dict: map[string]string) -> string +``` + +### Parameters + +* `fmt`: A string with placeholders in the form `{{key}}`. +* `dict`: A map from string to string, where each key corresponds to a placeholder in the format string. + +### Returns + +A new string with all placeholders replaced by their corresponding values from +the dictionary. If a key is missing in the dictionary, the placeholder is +replaces with an empty string. + +## Placeholder Format + +Use `{{key}}` to indicate a variable placeholder in the format string. +Keys must exactly match the strings in the dictionary. + +## License + +1-Clause BSD NON-AI License. See [LICENSE](./LICENSE) for details. + +## Contributing + +Contributions are welcome! Feel free to submit issues or pull requests. diff --git a/template.odin b/template.odin new file mode 100644 index 0000000..6fbb49f --- /dev/null +++ b/template.odin @@ -0,0 +1,76 @@ +package template + +import "core:strings" + +/* +template works as a state machine, it manipulates `b` (returned string) +and `key` (placeholder string), according to the states. No error +returns are needed because if `key` is not close it writes it as +it's not a placeholder +*/ + +state :: enum { + writing, + reading_key, + open_bracket, + close_bracket, +} + +template :: proc(fmt: string, dict: map[string]string ) -> string { + b, key: strings.Builder + defer strings.builder_destroy(&key) + + s:= state.writing + + for c in fmt do switch c { + case '{': + switch s { + case .open_bracket: + s=.reading_key + case .close_bracket: + strings.write_rune(&b, '}' ) + s=.writing + case .writing: + s=.open_bracket + case .reading_key: + } + case '}': + switch s { + case .open_bracket: + strings.write_rune(&b, '{' ) + s=.close_bracket + case .close_bracket: + s=.writing + strings.write_string(&b, dict[strings.to_string(key)] ) + strings.builder_reset(&key) + case .writing: + case .reading_key: + s=.close_bracket + } + case: + switch s { + case .open_bracket: + strings.write_rune(&b, '{' ) + strings.write_rune(&b, c ) + case .close_bracket: + strings.write_rune(&b, '}' ) + strings.write_rune(&b, c ) + case .writing: + strings.write_rune(&b, c ) + case .reading_key: + strings.write_rune(&key, c ) + } + } + + switch s { + case .open_bracket: + strings.write_rune(&b, '{' ) + case .close_bracket: + strings.write_rune(&b, '}' ) + case .writing: + case .reading_key: + strings.write_string(&b,strings.to_string(key)) + } + + return strings.to_string(b) +}