mirror of
https://github.com/kdnk/obsidian-automatic-linker.git
synced 2026-07-22 05:37:46 +00:00
fix: escape Obsidian alias links in tables
Why: - Aliased wiki links generated inside Markdown table cells used a raw pipe separator. - Markdown table formatters interpret that raw pipe as a column delimiter, which mangles table rows after automatic linking. What: - Escape pipe characters in links returned by Obsidian's generateMarkdownLink API when the replacement occurs inside a table. - Add a regression test covering an existing target file with a frontmatter alias inside a Markdown table cell. Closes: #35
This commit is contained in:
parent
b5e09f9b75
commit
f821e618f6
2 changed files with 83 additions and 1 deletions
79
src/__tests__/main-link-generator.test.ts
Normal file
79
src/__tests__/main-link-generator.test.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import { describe, expect, it, vi } from "vitest"
|
||||
import { buildCandidateTrieForTest } from "../replace-links/__tests__/test-helpers"
|
||||
import { DEFAULT_SETTINGS } from "../settings/settings-info"
|
||||
|
||||
class MockTFile {
|
||||
path: string
|
||||
|
||||
constructor(path: string) {
|
||||
this.path = path
|
||||
}
|
||||
}
|
||||
|
||||
vi.mock("obsidian", () => ({
|
||||
App: class {},
|
||||
Editor: class {},
|
||||
getFrontMatterInfo: () => ({ contentStart: 0 }),
|
||||
MarkdownView: class {},
|
||||
Notice: class {},
|
||||
parseFrontMatterAliases: () => [],
|
||||
Plugin: class {
|
||||
app: unknown
|
||||
|
||||
constructor(app: unknown) {
|
||||
this.app = app
|
||||
}
|
||||
},
|
||||
PluginSettingTab: class {},
|
||||
request: async () => ({}),
|
||||
Setting: class {
|
||||
setName() { return this }
|
||||
setDesc() { return this }
|
||||
setHeading() { return this }
|
||||
addToggle() { return this }
|
||||
addTextArea() { return this }
|
||||
},
|
||||
TFile: MockTFile,
|
||||
}))
|
||||
|
||||
describe("AutomaticLinkerPlugin link generator", () => {
|
||||
it("escapes alias separators generated by Obsidian inside markdown tables", async () => {
|
||||
const { default: AutomaticLinkerPlugin } = await import("../main")
|
||||
const settings = {
|
||||
scoped: false,
|
||||
baseDir: undefined,
|
||||
ignoreCase: true,
|
||||
}
|
||||
const { candidateMap, trie } = buildCandidateTrieForTest({
|
||||
files: [{ path: "notes/foo", aliases: ["bar"] }],
|
||||
settings,
|
||||
})
|
||||
const targetFile = new MockTFile("notes/foo.md")
|
||||
const app = {
|
||||
fileManager: {
|
||||
generateMarkdownLink: vi.fn(() => "[[notes/foo|bar]]"),
|
||||
},
|
||||
vault: {
|
||||
getAbstractFileByPath: vi.fn((path: string) => {
|
||||
if (path === "notes/foo.md") return targetFile
|
||||
return null
|
||||
}),
|
||||
getConfig: vi.fn(),
|
||||
},
|
||||
}
|
||||
const plugin = new AutomaticLinkerPlugin(app as never, {} as never)
|
||||
plugin.settings = {
|
||||
...DEFAULT_SETTINGS,
|
||||
formatGitHubURLs: false,
|
||||
formatJiraURLs: false,
|
||||
replaceUrlWithTitle: false,
|
||||
respectNewFileFolderPath: false,
|
||||
}
|
||||
;(plugin as unknown as { trie: typeof trie }).trie = trie
|
||||
;(plugin as unknown as { candidateMap: typeof candidateMap }).candidateMap = candidateMap
|
||||
|
||||
const result = plugin.modifyLinks("| bar | x |\n| --- | --- |\n", "current-file.md")
|
||||
|
||||
expect(result).toBe("| [[notes/foo\\|bar]] | x |\n| --- | --- |\n")
|
||||
})
|
||||
})
|
||||
|
|
@ -77,7 +77,10 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
if (targetFile instanceof TFile) {
|
||||
// File exists, use Obsidian's generateMarkdownLink API
|
||||
try {
|
||||
const link = this.app.fileManager.generateMarkdownLink(targetFile, sourcePath, "", alias || "")
|
||||
let link = this.app.fileManager.generateMarkdownLink(targetFile, sourcePath, "", alias || "")
|
||||
if (isInTable && link.includes("|")) {
|
||||
link = link.replace(/\|/g, "\\|")
|
||||
}
|
||||
return link
|
||||
}
|
||||
catch (error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue