Pass section

This commit is contained in:
PedroEdiaz
2025-06-19 21:57:18 -06:00
parent 774d1fd8eb
commit 0f76ad666a
2 changed files with 88 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
package mustache
import "core:log"
import "core:fmt"
import "core:strings"
state :: enum {
@@ -11,31 +11,21 @@ state :: enum {
}
mustache :: proc{mustache_reader, mustache_string}
/*
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.
*/
mustache_string :: proc(fmt: string, v: any , end_block: string = "") -> string {
mustache_string :: proc(fmt: string, data: any , section_key: string = "") -> string {
r : strings.Reader
strings.reader_init(&r, fmt)
return mustache(&r, v, end_block)
return mustache(&r, data, section_key)
}
mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) -> string {
mustache_reader :: proc(r: ^strings.Reader, data: any, section_key: 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
This is the main parser for mustache templates, it's a recursive decent parser, that works as a state machine,
it manipulates the processed template with data, `ret`, and the key to element on data `key`, according to the states.
This approach let us process the data as fast as posible.
*/
b, key: strings.Builder
ret, key: strings.Builder
defer strings.builder_destroy(&key)
s:= state.writing
@@ -53,7 +43,7 @@ mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) ->
case .open_bracket:
s=.reading_key
case .close_bracket:
strings.write_string(&b, "}{" )
strings.write_string(&ret, "}{" )
s=.writing
case .writing:
s=.open_bracket
@@ -63,7 +53,7 @@ mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) ->
case '}':
switch s {
case .open_bracket:
strings.write_string(&b, "{}" )
strings.write_string(&ret, "{}" )
s=.writing
case .close_bracket:
// Work with key
@@ -77,18 +67,33 @@ mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) ->
switch skey[0] {
case '/':
if skey[1:] == end_block {
return strings.to_string(b)
if skey[1:] == section_key {
return strings.to_string(ret)
}
case '#':
strings.write_string(&b, section(r, v, skey[1:]) )
strings.write_string(&ret, section(r, data, skey[1:]) )
case '^':
strings.write_string(&b, section(r, v, skey[1:], true) )
strings.write_string(&ret, section(r, data, skey[1:], true) )
case '&':
strings.write_string(&ret, fmt.tprintf("%v",decode(data, skey[1:])) )
case:
strings.write_string(&b, decode_string(v, skey) )
dec := decode(data, skey)
if dec == nil {
// If not decoded write as key
strings.write_string(&ret, "{{" )
strings.write_string(&ret, skey )
strings.write_string(&ret, "}}" )
break
}
clean := _clean_html(fmt.tprintf("%v", dec))
defer delete(clean)
strings.write_string(&ret, clean)
}
case .writing:
strings.write_rune(&b, '}' )
strings.write_rune(&ret, '}' )
s=.writing
case .reading_key:
s=.close_bracket
@@ -96,15 +101,15 @@ mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) ->
case:
switch s {
case .open_bracket:
strings.write_rune(&b, '{' )
strings.write_rune(&b, c )
strings.write_rune(&ret, '{' )
strings.write_rune(&ret, c )
s=.writing
case .close_bracket:
strings.write_rune(&key, '}' )
strings.write_rune(&key, c )
s=.reading_key
case .writing:
strings.write_rune(&b, c )
strings.write_rune(&ret, c )
s=.writing
case .reading_key:
strings.write_rune(&key, c )
@@ -114,18 +119,18 @@ mustache_reader :: proc(r: ^strings.Reader, v: any, end_block: string = "" ) ->
switch s {
case .open_bracket:
strings.write_rune(&b, '{' )
strings.write_rune(&ret, '{' )
case .reading_key:
strings.write_string(&b,"{{")
strings.write_string(&b,strings.to_string(key))
strings.write_string(&ret,"{{")
strings.write_string(&ret,strings.to_string(key))
case .close_bracket:
strings.write_string(&b,"{{")
strings.write_string(&b,strings.to_string(key))
strings.write_rune(&b, '}' )
strings.write_string(&ret,"{{")
strings.write_string(&ret,strings.to_string(key))
strings.write_rune(&ret, '}' )
case .writing:
}
return strings.to_string(b)
return strings.to_string(ret)
}
/*