-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 603286c
Showing
12 changed files
with
542 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.DS_Store | ||
/.build | ||
/.swiftpm | ||
/Packages | ||
/*.xcodeproj | ||
xcuserdata/ | ||
Package.resolved |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
disabled_rules: | ||
- trailing_comma | ||
- orphaned_doc_comment | ||
|
||
excluded: | ||
- .build | ||
- Tests/TidyHTMLPublishStepTests/Helpers/XCTestManifests.swift | ||
- Tests/LinuxMain.swift |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
© 2020 John Mueller | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// swift-tools-version:5.1 | ||
|
||
/** | ||
* TidyHTMLPublishStep | ||
* © 2020 John Mueller | ||
* MIT license, see LICENSE.md for details | ||
*/ | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "TidyHTMLPublishStep", | ||
products: [ | ||
.library(name: "TidyHTMLPublishStep", targets: ["TidyHTMLPublishStep"]), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/JohnSundell/Publish.git", from: "0.1.0"), | ||
.package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.0.0"), | ||
], | ||
targets: [ | ||
.target(name: "TidyHTMLPublishStep", dependencies: ["Publish", "SwiftSoup"]), | ||
.testTarget(name: "TidyHTMLPublishStepTests", dependencies: ["TidyHTMLPublishStep"]), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Tidy HTML step for Publish | ||
|
||
A `PublishingStep` for [Publish](https://github.com/JohnSundell/Publish) that nicely formats your website's HTML using [SwiftSoup](https://github.com/scinfu/SwiftSoup). | ||
|
||
## Installation | ||
|
||
To install the step, add it as a dependency within your `Package.swift` manifest: | ||
|
||
```swift | ||
let package = Package( | ||
... | ||
dependencies: [ | ||
... | ||
.package(url: "https://github.com/john-mueller/TidyHTMLPublishStep", from: "0.1.0") | ||
], | ||
targets: [ | ||
.target( | ||
... | ||
dependencies: [ | ||
... | ||
"TidyHTMLPublishStep" | ||
] | ||
) | ||
] | ||
... | ||
) | ||
``` | ||
|
||
Then import `TidyHTMLPublishStep` where you'd like to use it. | ||
|
||
## Usage | ||
|
||
The `tidyHTML(withIndentation:)` step should be inserted into your publishing pipeline *after* your HTML is generated. The default indentation is one space, if the parameter is omitted. | ||
|
||
```swift | ||
import TidyHTMLPublishStep | ||
... | ||
try DeliciousRecipes().publish(using: [ | ||
... | ||
.generateHTML(withTheme: .foundation), | ||
... | ||
.tidyHTML(indentedBy: .spaces(4)) | ||
... | ||
]) | ||
``` | ||
|
||
This package also provides an alternate convenience API to the `Website.publish(withTheme:...:additionalSteps:...)` method, replacing `additionalSteps` with `preGenerationSteps` and `postGenerationSteps`. The `tidyHTML` step should be passed to the `postGenerationSteps` parameter: | ||
|
||
```swift | ||
import TidyHTMLPublishStep | ||
... | ||
try DeliciousRecipes().publish( | ||
withTheme: theme, | ||
postGenerationSteps: [ | ||
.tidyHTML() | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* TidyHTMLPublishStep | ||
* © 2020 John Mueller | ||
* MIT license, see LICENSE.md for details | ||
*/ | ||
|
||
import Plot | ||
import Publish | ||
import SwiftSoup | ||
|
||
extension PublishingStep { | ||
public static func tidyHTML(indentedBy indent: Indentation.Kind? = nil) -> Self { | ||
.step(named: "Tidy HTML") { context in | ||
do { | ||
let root = try context.folder(at: "") | ||
|
||
let files = root.files.recursive | ||
|
||
for file in files where file.extension == "html" { | ||
let html = try file.readAsString() | ||
|
||
let outputSettings = OutputSettings() | ||
switch indent { | ||
case let .spaces(num), let .tabs(num): | ||
outputSettings.indentAmount(indentAmount: UInt(num)) | ||
default: | ||
break | ||
} | ||
|
||
let doc = try SwiftSoup.parse(html) | ||
doc.outputSettings(outputSettings) | ||
|
||
var tidyHTML = try doc.html() | ||
|
||
if case .tabs = indent { | ||
var isPreCode = false | ||
tidyHTML = tidyHTML.components(separatedBy: .newlines).map { line in | ||
if isPreCode { | ||
guard line.hasPrefix("</pre></code>") else { | ||
return line | ||
} | ||
isPreCode = false | ||
} | ||
|
||
let tabs = line.prefix(while: { $0 == " " }).map { _ in Character("\t") } | ||
let range = line.startIndex ..< line.index(line.startIndex, offsetBy: tabs.count) | ||
|
||
if line[range.upperBound...].hasPrefix("<pre><code>") { | ||
isPreCode = true | ||
} | ||
|
||
return line.replacingCharacters(in: range, with: String(tabs)) | ||
}.joined(separator: "\n") | ||
} | ||
|
||
try file.write(tidyHTML) | ||
} | ||
} catch { | ||
print("Error while tidying HTML:") | ||
print(error) | ||
} | ||
} | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
Sources/TidyHTMLPublishStep/Website+PostGenerationSteps.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* TidyHTMLPublishStep | ||
* © 2019 John Sundell, 2020 John Mueller | ||
* MIT license, see LICENSE.md for details | ||
* | ||
* This file was adapted from the Publish API | ||
*/ | ||
|
||
import Plot | ||
import Publish | ||
|
||
public extension Website { | ||
/// Publish this website using a default pipeline. To build a completely | ||
/// custom pipeline, use the `publish(using:)` method. | ||
/// - parameter theme: The HTML theme to generate the website using. | ||
/// - parameter indentation: How to indent the generated files. | ||
/// - parameter path: Any specific path to generate the website at. | ||
/// - parameter rssFeedSections: What sections to include in the site's RSS feed. | ||
/// - parameter rssFeedConfig: The configuration to use for the site's RSS feed. | ||
/// - parameter deploymentMethod: How to deploy the website. | ||
/// - parameter preGenerationSteps: Additional steps to add to the publishing | ||
/// pipeline. Will be executed right before the HTML generation process begins. | ||
/// - parameter postGenerationSteps: Additional steps to add to the publishing pipeline. | ||
/// Will be executed after generation steps, right before the deployment process begins. | ||
/// - parameter plugins: Plugins to be installed at the start of the publishing process. | ||
/// - parameter file: The file that this method is called from (auto-inserted). | ||
/// - parameter line: The line that this method is called from (auto-inserted). | ||
@discardableResult | ||
func publish(withTheme theme: Theme<Self>, | ||
indentation: Indentation.Kind? = nil, | ||
at path: Path? = nil, | ||
rssFeedSections: Set<SectionID> = Set(SectionID.allCases), | ||
rssFeedConfig: RSSFeedConfiguration? = .default, | ||
deployedUsing deploymentMethod: DeploymentMethod<Self>? = nil, | ||
preGenerationSteps: [PublishingStep<Self>] = [], | ||
postGenerationSteps: [PublishingStep<Self>] = [], | ||
plugins: [Plugin<Self>] = [], | ||
file: StaticString = #file) throws -> PublishedWebsite<Self> { | ||
try publish( | ||
at: path, | ||
using: [ | ||
.group(plugins.map(PublishingStep.installPlugin)), | ||
.optional(.copyResources()), | ||
.addMarkdownFiles(), | ||
.sortItems(by: \.date, order: .descending), | ||
.group(preGenerationSteps), | ||
.generateHTML(withTheme: theme, indentation: indentation), | ||
.unwrap(rssFeedConfig) { config in | ||
.generateRSSFeed( | ||
including: rssFeedSections, | ||
config: config | ||
) | ||
}, | ||
.generateSiteMap(indentedBy: indentation), | ||
.group(postGenerationSteps), | ||
.unwrap(deploymentMethod, PublishingStep.deploy), | ||
], | ||
file: file | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* TidyHTMLPublishStep | ||
* © 2020 John Mueller | ||
* MIT license, see LICENSE.md for details | ||
*/ | ||
|
||
import Foundation | ||
|
||
fputs("To run tests on Linux, use 'swift test --enable-test-discovery'\n", stderr) | ||
exit(1) |
51 changes: 51 additions & 0 deletions
51
Tests/TidyHTMLPublishStepTests/Helpers/HTMLFactoryMock.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* TidyHTMLPublishStep | ||
* © 2019 John Sundell, 2020 John Mueller | ||
* MIT license, see LICENSE.md for details | ||
* | ||
* This file was copied as-is from the Publish test target | ||
*/ | ||
|
||
import Plot | ||
import Publish | ||
|
||
final class HTMLFactoryMock<Site: Website>: HTMLFactory { | ||
typealias Closure<T> = (T, PublishingContext<Site>) throws -> HTML | ||
|
||
var makeIndexHTML: Closure<Index> = { _, _ in HTML(.body()) } | ||
var makeSectionHTML: Closure<Section<Site>> = { _, _ in HTML(.body()) } | ||
var makeItemHTML: Closure<Item<Site>> = { _, _ in HTML(.body()) } | ||
var makePageHTML: Closure<Page> = { _, _ in HTML(.body()) } | ||
var makeTagListHTML: Closure<TagListPage>? = { _, _ in HTML(.body()) } | ||
var makeTagDetailsHTML: Closure<TagDetailsPage>? = { _, _ in HTML(.body()) } | ||
|
||
func makeIndexHTML(for index: Index, | ||
context: PublishingContext<Site>) throws -> HTML { | ||
try makeIndexHTML(index, context) | ||
} | ||
|
||
func makeSectionHTML(for section: Section<Site>, | ||
context: PublishingContext<Site>) throws -> HTML { | ||
try makeSectionHTML(section, context) | ||
} | ||
|
||
func makeItemHTML(for item: Item<Site>, | ||
context: PublishingContext<Site>) throws -> HTML { | ||
try makeItemHTML(item, context) | ||
} | ||
|
||
func makePageHTML(for page: Page, | ||
context: PublishingContext<Site>) throws -> HTML { | ||
try makePageHTML(page, context) | ||
} | ||
|
||
func makeTagListHTML(for page: TagListPage, | ||
context: PublishingContext<Site>) throws -> HTML? { | ||
try makeTagListHTML?(page, context) | ||
} | ||
|
||
func makeTagDetailsHTML(for page: TagDetailsPage, | ||
context: PublishingContext<Site>) throws -> HTML? { | ||
try makeTagDetailsHTML?(page, context) | ||
} | ||
} |
Oops, something went wrong.