refactor: Adapt to new repository

This commit is contained in:
T. R. Bernstein
2025-09-30 18:48:15 +02:00
parent 17af3bace1
commit 6811c71bd6
66 changed files with 224 additions and 622 deletions

View File

@@ -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] = [:]

View File

@@ -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 {

View File

@@ -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

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
public class TemplateDoesNotExist: Error, CustomStringConvertible {
let templateNames: [String]
let loader: Loader?

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
public protocol Expression: CustomStringConvertible, Resolvable {
func evaluate(context: Context) throws -> Bool
}

View File

@@ -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

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
class FilterNode: NodeType {
let resolvable: Resolvable
let nodes: [NodeType]

View File

@@ -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 }

View File

@@ -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 {

View File

@@ -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 }

View File

@@ -1,11 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit
class IncludeNode: NodeType {
let templateName: Variable
let includeContext: String?

View File

@@ -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")
}

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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
}
}
}

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
#if !os(Linux)
import Foundation

View File

@@ -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 {

View File

@@ -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))
}

View File

@@ -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 {

View File

@@ -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]*$")
}

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation
typealias Number = Float