mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-16 22:32:42 +00:00
fix(markdown): bare prose paths need an extension, line suffix or depth
Slash-separated English pairs were recognized as file links in prose. Require stronger path intent there while preserving the existing inline-code recognition rule.
This commit is contained in:
@@ -444,14 +444,20 @@ it.each([
|
||||
it.each([
|
||||
"src/index.ts",
|
||||
"README.md",
|
||||
"packages/app",
|
||||
"./scripts/run",
|
||||
"./x/y",
|
||||
"../x/y",
|
||||
"/x/y",
|
||||
"a/b/c",
|
||||
String.raw`C:\Users\x`,
|
||||
"src/index.ts:12:3",
|
||||
"src/run:12",
|
||||
"src/run:12:3",
|
||||
"src/run:12-20",
|
||||
"~/dev/paseo",
|
||||
String.raw`C:\Users\x\file.txt`,
|
||||
"file.ts:12",
|
||||
"file.ts:12-20",
|
||||
"123/file",
|
||||
"src/123",
|
||||
"123.ts",
|
||||
"FILE.TS",
|
||||
"https://example.com/path",
|
||||
@@ -463,6 +469,20 @@ it.each([
|
||||
expect(linkRecognition.inlineCode.test(token)).toBe(true);
|
||||
});
|
||||
|
||||
it.each([
|
||||
"before/after",
|
||||
"and/or",
|
||||
"input/output",
|
||||
"read/write",
|
||||
"packages/app",
|
||||
"123/file",
|
||||
"src/123",
|
||||
])("requires stronger path intent in prose while preserving inline code: %s", (token) => {
|
||||
const { linkRecognition } = prepareMarkdownSource(`Compare ${token}, then continue.`);
|
||||
expect([...`Compare ${token}, then continue.`.matchAll(linkRecognition.text)]).toEqual([]);
|
||||
expect(linkRecognition.inlineCode.test(token)).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps prose and inline-code recognition enabled through the native regex adapter", () => {
|
||||
const { linkRecognition } = prepareMarkdownSource("3/4 src/index.ts");
|
||||
const native = toNativeLinkRecognition(linkRecognition);
|
||||
|
||||
@@ -16,20 +16,31 @@ const LINE_SUFFIX = String.raw`(?::\d+(?::\d+)?(?:-\d+(?::\d+)?)?)?`;
|
||||
const FILE_EXTENSIONS = [...ASSISTANT_FILE_EXTENSIONS]
|
||||
.map((extension) => extension.replace(/[a-z]/g, (letter) => `[${letter}${letter.toUpperCase()}]`))
|
||||
.join("|");
|
||||
const SEPARATED_PATH = String.raw`(?:[A-Za-z]:[\\/]|\.{0,2}\/|~\/)?(?=${PATH_CHARACTER}*(?:[\\/]${PATH_CHARACTER}*)*${PATH_LETTER})${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT})+`;
|
||||
const PATH_PREFIX = String.raw`(?:[A-Za-z]:[\\/]|\.{0,2}\/|~\/)`;
|
||||
const HAS_PATH_LETTER = String.raw`(?=${PATH_CHARACTER}*(?:[\\/]${PATH_CHARACTER}*)*${PATH_LETTER})`;
|
||||
const SEPARATED_PATH = String.raw`${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT})+`;
|
||||
const FILE_NAME = String.raw`${PATH_SEGMENT}\.(?:${FILE_EXTENSIONS})`;
|
||||
// The native adapter mistakes a literal + in lookbehind for a quantifier; use its hex escape.
|
||||
const FILE_PATTERN = new RegExp(
|
||||
String.raw`(?:https?://[^\s<>]+|(?<![a-zA-Z0-9\u0080-\uFFFF_@.%\x2b~:/\\-])(?:${SEPARATED_PATH}|${FILE_NAME})${LINE_SUFFIX}(?![a-zA-Z0-9\u0080-\uFFFF_@%+:/\\-]|\.${PATH_CHARACTER}))`,
|
||||
"g",
|
||||
);
|
||||
// Bare prose paths need a known extension, a line suffix, or at least two separators.
|
||||
const PROSE_PATH = String.raw`(?:${PATH_PREFIX}${HAS_PATH_LETTER}${SEPARATED_PATH}|${HAS_PATH_LETTER}(?:${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT})*[\\/]${FILE_NAME}|${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT}){2,}|${SEPARATED_PATH}(?=:)))`;
|
||||
const INLINE_CODE_PATH = String.raw`${PATH_PREFIX}?${HAS_PATH_LETTER}${SEPARATED_PATH}`;
|
||||
|
||||
function createFilePattern(path: string): RegExp {
|
||||
// The native adapter mistakes a literal + in lookbehind for a quantifier; use its hex escape.
|
||||
return new RegExp(
|
||||
String.raw`(?:https?://[^\s<>]+|(?<![a-zA-Z0-9\u0080-\uFFFF_@.%\x2b~:/\\-])(?:${path}|${FILE_NAME})${LINE_SUFFIX}(?![a-zA-Z0-9\u0080-\uFFFF_@%+:/\\-]|\.${PATH_CHARACTER}))`,
|
||||
"g",
|
||||
);
|
||||
}
|
||||
|
||||
const FILE_PATTERN = createFilePattern(PROSE_PATH);
|
||||
const INLINE_CODE_FILE_PATTERN = createFilePattern(INLINE_CODE_PATH);
|
||||
|
||||
function linkMetadata() {
|
||||
return {
|
||||
linkRecognition: {
|
||||
text: FILE_PATTERN,
|
||||
inlineCode: new RegExp(
|
||||
String.raw`^(?:${FILE_PATTERN.source})(?:\(\d+(?:,\d+)?(?:-\d+(?:,\d+)?)?\)| lines? \d+(?:-\d+)?)?$`,
|
||||
String.raw`^(?:${INLINE_CODE_FILE_PATTERN.source})(?:\(\d+(?:,\d+)?(?:-\d+(?:,\d+)?)?\)| lines? \d+(?:-\d+)?)?$`,
|
||||
),
|
||||
},
|
||||
linkSource: markdownLinkSource,
|
||||
|
||||
Reference in New Issue
Block a user