diff --git a/client/components/codeEditor/extensions/customKeyMaps.js b/client/components/codeEditor/extensions/customKeyMaps.js
index 974b0b1e2..6fe479348 100644
--- a/client/components/codeEditor/extensions/customKeyMaps.js
+++ b/client/components/codeEditor/extensions/customKeyMaps.js
@@ -83,7 +83,7 @@ const insertTab = (view)=>{
changes,
selection : EditorSelection.create(
view.state.selection.ranges.map((range)=>EditorSelection.cursor(
- mappedChanges.changes.mapPos(range.from, 1) + 2
+ mappedChanges.changes.mapPos(range.from, -1) + 2
)
)
)
diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx
index 05ca73bea..65de45177 100644
--- a/client/homebrew/brewRenderer/brewRenderer.jsx
+++ b/client/homebrew/brewRenderer/brewRenderer.jsx
@@ -6,7 +6,7 @@ import React, { useState, useRef, useMemo, useEffect } from 'react';
import _ from 'lodash';
import MarkdownLegacy from '@shared/markdownLegacy.js';
-import Markdown from '@shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
import ErrorBar from './errorBar/errorBar.jsx';
import ToolBar from './toolBar/toolBar.jsx';
@@ -203,7 +203,7 @@ const BrewRenderer = (props)=>{
return ;
} else {
if(pageText.startsWith('\\page')) {
- const firstLineTokens = Markdown.marked.lexer(pageText.split('\n', 1)[0])[0].tokens;
+ const firstLineTokens = hbfm.marked.lexer(pageText.split('\n', 1)[0])[0].tokens;
const injectedTags = firstLineTokens?.find((obj)=>obj.injectedTags !== undefined)?.injectedTags;
if(injectedTags) {
styles = { ...styles, ...injectedTags.styles };
@@ -231,7 +231,7 @@ const BrewRenderer = (props)=>{
// DO NOT REMOVE!!! REQUIRED FOR BACKWARDS COMPATIBILITY WITH NON-UPGRADABLE VERSIONS OF CHROME.
pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
- const html = Markdown.render(pageText, index);
+ const html = hbfm.render(pageText, index);
return ;
}
diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
index 9ef30917d..c012a167b 100644
--- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
+++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
@@ -1,7 +1,7 @@
import './notificationPopup.less';
import React, { useEffect, useState } from 'react';
import request from '../../utils/request-middleware.js';
-import Markdown from '@shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
import Dialog from '@components/dialog.jsx';
@@ -44,7 +44,7 @@ const NotificationPopup = ()=>{
return notifications.map((notification)=>(
')){
- const openTag = html.substring(0, html.indexOf('>')+1);
- html = html.substring(html.indexOf('>')+1);
- html = html.substring(0, html.lastIndexOf('
'));
-
- // Repeat the markdown processing for content inside the div, minus the preprocessing and postprocessing hooks which should only run once globally
- const opts = Marked.defaults;
- const tokens = Marked.lexer(html, opts);
- Marked.walkTokens(tokens, opts.walkTokens);
- return `${openTag} ${Marked.parser(tokens, opts)} `;
- }
- return html;
-};
-
-// Don't wrap {{ Spans alone on a line, or {{ Divs in tags
-renderer.paragraph = function(token){
- let match;
- const text = this.parser.parseInline(token.tokens);
- if(text.startsWith('
${text}\n`;
-};
-
-//Fix local links in the Preview iFrame to link inside the frame
-renderer.link = function (token) {
- let { href, title, tokens } = token;
- const text = this.parser.parseInline(tokens);
- let self = false;
- if(href[0] == '#') {
- self = true;
- }
- href = cleanUrl(href);
-
- if(href === null) {
- return text;
- }
- let out = `
${text}`;
- return out;
-};
-
-// Expose `src` attribute as `--HB_src` to make the URL accessible via CSS
-renderer.image = function (token) {
- const { href, title, text } = token;
- if(href === null)
- return text;
-
- let out = `

';
- return out;
-};
-
-// Disable default reflink behavior, as it steps on our variables extension
-tokenizer.def = function () {
- return undefined;
-};
-
-const mustacheSpans = {
- name : 'mustacheSpans',
- level : 'inline', // Is this a block-level or inline-level tokenizer?
- start(src) { return src.match(/{{[^{]/)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const completeSpan = /^{{[^\n]*}}/; // Regex for the complete token
- const inlineRegex = /{{(?=((?:[:=](?:"['\w,\-+*/()#%=?.&:!@$^;:\[\]_= ]*"|[\w\-+*/()#%.]*)|[^"=':{}\s]*)*))\1 *|}}/g;
- const match = completeSpan.exec(src);
- if(match) {
- //Find closing delimiter
- let blockCount = 0;
- let tags = {};
- let endTags = 0;
- let endToken = 0;
- let delim;
- while (delim = inlineRegex.exec(match[0])) {
- if(_.isEmpty(tags)) {
- tags = processStyleTags(delim[0].substring(2));
- endTags = delim[0].length;
- }
- if(delim[0].startsWith('{{')) {
- blockCount++;
- } else if(delim[0] == '}}' && blockCount !== 0) {
- blockCount--;
- if(blockCount == 0) {
- endToken = inlineRegex.lastIndex;
- break;
- }
- }
- }
-
- if(endToken) {
- const raw = src.slice(0, endToken);
- const text = raw.slice(endTags || -2, -2);
-
- return { // Token to generate
- type : 'mustacheSpans', // Should match "name" above
- raw : raw, // Text to consume from the source
- text : text, // Additional custom properties
- tags : tags,
- tokens : this.lexer.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc.
- };
- }
- }
- },
- renderer(token) {
- const tags = token.tags;
- tags.classes = ['inline-block', tags.classes].join(' ').trim();
- return `
`${key}="${value}"`).join(' ')}` : ''}` +
- `>${this.parser.parseInline(token.tokens)}`; // parseInline to turn child tokens into HTML
- }
-};
-
-const mustacheDivs = {
- name : 'mustacheDivs',
- level : 'block',
- start(src) { return src.match(/\n *{{[^{]/m)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const completeBlock = /^ *{{[^\n}]* *\n.*\n *}}/s; // Regex for the complete token
- const blockRegex = /^ *{{(?=((?:[:=](?:"['\w,\-+*/()#%=?.&:!@$^;:\[\]_= ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *$|^ *}}$/gm;
- const match = completeBlock.exec(src);
- if(match) {
- //Find closing delimiter
- let blockCount = 0;
- let tags = {};
- let endTags = 0;
- let endToken = 0;
- let delim;
- while (delim = blockRegex.exec(match[0])?.[0].trim()) {
- if(_.isEmpty(tags)) {
- tags = processStyleTags(delim.substring(2));
- endTags = delim.length + src.indexOf(delim);
- }
- if(delim.startsWith('{{')) {
- blockCount++;
- } else if(delim == '}}' && blockCount !== 0) {
- blockCount--;
- if(blockCount == 0) {
- endToken = blockRegex.lastIndex;
- break;
- }
- }
- }
-
- if(endToken) {
- const raw = src.slice(0, endToken);
- const text = raw.slice(endTags || -2, -2);
- return { // Token to generate
- type : 'mustacheDivs', // Should match "name" above
- raw : raw, // Text to consume from the source
- text : text, // Additional custom properties
- tags : tags,
- tokens : this.lexer.blockTokens(text)
- };
- }
- }
- },
- renderer(token) {
- const tags = token.tags;
- tags.classes = ['block', tags.classes].join(' ').trim();
- return `
`${key}="${value}"`).join(' ')}` : ''}` +
- `>${this.parser.parse(token.tokens)}
`; // parse to turn child tokens into HTML
- }
-};
-
-const mustacheInjectInline = {
- name : 'mustacheInjectInline',
- level : 'inline',
- start(src) { return src.match(/ *{[^{\n]/)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-+*/()#%=?.&:!@$^;:\[\]_= ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/g;
- const match = inlineRegex.exec(src);
- if(match) {
- const lastToken = tokens[tokens.length - 1];
- if(!lastToken || lastToken.type == 'mustacheInjectInline')
- return false;
-
- const tags = processStyleTags(match[1]);
- lastToken.originalType = lastToken.type;
- lastToken.type = 'mustacheInjectInline';
- lastToken.injectedTags = tags;
- return {
- type : 'mustacheInjectInline', // Should match "name" above
- raw : match[0], // Text to consume from the source
- text : ''
- };
- }
- },
- renderer(token) {
- if(!token.originalType){
- return;
- }
- token.type = token.originalType;
- const text = this.parser.parseInline([token]);
- const originalTags = extractHTMLStyleTags(text);
- const injectedTags = token.injectedTags;
- const tags = mergeHTMLTags(originalTags, injectedTags);
- const openingTag = /(<[^\s<>]+)[^\n<>]*(>.*)/s.exec(text);
- if(openingTag) {
- return `${openingTag[1]}` +
- `${tags.classes ? ` class="${tags.classes}"` : ''}` +
- `${tags.id ? ` id="${tags.id}"` : ''}` +
- `${!_.isEmpty(tags.styles) ? ` style="${Object.entries(tags.styles).map(([key, value])=>`${key}:${value};`).join(' ')}"` : ''}` +
- `${!_.isEmpty(tags.attributes) ? ` ${Object.entries(tags.attributes).map(([key, value])=>`${key}="${value}"`).join(' ')}` : ''}` +
- `${openingTag[2]}`; // parse to turn child tokens into HTML
- }
- return text;
- }
-};
-
-const mustacheInjectBlock = {
- extensions : [{
- name : 'mustacheInjectBlock',
- level : 'block',
- start(src) { return src.match(/\n *{[^{\n]/m)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-+*/()#%=?.&:!@$^;:\[\]_= ]*"|[\w\-+*/()#%.]*)|[^"=':{}\s]*)*))\1}/ym;
- const match = inlineRegex.exec(src);
- if(match) {
- const lastToken = tokens[tokens.length - 1];
- if(!lastToken || lastToken.type == 'mustacheInjectBlock')
- return false;
-
- lastToken.originalType = 'mustacheInjectBlock';
- lastToken.injectedTags = processStyleTags(match[1]);
- return {
- type : 'mustacheInjectBlock', // Should match "name" above
- raw : match[0], // Text to consume from the source
- text : ''
- };
- }
- },
- renderer(token) {
- if(!token.originalType){
- return;
- }
- token.type = token.originalType;
- const text = this.parser.parse([token]);
- const originalTags = extractHTMLStyleTags(text);
- const injectedTags = token.injectedTags;
- const tags = mergeHTMLTags(originalTags, injectedTags);
- const openingTag = /(<[^\s<>]+)[^\n<>]*(>.*)/s.exec(text);
- if(openingTag) {
- return `${openingTag[1]}` +
- `${tags.classes ? ` class="${tags.classes}"` : ''}` +
- `${tags.id ? ` id="${tags.id}"` : ''}` +
- `${!_.isEmpty(tags.styles) ? ` style="${Object.entries(tags.styles).map(([key, value])=>`${key}:${value};`).join(' ')}"` : ''}` +
- `${!_.isEmpty(tags.attributes) ? ` ${Object.entries(tags.attributes).map(([key, value])=>`${key}="${value}"`).join(' ')}` : ''}` +
- `${openingTag[2]}`; // parse to turn child tokens into HTML
- }
- return text;
- }
- }],
- walkTokens(token) {
- // After token tree is finished, tag tokens to apply styles to so Renderer can find them
- // Does not work with tables since Marked.js tables generate invalid "tokens", and changing "type" ruins Marked handling that edge-case
- if(token.originalType == 'mustacheInjectBlock' && token.type !== 'table') {
- token.originalType = token.type;
- token.type = 'mustacheInjectBlock';
- }
- }
-};
-
-const forcedParagraphBreaks = {
- name : 'hardBreaks',
- level : 'block',
- start(src) { return src.match(/\n:+$/m)?.index; }, // Hint to Marked.js to stop and check for a match
- tokenizer(src, tokens) {
- const regex = /^(:+)(?:\n|$)/ym;
- const match = regex.exec(src);
- if(match?.length) {
- return {
- type : 'hardBreaks', // Should match "name" above
- raw : match[0], // Text to consume from the source
- length : match[1].length,
- text : ''
- };
- }
- },
- renderer(token) {
- return `
\n`.repeat(token.length);
- }
-};
-
-// Emoji options
-// To add more icon fonts, need to do these things
-// 1) Add the font file as .woff2 to themes/fonts/iconFonts folder
-// 2) Create a .less file mapping CSS class names to the font character
-// 3) Create a .js file mapping Autosuggest names to CSS class names
-// 4) Import the .less file into shared/naturalcrit/codeEditor/codeEditor.less
-// 5) Import the .less file into themes/V3/blank.style.less
-// 6) Import the .js file to shared/naturalcrit/codeEditor/autocompleteEmoji.js and add to `emojis` object
-// 7) Import the .js file here to markdown.js, and add to `emojis` object below
-const MarkedEmojiOptions = {
- emojis : {
- ...diceFont,
- ...elderberryInn,
- ...fontAwesome,
- ...gameIcons,
- },
- renderer : (token)=>`
`
-};
-
-const tableTerminators = [
- `:+\\n`, // hardBreak
- ` *{[^\n]+}`, // blockInjector
- ` *{{[^{\n]*\n.*?\n}}` // mustacheDiv
-];
-
-const markdeepOptions = { langs: ['asciiArt'] };
-
-Marked.use(markedVariables());
-Marked.use(MarkedDiagramsMarkdeep(markdeepOptions));
-Marked.use(MarkedDefinitionLists());
-Marked.use({ extensions: [forcedParagraphBreaks, mustacheSpans, mustacheDivs, mustacheInjectInline] });
-Marked.use(mustacheInjectBlock);
-Marked.use(MarkedAlignedParagraphs());
-Marked.use(MarkedSubSuperText());
-Marked.use(MarkedNonbreakingSpaces());
-Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
-Marked.use(MarkedExtendedTables({ interruptPatterns: tableTerminators }), MarkedGFMHeadingId({ globalSlugs: true }),
- MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
-
-function cleanUrl(href) {
- try {
- href = encodeURI(href).replace(/%25/g, '%');
- } catch {
- return null;
- }
- return href;
-}
-
-const escapeTest = /[&<>"']/;
-const escapeReplace = /[&<>"']/g;
-const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
-const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
-const escapeReplacements = {
- '&' : '&',
- '<' : '<',
- '>' : '>',
- '"' : '"',
- '\'' : '''
-};
-const getEscapeReplacement = (ch)=>escapeReplacements[ch];
-const escape = function (html, encode) {
- if(encode) {
- if(escapeTest.test(html)) {
- return html.replace(escapeReplace, getEscapeReplacement);
- }
- } else {
- if(escapeTestNoEncode.test(html)) {
- return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
- }
- }
- return html;
-};
-
-const tagTypes = ['div', 'span', 'a'];
-const tagRegex = new RegExp(`(${
- _.map(tagTypes, (type)=>{
- return `\\<${type}\\b|\\${type}>`;
- }).join('|')})`, 'g');
-
-// Special "void" tags that can be self-closed but don't need to be.
-const voidTags = new Set([
- 'area', 'base', 'br', 'col', 'command', 'hr', 'img',
- 'input', 'keygen', 'link', 'meta', 'param', 'source'
-]);
-
-const processStyleTags = (string)=>{
- //split tags up. quotes can only occur right after : or =.
- //TODO: can we simplify to just split on commas?
- const tags = string.match(/(?:[^, ":=]+|[:=](?:"[^"]*"|))+/g);
-
- const id = _.remove(tags, (tag)=>tag.startsWith('#')).map((tag)=>tag.slice(1))[0] || null;
- const classes = _.remove(tags, (tag)=>(!tag.includes(':')) && (!tag.includes('='))).join(' ') || null;
- const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"'))
- ?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
- .reduce((obj, attr)=>{
- const index = attr.indexOf('=');
- let [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
- value = value.replace(/"/g, '');
- obj[key.trim()] = value.trim();
- return obj;
- }, {}) || null;
- const styles = tags?.length ? tags.reduce((styleObj, style)=>{
- const index = style.indexOf(':');
- const [key, value] = [style.substring(0, index), style.substring(index + 1)];
- styleObj[key.trim()] = value.replace(/"?([^"]*)"?/g, '$1').trim();
- return styleObj;
- }, {}) : null;
-
- return {
- id : id,
- classes : classes,
- styles : _.isEmpty(styles) ? null : styles,
- attributes : _.isEmpty(attributes) ? null : attributes
- };
-};
-
-//Given a string representing an HTML element, extract all of its properties (id, class, style, and other attributes)
-const extractHTMLStyleTags = (htmlString)=>{
- const firstElementOnly = htmlString.split('>')[0];
- const id = firstElementOnly.match(/id="([^"]*)"/)?.[1] || null;
- const classes = firstElementOnly.match(/class="([^"]*)"/)?.[1] || null;
- const styles = firstElementOnly.match(/style="([^"]*)"/)?.[1]
- ?.split(';').reduce((styleObj, style)=>{
- if(style.trim() === '') return styleObj;
- const index = style.indexOf(':');
- const [key, value] = [style.substring(0, index), style.substring(index + 1)];
- styleObj[key.trim()] = value.trim();
- return styleObj;
- }, {}) || null;
- const attributes = firstElementOnly.match(/[a-zA-Z]+="[^"]*"/g)
- ?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
- .reduce((obj, attr)=>{
- const index = attr.indexOf('=');
- const [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
- obj[key.trim()] = value.replace(/"/g, '');
- return obj;
- }, {}) || null;
-
- return {
- id : id,
- classes : classes,
- styles : _.isEmpty(styles) ? null : styles,
- attributes : _.isEmpty(attributes) ? null : attributes
- };
-};
-
-const mergeHTMLTags = (originalTags, newTags)=>{
- return {
- id : newTags.id || originalTags.id || null,
- classes : [originalTags.classes, newTags.classes].join(' ').trim() || null,
- styles : Object.assign(originalTags.styles ?? {}, newTags.styles ?? {}),
- attributes : Object.assign(originalTags.attributes ?? {}, newTags.attributes ?? {})
- };
-};
-
-const Markdown = {
- marked : Marked,
- render : (rawBrewText, pageNumber=0)=>{
- setMarkedVariablePage(pageNumber);
-
- const lastPageNumber = pageNumber > 0 ? getMarkedVariable('HB_pageNumber', pageNumber - 1) : 0;
- setMarkedVariable('HB_pageNumber', //Add document variables for this page
- !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber,
- pageNumber);
-
- if(pageNumber==0) MarkedGFMResetHeadingIDs();
-
- rawBrewText = rawBrewText.replace(/^\\column(?:break)?$/gm, `\n
\n`);
-
- const opts = Marked.defaults;
-
- rawBrewText = opts.hooks.preprocess(rawBrewText);
- const tokens = Marked.lexer(rawBrewText, opts);
-
- Marked.walkTokens(tokens, opts.walkTokens);
-
- const html = Marked.parser(tokens, opts);
- return opts.hooks.postprocess(html);
- },
-
- validate : (rawBrewText)=>{
- const errors = [];
- const leftovers = _.reduce(rawBrewText.split('\n'), (acc, line, _lineNumber)=>{
- const lineNumber = _lineNumber + 1;
- const matches = line.match(tagRegex);
- if(!matches || !matches.length) return acc;
-
- _.each(matches, (match)=>{
- _.each(tagTypes, (type)=>{
- if(match == `<${type}`){
- acc.push({
- type : type,
- line : lineNumber
- });
- }
- if(match === `${type}>`){
- // Closing tag: Check we expect it to be closed.
- // The accumulator may contain a sequence of voidable opening tags,
- // over which we skip before checking validity of the close.
- while (acc.length && voidTags.has(_.last(acc).type) && _.last(acc).type != type) {
- acc.pop();
- }
- // Now check that what remains in the accumulator is valid.
- if(!acc.length){
- errors.push({
- line : lineNumber,
- type : type,
- text : 'Unmatched closing tag',
- id : 'CLOSE'
- });
- } else if(_.last(acc).type == type){
- acc.pop();
- } else {
- errors.push({
- line : `${_.last(acc).line} to ${lineNumber}`,
- type : type,
- text : 'Type mismatch on closing tag',
- id : 'MISMATCH'
- });
- acc.pop();
- }
- }
- });
- });
- return acc;
- }, []);
-
- _.each(leftovers, (unmatched)=>{
- errors.push({
- line : unmatched.line,
- type : unmatched.type,
- text : 'Unmatched opening tag',
- id : 'OPEN'
- });
- });
-
- return errors;
- },
-};
-
-export default Markdown;
-
diff --git a/shared/naturalcrit/styles/core.less b/shared/naturalcrit/styles/core.less
index 3ff3e37fe..02d3dbab8 100644
--- a/shared/naturalcrit/styles/core.less
+++ b/shared/naturalcrit/styles/core.less
@@ -23,7 +23,6 @@ html,body, #reactRoot {
text-transform : uppercase;
text-decoration : none;
cursor : pointer;
- outline : none;
background-color : @backgroundColor;
border : none;
&:hover { background-color : darken(@backgroundColor, 5%); }
diff --git a/tests/markdown/basic.test.js b/tests/markdown/basic.test.js
index 6a131eb91..a01c032fd 100644
--- a/tests/markdown/basic.test.js
+++ b/tests/markdown/basic.test.js
@@ -1,10 +1,10 @@
-import Markdown from '../../shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
test('Processes the markdown within an HTML block if its just a class wrapper', function() {
const source = '
*Bold text*
';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered).toBe('
');
});
@@ -12,6 +12,6 @@ test('Processes the markdown within an HTML block if its just a class wrapper',
//
// test('Check markdown is using the custom renderer; specifically that it adds target=_self attribute to internal links in HTML blocks', function() {
// const source = '
[Has _self Attribute?](#p1)
';
-// const rendered = Markdown.render(source);
+// const rendered = hbfm.render(source);
// expect(rendered).toBe('
');
// });
diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js
index 35ad12ef7..e2fd4f744 100644
--- a/tests/markdown/definition-lists.test.js
+++ b/tests/markdown/definition-lists.test.js
@@ -1,23 +1,23 @@
-import Markdown from '../../shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
describe('Inline Definition Lists', ()=>{
test('No Term 1 Definition', function() {
const source = ':: My First Definition\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- My First Definition
\n
');
});
test('Single Definition Term', function() {
const source = 'My term :: My First Definition\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- My term
- My First Definition
\n
');
});
test('Multiple Definition Terms', function() {
const source = 'Term 1::Definition of Term 1\nTerm 2::Definition of Term 2\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
- Definition of Term 1
\n- Term 2
- Definition of Term 2
\n
');
});
});
@@ -25,79 +25,79 @@ describe('Inline Definition Lists', ()=>{
describe('Multiline Definition Lists', ()=>{
test('Single Term, Single Definition', function() {
const source = 'Term 1\n::Definition 1\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1
');
});
test('Single Term, Plural Definitions', function() {
const source = 'Term 1\n::Definition 1\n::Definition 2\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1
\n- Definition 2
');
});
test('Multiple Term, Single Definitions', function() {
const source = 'Term 1\n::Definition 1\n\nTerm 2\n::Definition 1\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1
\n- Term 2
\n- Definition 1
');
});
test('Multiple Term, Plural Definitions', function() {
const source = 'Term 1\n::Definition 1\n::Definition 2\n\nTerm 2\n::Definition 1\n::Definition 2\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1
\n- Definition 2
\n- Term 2
\n- Definition 1
\n- Definition 2
');
});
test('Single Term, Single multi-line definition', function() {
const source = 'Term 1\n::Definition 1\nand more and\nmore and more\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1 and more and more and more
');
});
test('Single Term, Plural multi-line definitions', function() {
const source = 'Term 1\n::Definition 1\nand more and more\n::Definition 2\nand more\nand more\n::Definition 3\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1 and more and more
\n- Definition 2 and more and more
\n- Definition 3
');
});
test('Multiple Term, Single multi-line definition', function() {
const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1 and more and more
\n- Term 2
\n- Definition 1
\n- Definition 2
');
});
test('Multiple Term, Single multi-line definition, followed by an inline dl', function() {
const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n::Inline Definition (no term)';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1 and more and more
\n- Term 2
\n- Definition 1
\n- Definition 2
- Inline Definition (no term)
\n
');
});
test('Multiple Term, Single multi-line definition, followed by paragraph', function() {
const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\nParagraph';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
\n- Definition 1 and more and more
\n- Term 2
\n- Definition 1
\n- Definition 2
Paragraph
');
});
test('Block Token cannot be the Term of a multi-line definition', function() {
const source = '## Header\n::Definition 1 of a single-line DL\n::Definition 1 of another single-line DL';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('\n
- Definition 1 of a single-line DL
\n- Definition 1 of another single-line DL
\n
');
});
test('Inline DL has priority over Multiline', function() {
const source = 'Term 1 :: Inline definition 1\n:: Inline definition 2 (no DT)';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
- Term 1
- Inline definition 1
\n- Inline definition 2 (no DT)
\n
');
});
test('Multiline Definition Term must have at least one non-empty Definition', function() {
const source = 'Term 1\n::';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
Term 1
\n
\n
`);
});
test('Multiline Definition List must have at least one non-newline character after ::', function() {
const source = 'Term 1\n::\nDefinition 1\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
Term 1
\n
\n
\n
Definition 1
`);
});
});
diff --git a/tests/markdown/emojis.test.js b/tests/markdown/emojis.test.js
index 072de10f9..cbbdbf0f5 100644
--- a/tests/markdown/emojis.test.js
+++ b/tests/markdown/emojis.test.js
@@ -1,4 +1,4 @@
-import Markdown from '../../shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
import dedent from 'dedent';
// Marked.js adds line returns after closing tags on some default tokens.
@@ -12,37 +12,37 @@ const emoji = 'df_d12_2';
describe(`When emojis/icons are active`, ()=>{
it('when a word is between two colons (:word:), and a matching emoji exists, it is rendered as an emoji', function() {
const source = `:${emoji}:`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('when a word is between two colons (:word:), and no matching emoji exists, it is not parsed', function() {
const source = `:invalid:`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
:invalid:
`);
});
it('two valid emojis with no whitespace are prioritized over definition lists', function() {
const source = `:${emoji}::${emoji}:`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('definition lists that are not also part of an emoji can coexist with normal emojis', function() {
const source = `definition :: term ${emoji}::${emoji}:`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
- definition
- term df_d12_2:
`);
});
it('A valid emoji is compatible with curly injectors', function() {
const source = `:${emoji}:{color:blue,myClass}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Emojis are not parsed inside of curly span CSS blocks', function() {
const source = `{{color:${emoji} text}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
text`);
});
@@ -50,7 +50,7 @@ describe(`When emojis/icons are active`, ()=>{
const source = dedent`{{color:${emoji}
text
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
diff --git a/tests/markdown/hard-breaks.test.js b/tests/markdown/hard-breaks.test.js
index 1f48f8f1e..cc8da9304 100644
--- a/tests/markdown/hard-breaks.test.js
+++ b/tests/markdown/hard-breaks.test.js
@@ -1,47 +1,47 @@
-import Markdown from '../../shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
describe('Hard Breaks', ()=>{
test('Single Break', function() {
const source = ':\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
test('Double Break', function() {
const source = '::\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
`);
});
test('Triple Break', function() {
const source = ':::\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
`);
});
test('Many Break', function() {
const source = '::::::::::\n\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
\n
`);
});
test('Multiple sets of Breaks', function() {
const source = ':::\n:::\n:::';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
`);
});
test('Break directly between two paragraphs', function() {
const source = 'Line 1\n::\nLine 2';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
Line 1
\n
\n
\n
Line 2
`);
});
test('Ignored inside a code block', function() {
const source = '```\n\n:\n\n```\n';
- const rendered = Markdown.render(source).trim();
+ const rendered = hbfm.render(source).trim();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n:\n
`);
});
});
diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js
index 378263e58..dceb6e1e1 100644
--- a/tests/markdown/mustache-syntax.test.js
+++ b/tests/markdown/mustache-syntax.test.js
@@ -1,7 +1,7 @@
/* eslint-disable max-lines */
import dedent from 'dedent';
-import Markdown from '../../shared/markdown.js';
+import { hbfm } from 'hbmarkedwrapper';
// Marked.js adds line returns after closing tags on some default tokens.
// This removes those line returns for comparison sake.
@@ -15,112 +15,112 @@ String.prototype.trimReturns = function(){
describe('Inline: When using the Inline syntax {{ }}', ()=>{
it('Renders a mustache span with text only', function() {
const source = '{{ text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text only, but with spaces', function() {
const source = '{{ this is a text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
this is a text');
});
it('Renders an empty mustache span', function() {
const source = '{{}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('Renders a mustache span with just a space', function() {
const source = '{{ }}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('Renders a mustache span with a few spaces only', function() {
const source = '{{ }}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('Renders a mustache span with text and class', function() {
const source = '{{my-class text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and two classes', function() {
const source = '{{my-class,my-class2 text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text with spaces and class', function() {
const source = '{{my-class this is a text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
this is a text');
});
it('Renders a mustache span with text and id', function() {
const source = '{{#my-span text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and two ids', function() {
const source = '{{#my-span,#my-favorite-span text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and css property', function() {
const source = '{{color:red text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and two css properties', function() {
const source = '{{color:red,padding:5px text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and css property which contains quotes', function() {
const source = '{{font-family:"trebuchet ms" text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text and two css properties which contains quotes', function() {
const source = '{{font-family:"trebuchet ms",padding:"5px 10px" text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a mustache span with text with quotes and css property which contains double quotes', function() {
const source = '{{font-family:"trebuchet ms" text "with quotes"}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text “with quotes”');
});
it('Renders a mustache span with text with quotes and css property which contains double and simple quotes', function() {
const source = `{{--stringVariable:"'string'" text "with quotes"}}`;
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
text “with quotes”`);
});
it('Renders a mustache span with text, id, class and a couple of css properties', function() {
const source = '{{pen,#author,color:orange,font-family:"trebuchet ms" text}}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span with added attributes', function() {
const source = 'Text and {{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e, text}} and more text!';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Text and text and more text!
\n');
});
});
@@ -132,7 +132,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{
text
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -140,14 +140,14 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a single paragraph with opening and closing brackets', function() {
const source = dedent`{{
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
{{}}
`);
});
@@ -155,7 +155,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{cat
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -163,7 +163,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{cat
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -171,7 +171,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{cat,dog
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -179,7 +179,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{color:red
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -187,7 +187,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{--stringVariable:"'string'"
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -195,7 +195,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{--stringVariable:"'string'"
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -203,7 +203,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{cat,color:red
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -211,7 +211,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{color:red,cat,#dog
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -219,7 +219,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{#cat,#dog
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -227,13 +227,13 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
const source = dedent`{{color:red,cat,#dog,a="b and c",d="e"
Sample text.
}}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with added attributes', function() {
const source = '{{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e\nText and text and more text!\n}}\n';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Text and text and more text!
\n
');
});
});
@@ -245,116 +245,116 @@ describe('Injection: When an injection tag follows an element', ()=>{
describe('and that element is an inline-block', ()=>{
it('Renders a span "text" with no injection', function() {
const source = '{{ text}}{}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with injected Class name', function() {
const source = '{{ text}}{ClassName}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with injected attribute', function() {
const source = '{{ text}}{a="b and c"}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with injected style', function() {
const source = '{{ text}}{color:red}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with injected style using a string variable', function() {
const source = `{{ text}}{--stringVariable:"'string'"}`;
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
text`);
});
it('Renders a span "text" with two injected styles', function() {
const source = '{{ text}}{color:red,background:blue}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with its own ID, overwritten with an injected ID', function() {
const source = '{{#oldId text}}{#newId}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with its own attributes, overwritten with an injected attribute, plus a new one', function() {
const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new"}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with its own attributes, overwritten with an injected attribute, ignoring "class", "style", and "id"', function() {
const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new",class="new",style="new",id="new"}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with its own styles, appended with injected styles', function() {
const source = '{{color:blue,height:10px text}}{width:10px,color:red}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders a span "text" with its own classes, appended with injected classes', function() {
const source = '{{classA,classB text}}{classA,classC}';
- const rendered = Markdown.render(source);
+ const rendered = hbfm.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
it('Renders an emphasis element with injected Class name', function() {
const source = '*emphasis*{big}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
emphasis
');
});
it('Renders a code element with injected style', function() {
const source = '`code`{background:gray}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
code
');
});
it('Renders an image element with injected style', function() {
const source = '{position:absolute}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

');
});
it('Renders an element modified by only the first of two consecutive injections', function() {
const source = '{{ text}}{color:red}{background:blue}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text{background:blue}
');
});
it('Renders an parent and child element, each modified by an injector', function() {
const source = dedent`**bolded text**{color:red}
{color:blue}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
bolded text
');
});
it('Renders an image with added attributes', function() {
const source = ` {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`);
});
it('Renders an image with "=" in the url, and added attributes', function() {
const source = ` {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`);
});
it('Renders an image and added attributes with "=" in the value, ', function() {
const source = ` {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e,otherUrl="url?auth=12345"}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`);
});
});
@@ -362,19 +362,19 @@ describe('Injection: When an injection tag follows an element', ()=>{
describe('and that element is a block', ()=>{
it('renders a div "text" with no injection', function() {
const source = '{{\ntext\n}}\n{}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('renders a div "text" with injected Class name', function() {
const source = '{{\ntext\n}}\n{ClassName}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('renders a div "text" with injected style', function() {
const source = '{{\ntext\n}}\n{color:red}';
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
@@ -383,7 +383,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{color:red,background:blue}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -392,7 +392,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{--stringVariable:"'string'"}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -401,7 +401,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{#newId}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
@@ -410,7 +410,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{attrA="new",attrC="new"}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
@@ -419,7 +419,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{attrA="new",attrC="new",class="new",style="new",id="new"}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
@@ -428,7 +428,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{width:10px,color:red}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
@@ -437,14 +437,14 @@ describe('Injection: When an injection tag follows an element', ()=>{
text
}}
{classA,classC}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
it('renders an h2 header "text" with injected class name', function() {
const source = dedent`## text
{ClassName}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text
');
});
@@ -455,7 +455,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
| 300 | 2 |
{ClassName}`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
| Experience Points | Level |
|---|
| 0 | 1 |
| 300 | 2 |
`);
});
@@ -466,7 +466,7 @@ describe('Injection: When an injection tag follows an element', ()=>{
// - Dark Chant of the Dentists
// - Divine Spell of Crossdressing
// {color:red}`;
- // const rendered = Markdown.render(source).trimReturns();
+ // const rendered = hbfm.render(source).trimReturns();
// expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`...`); // FIXME: expect this to be injected into