refactor: Adapt to new repository
This commit is contained in:
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// A container for template variables.
|
||||
public class Context {
|
||||
var dictionaries: [[String: Any?]]
|
||||
@@ -61,6 +55,7 @@ public class Context {
|
||||
/// Pop the last level off of the Context
|
||||
///
|
||||
/// - returns: The popped level
|
||||
// swiftlint:disable:next discouraged_optional_collection
|
||||
fileprivate func pop() -> [String: Any?]? {
|
||||
dictionaries.popLast()
|
||||
}
|
||||
@@ -78,7 +73,7 @@ public class Context {
|
||||
}
|
||||
|
||||
/// Flatten all levels of context data into 1, merging duplicate variables
|
||||
///
|
||||
///
|
||||
/// - returns: All collected variables
|
||||
public func flatten() -> [String: Any] {
|
||||
var accumulator: [String: Any] = [:]
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// Marker protocol so we can know which types support `@dynamicMemberLookup`. Add this to your own types that support
|
||||
/// lookup by String.
|
||||
public protocol DynamicMemberLookup {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// Container for environment data, such as registered extensions
|
||||
public struct Environment {
|
||||
/// The class for loading new templates
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
public class TemplateDoesNotExist: Error, CustomStringConvertible {
|
||||
let templateNames: [String]
|
||||
let loader: Loader?
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
public protocol Expression: CustomStringConvertible, Resolvable {
|
||||
func evaluate(context: Context) throws -> Bool
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// Container for registered tags and filters
|
||||
open class Extension {
|
||||
typealias TagParser = (TokenParser, Token) throws -> NodeType
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
class FilterNode: NodeType {
|
||||
let resolvable: Resolvable
|
||||
let nodes: [NodeType]
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
func capitalise(_ value: Any?) -> Any? {
|
||||
if let array = value as? [Any?] {
|
||||
return array.map { stringify($0).capitalized }
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ForNode: NodeType {
|
||||
@@ -231,7 +225,7 @@ struct LoopTerminationNode: NodeType {
|
||||
self.token = token
|
||||
}
|
||||
|
||||
static func parse(_ parser: TokenParser, token: Token) throws -> LoopTerminationNode {
|
||||
static func parse(_ parser: TokenParser, token: Token) throws -> Self {
|
||||
let components = token.components
|
||||
|
||||
guard components.count <= 2 else {
|
||||
@@ -241,7 +235,7 @@ struct LoopTerminationNode: NodeType {
|
||||
throw TemplateSyntaxError("'\(token.contents)' can be used only inside loop body")
|
||||
}
|
||||
|
||||
return LoopTerminationNode(name: components[0], label: components.count == 2 ? components[1] : nil, token: token)
|
||||
return Self(name: components[0], label: components.count == 2 ? components[1] : nil, token: token)
|
||||
}
|
||||
|
||||
func render(_ context: Context) throws -> String {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
enum Operator {
|
||||
case infix(String, Int, InfixOperator.Type)
|
||||
case prefix(String, Int, PrefixOperator.Type)
|
||||
@@ -17,7 +11,7 @@ enum Operator {
|
||||
}
|
||||
}
|
||||
|
||||
static let all: [Operator] = [
|
||||
static let all: [Self] = [
|
||||
.infix("in", 5, InExpression.self),
|
||||
.infix("or", 6, OrExpression.self),
|
||||
.infix("and", 7, AndExpression.self),
|
||||
@@ -118,6 +112,7 @@ final class IfExpressionParser {
|
||||
private init(components: ArraySlice<String>, environment: Environment, token: Token) throws {
|
||||
var parsedComponents = Set<Int>()
|
||||
var bracketsBalance = 0
|
||||
// swiftlint:disable:next closure_body_length
|
||||
self.tokens = try zip(components.indices, components).compactMap { index, component in
|
||||
guard !parsedComponents.contains(index) else { return nil }
|
||||
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import PathKit
|
||||
|
||||
class IncludeNode: NodeType {
|
||||
let templateName: Variable
|
||||
let includeContext: String?
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
class BlockContext {
|
||||
class var contextKey: String { "block_context" }
|
||||
|
||||
@@ -62,7 +56,7 @@ class ExtendsNode: NodeType {
|
||||
}
|
||||
|
||||
let parsedNodes = try parser.parse()
|
||||
guard (parsedNodes.any { $0 is ExtendsNode }) == nil else {
|
||||
guard (parsedNodes.any { $0 is Self }) == nil else {
|
||||
throw TemplateSyntaxError("'extends' cannot appear more than once in the same template")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A structure used to represent a template variable, and to resolve it in a given context.
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// Used to lazily set context data. Useful for example if you have some data that requires heavy calculations, and may
|
||||
/// not be used in every render possiblity.
|
||||
public final class LazyValueWrapper {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable large_tuple
|
||||
typealias Line = (content: String, number: UInt, range: Range<String.Index>)
|
||||
/// Location in some content (text)
|
||||
public typealias ContentLocation = (content: String, lineNumber: UInt, lineOffset: Int)
|
||||
// swiftlint:enable large_tuple
|
||||
|
||||
struct Lexer {
|
||||
let templateName: String?
|
||||
@@ -257,6 +255,3 @@ extension String {
|
||||
return String(self[first..<last])
|
||||
}
|
||||
}
|
||||
|
||||
/// Location in some content (text)
|
||||
public typealias ContentLocation = (content: String, lineNumber: UInt, lineOffset: Int)
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PathKit
|
||||
|
||||
@@ -41,8 +35,8 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
|
||||
}
|
||||
|
||||
public init(bundle: [Bundle]) {
|
||||
self.paths = bundle.map { bundle in
|
||||
Path(bundle.bundlePath)
|
||||
self.paths = bundle.compactMap { bundle in
|
||||
Path(bundle.path)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,13 +46,13 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
|
||||
|
||||
public func loadTemplate(name: String, environment: Environment) throws -> Template {
|
||||
for path in paths {
|
||||
let templatePath = try path.safeJoin(path: Path(name))
|
||||
let templatePath = try path.safeJoin(path: name)
|
||||
|
||||
if !templatePath.exists {
|
||||
continue
|
||||
}
|
||||
|
||||
let content: String = try templatePath.read()
|
||||
let content: String = try String(contentsOf: templatePath)
|
||||
return environment.templateClass.init(templateString: content, environment: environment, name: name)
|
||||
}
|
||||
|
||||
@@ -68,10 +62,10 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
|
||||
public func loadTemplate(names: [String], environment: Environment) throws -> Template {
|
||||
for path in paths {
|
||||
for templateName in names {
|
||||
let templatePath = try path.safeJoin(path: Path(templateName))
|
||||
let templatePath = try path.safeJoin(path: templateName)
|
||||
|
||||
if templatePath.exists {
|
||||
let content: String = try templatePath.read()
|
||||
let content: String = try String(contentsOf: templatePath)
|
||||
return environment.templateClass.init(templateString: content, environment: environment, name: templateName)
|
||||
}
|
||||
}
|
||||
@@ -108,10 +102,10 @@ public class DictionaryLoader: Loader {
|
||||
}
|
||||
|
||||
extension Path {
|
||||
func safeJoin(path: Path) throws -> Path {
|
||||
let newPath = self + path
|
||||
func safeJoin(path: String) throws -> Path {
|
||||
let newPath = self / path
|
||||
|
||||
if !newPath.absolute().description.hasPrefix(absolute().description) {
|
||||
if !newPath.string.hasPrefix(self.string) {
|
||||
throw SuspiciousFileOperation(basePath: self, path: newPath)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Represents a parsed node
|
||||
@@ -184,6 +178,8 @@ func unwrap(_ array: [Any?]) -> [Any] {
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
} else { return item as Any }
|
||||
} else {
|
||||
return item as Any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
import Foundation
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
/// Creates a checker that will stop parsing if it encounters a list of tags.
|
||||
/// Useful for example for scanning until a given "end"-node.
|
||||
public func until(_ tags: [String]) -> ((TokenParser, Token) -> Bool) {
|
||||
@@ -98,7 +92,7 @@ public class TokenParser {
|
||||
tokens.first?.whitespace?.leading
|
||||
}
|
||||
|
||||
/// Insert a token
|
||||
/// Insert a token
|
||||
public func prependToken(_ token: Token) {
|
||||
tokens.insert(token, at: 0)
|
||||
if parsedTokens.last == token {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PathKit
|
||||
|
||||
@@ -47,13 +41,17 @@ open class Template: ExpressibleByStringLiteral {
|
||||
/// Create a template with a file found at the given URL
|
||||
@available(*, deprecated, message: "Use Environment/FileSystemLoader instead")
|
||||
public convenience init(URL: Foundation.URL) throws {
|
||||
try self.init(path: Path(URL.path))
|
||||
guard let path = Path(url: URL) else {
|
||||
throw TemplateDoesNotExist(templateNames: [URL.lastPathComponent])
|
||||
}
|
||||
try self.init(path: path)
|
||||
}
|
||||
|
||||
/// Create a template with a file found at the given path
|
||||
@available(*, deprecated, message: "Use Environment/FileSystemLoader instead")
|
||||
public convenience init(path: Path, environment: Environment? = nil, name: String? = nil) throws {
|
||||
self.init(templateString: try path.read(), environment: environment, name: name)
|
||||
let value = try String(contentsOf: path)
|
||||
self.init(templateString: value, environment: environment, name: name)
|
||||
}
|
||||
|
||||
// MARK: ExpressibleByStringLiteral
|
||||
@@ -81,8 +79,8 @@ open class Template: ExpressibleByStringLiteral {
|
||||
return try renderNodes(nodes, context)
|
||||
}
|
||||
|
||||
// swiftlint:disable discouraged_optional_collection
|
||||
/// Render the given template
|
||||
// swiftlint:disable:next discouraged_optional_collection
|
||||
open func render(_ dictionary: [String: Any]? = nil) throws -> String {
|
||||
try render(Context(dictionary: dictionary ?? [:], environment: environment))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension String {
|
||||
@@ -83,9 +77,9 @@ public struct SourceMap: Equatable {
|
||||
self.location = location
|
||||
}
|
||||
|
||||
static let unknown = SourceMap()
|
||||
static let unknown = Self()
|
||||
|
||||
public static func == (lhs: SourceMap, rhs: SourceMap) -> Bool {
|
||||
public static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs.filename == rhs.filename && lhs.location == rhs.location
|
||||
}
|
||||
}
|
||||
@@ -100,7 +94,7 @@ public struct WhitespaceBehaviour: Equatable {
|
||||
let leading: Behaviour
|
||||
let trailing: Behaviour
|
||||
|
||||
public static let unspecified = WhitespaceBehaviour(leading: .unspecified, trailing: .unspecified)
|
||||
public static let unspecified = Self(leading: .unspecified, trailing: .unspecified)
|
||||
}
|
||||
|
||||
public class Token: Equatable {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct TrimBehaviour: Equatable {
|
||||
@@ -30,13 +24,13 @@ public struct TrimBehaviour: Equatable {
|
||||
}
|
||||
|
||||
/// doesn't touch newlines
|
||||
public static let nothing = TrimBehaviour(leading: .nothing, trailing: .nothing)
|
||||
public static let nothing = Self(leading: .nothing, trailing: .nothing)
|
||||
|
||||
/// removes whitespace before a block and whitespace and a single newline after a block
|
||||
public static let smart = TrimBehaviour(leading: .whitespace, trailing: .whitespaceAndOneNewLine)
|
||||
public static let smart = Self(leading: .whitespace, trailing: .whitespaceAndOneNewLine)
|
||||
|
||||
/// removes all whitespace and newlines before and after a block
|
||||
public static let all = TrimBehaviour(leading: .whitespaceAndNewLines, trailing: .whitespaceAndNewLines)
|
||||
public static let all = Self(leading: .whitespaceAndNewLines, trailing: .whitespaceAndNewLines)
|
||||
|
||||
static func leadingRegex(trim: Trim) -> NSRegularExpression {
|
||||
switch trim {
|
||||
@@ -64,13 +58,18 @@ public struct TrimBehaviour: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable force_try
|
||||
// swiftlint:disable:next force_try
|
||||
private static let leadingWhitespaceAndNewlines = try! NSRegularExpression(pattern: "^\\s+")
|
||||
// swiftlint:disable:next force_try
|
||||
private static let trailingWhitespaceAndNewLines = try! NSRegularExpression(pattern: "\\s+$")
|
||||
|
||||
// swiftlint:disable:next force_try
|
||||
private static let leadingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "^[ \t]*\n")
|
||||
// swiftlint:disable:next force_try
|
||||
private static let trailingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "\n[ \t]*$")
|
||||
|
||||
// swiftlint:disable:next force_try
|
||||
private static let leadingWhitespace = try! NSRegularExpression(pattern: "^[ \t]*")
|
||||
// swiftlint:disable:next force_try
|
||||
private static let trailingWhitespace = try! NSRegularExpression(pattern: "[ \t]*$")
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//
|
||||
// Stencil
|
||||
// Copyright © 2022 Stencil
|
||||
// MIT Licence
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
typealias Number = Float
|
||||
|
||||
Reference in New Issue
Block a user