From 2ce8d2f376358df9770c9a4ad3a946f1e1c74056 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Sun, 1 Dec 2019 15:43:05 -0800 Subject: [PATCH] Make the site generator recursively render public files - Now renders markdown - Separates templates from content now --- SiteGenerator/Package.resolved | 9 +++ SiteGenerator/Package.swift | 16 ++--- .../Sources/SiteGenerator/Generator.swift | 66 +++++++++++++++++-- bin/test | 1 + tests/test-index/expected/index.html | 4 +- tests/test-index/in/public/index.html | 4 -- tests/test-index/in/public/index.md | 1 + .../layout.html => templates/site.html} | 3 +- 8 files changed, 80 insertions(+), 24 deletions(-) delete mode 100644 tests/test-index/in/public/index.html create mode 100644 tests/test-index/in/public/index.md rename tests/test-index/in/{public/layout.html => templates/site.html} (79%) diff --git a/SiteGenerator/Package.resolved b/SiteGenerator/Package.resolved index 8f069df..87ad4ee 100644 --- a/SiteGenerator/Package.resolved +++ b/SiteGenerator/Package.resolved @@ -1,6 +1,15 @@ { "object": { "pins": [ + { + "package": "Ink", + "repositoryURL": "https://github.com/johnsundell/ink.git", + "state": { + "branch": null, + "revision": "af743ad6882bfe1adb0acf7453d36d2075ebb1d5", + "version": "0.1.3" + } + }, { "package": "PathKit", "repositoryURL": "https://github.com/kylef/PathKit.git", diff --git a/SiteGenerator/Package.swift b/SiteGenerator/Package.swift index 843e2d3..b00be37 100644 --- a/SiteGenerator/Package.swift +++ b/SiteGenerator/Package.swift @@ -6,16 +6,14 @@ import PackageDescription let package = Package( name: "SiteGenerator", dependencies: [ - .package(url: "https://github.com/stencilproject/Stencil.git", from: "0.13.0") + .package(url: "https://github.com/stencilproject/Stencil.git", from: "0.13.0"), + .package(url: "https://github.com/johnsundell/ink.git", from: "0.1.0"), ], targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages which this package depends on. - .target( - name: "SiteGenerator", - dependencies: ["Stencil"]), - .testTarget( - name: "SiteGeneratorTests", - dependencies: ["SiteGenerator"]), + .target( name: "SiteGenerator", dependencies: [ + "Ink", + "Stencil", + ]), + .testTarget(name: "SiteGeneratorTests", dependencies: ["SiteGenerator"]), ] ) diff --git a/SiteGenerator/Sources/SiteGenerator/Generator.swift b/SiteGenerator/Sources/SiteGenerator/Generator.swift index f5e5936..f1ad536 100644 --- a/SiteGenerator/Sources/SiteGenerator/Generator.swift +++ b/SiteGenerator/Sources/SiteGenerator/Generator.swift @@ -6,6 +6,7 @@ // import Foundation +import Ink import PathKit import Stencil @@ -16,19 +17,72 @@ public final class Generator { public let sourceURL: URL private let renderer: Environment + private let mdParser: MarkdownParser public init(sourceURL: URL) throws { - let publicURL = sourceURL.appendingPathComponent("public") - self.renderer = Environment(loader: FileSystemLoader(paths: [Path(publicURL.path)])) let siteURL = sourceURL.appendingPathComponent("site.json") self.site = try Site.decode(from: siteURL) self.sourceURL = sourceURL + + let templatesURL = sourceURL.appendingPathComponent("templates") + self.renderer = Environment(loader: FileSystemLoader(paths: [Path(templatesURL.path)])) + + self.mdParser = MarkdownParser(modifiers: []) } public func generate(targetURL: URL) throws { - try fileManager.createDirectory(at: targetURL, withIntermediateDirectories: true, attributes: nil) - let indexHTML = try renderer.renderTemplate(name: "index.html", context: ["site": site]) - let indexURL = targetURL.appendingPathComponent("index.html") - try indexHTML.write(to: indexURL, atomically: true, encoding: .utf8) + // Iterate through all files in public recursively and render or copy each one + let publicURL = sourceURL.appendingPathComponent("public") + try renderPath(publicURL.path, to: targetURL) + } + + func renderPath(_ path: String, to targetURL: URL) throws { + for filename in try fileManager.contentsOfDirectory(atPath: path) { + + // Recurse into subdirectories, updating the target directory as well. + let fileURL = URL(fileURLWithPath: path).appendingPathComponent(filename) + var isDir: ObjCBool = false + fileManager.fileExists(atPath: fileURL.path, isDirectory: &isDir) + guard !isDir.boolValue else { + try renderPath(fileURL.path, to: targetURL.appendingPathComponent(filename)) + return + } + + // Make sure this path exists so we can write to it. + try fileManager.createDirectory(at: targetURL, withIntermediateDirectories: true, attributes: nil) + + // Handle the file, transforming it if necessary. + let ext = filename.split(separator: ".").last! + switch ext { + + case "md": + let htmlURL = targetURL.appendingPathComponent(filename.replacingOccurrences(of: ".md", with: ".html")) + try renderMarkdown(from: fileURL, to: htmlURL, template: "site", context: [:]) + + default: + // Who knows. Copy the file unchanged. + let src = URL(fileURLWithPath: path).appendingPathComponent(filename) + let dest = targetURL.appendingPathComponent(filename) + try fileManager.copyItem(at: src, to: dest) + } + + } + } + + func renderMarkdown( + from sourceURL: URL, + to targetURL: URL, + template: String, + context: [String: Any] + ) throws { + let bodyMarkdown = try String(contentsOf: sourceURL, encoding: .utf8) + let bodyResult = mdParser.parse(bodyMarkdown) + let bodyHTML = bodyResult.html.trimmingCharacters(in: .whitespacesAndNewlines) + var context = context + context["site"] = site + context["body"] = bodyHTML + context.merge(bodyResult.metadata, uniquingKeysWith: { _, new in new }) + let siteHTML = try renderer.renderTemplate(name: "\(template).html", context: context) + try siteHTML.write(to: targetURL, atomically: true, encoding: .utf8) } } diff --git a/bin/test b/bin/test index f24d106..27c8b19 100755 --- a/bin/test +++ b/bin/test @@ -8,6 +8,7 @@ cp .build/x86_64-apple-macosx/debug/SiteGenerator ../bin/sitegen popd >/dev/null for site in Tests/test-*; do + rm -rf "$site/actual" bin/compile "$site/in" "$site/actual" # >/dev/null diff -ru "$site/expected" "$site/actual" rm -r "$site/actual" diff --git a/tests/test-index/expected/index.html b/tests/test-index/expected/index.html index ac26573..4299de6 100644 --- a/tests/test-index/expected/index.html +++ b/tests/test-index/expected/index.html @@ -5,8 +5,6 @@

Valar Morghulis

- -

hello world

- +

hello world

diff --git a/tests/test-index/in/public/index.html b/tests/test-index/in/public/index.html deleted file mode 100644 index 99a41fc..0000000 --- a/tests/test-index/in/public/index.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "layout.html" %} -{% block content %} -

hello world

-{% endblock %} diff --git a/tests/test-index/in/public/index.md b/tests/test-index/in/public/index.md new file mode 100644 index 0000000..95d09f2 --- /dev/null +++ b/tests/test-index/in/public/index.md @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/tests/test-index/in/public/layout.html b/tests/test-index/in/templates/site.html similarity index 79% rename from tests/test-index/in/public/layout.html rename to tests/test-index/in/templates/site.html index 6c6d145..7ff05a3 100644 --- a/tests/test-index/in/public/layout.html +++ b/tests/test-index/in/templates/site.html @@ -5,7 +5,6 @@

{{ site.title }}

- {% block content %} - {% endblock %} + {{ body }}