fix(ai): accents dans les chemins et resolution des chemins prefixes par le vault (BUG-042)
- accents : classes de caracteres Unicode (\p{L}\p{N}\p{M}) pour les motifs
de liens et _looksLikePath (PATH_NAME_RE) -> les chemins/fichiers accentues
produisent enfin un lien cliquable ; comparaison de chemins normalisee NFC
(_normKey), donc une mention decomposee (e + accent combinant, style macOS)
correspond a une entree d'index precomposee, et inversement.
- prefixe de vault : _splitVaultPrefix() retire un premier segment egal au nom
d'un vault connu (TestVault/Recettes/Pizza Maison.md) ; _fetchPathsForVault()
interroge l'index de CE vault sans ecraser le cache du vault actif ;
_openFileLink/_revealPath recoivent le vault cible ; repli 'retirer le
premier segment' si le prefixe ne correspond a aucun vault connu.
Tests : frontend IA 62/62 (+5), 9 suites JSDOM, validate-imports 36 modules,
pytest 963 passed / 6 skipped. Verifie aussi contre l'instance live sur donnees
reelles accentuees/espaces (Recettes/Preparation.md, Recettes/Pat... ) : 8/8.
This commit is contained in:
@@ -463,7 +463,7 @@ async function main() {
|
||||
const revealed = [];
|
||||
b._openFileLink = (p) => { opened.push(p); return Promise.resolve(); };
|
||||
b._revealPath = (p) => { revealed.push(p); return Promise.resolve(); };
|
||||
b._ensurePaths = async () => ([
|
||||
b._fetchPathsForVault = async () => ([
|
||||
{ path: "Mon dossier/Ma note.md", name: "Ma note.md", type: "file" },
|
||||
{ path: "Mon dossier/Sous dossier", name: "Sous dossier", type: "directory" },
|
||||
]);
|
||||
@@ -474,6 +474,63 @@ async function main() {
|
||||
assert.deepEqual(revealed, ["Mon dossier/Sous dossier"], "spaced directory resolves too");
|
||||
});
|
||||
|
||||
// ── 12c. Accents and vault-prefixed paths ──
|
||||
await test("_looksLikePath accepts accented names", () => {
|
||||
const b = new BooksLM();
|
||||
assert.equal(b._looksLikePath("Café.md"), true, "accented filename is a path");
|
||||
assert.equal(b._looksLikePath("Recettes/Préparation.md"), true, "accented path is a path");
|
||||
assert.ok(b._renderMarkdown("Voir `Recettes/Préparation.md`.").includes('data-path="Recettes/Préparation.md"'),
|
||||
"accented inline code becomes a link");
|
||||
});
|
||||
|
||||
await test("bare accented paths become links without the index", () => {
|
||||
const b = new BooksLM();
|
||||
const html = b._renderMarkdown("Ouvre Recettes/Préparation.md puis relis.");
|
||||
assert.ok(html.includes('data-path="Recettes/Préparation.md"'), "accented bare path linkified");
|
||||
});
|
||||
|
||||
await test("decomposed accents match precomposed index entries", async () => {
|
||||
const b = new BooksLM();
|
||||
b._activeVault = () => "TestVault";
|
||||
b._fetchPathsForVault = async () => ([{ path: "Recettes/Préparation.md", name: "Préparation.md", type: "file" }]);
|
||||
const opened = [];
|
||||
b._openFileLink = (p) => { opened.push(p); return Promise.resolve(); };
|
||||
|
||||
// NFD input (e + combining acute) against an NFC index entry.
|
||||
const nfd = "Recettes/Pre\u0301paration.md";
|
||||
await b._activatePath(nfd, "file");
|
||||
assert.deepEqual(opened, ["Recettes/Préparation.md"], "NFD mention resolves to the NFC path");
|
||||
});
|
||||
|
||||
await test("_splitVaultPrefix strips a leading vault name", () => {
|
||||
const b = new BooksLM();
|
||||
b._vault = "TestVault";
|
||||
assert.deepEqual(
|
||||
b._splitVaultPrefix("TestVault/Recettes/Pizza Maison.md"),
|
||||
{ vault: "TestVault", path: "Recettes/Pizza Maison.md" },
|
||||
"vault prefix split off",
|
||||
);
|
||||
assert.deepEqual(
|
||||
b._splitVaultPrefix("Recettes/Pizza Maison.md"),
|
||||
{ vault: null, path: "Recettes/Pizza Maison.md" },
|
||||
"no prefix when the first segment is not a vault",
|
||||
);
|
||||
});
|
||||
|
||||
await test("a vault-prefixed path opens the file in that vault", async () => {
|
||||
const b = new BooksLM();
|
||||
b._vault = "TestVault";
|
||||
b._activeVault = () => "TestVault";
|
||||
b._fetchPathsForVault = async (v) => (v === "TestVault"
|
||||
? [{ path: "Recettes/Pizza Maison.md", name: "Pizza Maison.md", type: "file" }]
|
||||
: []);
|
||||
const opened = [];
|
||||
b._openFileLink = (p, v) => { opened.push([v, p]); return Promise.resolve(); };
|
||||
|
||||
await b._activatePath("TestVault/Recettes/Pizza Maison.md", "file");
|
||||
assert.deepEqual(opened, [["TestVault", "Recettes/Pizza Maison.md"]], "opened in the named vault");
|
||||
});
|
||||
|
||||
await test("_renderMarkdown keeps external links external", () => {
|
||||
const b = new BooksLM();
|
||||
const html = b._renderMarkdown("[site](https://example.com/page)");
|
||||
|
||||
Reference in New Issue
Block a user