Skip to content

Commit 041da5d

Browse files
authored
Merge pull request #3357 from byronluk/byronluk/inline-links
fix: convert internal heading links when task is rendered in different file Fixes #3297.
2 parents df2b66b + 4b9618d commit 041da5d

File tree

7 files changed

+1242
-1
lines changed

7 files changed

+1242
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Internal Heading Links
2+
3+
```tasks
4+
filter by function task.file.filename.includes("internal_heading_links")
5+
```
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Other File
2+
3+
## Some Header
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Internal Heading Links Test
2+
3+
This file contains test cases for internal heading links in tasks.
4+
5+
## Simple Headers
6+
7+
## Another Header
8+
9+
## Basic Internal Links
10+
11+
- [ ] #task Task with [[#Basic Internal Links]]
12+
13+
## Multiple Links In One Task
14+
15+
- [ ] #task Task with [[#Multiple Links In One Task]] and [[#Simple Headers]]
16+
17+
## External File Links
18+
19+
- [ ] #task Task with [[Other File]]
20+
21+
## Mixed Link Types
22+
23+
- [ ] #task Task with [[Other File]] and [[#Mixed Link Types]]
24+
25+
## Header Links With File Reference
26+
27+
- [ ] #task [[#Header Links With File Reference]] then [[Other File#Some Header]] and [[#Another Header]]
28+
29+
## Headers-With_Special Characters
30+
31+
- [ ] #task Task with [[#Headers-With_Special Characters]]
32+
33+
## Aliased Links
34+
35+
- [ ] #task Task with [[#Aliased Links|I am an alias]]
36+
37+
## Links In Code Blocks
38+
39+
- [ ] #task Task with `[[#Links In Code Blocks]]` code block
40+
41+
## Escaped Links
42+
43+
- [ ] #task Task with \[\[#Escaped Links\]\] escaped link

src/Renderer/QueryResultsRenderer.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,9 @@ export class QueryResultsRenderer {
418418
queryRendererParameters: QueryRendererParameters,
419419
) {
420420
const isFilenameUnique = this.isFilenameUnique({ task }, queryRendererParameters.allMarkdownFiles);
421-
const listItem = await taskLineRenderer.renderTaskLine(task, taskIndex, isFilenameUnique);
421+
const processedTask = this.processTaskLinks(task);
422+
423+
const listItem = await taskLineRenderer.renderTaskLine(processedTask, taskIndex, isFilenameUnique);
422424

423425
// Remove all footnotes. They don't re-appear in another document.
424426
const footnotes = listItem.querySelectorAll('[data-footnote-id]');
@@ -545,6 +547,43 @@ export class QueryResultsRenderer {
545547
}
546548
}
547549

550+
private processTaskLinks(task: Task): Task {
551+
// Skip if task is from the same file as the query
552+
if (this.filePath === task.path) {
553+
return task;
554+
}
555+
556+
const linkCache = task.file.cachedMetadata.links;
557+
if (!linkCache) return task;
558+
559+
// Find links in the task description
560+
const taskLinks = linkCache.filter((link) => {
561+
return (
562+
link.position.start.line === task.taskLocation.lineNumber &&
563+
task.description.includes(link.original) &&
564+
link.link.startsWith('#')
565+
);
566+
});
567+
if (taskLinks.length === 0) return task;
568+
569+
let description = task.description;
570+
571+
// a task can only be from one file, so we can replace all the internal links
572+
//in the description with the new file path
573+
for (const link of taskLinks) {
574+
const fullLink = `[[${task.path}${link.link}|${link.displayText}]]`;
575+
description = description.replace(link.original, fullLink);
576+
}
577+
578+
// Return a new Task with the updated description
579+
return new Task({
580+
...task,
581+
description,
582+
// Preserve the original task's location information
583+
taskLocation: task.taskLocation,
584+
});
585+
}
586+
548587
private addPostponeButton(listItem: HTMLElement, task: Task, shortMode: boolean) {
549588
const amount = 1;
550589
const timeUnit = 'day';

tests/Obsidian/AllCacheSampleData.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import inheritance_task_listitem from './__test_data__/inheritance_task_listitem
3535
import inheritance_task_listitem_mixed_grandchildren from './__test_data__/inheritance_task_listitem_mixed_grandchildren.json';
3636
import inheritance_task_listitem_task from './__test_data__/inheritance_task_listitem_task.json';
3737
import inheritance_task_mixed_children from './__test_data__/inheritance_task_mixed_children.json';
38+
import internal_heading_links from './__test_data__/internal_heading_links.json';
3839
import jason_properties from './__test_data__/jason_properties.json';
3940
import link_in_file_body from './__test_data__/link_in_file_body.json';
4041
import link_in_file_body_with_custom_display_text from './__test_data__/link_in_file_body_with_custom_display_text.json';
@@ -113,6 +114,7 @@ export function allCacheSampleData() {
113114
inheritance_task_listitem_mixed_grandchildren,
114115
inheritance_task_listitem_task,
115116
inheritance_task_mixed_children,
117+
internal_heading_links,
116118
jason_properties,
117119
link_in_file_body,
118120
link_in_file_body_with_custom_display_text,

0 commit comments

Comments
 (0)