SwiftLint/Source/SwiftLintFramework/Models/RuleList+Documentation.swift

95 lines
3.3 KiB
Swift

import Foundation
extension RuleList {
public func generateDocumentation() -> String {
let rules = list.sorted { $0.0 < $1.0 }.map { $0.value }
let rulesText = rules.map(ruleMarkdown)
let rulesSummary = rules.map(ruleSummary)
var text = h1("Rules")
text += rulesSummary.joined()
text += "--------\n"
text += rulesText.joined(separator: "\n\n")
return text
}
private func ruleSummary(_ rule: Rule.Type) -> String {
return summaryItem(rule.description.name)
}
private func ruleMarkdown(_ rule: Rule.Type) -> String {
let description = rule.description
var content = h2(description.name)
content += detailsSummary(rule.init())
content += description.description + "\n"
if !description.nonTriggeringExamples.isEmpty || !description.triggeringExamples.isEmpty {
content += h3("Examples")
}
if !description.nonTriggeringExamples.isEmpty {
let examples = description.nonTriggeringExamples.map(formattedCode).joined(separator: "\n")
content += details(summary: "Non Triggering Examples", details: examples)
}
if !description.triggeringExamples.isEmpty {
let examples = description.triggeringExamples.map(formattedCode).joined(separator: "\n")
content += details(summary: "Triggering Examples", details: examples)
}
return content
}
private func details(summary: String, details: String) -> String {
var content = "<details>\n"
content += "<summary>\(summary)</summary>\n\n"
content += details + "\n"
content += "</details>\n"
return content
}
private func formattedCode(_ code: String) -> String {
var content = "```swift\n"
content += code
content += "\n```\n"
return content
}
private func detailsSummary(_ rule: Rule) -> String {
let columns = ["Identifier", "Enabled by default", "Supports autocorrection",
"Kind", "Analyzer", "Minimum Swift Compiler Version"]
var content = columns.joined(separator: " | ") + "\n"
content += columns.map { _ in "---" }.joined(separator: " | ") + "\n"
let identifier = type(of: rule).description.identifier
let defaultStatus = rule.isOptIn ? "Disabled" : "Enabled"
let correctable = rule is CorrectableRule ? "Yes" : "No"
let kind = type(of: rule).description.kind
let analyzer = rule is AnalyzerRule ? "Yes" : "No"
let minSwiftVersion = type(of: rule).description.minSwiftVersion.rawValue
let rowMembers = ["`\(identifier)`", defaultStatus, correctable, "\(kind)", analyzer, minSwiftVersion]
content += rowMembers.joined(separator: " | ") + " \n\n"
return content
}
private func h1(_ text: String) -> String {
return "\n# \(text)\n\n"
}
private func h2(_ text: String) -> String {
return "\n## \(text)\n\n"
}
private func h3(_ text: String) -> String {
return "\n### \(text)\n\n"
}
private func summaryItem(_ text: String) -> String {
let anchor = text.lowercased().components(separatedBy: .whitespaces).joined(separator: "-")
return "* [\(text)](#\(anchor))\n"
}
}