kdnk_obsidian-automatic-linker/src/replace-urls/replace-urls.ts
Kodai Nakamura cf5562f0cb fix: restore wikilink protection for URL replacement
Why:
Linear URLs were being rewritten inside existing wikilinks, and protected markdown segments were not treating linear:// URLs as URLs. That regressed helper compatibility and selection safety.

What:
- Skip raw URL replacement matches that fall inside wikilinks while keeping the helper direct and linear-aware.
- Extend protected markdown URL segmentation to include linear://.
- Add regression tests for raw replacement, segmentation, and selection formatting.
2026-06-22 03:41:26 +09:00

39 lines
1.2 KiB
TypeScript

import { AutomaticLinkerSettings } from "../settings/settings-info"
const URL_PATTERN = /(?:https?:\/\/|linear:\/\/)[^\s<>\]]+/g
const WIKILINK_PATTERN = /\[\[[\s\S]*?\]\]/g
const collectWikilinkRanges = (text: string): Array<{ start: number, end: number }> => {
const ranges: Array<{ start: number, end: number }> = []
let match: RegExpExecArray | null
while ((match = WIKILINK_PATTERN.exec(text)) !== null) {
ranges.push({
start: match.index,
end: match.index + match[0].length,
})
}
return ranges
}
const isInsideRange = (
index: number,
ranges: Array<{ start: number, end: number }>,
): boolean => ranges.some(range => index >= range.start && index < range.end)
export const replaceURLs = (
fileContent: string,
settings: AutomaticLinkerSettings,
formatter: (url: string, settings: AutomaticLinkerSettings) => string,
) => {
const wikilinkRanges = collectWikilinkRanges(fileContent)
return fileContent.replace(URL_PATTERN, (match, offset) => {
if (isInsideRange(offset, wikilinkRanges)) {
return match
}
return formatter(match, settings)
})
}