Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2021 Apple Inc. and the Swift project authors
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -77,6 +77,8 @@ extension RenderBlockContent: TextIndexing {
.joined(separator: " ")
case .video(let video):
return video.metadata?.rawIndexableTextContent(references: references) ?? ""
case .thematicBreak:
return ""
default:
fatalError("unknown RenderBlockContent case in rawIndexableTextContent")
}
Expand Down
14 changes: 11 additions & 3 deletions Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2021 Apple Inc. and the Swift project authors
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -76,7 +76,10 @@ public enum RenderBlockContent: Equatable {

/// A video with an optional caption.
case video(Video)


/// An authored thematic break between block elements.
case thematicBreak

// Warning: If you add a new case to this enum, make sure to handle it in the Codable
// conformance at the bottom of this file, and in the `rawIndexableTextContent` method in
// RenderBlockContent+TextIndexing.swift!
Expand Down Expand Up @@ -776,11 +779,13 @@ extension RenderBlockContent: Codable {
metadata: container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata)
)
)
case .thematicBreak:
self = .thematicBreak
}
}

private enum BlockType: String, Codable {
case paragraph, aside, codeListing, heading, orderedList, unorderedList, step, endpointExample, dictionaryExample, table, termList, row, small, tabNavigator, links, video
case paragraph, aside, codeListing, heading, orderedList, unorderedList, step, endpointExample, dictionaryExample, table, termList, row, small, tabNavigator, links, video, thematicBreak
}

private var type: BlockType {
Expand All @@ -801,6 +806,7 @@ extension RenderBlockContent: Codable {
case .tabNavigator: return .tabNavigator
case .links: return .links
case .video: return .video
case .thematicBreak: return .thematicBreak
default: fatalError("unknown RenderBlockContent case in type property")
}
}
Expand Down Expand Up @@ -862,6 +868,8 @@ extension RenderBlockContent: Codable {
case .video(let video):
try container.encode(video.identifier, forKey: .identifier)
try container.encodeIfPresent(video.metadata, forKey: .metadata)
case .thematicBreak:
break
default:
fatalError("unknown RenderBlockContent case in encode method")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -376,6 +376,10 @@ struct RenderContentCompiler: MarkupVisitor {
content: content
))]
}

mutating func visitThematicBreak(_ thematicBreak: ThematicBreak) -> [RenderContent] {
return [RenderBlockContent.thematicBreak]
}

func defaultVisit(_ markup: Markup) -> [RenderContent] {
return []
Expand Down
6 changes: 5 additions & 1 deletion Sources/SwiftDocC/Semantics/MarkupReferenceResolver.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -171,6 +171,10 @@ struct MarkupReferenceResolver: MarkupRewriter {

return symbolLink
}

mutating func visitThematicBreak(_ thematicBreak: ThematicBreak) -> Markup? {
return thematicBreak
}

mutating func visitBlockDirective(_ blockDirective: BlockDirective) -> Markup? {
switch blockDirective.name {
Expand Down
19 changes: 18 additions & 1 deletion Sources/SwiftDocC/SwiftDocC.docc/Resources/RenderNode.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.0.0",
"info": {
"description": "Render Node API",
"version": "0.4.0",
"version": "0.4.1",
"title": "Render Node API"
},
"paths": { },
Expand Down Expand Up @@ -437,6 +437,9 @@
{
"$ref": "#/components/schemas/Video"
},
{
"$ref": "#/components/schemas/ThematicBreak"
},
{
"$ref": "#/components/schemas/Aside"
},
Expand Down Expand Up @@ -695,6 +698,20 @@
}
}
},
"ThematicBreak": {
"type": "object",
"required": [
"type",
],
"properties": {
"type": {
"type": "string",
"enum": [
"thematicBreak"
]
}
}
},
"Aside": {
"type": "object",
"required": [
Expand Down
23 changes: 23 additions & 0 deletions Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3452,4 +3452,27 @@ Document
])
}
}

func testThematicBreak() throws {
let source = """

---

"""

let markup = Document(parsing: source, options: .parseBlockDirectives)

XCTAssertEqual(markup.childCount, 1)

let (bundle, context) = try testBundleAndContext()

var contentTranslator = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/TestThematicBreak", sourceLanguage: .swift))

let renderContent = try XCTUnwrap(markup.children.reduce(into: [], { result, item in result.append(contentsOf: contentTranslator.visit(item))}) as? [RenderBlockContent])
let expectedContent: [RenderBlockContent] = [
.thematicBreak
]

XCTAssertEqual(expectedContent, renderContent)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

@testable import SwiftDocC
import Markdown
import XCTest

class RenderBlockContent_ThematicBreakTests: XCTestCase {
func testThematicBreakCodability() throws {
try assertRoundTripCoding(RenderBlockContent.thematicBreak)
}

func testThematicBreakIndexable() throws {
let thematicBreak = RenderBlockContent.thematicBreak
XCTAssertEqual("", thematicBreak.rawIndexableTextContent(references: [:]))
}

// MARK: - Thematic Break Markdown Variants
func testThematicBreakVariants() throws {
let source = """

---
***
___

"""

let markup = Document(parsing: source, options: .parseBlockDirectives)

XCTAssertEqual(markup.childCount, 3)

let (bundle, context) = try testBundleAndContext()

var contentTranslator = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/TestThematicBreak", sourceLanguage: .swift))

let renderContent = try XCTUnwrap(markup.children.reduce(into: [], { result, item in result.append(contentsOf: contentTranslator.visit(item))}) as? [RenderBlockContent])
let expectedContent: [RenderBlockContent] = [
.thematicBreak,
.thematicBreak,
.thematicBreak
]

XCTAssertEqual(expectedContent, renderContent)
}

func testThematicBreakVariantsWithSpaces() throws {
let source = """

- - -
* * *
_ _ _

"""

let markup = Document(parsing: source, options: .parseBlockDirectives)

XCTAssertEqual(markup.childCount, 3)

let (bundle, context) = try testBundleAndContext()

var contentTranslator = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/TestThematicBreak", sourceLanguage: .swift))

let renderContent = try XCTUnwrap(markup.children.reduce(into: [], { result, item in result.append(contentsOf: contentTranslator.visit(item))}) as? [RenderBlockContent])
let expectedContent: [RenderBlockContent] = [
.thematicBreak,
.thematicBreak,
.thematicBreak
]

XCTAssertEqual(expectedContent, renderContent)
}

func testThematicBreakMoreThanThreeCharacters() throws {
let source = """

----
*****
______
- - - - - -
* * * * *
_ _ _ _ _ _ _ _

"""

let markup = Document(parsing: source, options: .parseBlockDirectives)

XCTAssertEqual(markup.childCount, 6)

let (bundle, context) = try testBundleAndContext()

var contentTranslator = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/TestThematicBreak", sourceLanguage: .swift))

let renderContent = try XCTUnwrap(markup.children.reduce(into: [], { result, item in result.append(contentsOf: contentTranslator.visit(item))}) as? [RenderBlockContent])
let expectedContent: [RenderBlockContent] = [
.thematicBreak, .thematicBreak, .thematicBreak, .thematicBreak, .thematicBreak, .thematicBreak
]

XCTAssertEqual(expectedContent, renderContent)
}
}
Loading