Merge pull request #46 from JohnSundell/html-merging

HTMLOutputFormat: Merge same-type tokens along with whitespace
This commit is contained in:
John Sundell 2019-03-10 21:50:00 +01:00 committed by GitHub
commit 73ffdd2e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 5 deletions

View File

@ -27,26 +27,60 @@ public extension HTMLOutputFormat {
struct Builder: OutputBuilder {
private let classPrefix: String
private var html = ""
private var pendingToken: (string: String, type: TokenType)?
private var pendingWhitespace: String?
fileprivate init(classPrefix: String) {
self.classPrefix = classPrefix
}
public mutating func addToken(_ token: String, ofType type: TokenType) {
html.append("<span class=\"\(classPrefix)\(type.string)\">\(token.escaped)</span>")
if var pending = pendingToken {
guard pending.type != type else {
pendingWhitespace.map { pending.string += $0 }
pendingWhitespace = nil
pending.string += token
pendingToken = pending
return
}
}
appendPending()
pendingToken = (token, type)
}
public mutating func addPlainText(_ text: String) {
appendPending()
html.append(text.escaped)
}
public mutating func addWhitespace(_ whitespace: String) {
html.append(whitespace)
if pendingToken != nil {
pendingWhitespace = (pendingWhitespace ?? "") + whitespace
} else {
html.append(whitespace)
}
}
public func build() -> String {
public mutating func build() -> String {
appendPending()
return html
}
private mutating func appendPending() {
if let pending = pendingToken {
html.append("""
<span class="\(classPrefix)\(pending.type.string)">\(pending.string.escaped)</span>
""")
pendingToken = nil
}
if let whitespace = pendingWhitespace {
html.append(whitespace)
pendingWhitespace = nil
}
}
}
}

View File

@ -21,5 +21,5 @@ public protocol OutputBuilder {
/// Add some whitespace to the builder
mutating func addWhitespace(_ whitespace: String)
/// Build the final output based on the builder's current state
func build() -> Output
mutating func build() -> Output
}

View File

@ -10,6 +10,20 @@ final class HTMLOutputFormatTests: SplashTestCase {
highlighter = SyntaxHighlighter(format: HTMLOutputFormat())
}
func testBasicGeneration() {
let html = highlighter.highlight("""
public struct Test: SomeProtocol {
func hello() -> Int { return 7 }
}
""")
XCTAssertEqual(html, """
<span class="keyword">public struct</span> Test: <span class="type">SomeProtocol</span> {
<span class="keyword">func</span> hello() -&gt; <span class="type">Int</span> { <span class="keyword">return</span> <span class="number">7</span> }
}
""")
}
func testStrippingGreaterAndLessThanCharactersFromOutput() {
let html = highlighter.highlight("Array<String>")
@ -18,6 +32,14 @@ final class HTMLOutputFormatTests: SplashTestCase {
""")
}
func testCommentMerging() {
let html = highlighter.highlight("// Hey I'm a comment!")
XCTAssertEqual(html, """
<span class="comment">// Hey I'm a comment!</span>
""")
}
func testAllTestsRunOnLinux() {
XCTAssertTrue(TestCaseVerifier.verifyLinuxTests((type(of: self)).allTests))
}
@ -26,7 +48,9 @@ final class HTMLOutputFormatTests: SplashTestCase {
extension HTMLOutputFormatTests {
static var allTests: [(String, TestClosure<HTMLOutputFormatTests>)] {
return [
("testStrippingGreaterAndLessThanCharactersFromOutput", testStrippingGreaterAndLessThanCharactersFromOutput)
("testBasicGeneration", testBasicGeneration),
("testStrippingGreaterAndLessThanCharactersFromOutput", testStrippingGreaterAndLessThanCharactersFromOutput),
("testCommentMerging", testCommentMerging)
]
}
}