diff --git a/core/models/cosmoscope.js b/core/models/cosmoscope.js index 1c434992..c1bdd322 100644 --- a/core/models/cosmoscope.js +++ b/core/models/cosmoscope.js @@ -323,7 +323,7 @@ class Cosmoscope extends Graph { const fileId = file.metas['id'] || file.metas['title'].toLowerCase(); - quotesWithContexts.forEach(({ id, contexts }) => { + quotesWithContexts.forEach(({ id, type, contexts }) => { if (!bibliography.library[id]) return; if (referenceRecords.has(id)) { @@ -333,19 +333,29 @@ class Cosmoscope extends Graph { referenceRecords.set(id, { contexts, targets: new Set([fileId]), + type, }); } }); } } - referenceRecords.forEach(({ targets, contexts }, key) => { + referenceRecords.forEach(({ targets, contexts, type }, key) => { nodes.push( new Node(key, bibliography.library[key]['title'] || '', [opts['references_type_label']]), ); Array.from(targets).forEach((id) => links.push( - new Link(undefined, contexts, 'undefined', undefined, undefined, undefined, id, key), + new Link( + undefined, + contexts, + type || 'undefined', + undefined, + undefined, + undefined, + id, + key, + ), ), ); }); diff --git a/core/utils/citeExtractor.js b/core/utils/citeExtractor.js index 7ce64377..30e3992a 100644 --- a/core/utils/citeExtractor.js +++ b/core/utils/citeExtractor.js @@ -168,6 +168,8 @@ export default function extractCitations(markdown) { thisCitation['suppress-author'] = rawPrefix.trim().endsWith('-'); if (thisCitation['suppress-author']) { thisCitation.prefix = rawPrefix.substring(0, rawPrefix.trim().length - 1).trim(); + } else if (rawPrefix.trim().endsWith(':')) { + thisCitation.type = rawPrefix.trim().slice(0, -1); } else { thisCitation.prefix = rawPrefix.trim(); } diff --git a/core/utils/citeExtractor.spec.js b/core/utils/citeExtractor.spec.js index 011d07f8..29c83f30 100644 --- a/core/utils/citeExtractor.spec.js +++ b/core/utils/citeExtractor.spec.js @@ -306,6 +306,22 @@ const tests = [ ], description: 'extracts an in-text citation with a URL as citekey and optional locator/suffix', }, + { + input: 'Blah blah [agreesWith: @doe99; about: @smith2000].', + expected: [ + { + from: 10, + to: 49, + composite: false, + source: '[agreesWith: @doe99; about: @smith2000]', + citations: [ + { ...defaults, id: 'doe99', type: 'agreesWith' }, + { ...defaults, id: 'smith2000', type: 'about' }, + ], + }, + ], + description: 'extracts regular citation with type', + }, // The next tests check that locators without explicit page number are detected { input: '@{https://example.com/bib?name=foobar&date=2000} [33] says blah.', diff --git a/core/utils/quoteIdsWithContexts.js b/core/utils/quoteIdsWithContexts.js index 1d6700d6..63720ca2 100644 --- a/core/utils/quoteIdsWithContexts.js +++ b/core/utils/quoteIdsWithContexts.js @@ -12,13 +12,14 @@ export default function quoteIdsWithContexts(markdown) { extractParaphs(markdown).forEach((paraph) => { extractCitations(paraph).forEach((result) => { - result.citations.forEach(({ id }) => { + result.citations.forEach(({ id, type }) => { if (quotes[id]) { quotes[id].contexts.add(paraph); } else { quotes[id] = { contexts: new Set([paraph]), id, + type, }; } }); diff --git a/core/utils/quoteIdsWithContexts.spec.js b/core/utils/quoteIdsWithContexts.spec.js index 42ef52b3..5a50ee7a 100644 --- a/core/utils/quoteIdsWithContexts.spec.js +++ b/core/utils/quoteIdsWithContexts.spec.js @@ -20,6 +20,20 @@ Second paragraph quoting @doe99.`; ]); }); + it('should parse quote with type', () => { + const text = 'First paragraph quoting [agreesWith: @smith04].'; + + const result = quotesWithContexts(text); + + expect(result).toEqual([ + expect.objectContaining({ + contexts: ['First paragraph quoting [agreesWith: @smith04].'], + id: 'smith04', + type: 'agreesWith', + }), + ]); + }); + it('should parse many quotes per paragraph', () => { const text = `First paragraph quoting @smith04. diff --git a/e2e/citeproc/config.yml b/e2e/citeproc/config.yml index 19b208b5..4e67fbd0 100644 --- a/e2e/citeproc/config.yml +++ b/e2e/citeproc/config.yml @@ -28,6 +28,9 @@ link_types: adjacent concept: stroke: dotted color: "#e1e1e1" + agreesWith: + stroke: simple + color: "green" references_as_nodes: true references_type_label: "reference" record_filters: [] diff --git a/e2e/record.cy.js b/e2e/record.cy.js index 73146dca..714a9caa 100644 --- a/e2e/record.cy.js +++ b/e2e/record.cy.js @@ -191,8 +191,9 @@ describe('Record', () => { cy.get('@backlink').find('.highlight').should('have.text', 'tools for thought'); }); - it('should link type', () => { + it('should display link type', () => { cy.get('@backlink').should('contain.text', 'adjacent concept'); + cy.get('@link').should('contain.text', 'agreesWith'); }); }); diff --git a/e2e/records/tools-for-thought.md b/e2e/records/tools-for-thought.md index 6252a2d8..d2bf81a9 100644 --- a/e2e/records/tools-for-thought.md +++ b/e2e/records/tools-for-thought.md @@ -6,6 +6,6 @@ tag: - quotes --- -« Tools to augment human intelligence » [@engelbart1962; quoted by @matuschak2019]. +« Tools to augment human intelligence » [agreesWith: @engelbart1962; quoted by @matuschak2019]. ![alt text](otlet.jpg "Title") \ No newline at end of file