0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-03 01:52:42 +00:00

Updated and reworked to handle more definition*

Updated to allow multiple definition terms and definitions per term

<Term>::<definition>
<Term>::<definition1>::<definition2>
::<definition3>

```
**Example** ::
::V3 uses HTML *definition lists* to create "lists" with hanging indents.
::Three
I'm a term::Four

**<u>Hello</u>**::I\'m a different
::List
:
```
This commit is contained in:
David Bolack
2023-12-20 22:57:37 -06:00
parent eeba037244
commit 96d973528c
3 changed files with 42 additions and 23 deletions

View File

@@ -237,32 +237,45 @@ const superSubScripts = {
const definitionLists = { const definitionLists = {
name : 'definitionLists', name : 'definitionLists',
level : 'block', 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) { tokenizer(src, tokens) {
const regex = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym; const regex = /^([^\n:]*?)::(.*)(?:\n|$)/ym;
let match; let match;
let endIndex = 0; const endIndex = src.match(`\n\n`)?.index + 2;
const definitions = []; const allDefinitions = [];
let currentDefinition = [];
while (match = regex.exec(src)) { while (match = regex.exec(src)) {
definitions.push({ if(match[1].trim()?.length) {
dt : this.lexer.inlineTokens(match[1].trim()), if(currentDefinition?.dt?.length) {
dd : match[2].split('::').map((s)=>this.lexer.inlineTokens(s.trim())) allDefinitions.push(currentDefinition);
}); currentDefinition = [];
endIndex = regex.lastIndex; }
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 { return {
type : 'definitionLists', type : 'definitionLists',
raw : src.slice(0, endIndex), raw : src.slice(0, endIndex),
definitions definitions : allDefinitions
}; };
} }
}, },
renderer(token) { renderer(token) {
return `<dl>${token.definitions.reduce((html, def)=>{ let returnVal = `<dl>`;
token.definitions.forEach((def)=>{
const dds = def.dd.map((s)=>`<dd>${this.parser.parseInline(s)}</dd>`).join('\n'); const dds = def.dd.map((s)=>`<dd>${this.parser.parseInline(s)}</dd>`).join('\n');
return `${html}<dt>${this.parser.parseInline(def.dt)}</dt>${dds}`; returnVal += `<div><dt>${this.parser.parseInline(def.dt)}</dt>${dds}</div>`;
}, '')}</dl>`; });
return `${returnVal}</dl>`;
} }
}; };

View File

@@ -4,21 +4,27 @@ const Markdown = require('naturalcrit/markdown.js');
describe('Dictionary Terms', ()=>{ describe('Dictionary Terms', ()=>{
test('Single Definition', function() { 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); const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><dt>My term</dt><dd>My First Definition</dd></dl>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><div><dt>My term</dt><dd>My First Definition</dd></div></dl>');
}); });
test('Two Definitions', function() { 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); const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><dt>My term</dt><dd>My First Definition</dd>\n<dd>My Second Definition</dd></dl>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><div><dt>My term</dt><dd>My First Definition</dd>\n<dd>My Second Definition</dd></div></dl>');
}); });
test('Three Definitions', function() { 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); const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><dt>My term</dt><dd>My First Definition</dd>\n<dd>My Second Definition</dd>\n<dd>My Third Definition</dd></dl>'); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<dl><div><dt>My term</dt><dd>My First Definition</dd>\n<dd>My Second Definition</dd>\n<dd>My Third Definition</dd></div></dl>');
});
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('<dl><div><dt><strong>Example</strong></dt><dd>V3 uses HTML <em>definition lists</em> to create “lists” with hanging indents.</dd>\n<dd>Three</dd>\n<dd>Four</dd></div></dl><dl><div><dt>Hello</dt><dd>I\m a different</dd>\n<dd>List</dd></div></dl>');
}); });
}); });

View File

@@ -968,7 +968,7 @@ body { counter-reset : phb-page-numbers; }
& + * { margin-top : 0.17cm; } & + * { margin-top : 0.17cm; }
} }
p + dl { margin-top : 0.17cm; } p + dl { margin-top : 0.17cm; }
dt { dt {
display : inline; display : inline;
margin-right : 5px; margin-right : 5px;
margin-left : -1em; margin-left : -1em;