From ec7c1342eddcbc7528045e19268950a64791e20c Mon Sep 17 00:00:00 2001 From: Guillaume Brioudes Date: Mon, 2 Dec 2024 19:00:42 +0100 Subject: [PATCH] feat: slugify ids --- core/models/record.js | 32 ++++++++++--------------- core/models/record.spec.js | 44 ++++++++++++++++++---------------- core/utils/convertWikilinks.js | 4 +++- core/utils/parseWikilinks.js | 5 ++-- 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/core/models/record.js b/core/models/record.js index 88a737a..be0e54f 100644 --- a/core/models/record.js +++ b/core/models/record.js @@ -69,27 +69,12 @@ export default class Record { static recordFromFile(file, config) { const { content, head } = readYmlFm(file, { schema: 'failsafe' }); - const links = parseWikilinks(content, config); - const props = { ...normalizeInput(head, config), - links, + links: parseWikilinks(content, config), content, }; - if (typeof props.types === 'string') { - props.types = [props.types]; - } - if (typeof props.tags === 'string') { - props.tags = [props.tags]; - } - if (typeof props.begin === 'string') { - props.begin = new Date(props.begin).getTime() / 1000; - } - if (typeof props.end === 'string') { - props.end = new Date(props.end).getTime() / 1000; - } - const { error } = schema.validate(props); if (error) { throw new Error(`Record contains error: ${error.message}`); @@ -100,7 +85,7 @@ export default class Record { id: props.id, title: props.title, content: props.content, - links, + links: props.links, tags: props.tags, types: props.types, begin: props.begin, @@ -141,8 +126,6 @@ export default class Record { }, config, ); - - return undefined; } /** @@ -154,6 +137,10 @@ export default class Record { static recordFromCiteItem(citeItem, config, bibliography) { const libraryItem = bibliography.library[citeItem.id]; + if (!libraryItem) { + throw new Error(`Library item "${citeItem.id}" is unknown`); + } + const props = { id: citeItem.id, title: libraryItem['title'], @@ -318,6 +305,9 @@ function normalizeInput(head, config) { ...normalizedHead, }; + if (!props.id && props.title) { + props.id = props.title; + } if (typeof props.types === 'string') { props.types = [props.types]; } @@ -331,6 +321,10 @@ function normalizeInput(head, config) { props.end = new Date(props.end).getTime() / 1000; } + if (props.id) { + props.id = slugify(props.id); + } + if (props.types) { const knownTypes = config.getTypesRecords(); props.types = props.types.reduce((acc, curr, i, arr) => { diff --git a/core/models/record.spec.js b/core/models/record.spec.js index 0493100..b22ac72 100644 --- a/core/models/record.spec.js +++ b/core/models/record.spec.js @@ -61,27 +61,6 @@ describe('Record model', () => { expect(record.thumbnail).toBeUndefined(); }); - it('should generate the correct YAML front matter', () => { - const record = new Record(props, config); - - const file = record.getFileContent(true); - - expect(file).toEqual(`--- -id: "20200501150208" -title: Test Record -types: - - type1 - - type2 -tags: - - tag1 - - tag2 -thumbnail: img.jpg -author: John Doe ---- - -This is a test content`); - }); - it('should generate YAML front matter with id', () => { const record = new Record({ ...props, tags: undefined }, config); @@ -164,6 +143,29 @@ File linked to [[20210901132906]]`; }); }); + it('should title became id if no id', () => { + const file = `--- +title: Test Record +--- + +Content`; + + const result = Record.recordFromFile(file, config); + expect(result).toEqual({ + id: 'test-record', + title: 'Test Record', + content: '\n\nContent', + links: [], + types: ['undefined'], + tags: [], + metas: {}, + begin: undefined, + end: undefined, + thumbnail: undefined, + config: config, + }); + }); + it('should get from citeproc item', () => { /** @type {import('../utils/citeExtractor.js'.CiteItem)} */ const citeItem = { diff --git a/core/utils/convertWikilinks.js b/core/utils/convertWikilinks.js index 31dc112..7b3b1c6 100644 --- a/core/utils/convertWikilinks.js +++ b/core/utils/convertWikilinks.js @@ -1,3 +1,5 @@ +import slugify from './slugify'; + const wikilinkRE = new RegExp(/\[\[((?[^:|\]]+?):)?(?.+?)(\|(?.+?))?\]\]/, 'g'); /** @@ -12,7 +14,7 @@ const wikilinkRE = new RegExp(/\[\[((?[^:|\]]+?):)?(?.+?)(\|(?.+ function convertWikilinks(markdown, records, opts, idToHighlight) { return markdown.replace(wikilinkRE, (match, _, type, targetId, __, text) => { - const record = records.get(targetId.toLowerCase()); + const record = records.get(slugify(targetId)); if (!record) return match; diff --git a/core/utils/parseWikilinks.js b/core/utils/parseWikilinks.js index fb33278..c6bba41 100644 --- a/core/utils/parseWikilinks.js +++ b/core/utils/parseWikilinks.js @@ -1,4 +1,5 @@ import extractParaphs from './paraphExtractor'; +import slugify from './slugify'; /** * @typedef Link @@ -27,7 +28,7 @@ export default function parseWikilinks(markdown, config) { for (const match of markdown.matchAll(wikilinkRE) || []) { const [full, _, type, id, __, placeholder] = match; - const target = id.toLowerCase(); + const target = slugify(id); linksDict.set(target, { type: type || 'undefined', @@ -40,7 +41,7 @@ export default function parseWikilinks(markdown, config) { extractParaphs(markdown).forEach((paraph) => { for (const match of paraph.matchAll(wikilinkRE)) { const [full, _, type, id] = match; - const target = id.toLowerCase(); + const target = slugify(id); linksDict.get(target).contexts.add(paraph); }