mirror of
https://github.com/sbrow/thor.git
synced 2026-08-26 11:23:32 -04:00
refactor(mustache): Simplified Node parser.
This commit is contained in:
Executable
BIN
Binary file not shown.
+141
-169
@@ -47,25 +47,24 @@ Node_Kind :: enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node :: struct {
|
Node :: struct {
|
||||||
kind: Node_Kind,
|
kind: Node_Kind,
|
||||||
text: string,
|
text: string,
|
||||||
key: string,
|
key: string,
|
||||||
filters: [dynamic; MAX_PIPES]Pipe_Filter,
|
filters: [dynamic; MAX_PIPES]Pipe_Filter,
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
indent: string,
|
indent: string,
|
||||||
first_child: int,
|
children: []Node,
|
||||||
child_count: int,
|
content: string,
|
||||||
content: string,
|
pos: int,
|
||||||
pos: int,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// node_span returns the number of flat-array entries a node occupies:
|
// node_span returns the number of flat-array entries a node occupies:
|
||||||
// 1 for leaf nodes, 1 + child_count for container nodes (whose children
|
// 1 for leaf nodes, 1 + len(children) for container nodes (whose children
|
||||||
// are stored contiguously after them in the array).
|
// are stored contiguously after them in the array).
|
||||||
node_span :: proc(n: Node) -> int {
|
node_span :: proc(n: Node) -> int {
|
||||||
#partial switch n.kind {
|
#partial switch n.kind {
|
||||||
case .Section, .Inverted, .Parent, .Block:
|
case .Section, .Inverted, .Parent, .Block:
|
||||||
return 1 + n.child_count
|
return 1 + len(n.children)
|
||||||
case:
|
case:
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -78,10 +77,8 @@ Template :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Block_Override :: struct {
|
Block_Override :: struct {
|
||||||
all_nodes: []Node,
|
nodes: []Node,
|
||||||
first: int,
|
source: Template,
|
||||||
count: int,
|
|
||||||
source: Template,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_template :: proc(tmpl: ^Template) {
|
delete_template :: proc(tmpl: ^Template) {
|
||||||
@@ -122,7 +119,7 @@ parse :: proc(
|
|||||||
}
|
}
|
||||||
tmpl.source = source
|
tmpl.source = source
|
||||||
tmpl.path = path
|
tmpl.path = path
|
||||||
deindent_blocks(tmpl.nodes[:], 0, len(tmpl.nodes), allocator)
|
deindent_blocks(tmpl.nodes[:], allocator)
|
||||||
return tmpl, nil
|
return tmpl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +141,7 @@ render :: proc(
|
|||||||
append(&ctx, data)
|
append(&ctx, data)
|
||||||
|
|
||||||
all_nodes := tmpl.nodes[:]
|
all_nodes := tmpl.nodes[:]
|
||||||
err = render_nodes(tmpl, all_nodes, all_nodes, &ctx, partials, &builder)
|
err = render_nodes(tmpl, all_nodes, &ctx, partials, &builder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@@ -170,6 +167,7 @@ parse_tokens :: proc(
|
|||||||
nodes = make([dynamic]Node, 0, len(tokens), allocator)
|
nodes = make([dynamic]Node, 0, len(tokens), allocator)
|
||||||
pos := 0
|
pos := 0
|
||||||
err = parse_section(tokens, &pos, &nodes, "", source, allocator, 0)
|
err = parse_section(tokens, &pos, &nodes, "", source, allocator, 0)
|
||||||
|
assert(len(nodes) <= cap(nodes))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,12 +185,12 @@ parse_section :: proc(
|
|||||||
|
|
||||||
switch tok.kind {
|
switch tok.kind {
|
||||||
case .Text:
|
case .Text:
|
||||||
append(nodes, Node{kind = .Text, text = tok.value, first_child = -1, pos = tok.pos})
|
append(nodes, Node{kind = .Text, text = tok.value, pos = tok.pos})
|
||||||
pos^ += 1
|
pos^ += 1
|
||||||
|
|
||||||
case .Variable:
|
case .Variable:
|
||||||
idx := len(nodes)
|
idx := len(nodes)
|
||||||
append(nodes, Node{kind = .Variable, first_child = -1})
|
append(nodes, Node{kind = .Variable})
|
||||||
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return Error_Body {
|
return Error_Body {
|
||||||
@@ -206,7 +204,7 @@ parse_section :: proc(
|
|||||||
|
|
||||||
case .Unescaped:
|
case .Unescaped:
|
||||||
idx := len(nodes)
|
idx := len(nodes)
|
||||||
append(nodes, Node{kind = .Unescaped, first_child = -1})
|
append(nodes, Node{kind = .Unescaped})
|
||||||
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return Error_Body {
|
return Error_Body {
|
||||||
@@ -226,7 +224,7 @@ parse_section :: proc(
|
|||||||
idx := len(nodes)
|
idx := len(nodes)
|
||||||
content_start := 0
|
content_start := 0
|
||||||
if pos^ < len(tokens) {content_start = tokens[pos^].pos}
|
if pos^ < len(tokens) {content_start = tokens[pos^].pos}
|
||||||
append(nodes, Node{kind = .Section, first_child = -1, pos = tok.pos})
|
append(nodes, Node{kind = .Section, pos = tok.pos})
|
||||||
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return Error_Body {
|
return Error_Body {
|
||||||
@@ -239,8 +237,7 @@ parse_section :: proc(
|
|||||||
parse_section(tokens, pos, nodes, pipe_key, source, allocator, tok.pos) or_return
|
parse_section(tokens, pos, nodes, pipe_key, source, allocator, tok.pos) or_return
|
||||||
close_pos := 0
|
close_pos := 0
|
||||||
if pos^ - 1 >= 0 && pos^ - 1 < len(tokens) {close_pos = tokens[pos^ - 1].pos}
|
if pos^ - 1 >= 0 && pos^ - 1 < len(tokens) {close_pos = tokens[pos^ - 1].pos}
|
||||||
nodes[idx].first_child = idx + 1
|
nodes[idx].children = nodes[idx + 1:len(nodes)]
|
||||||
nodes[idx].child_count = len(nodes) - idx - 1
|
|
||||||
nodes[idx].content = source[content_start:close_pos]
|
nodes[idx].content = source[content_start:close_pos]
|
||||||
|
|
||||||
case .Inverted_Open:
|
case .Inverted_Open:
|
||||||
@@ -248,7 +245,7 @@ parse_section :: proc(
|
|||||||
idx := len(nodes)
|
idx := len(nodes)
|
||||||
content_start := 0
|
content_start := 0
|
||||||
if pos^ < len(tokens) {content_start = tokens[pos^].pos}
|
if pos^ < len(tokens) {content_start = tokens[pos^].pos}
|
||||||
append(nodes, Node{kind = .Inverted, first_child = -1, pos = tok.pos})
|
append(nodes, Node{kind = .Inverted, pos = tok.pos})
|
||||||
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
pipe_key, perr := parse_pipeline(tok.value, &nodes[idx].filters, tok.pos)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return Error_Body {
|
return Error_Body {
|
||||||
@@ -261,8 +258,7 @@ parse_section :: proc(
|
|||||||
parse_section(tokens, pos, nodes, pipe_key, source, allocator, tok.pos) or_return
|
parse_section(tokens, pos, nodes, pipe_key, source, allocator, tok.pos) or_return
|
||||||
close_pos := 0
|
close_pos := 0
|
||||||
if pos^ - 1 >= 0 && pos^ - 1 < len(tokens) {close_pos = tokens[pos^ - 1].pos}
|
if pos^ - 1 >= 0 && pos^ - 1 < len(tokens) {close_pos = tokens[pos^ - 1].pos}
|
||||||
nodes[idx].first_child = idx + 1
|
nodes[idx].children = nodes[idx + 1:len(nodes)]
|
||||||
nodes[idx].child_count = len(nodes) - idx - 1
|
|
||||||
nodes[idx].content = source[content_start:close_pos]
|
nodes[idx].content = source[content_start:close_pos]
|
||||||
|
|
||||||
case .Section_Close:
|
case .Section_Close:
|
||||||
@@ -301,7 +297,6 @@ parse_section :: proc(
|
|||||||
key = tok.value,
|
key = tok.value,
|
||||||
is_dynamic = tok.is_dynamic,
|
is_dynamic = tok.is_dynamic,
|
||||||
indent = tok.indent,
|
indent = tok.indent,
|
||||||
first_child = -1,
|
|
||||||
pos = tok.pos,
|
pos = tok.pos,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -316,13 +311,11 @@ parse_section :: proc(
|
|||||||
kind = .Parent,
|
kind = .Parent,
|
||||||
key = tok.value,
|
key = tok.value,
|
||||||
indent = tok.indent,
|
indent = tok.indent,
|
||||||
first_child = -1,
|
|
||||||
pos = tok.pos,
|
pos = tok.pos,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
parse_section(tokens, pos, nodes, tok.value, source, allocator, tok.pos) or_return
|
parse_section(tokens, pos, nodes, tok.value, source, allocator, tok.pos) or_return
|
||||||
nodes[idx].first_child = idx + 1
|
nodes[idx].children = nodes[idx + 1:len(nodes)]
|
||||||
nodes[idx].child_count = len(nodes) - idx - 1
|
|
||||||
|
|
||||||
case .Block_Open:
|
case .Block_Open:
|
||||||
pos^ += 1
|
pos^ += 1
|
||||||
@@ -333,13 +326,11 @@ parse_section :: proc(
|
|||||||
kind = .Block,
|
kind = .Block,
|
||||||
key = tok.value,
|
key = tok.value,
|
||||||
indent = tok.indent,
|
indent = tok.indent,
|
||||||
first_child = -1,
|
|
||||||
pos = tok.pos,
|
pos = tok.pos,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
parse_section(tokens, pos, nodes, tok.value, source, allocator, tok.pos) or_return
|
parse_section(tokens, pos, nodes, tok.value, source, allocator, tok.pos) or_return
|
||||||
nodes[idx].first_child = idx + 1
|
nodes[idx].children = nodes[idx + 1:len(nodes)]
|
||||||
nodes[idx].child_count = len(nodes) - idx - 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,43 +348,38 @@ parse_section :: proc(
|
|||||||
// Post-parse: de-indent block content
|
// Post-parse: de-indent block content
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
deindent_blocks :: proc(all_nodes: []Node, start: int, end: int, allocator := context.allocator) {
|
deindent_blocks :: proc(nodes: []Node, allocator := context.allocator) {
|
||||||
i := start
|
i := 0
|
||||||
for i < end {
|
for i < len(nodes) {
|
||||||
#partial switch all_nodes[i].kind {
|
#partial switch nodes[i].kind {
|
||||||
case .Block:
|
case .Block:
|
||||||
if all_nodes[i].child_count > 0 {
|
if len(nodes[i].children) > 0 {
|
||||||
cs := all_nodes[i].first_child
|
children := nodes[i].children
|
||||||
ce := cs + all_nodes[i].child_count
|
deindent_blocks(children, allocator)
|
||||||
deindent_blocks(all_nodes, cs, ce, allocator)
|
|
||||||
|
|
||||||
children := all_nodes[cs:ce]
|
|
||||||
common := find_common_indent(children)
|
common := find_common_indent(children)
|
||||||
if len(common) > 0 {
|
if len(common) > 0 {
|
||||||
if len(all_nodes[i].indent) == 0 {
|
if len(nodes[i].indent) == 0 {
|
||||||
all_nodes[i].indent = common
|
nodes[i].indent = common
|
||||||
}
|
}
|
||||||
for j := cs; j < ce; {
|
for j := 0; j < len(children); {
|
||||||
if all_nodes[j].kind == .Text && len(all_nodes[j].text) > 0 {
|
if children[j].kind == .Text && len(children[j].text) > 0 {
|
||||||
all_nodes[j].text = remove_line_indent(
|
children[j].text = remove_line_indent(
|
||||||
all_nodes[j].text,
|
children[j].text,
|
||||||
common,
|
common,
|
||||||
allocator,
|
allocator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
j += node_span(all_nodes[j])
|
j += node_span(children[j])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case .Section, .Inverted, .Parent:
|
case .Section, .Inverted, .Parent:
|
||||||
if all_nodes[i].child_count > 0 {
|
if len(nodes[i].children) > 0 {
|
||||||
cs := all_nodes[i].first_child
|
deindent_blocks(nodes[i].children, allocator)
|
||||||
ce := cs + all_nodes[i].child_count
|
|
||||||
deindent_blocks(all_nodes, cs, ce, allocator)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += node_span(all_nodes[i])
|
i += node_span(nodes[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,9 +509,9 @@ render_template :: proc(
|
|||||||
context.temp_allocator,
|
context.temp_allocator,
|
||||||
context.temp_allocator,
|
context.temp_allocator,
|
||||||
) or_return
|
) or_return
|
||||||
return render_nodes(reparse, reparse.nodes[:], reparse.nodes[:], ctx, partials, b, blocks)
|
return render_nodes(reparse, reparse.nodes[:], ctx, partials, b, blocks)
|
||||||
}
|
}
|
||||||
return render_nodes(pt, pt.nodes[:], pt.nodes[:], ctx, partials, b, blocks)
|
return render_nodes(pt, pt.nodes[:], ctx, partials, b, blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -534,7 +520,6 @@ render_template :: proc(
|
|||||||
|
|
||||||
render_nodes :: proc(
|
render_nodes :: proc(
|
||||||
current: Template,
|
current: Template,
|
||||||
all_nodes: []Node,
|
|
||||||
nodes: []Node,
|
nodes: []Node,
|
||||||
ctx: ^[dynamic]any,
|
ctx: ^[dynamic]any,
|
||||||
partials: map[string]Template,
|
partials: map[string]Template,
|
||||||
@@ -571,16 +556,15 @@ render_nodes :: proc(
|
|||||||
if perr == nil {
|
if perr == nil {
|
||||||
temp: strings.Builder
|
temp: strings.Builder
|
||||||
strings.builder_init(&temp, context.temp_allocator)
|
strings.builder_init(&temp, context.temp_allocator)
|
||||||
render_nodes(
|
render_nodes(
|
||||||
sub_tpl,
|
sub_tpl,
|
||||||
sub_tpl.nodes[:],
|
sub_tpl.nodes[:],
|
||||||
sub_tpl.nodes[:],
|
ctx,
|
||||||
ctx,
|
partials,
|
||||||
partials,
|
&temp,
|
||||||
&temp,
|
blocks,
|
||||||
blocks,
|
) or_return
|
||||||
) or_return
|
write_value(b, strings.to_string(temp), escape = true)
|
||||||
write_value(b, strings.to_string(temp), escape = true)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write_value(b, val, escape = true)
|
write_value(b, val, escape = true)
|
||||||
@@ -609,16 +593,15 @@ render_nodes :: proc(
|
|||||||
if perr == nil {
|
if perr == nil {
|
||||||
temp: strings.Builder
|
temp: strings.Builder
|
||||||
strings.builder_init(&temp, context.temp_allocator)
|
strings.builder_init(&temp, context.temp_allocator)
|
||||||
render_nodes(
|
render_nodes(
|
||||||
sub_tpl,
|
sub_tpl,
|
||||||
sub_tpl.nodes[:],
|
sub_tpl.nodes[:],
|
||||||
sub_tpl.nodes[:],
|
ctx,
|
||||||
ctx,
|
partials,
|
||||||
partials,
|
&temp,
|
||||||
&temp,
|
blocks,
|
||||||
blocks,
|
) or_return
|
||||||
) or_return
|
write_value(b, strings.to_string(temp), escape = false)
|
||||||
write_value(b, strings.to_string(temp), escape = false)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write_value(b, val, escape = false)
|
write_value(b, val, escape = false)
|
||||||
@@ -645,41 +628,39 @@ render_nodes :: proc(
|
|||||||
context.temp_allocator,
|
context.temp_allocator,
|
||||||
)
|
)
|
||||||
if perr == nil {
|
if perr == nil {
|
||||||
|
render_nodes(
|
||||||
|
sub_tpl,
|
||||||
|
sub_tpl.nodes[:],
|
||||||
|
ctx,
|
||||||
|
partials,
|
||||||
|
b,
|
||||||
|
blocks,
|
||||||
|
) or_return
|
||||||
|
}
|
||||||
|
} else if is_truthy(val) {
|
||||||
|
children := node.children
|
||||||
|
elem_info, count, data := list_info(val)
|
||||||
|
if elem_info != nil {
|
||||||
|
for j in 0 ..< count {
|
||||||
|
elem := extract_list_element(elem_info, data, j)
|
||||||
|
append(ctx, elem)
|
||||||
|
defer pop(ctx)
|
||||||
render_nodes(
|
render_nodes(
|
||||||
sub_tpl,
|
current,
|
||||||
sub_tpl.nodes[:],
|
children,
|
||||||
sub_tpl.nodes[:],
|
|
||||||
ctx,
|
ctx,
|
||||||
partials,
|
partials,
|
||||||
b,
|
b,
|
||||||
blocks,
|
blocks,
|
||||||
) or_return
|
) or_return
|
||||||
}
|
}
|
||||||
} else if is_truthy(val) {
|
} else {
|
||||||
children := all_nodes[node.first_child:node.first_child + node.child_count]
|
append(ctx, val)
|
||||||
elem_info, count, data := list_info(val)
|
defer pop(ctx)
|
||||||
if elem_info != nil {
|
render_nodes(current, children, ctx, partials, b, blocks) or_return
|
||||||
for j in 0 ..< count {
|
|
||||||
elem := extract_list_element(elem_info, data, j)
|
|
||||||
append(ctx, elem)
|
|
||||||
defer pop(ctx)
|
|
||||||
render_nodes(
|
|
||||||
current,
|
|
||||||
all_nodes,
|
|
||||||
children,
|
|
||||||
ctx,
|
|
||||||
partials,
|
|
||||||
b,
|
|
||||||
blocks,
|
|
||||||
) or_return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
append(ctx, val)
|
|
||||||
defer pop(ctx)
|
|
||||||
render_nodes(current, all_nodes, children, ctx, partials, b, blocks) or_return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
i += 1 + node.child_count
|
}
|
||||||
|
i += 1 + len(node.children)
|
||||||
|
|
||||||
case .Inverted:
|
case .Inverted:
|
||||||
val := resolve_name(node.key, ctx[:])
|
val := resolve_name(node.key, ctx[:])
|
||||||
@@ -693,11 +674,10 @@ render_nodes :: proc(
|
|||||||
}
|
}
|
||||||
val = transformed
|
val = transformed
|
||||||
}
|
}
|
||||||
if !is_truthy(val) {
|
if !is_truthy(val) {
|
||||||
children := all_nodes[node.first_child:node.first_child + node.child_count]
|
render_nodes(current, node.children, ctx, partials, b, blocks) or_return
|
||||||
render_nodes(current, all_nodes, children, ctx, partials, b, blocks) or_return
|
}
|
||||||
}
|
i += 1 + len(node.children)
|
||||||
i += 1 + node.child_count
|
|
||||||
|
|
||||||
case .Partial:
|
case .Partial:
|
||||||
name := node.key
|
name := node.key
|
||||||
@@ -713,63 +693,58 @@ render_nodes :: proc(
|
|||||||
}
|
}
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
case .Block:
|
case .Block:
|
||||||
content_nodes: []Node
|
content_nodes: []Node
|
||||||
content_pool: []Node
|
content_blocks := blocks
|
||||||
content_blocks := blocks
|
render_current := current
|
||||||
render_current := current
|
|
||||||
|
|
||||||
found_override := false
|
found_override := false
|
||||||
if blocks != nil {
|
if blocks != nil {
|
||||||
if o, ok := blocks[node.key]; ok {
|
if o, ok := blocks[node.key]; ok {
|
||||||
content_nodes = o.all_nodes[o.first:o.first + o.count]
|
content_nodes = o.nodes
|
||||||
content_pool = o.all_nodes
|
found_override = true
|
||||||
found_override = true
|
render_current = o.source
|
||||||
render_current = o.source
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found_override {
|
|
||||||
content_nodes = all_nodes[node.first_child:node.first_child + node.child_count]
|
|
||||||
content_pool = all_nodes
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !found_override {
|
||||||
|
content_nodes = node.children
|
||||||
|
}
|
||||||
|
|
||||||
if len(node.indent) > 0 {
|
if len(node.indent) > 0 {
|
||||||
temp: strings.Builder
|
temp: strings.Builder
|
||||||
strings.builder_init(&temp, context.temp_allocator)
|
strings.builder_init(&temp, context.temp_allocator)
|
||||||
render_nodes(
|
render_nodes(
|
||||||
render_current,
|
render_current,
|
||||||
content_pool,
|
content_nodes,
|
||||||
content_nodes,
|
ctx,
|
||||||
ctx,
|
partials,
|
||||||
partials,
|
&temp,
|
||||||
&temp,
|
content_blocks,
|
||||||
content_blocks,
|
) or_return
|
||||||
) or_return
|
write_indented(b, node.indent, strings.to_string(temp))
|
||||||
write_indented(b, node.indent, strings.to_string(temp))
|
} else {
|
||||||
} else {
|
render_nodes(
|
||||||
render_nodes(
|
render_current,
|
||||||
render_current,
|
content_nodes,
|
||||||
content_pool,
|
ctx,
|
||||||
content_nodes,
|
partials,
|
||||||
ctx,
|
b,
|
||||||
partials,
|
content_blocks,
|
||||||
b,
|
) or_return
|
||||||
content_blocks,
|
}
|
||||||
) or_return
|
i += 1 + len(node.children)
|
||||||
}
|
|
||||||
i += 1 + node.child_count
|
|
||||||
|
|
||||||
case .Parent:
|
case .Parent:
|
||||||
parent_children := all_nodes[node.first_child:node.first_child + node.child_count]
|
parent_children := node.children
|
||||||
merged := merge_block_overrides(parent_children, all_nodes, blocks, current)
|
merged := merge_block_overrides(parent_children, blocks, current)
|
||||||
pt, found := partials[node.key]
|
pt, found := partials[node.key]
|
||||||
if !found {
|
if !found {
|
||||||
warn_missing_partial(current, partials, node, node.key)
|
warn_missing_partial(current, partials, node, node.key)
|
||||||
} else {
|
} else {
|
||||||
warn_unmatched_block_overrides(current, pt, parent_children)
|
warn_unmatched_block_overrides(current, pt, parent_children)
|
||||||
render_template(pt, ctx, partials, b, merged, node.indent) or_return
|
render_template(pt, ctx, partials, b, merged, node.indent) or_return
|
||||||
}
|
}
|
||||||
i += 1 + node.child_count
|
i += 1 + len(node.children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -777,7 +752,6 @@ render_nodes :: proc(
|
|||||||
|
|
||||||
merge_block_overrides :: proc(
|
merge_block_overrides :: proc(
|
||||||
children: []Node,
|
children: []Node,
|
||||||
all_nodes: []Node,
|
|
||||||
existing: map[string]Block_Override,
|
existing: map[string]Block_Override,
|
||||||
source: Template,
|
source: Template,
|
||||||
) -> map[string]Block_Override {
|
) -> map[string]Block_Override {
|
||||||
@@ -793,10 +767,8 @@ merge_block_overrides :: proc(
|
|||||||
if child.kind == .Block {
|
if child.kind == .Block {
|
||||||
if _, exists := result[child.key]; !exists {
|
if _, exists := result[child.key]; !exists {
|
||||||
result[child.key] = Block_Override {
|
result[child.key] = Block_Override {
|
||||||
all_nodes = all_nodes,
|
nodes = child.children,
|
||||||
first = child.first_child,
|
source = source,
|
||||||
count = child.child_count,
|
|
||||||
source = source,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user