Skip to content

Commit

Permalink
Allow anchor <doc:#heading> within same article
Browse files Browse the repository at this point in the history
  • Loading branch information
natikgadzhi committed Jul 3, 2023
1 parent 2026dcc commit b86cb77
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -764,10 +764,16 @@ extension PathHierarchy {
let isAbsolute = path.first == "/"
|| String(components.first ?? "") == NodeURLGenerator.Path.documentationFolderName
|| String(components.first ?? "") == NodeURLGenerator.Path.tutorialsFolderName


// If there is a # character in the last component, split that into two components
if let hashIndex = components.last?.firstIndex(of: "#") {
let last = components.removeLast()
components.append(last[..<hashIndex])
// Allow anrhor-only links where there's nothing before #.
// In case the pre-# part is empty, and we're omitting empty components, don't add it in.
let pathName = last[..<hashIndex]
if !pathName.isEmpty || !omittingEmptyComponents {
components.append(pathName)
}

let fragment = String(last[hashIndex...].dropFirst())
return (components.map(Self.parse(pathComponent:)) + [PathComponent(full: fragment, name: fragment, kind: nil, hash: nil)], isAbsolute)
Expand Down
25 changes: 25 additions & 0 deletions Tests/SwiftDocCTests/Infrastructure/PathHierarchyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,30 @@ class PathHierarchyTests: XCTestCase {
XCTAssertNil(articleNode.symbol, "General documentation link find the article")
}

func testArticleSelfAnchorLinks() throws {
try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver)
let (_, _, context) = try testBundleAndContext(copying: "MixedLanguageFramework") { url in
try """
# ArticleWithHeading
## TestTargetHeading
This article has the same path as a symbol. See also:
- <doc:TestTargetHeading>
- <doc:#TestTargetHeading>
""".write(to: url.appendingPathComponent("ArticleWithHeading.md"), atomically: true, encoding: .utf8)
}

let tree = try XCTUnwrap(context.hierarchyBasedLinkResolver?.pathHierarchy)
let articleNode = try tree.findNode(path: "/MixedLanguageFramework/ArticleWithHeading", onlyFindSymbols: false)

let linkNode = try tree.find(path: "TestTargetHeading", parent: articleNode.identifier, onlyFindSymbols: false)
let anchorLinkNode = try tree.find(path: "#TestTargetHeading", parent: articleNode.identifier, onlyFindSymbols: false)
XCTAssertNotNil(linkNode)
XCTAssertNotNil(anchorLinkNode)
}

func testOverloadedSymbols() throws {
try XCTSkipUnless(LinkResolutionMigrationConfiguration.shouldUseHierarchyBasedLinkResolver)
let (_, context) = try testBundleAndContext(named: "OverloadedSymbols")
Expand Down Expand Up @@ -1555,6 +1579,7 @@ class PathHierarchyTests: XCTestCase {
assertParsedPathComponents("first/", [("first", nil, nil)])
assertParsedPathComponents("first//second", [("first", nil, nil), ("second", nil, nil)])
assertParsedPathComponents("first/second#third", [("first", nil, nil), ("second", nil, nil), ("third", nil, nil)])
assertParsedPathComponents("#first", [("first", nil, nil)])

// Check disambiguation
assertParsedPathComponents("path-hash", [("path", nil, "hash")])
Expand Down

0 comments on commit b86cb77

Please sign in to comment.