Render optimisation

This commit is contained in:
Adam Fowler
2021-03-18 10:55:55 +00:00
parent c560bd0fd9
commit 9b17bd6827
3 changed files with 46 additions and 40 deletions

View File

@@ -143,12 +143,6 @@ extension HBMustacheTemplate {
// partial // partial
parser.unsafeAdvance() parser.unsafeAdvance()
let (name, _) = try parseName(&parser) let (name, _) = try parseName(&parser)
/* if newLine && hasLineFinished(&parser) {
setNewLine = true
if parser.current() == "\n" {
parser.unsafeAdvance()
}
} */
if whiteSpaceBefore.count > 0 { if whiteSpaceBefore.count > 0 {
tokens.append(.text(whiteSpaceBefore)) tokens.append(.text(whiteSpaceBefore))
} }

View File

@@ -2,47 +2,59 @@
extension HBMustacheTemplate { extension HBMustacheTemplate {
/// Render template using object /// Render template using object
/// - Parameters: /// - Parameters:
/// - object: Object /// - stack: Object
/// - context: Context that render is occurring in. Contains information about position in sequence /// - context: Context that render is occurring in. Contains information about position in sequence
/// - indentation: indentation of partial
/// - Returns: Rendered text /// - Returns: Rendered text
func render(_ object: [Any], context: HBMustacheContext? = nil, indentation: String? = nil) -> String { func render(_ stack: [Any], context: HBMustacheContext? = nil, indentation: String? = nil) -> String {
var string = "" var string = ""
for token in tokens { if let indentation = indentation {
if let indentation = indentation, string.last == "\n" { for token in tokens {
string += indentation if string.last == "\n" {
string += indentation
}
string += renderToken(token, stack: stack, context: context)
} }
switch token { } else {
case let .text(text): for token in tokens {
string += text string += renderToken(token, stack: stack, context: context)
case let .variable(variable, method):
if let child = getChild(named: variable, from: object, method: method, context: context) {
if let template = child as? HBMustacheTemplate {
string += template.render(object)
} else {
string += String(describing: child).htmlEscape()
}
}
case let .unescapedVariable(variable, method):
if let child = getChild(named: variable, from: object, method: method, context: context) {
string += String(describing: child)
}
case let .section(variable, method, template):
let child = getChild(named: variable, from: object, method: method, context: context)
string += renderSection(child, stack: object, with: template)
case let .invertedSection(variable, method, template):
let child = getChild(named: variable, from: object, method: method, context: context)
string += renderInvertedSection(child, stack: object, with: template)
case let .partial(name, indentation):
if let template = library?.getTemplate(named: name) {
string += template.render(object, indentation: indentation)
}
} }
} }
return string return string
} }
func renderToken(_ token: Token, stack: [Any], context: HBMustacheContext? = nil) -> String {
switch token {
case let .text(text):
return text
case let .variable(variable, method):
if let child = getChild(named: variable, from: stack, method: method, context: context) {
if let template = child as? HBMustacheTemplate {
return template.render(stack)
} else {
return String(describing: child).htmlEscape()
}
}
case let .unescapedVariable(variable, method):
if let child = getChild(named: variable, from: stack, method: method, context: context) {
return String(describing: child)
}
case let .section(variable, method, template):
let child = getChild(named: variable, from: stack, method: method, context: context)
return renderSection(child, stack: stack, with: template)
case let .invertedSection(variable, method, template):
let child = getChild(named: variable, from: stack, method: method, context: context)
return renderInvertedSection(child, stack: stack, with: template)
case let .partial(name, indentation):
if let template = library?.getTemplate(named: name) {
return template.render(stack, indentation: indentation)
}
}
return ""
}
/// Render a section /// Render a section
/// - Parameters: /// - Parameters:
/// - child: Object to render section for /// - child: Object to render section for

View File

@@ -661,8 +661,8 @@ final class SpecSectionTests: XCTestCase {
func testVariables() throws { func testVariables() throws {
let object: [String: Any] = ["foo": "bar"] let object: [String: Any] = ["foo": "bar"]
let template = #""{{#foo}} {{.}} is {{foo}} {{/foo}}""# let template = #""{{#foo}}{{.}} is {{foo}}{{/foo}}""#
let expected = #"" bar is bar ""# let expected = #""bar is bar""#
try test(object, template, expected) try test(object, template, expected)
} }