diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js
index 1fc14b534..7a584a927 100644
--- a/shared/naturalcrit/markdown.js
+++ b/shared/naturalcrit/markdown.js
@@ -237,32 +237,45 @@ const superSubScripts = {
const definitionLists = {
name : 'definitionLists',
level : 'block',
- start(src) { return src.match(/^.*?::.*/m)?.index; }, // Hint to Marked.js to stop and check for a match
+ start(src) { return src.match(/^.*?::.*\n\n/m)?.index; }, // Hint to Marked.js to stop and check for a match
tokenizer(src, tokens) {
- const regex = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym;
+ const regex = /^([^\n:]*?)::(.*)(?:\n|$)/ym;
let match;
- let endIndex = 0;
- const definitions = [];
+ const endIndex = src.match(`\n\n`)?.index + 2;
+ const allDefinitions = [];
+ let currentDefinition = [];
while (match = regex.exec(src)) {
- definitions.push({
- dt : this.lexer.inlineTokens(match[1].trim()),
- dd : match[2].split('::').map((s)=>this.lexer.inlineTokens(s.trim()))
- });
- endIndex = regex.lastIndex;
+ if(match[1].trim()?.length) {
+ if(currentDefinition?.dt?.length) {
+ allDefinitions.push(currentDefinition);
+ currentDefinition = [];
+ }
+ currentDefinition = {
+ dt : this.lexer.inlineTokens(match[1].trim()),
+ dd : []
+ };
+ }
+ currentDefinition.dd = currentDefinition.dd.concat(match[2].split('::').filter((item)=>item).map((s)=>this.lexer.inlineTokens(s.trim())));
+ if(!currentDefinition.dd?.length) {
+ currentDefinition.dd = [this.lexer.inlineTokens('')];
+ }
}
- if(definitions.length) {
+ if(currentDefinition.hasOwnProperty('dt')) { allDefinitions.push(currentDefinition); }
+ if(allDefinitions.length) {
return {
- type : 'definitionLists',
- raw : src.slice(0, endIndex),
- definitions
+ type : 'definitionLists',
+ raw : src.slice(0, endIndex),
+ definitions : allDefinitions
};
}
},
renderer(token) {
- return `
${token.definitions.reduce((html, def)=>{
+ let returnVal = ``;
+ token.definitions.forEach((def)=>{
const dds = def.dd.map((s)=>`- ${this.parser.parseInline(s)}
`).join('\n');
- return `${html}- ${this.parser.parseInline(def.dt)}
${dds}`;
- }, '')}
`;
+ returnVal += `- ${this.parser.parseInline(def.dt)}
${dds}`;
+ });
+ return `${returnVal}
`;
}
};
diff --git a/tests/markdown/marked-extensions.test.js b/tests/markdown/marked-extensions.test.js
index 52f2da38f..5f8c7718e 100644
--- a/tests/markdown/marked-extensions.test.js
+++ b/tests/markdown/marked-extensions.test.js
@@ -4,21 +4,27 @@ const Markdown = require('naturalcrit/markdown.js');
describe('Dictionary Terms', ()=>{
test('Single Definition', function() {
- const source = 'My term :: My First Definition';
+ const source = 'My term :: My First Definition\n\n';
const rendered = Markdown.render(source);
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
');
});
test('Two Definitions', function() {
- const source = 'My term :: My First Definition :: My Second Definition';
+ const source = 'My term :: My First Definition :: My Second Definition\n\n';
const rendered = Markdown.render(source);
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
\n- My Second Definition
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
\n- My Second Definition
');
});
test('Three Definitions', function() {
- const source = 'My term :: My First Definition :: My Second Definition :: My Third Definition';
+ const source = 'My term :: My First Definition :: My Second Definition :: My Third Definition\n\n';
const rendered = Markdown.render(source);
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
\n- My Second Definition
\n- My Third Definition
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- My term
- My First Definition
\n- My Second Definition
\n- My Third Definition
');
+ });
+
+ test('Multiline Definitions', function() {
+ const source = '**Example** :: V3 uses HTML *definition lists* to create "lists" with hanging indents.\n::Three\n::Four\n\nHello::I\'m a different\n::List\n\n';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('- Example
- V3 uses HTML definition lists to create “lists” with hanging indents.
\n- Three
\n- Four
- Hello
- I\’m a different
\n- List
');
});
});
diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less
index 2a2c49772..fbb00c670 100644
--- a/themes/V3/5ePHB/style.less
+++ b/themes/V3/5ePHB/style.less
@@ -968,7 +968,7 @@ body { counter-reset : phb-page-numbers; }
& + * { margin-top : 0.17cm; }
}
p + dl { margin-top : 0.17cm; }
- dt {
+ dt {
display : inline;
margin-right : 5px;
margin-left : -1em;