removed trailing witespaces
This commit is contained in:
@@ -9,7 +9,7 @@ public struct Environment {
|
||||
extensions: [Extension]? = nil,
|
||||
templateClass: Template.Type = Template.self,
|
||||
errorReporter: ErrorReporter = SimpleErrorReporter()) {
|
||||
|
||||
|
||||
self.templateClass = templateClass
|
||||
self.errorReporter = errorReporter
|
||||
self.loader = loader
|
||||
@@ -41,11 +41,11 @@ public struct Environment {
|
||||
let template = templateClass.init(templateString: string, environment: self)
|
||||
return try render(template: template, context: context)
|
||||
}
|
||||
|
||||
|
||||
func render(template: Template, context: [String: Any]?) throws -> String {
|
||||
// update template environment as it can be created from string literal with default environment
|
||||
template.environment = self
|
||||
return try template.render(context)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -27,21 +27,21 @@ public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible {
|
||||
var allTokens: [Token] {
|
||||
return stackTrace + (token.map({ [$0] }) ?? [])
|
||||
}
|
||||
|
||||
|
||||
public init(reason: String, token: Token? = nil, stackTrace: [Token] = []) {
|
||||
self.reason = reason
|
||||
self.stackTrace = stackTrace
|
||||
self.token = token
|
||||
}
|
||||
|
||||
|
||||
public init(_ description: String) {
|
||||
self.init(reason: description)
|
||||
}
|
||||
|
||||
|
||||
public static func ==(lhs:TemplateSyntaxError, rhs:TemplateSyntaxError) -> Bool {
|
||||
return lhs.description == rhs.description && lhs.token == rhs.token && lhs.stackTrace == rhs.stackTrace
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public protocol ErrorReporter: class {
|
||||
@@ -49,24 +49,24 @@ public protocol ErrorReporter: class {
|
||||
}
|
||||
|
||||
open class SimpleErrorReporter: ErrorReporter {
|
||||
|
||||
|
||||
open func renderError(_ error: Error) -> String {
|
||||
guard let templateError = error as? TemplateSyntaxError else { return error.localizedDescription }
|
||||
|
||||
|
||||
func describe(token: Token) -> String {
|
||||
let templateName = token.sourceMap.filename ?? ""
|
||||
let line = token.sourceMap.line
|
||||
let highlight = "\(String(Array(repeating: " ", count: line.offset)))^\(String(Array(repeating: "~", count: max(token.contents.characters.count - 1, 0))))"
|
||||
|
||||
|
||||
return "\(templateName)\(line.number):\(line.offset): error: \(templateError.reason)\n"
|
||||
+ "\(line.content)\n"
|
||||
+ "\(highlight)\n"
|
||||
}
|
||||
|
||||
|
||||
var descriptions = templateError.stackTrace.reduce([]) { $0 + [describe(token: $1)] }
|
||||
let description = templateError.token.map(describe(token:)) ?? templateError.reason
|
||||
descriptions.append(description)
|
||||
return descriptions.joined(separator: "\n")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -88,21 +88,21 @@ final class NotExpression: Expression, PrefixOperator, CustomStringConvertible {
|
||||
final class InExpression: Expression, InfixOperator, CustomStringConvertible {
|
||||
let lhs: Expression
|
||||
let rhs: Expression
|
||||
|
||||
|
||||
init(lhs: Expression, rhs: Expression) {
|
||||
self.lhs = lhs
|
||||
self.rhs = rhs
|
||||
}
|
||||
|
||||
|
||||
var description: String {
|
||||
return "(\(lhs) in \(rhs))"
|
||||
}
|
||||
|
||||
|
||||
func evaluate(context: Context) throws -> Bool {
|
||||
if let lhs = lhs as? VariableExpression, let rhs = rhs as? VariableExpression {
|
||||
let lhsValue = try lhs.variable.resolve(context)
|
||||
let rhsValue = try rhs.variable.resolve(context)
|
||||
|
||||
|
||||
if let lhs = lhsValue as? AnyHashable, let rhs = rhsValue as? [AnyHashable] {
|
||||
return rhs.contains(lhs)
|
||||
} else if let lhs = lhsValue as? String, let rhs = rhsValue as? String {
|
||||
@@ -111,10 +111,10 @@ final class InExpression: Expression, InfixOperator, CustomStringConvertible {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
final class OrExpression: Expression, InfixOperator, CustomStringConvertible {
|
||||
|
||||
@@ -42,9 +42,9 @@ class DefaultExtension: Extension {
|
||||
registerTag("for", parser: ForNode.parse)
|
||||
registerTag("if", parser: IfNode.parse)
|
||||
registerTag("ifnot", parser: IfNode.parse_ifnot)
|
||||
#if !os(Linux)
|
||||
registerTag("now", parser: NowNode.parse)
|
||||
#endif
|
||||
#if !os(Linux)
|
||||
registerTag("now", parser: NowNode.parse)
|
||||
#endif
|
||||
registerTag("include", parser: IncludeNode.parse)
|
||||
registerTag("extends", parser: ExtendsNode.parse)
|
||||
registerTag("block", parser: BlockNode.parse)
|
||||
|
||||
@@ -12,8 +12,8 @@ class ForNode : NodeType {
|
||||
let components = token.components()
|
||||
|
||||
guard components.count >= 3 && components[2] == "in" &&
|
||||
(components.count == 4 || (components.count >= 6 && components[4] == "where")) else {
|
||||
throw TemplateSyntaxError("'for' statements should use the following syntax 'for x in y where condition'.")
|
||||
(components.count == 4 || (components.count >= 6 && components[4] == "where")) else {
|
||||
throw TemplateSyntaxError("'for' statements should use the following syntax 'for x in y where condition'.")
|
||||
}
|
||||
|
||||
let loopVariables = components[1].characters
|
||||
@@ -38,7 +38,7 @@ class ForNode : NodeType {
|
||||
guard let token = parser.nextToken() else {
|
||||
throw TemplateSyntaxError("`endfor` was not found.")
|
||||
}
|
||||
|
||||
|
||||
if token.contents == "empty" {
|
||||
emptyNodes = try parser.parse(until(["endfor"]))
|
||||
_ = parser.nextToken()
|
||||
@@ -134,14 +134,14 @@ class ForNode : NodeType {
|
||||
"last": index == (count - 1),
|
||||
"counter": index + 1,
|
||||
"counter0": index,
|
||||
]
|
||||
]
|
||||
|
||||
return try context.push(dictionary: ["forloop": forContext]) {
|
||||
return try push(value: item, context: context) {
|
||||
try renderNodes(nodes, context)
|
||||
}
|
||||
}
|
||||
}.joined(separator: "")
|
||||
}.joined(separator: "")
|
||||
}
|
||||
|
||||
return try context.push {
|
||||
|
||||
@@ -53,7 +53,7 @@ enum IfToken {
|
||||
case .variable(_):
|
||||
return 0
|
||||
case .end:
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class BlockContext {
|
||||
self.blocks[blockName] = [block]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func popBlock(named blockName: String) -> BlockNode? {
|
||||
if var blocks = blocks[blockName] {
|
||||
let block = blocks.removeFirst()
|
||||
@@ -86,7 +86,7 @@ class ExtendsNode : NodeType {
|
||||
}
|
||||
|
||||
let baseTemplate = try context.environment.loadTemplate(name: templateName)
|
||||
|
||||
|
||||
let blockContext: BlockContext
|
||||
if let _blockContext = context[BlockContext.contextKey] as? BlockContext {
|
||||
blockContext = _blockContext
|
||||
@@ -148,7 +148,7 @@ class BlockNode : NodeType {
|
||||
// child node is a block node from child template that extends this node (has the same name)
|
||||
|
||||
var newContext: [String: Any] = [BlockContext.contextKey: blockContext]
|
||||
|
||||
|
||||
if let blockSuperNode = child.nodes.first(where: {
|
||||
if case .variable(let variable, _)? = $0.token, variable == "block.super" { return true }
|
||||
else { return false}
|
||||
@@ -170,7 +170,7 @@ class BlockNode : NodeType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// render extension node
|
||||
do {
|
||||
return try context.push(dictionary: newContext) {
|
||||
|
||||
@@ -47,7 +47,7 @@ struct Lexer {
|
||||
"{{": "}}",
|
||||
"{%": "%}",
|
||||
"{#": "#}",
|
||||
]
|
||||
]
|
||||
|
||||
while !scanner.isEmpty {
|
||||
if let text = scanner.scan(until: ["{{", "{%", "{#"]) {
|
||||
@@ -66,14 +66,14 @@ struct Lexer {
|
||||
|
||||
return tokens
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Scanner {
|
||||
let originalContent: String
|
||||
var content: String
|
||||
var range: Range<String.Index>
|
||||
|
||||
|
||||
init(_ content: String) {
|
||||
self.originalContent = content
|
||||
self.content = content
|
||||
@@ -83,7 +83,7 @@ class Scanner {
|
||||
var isEmpty: Bool {
|
||||
return content.isEmpty
|
||||
}
|
||||
|
||||
|
||||
func scan(until: String, returnUntil: Bool = false) -> String {
|
||||
var index = content.startIndex
|
||||
|
||||
@@ -94,7 +94,7 @@ class Scanner {
|
||||
range = range.upperBound..<range.upperBound
|
||||
while index != content.endIndex {
|
||||
let substring = content.substring(from: index)
|
||||
|
||||
|
||||
if substring.hasPrefix(until) {
|
||||
let result = content.substring(to: index)
|
||||
|
||||
@@ -174,12 +174,12 @@ extension String {
|
||||
let last = findLastNot(character: character) ?? endIndex
|
||||
return String(self[first..<last])
|
||||
}
|
||||
|
||||
|
||||
public func rangeLine(_ range: Range<String.Index>) -> RangeLine {
|
||||
var lineNumber: UInt = 0
|
||||
var offset: Int = 0
|
||||
var lineContent = ""
|
||||
|
||||
|
||||
for line in components(separatedBy: CharacterSet.newlines) {
|
||||
lineNumber += 1
|
||||
lineContent = line
|
||||
@@ -189,7 +189,7 @@ extension String {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (lineContent, lineNumber, offset)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Foundation
|
||||
public protocol NodeType {
|
||||
/// Render the node in the given context
|
||||
func render(_ context:Context) throws -> String
|
||||
|
||||
|
||||
/// Reference to this node's token
|
||||
var token: Token? { get }
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class TokenParser {
|
||||
|
||||
throw TemplateSyntaxError("Unknown filter '\(name)'")
|
||||
}
|
||||
|
||||
|
||||
public func compileFilter(_ filterToken: String, containedIn containingToken: Token) throws -> Resolvable {
|
||||
do {
|
||||
return try FilterExpression(token: filterToken, parser: self)
|
||||
@@ -121,7 +121,7 @@ public class TokenParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@available(*, deprecated, message: "Use compileFilter(_:containedIn:)")
|
||||
public func compileFilter(_ token: String) throws -> Resolvable {
|
||||
return try FilterExpression(token: token, parser: self)
|
||||
|
||||
@@ -43,14 +43,14 @@ extension String {
|
||||
public struct SourceMap: Equatable {
|
||||
public let filename: String?
|
||||
public let line: RangeLine
|
||||
|
||||
|
||||
init(filename: String? = nil, line: RangeLine = ("", 0, 0)) {
|
||||
self.filename = filename
|
||||
self.line = line
|
||||
}
|
||||
|
||||
|
||||
static let unknown = SourceMap()
|
||||
|
||||
|
||||
public static func ==(lhs: SourceMap, rhs: SourceMap) -> Bool {
|
||||
return lhs.filename == rhs.filename && lhs.line == rhs.line
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public enum Token : Equatable {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public var sourceMap: SourceMap {
|
||||
switch self {
|
||||
case .block(_, let sourceMap),
|
||||
|
||||
@@ -95,11 +95,11 @@ public struct Variable : Equatable, Resolvable {
|
||||
current = array.count
|
||||
}
|
||||
} else if let object = current as? NSObject { // NSKeyValueCoding
|
||||
#if os(Linux)
|
||||
return nil
|
||||
#else
|
||||
current = object.value(forKey: bit)
|
||||
#endif
|
||||
#if os(Linux)
|
||||
return nil
|
||||
#else
|
||||
current = object.value(forKey: bit)
|
||||
#endif
|
||||
} else if let value = current {
|
||||
current = Mirror(reflecting: value).getValue(for: bit)
|
||||
if current == nil {
|
||||
|
||||
Reference in New Issue
Block a user