diff --git a/README.md b/README.md index 63eb789..7e996a2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # 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 @@ -11,67 +10,23 @@ with values from a provided dictionary. - 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. +## Non Featureas +- No conditionals nor nested templates. +- Not a full-featured template engine. ## Usage +For library usage and more information run: -```odin -import "template" - -main :: proc() { - fmt := "Hello, {{name}}! Welcome to {{place}}." - values := map[string]string{ - "name": "Alice", - "place": "Odinland", - } - defer delete(values) - - result := template.template(fmt, values) - defer delete(result) - - fmt.println(result) // Output: Hello, Alice! Welcome to Odinland. -} +```sh +odin doc . ``` ## Installation -Clone or copy the template module into your Odin project directory: - -```sh -git clone https://github.com/nviam/odin-templateless.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. +Clone or copy the template module into your Odin project directory. ## License - 1-Clause BSD NON-AI License. See [LICENSE](./LICENSE) for details. ## Contributing - Contributions are welcome! Feel free to submit issues or pull requests. For every issue please add a test diff --git a/template.odin b/template.odin index 4586456..0875346 100644 --- a/template.odin +++ b/template.odin @@ -2,13 +2,7 @@ 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 -*/ - +@private state :: enum { writing, reading_key, @@ -16,7 +10,24 @@ state :: enum { close_bracket, } +/* +Input: +- 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. +*/ template :: proc(fmt: string, dict: map[string]string ) -> string { + /* + 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 + */ + b, key: strings.Builder defer strings.builder_destroy(&key) @@ -46,6 +57,7 @@ template :: proc(fmt: string, dict: map[string]string ) -> string { s=.writing case .writing: strings.write_rune(&b, '}' ) + s=.writing case .reading_key: s=.close_bracket } @@ -61,6 +73,7 @@ template :: proc(fmt: string, dict: map[string]string ) -> string { s=.reading_key case .writing: strings.write_rune(&b, c ) + s=.writing case .reading_key: strings.write_rune(&key, c ) } @@ -69,15 +82,37 @@ template :: proc(fmt: string, dict: map[string]string ) -> string { switch s { case .open_bracket: strings.write_rune(&b, '{' ) + case .reading_key: + strings.write_string(&b,"{{") + strings.write_string(&b,strings.to_string(key)) case .close_bracket: strings.write_string(&b,"{{") strings.write_string(&b,strings.to_string(key)) strings.write_rune(&b, '}' ) case .writing: - case .reading_key: - strings.write_string(&b,"{{") - strings.write_string(&b,strings.to_string(key)) } return strings.to_string(b) } + +/* +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/testing.odin b/testing.odin index 713e05a..fce18c9 100644 --- a/testing.odin +++ b/testing.odin @@ -1,3 +1,4 @@ +#+private package template import "core:testing" @@ -97,3 +98,10 @@ test13 :: proc(t: ^testing.T){ defer delete(tmp) testing.expect(t, tmp==" ", tmp) } +@(test) +test14 :: proc(t: ^testing.T){ + fmt := "{{{}}}" + tmp := template(fmt,{}) + defer delete(tmp) + testing.expect(t, tmp=="}", tmp) +}