diff --git a/client/components/codeEditor/codeEditor.jsx b/client/components/codeEditor/codeEditor.jsx
index 25bf4f88e..5ac254132 100644
--- a/client/components/codeEditor/codeEditor.jsx
+++ b/client/components/codeEditor/codeEditor.jsx
@@ -43,9 +43,9 @@ const themes = { default: defaultCM5Theme, ...cm5Themes, darkbrewery };
const themeCompartment = new Compartment();
const highlightCompartment = new Compartment();
-import { generalKeymap, markdownKeymap } from './extensions/customKeyMaps.js';
+import { generalKeymap, markdownKeymap, cssKeymap, formatCSS } from './extensions/customKeyMaps.js';
import foldOnPages from './extensions/customFolding.js';
-import { customHighlightPlugin, customHighlightStyle } from './extensions/customHighlight.js';
+import { customHighlightStyle , customHighlightPlugin } from './extensions/customHighlight.js';
import { legacyCustomHighlightStyle } from './extensions/legacyCustomHighlight.js';
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
@@ -186,7 +186,7 @@ const CodeEditor = forwardRef(
//keyboard shortcut
keymap.of([...defaultKeymap, foldKeymap, ...searchKeymap]),
generalKeymap,
- ...(tab !== 'brewStyles' ? [markdownKeymap] : []),
+ ...(tab === 'brewStyles' ? [cssKeymap] : [markdownKeymap]),
//multiple cursors and selections
drawSelection(),
@@ -356,6 +356,8 @@ const CodeEditor = forwardRef(
}, 400);
},
+ formatCode : ()=>formatCSS(viewRef.current),
+
undo : ()=>undo(viewRef.current),
redo : ()=>redo(viewRef.current),
diff --git a/client/components/codeEditor/codeEditor.less b/client/components/codeEditor/codeEditor.less
index ca77f29a8..1d1e1ae96 100644
--- a/client/components/codeEditor/codeEditor.less
+++ b/client/components/codeEditor/codeEditor.less
@@ -15,6 +15,18 @@
}
}
+@keyframes slideacross {
+ 0% {
+ bottom: -200px;
+ left: -200px;
+ }
+
+ 100% {
+ bottom:100%;
+ left:100%;
+ }
+}
+
:where(.codeEditor) {
width : 100%;
height : calc(100% - 25px);
@@ -23,6 +35,27 @@
.cm-editor {
height : 100%;
outline : none !important;
+
+ &.cm-flash {
+ position:relative;
+ &::after {
+ position:absolute;
+ content:'';
+ bottom:-200px;
+ left:-200px;
+ translate:-50%;
+ width:200%;
+ height:100px;
+ background:linear-gradient(0deg, #89eafc00 0px, #89ebfc8e 50px, #89eafc00 100px, transparent);
+ display:block;
+
+ rotate:30deg;
+
+ @media screen and (prefers-reduced-motion: no-preference) {
+ animation: .5s linear 1 slideacross ;
+ }
+ }
+ }
}
&.brewSnippets .cm-snippetLine,
diff --git a/client/components/codeEditor/extensions/customHighlight.js b/client/components/codeEditor/extensions/customHighlight.js
index 33c68da7a..cb44d3fd9 100644
--- a/client/components/codeEditor/extensions/customHighlight.js
+++ b/client/components/codeEditor/extensions/customHighlight.js
@@ -251,13 +251,13 @@ function tokenizeCustomMarkdown(text) {
);
if(match) endCh = match.index + match[0].length;
const closingMatch = lineText.match(/ *(}})/d);
-
+
if(closingMatch) {
tokens.push({ line: lineNumber, from: closingMatch.indices[1][0], to: closingMatch.indices[1][1], type: customTags.block });
} else {
tokens.push({ line: lineNumber, type: customTags.block });
}
-
+
}
});
@@ -350,10 +350,9 @@ class ImageWidget extends WidgetType {
toDOM() {
const img = document.createElement('img');
- img.loading = "lazy";
+ img.loading = 'lazy';
img.className = 'cm-preview';
img.src = this.url;
-
img.onerror = ()=>{
img.src = 'client/icons/broken-image.jpg';
@@ -403,8 +402,8 @@ export function customHighlightPlugin(renderer, tab) {
const url = getUrl(node, view.state.doc);
const widgetPosition = node.node.lastChild.from;
- //this is not exactly standard, but should hold,
- //and is the shortest way i could find of positioning
+ //this is not exactly standard, but should hold,
+ //and is the shortest way i could find of positioning
//the image inside the cm-image node
if(!url) return;
diff --git a/client/components/codeEditor/extensions/customKeyMaps.js b/client/components/codeEditor/extensions/customKeyMaps.js
index 581268222..974b0b1e2 100644
--- a/client/components/codeEditor/extensions/customKeyMaps.js
+++ b/client/components/codeEditor/extensions/customKeyMaps.js
@@ -3,7 +3,60 @@ import { keymap } from '@codemirror/view';
import { undo, redo, indentMore, indentLess, deleteLine } from '@codemirror/commands';
import { EditorSelection } from '@codemirror/state';
import { Prec } from '@codemirror/state';
+import * as prettier from 'prettier/standalone';
+import * as postcssPlugin from 'prettier/plugins/postcss';
+export async function formatCSS(view) {
+ try {
+ const { from, to, empty } = view.state.selection.main;
+ const fullDoc = view.state.doc.toString();
+ const selection = view.state.doc.sliceString(from, to);
+ const code = empty ? fullDoc : selection;
+
+ let formatted = await prettier.format(code, {
+ parser: 'css',
+ plugins: [postcssPlugin],
+
+ // formatting options
+ tabWidth: 2,
+ useTabs: false,
+ printWidth: 100,
+ singleQuote: false,
+ trailingComma: 'all',
+ bracketSpacing: true,
+ endOfLine: 'lf'
+ });
+
+ //format manually single declaration rules to span one line.
+ //Prettier can't do it by default, this is crude but it works
+ formatted = formatted.replace(
+ /([^{]+)\{\s*\n\s*([^;\n]+:[^;\n]+;)\s*\n\s*\}(\s*)/g,
+ (_, selector, decl, whitespace) =>
+ `${selector} { ${decl.trim()} }${whitespace}`
+ );
+ if(formatted === code) return true;
+
+ const dom = view.dom;
+ dom.classList.add('cm-flash');
+
+ setTimeout(()=>{
+ dom.classList.remove('cm-flash');
+
+ view.dispatch({
+ changes : {
+ from : empty ? 0 : from,
+ to : empty ? view.state.doc.length : to,
+ insert : formatted
+ }
+ });
+
+ }, 500);
+ } catch (err) {
+ console.error('Error formatting css: ', err);
+ }
+
+ return true;
+}
const insertTab = (view)=>{
// If any selection spans multiple lines, delegates to CodeMirror's indentMore
// Otherwise inserts two spaces at each cursor/selection
@@ -188,6 +241,11 @@ export const generalKeymap = Prec.high(keymap.of([
{ key: 'Mod-d', run: deleteLine }, //annoyingly overrides "selectNextOccurrence" because users asked
]));
+export const cssKeymap = Prec.highest(keymap.of([
+ { key: 'Mod-Shift-f', run: formatCSS },
+ { key: 'Alt-Shift-f', run: formatCSS },
+]));
+
export const markdownKeymap = Prec.highest(keymap.of([
{ key: 'Mod-b', run: wrapSelection('**', '**') }, // makeBold
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
tags -renderer.paragraph = function(token){ - let match; - const text = this.parser.parseInline(token.tokens); - if(text.startsWith('
Bold text
\nParagraph
'); }); 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('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\nDefinition 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(`
`); }); 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(`
text
Line 1
\n\n\nLine 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(`text
{{}}
`); }); @@ -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(`Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Sample text.
Text and text and more text!
\nemphasis
'); }); 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

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(`


text
text
text
text
text
text
text
text
text
text
| Experience Points | Level |
|---|---|
| 0 | 1 |
| 300 | 2 |
{secondInjection}
'); }); @@ -487,7 +487,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ {innerDiv} }} {outerDiv}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('outer text
inner text
Hello
`); }); test('Right Justify', function() { const source = '-: Hello'; - const rendered = Markdown.render(source); + const rendered = hbfm.render(source); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Hello
`); }); test('Center Justify', function() { const source = ':-: Hello'; - const rendered = Markdown.render(source); + const rendered = hbfm.render(source); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`Hello
`); }); test('Ignored inside a code block', function() { const source = '```\n\n:- Hello\n\n```\n'; - const rendered = Markdown.render(source); + const rendered = hbfm.render(source); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`\n:- Hello\n\n`);
});
});
diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js
index 180839a78..d9da1be07 100644
--- a/tests/markdown/variables.test.js
+++ b/tests/markdown/variables.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.
@@ -12,7 +12,7 @@ String.prototype.trimReturns = function(){
const renderAllPages = function(pages){
const outputs = [];
pages.forEach((page, index)=>{
- const output = Markdown.render(page, index);
+ const output = hbfm.render(page, index);
outputs.push(output);
});
@@ -29,7 +29,7 @@ describe('Block-level variables', ()=>{
$[var]
`;
- const rendered = Markdown.render(source).trimReturns();
+ const rendered = hbfm.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('string
'); }); @@ -40,7 +40,7 @@ describe('Block-level variables', ()=>{ lines $[var]`; - const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns(); + const rendered = hbfm.render(source).replace(/\s/g, ' ').trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('string across multiple lines
'); }); @@ -54,7 +54,7 @@ describe('Block-level variables', ()=>{ | C | D | $[var]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(dedent`| H1 | @@ -71,7 +71,7 @@ describe('Block-level variables', ()=>{ $[var] [var]: string`; - const rendered = Markdown.render(source).replace(/\s/g, ' ').trimReturns(); + const rendered = hbfm.render(source).replace(/\s/g, ' ').trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
|---|
| title 1 | title 2 | title 3 | title 4 |
|---|---|---|---|
| foo | Ipsum | ) | ) |




Positive: +
Negative: -
'); }); it('Signed Test', function() { const source = `[a]: 13\n\n[b]: -11\n\nPositive: $[signed(a)]\n\nNegative: $[signed(b)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Positive: +13
Negative: -11
'); }); it('Roman Numerals Test', function() { const source = `[a]: 18\n\nRoman Numeral: $[toRomans(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Roman Numeral: XVIII
'); }); it('Roman Numerals Test - Uppercase', function() { const source = `[a]: 18\n\nRoman Numeral: $[toRomansUpper(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Roman Numeral: XVIII
'); }); it('Roman Numerals Test - Lowercase', function() { const source = `[a]: 18\n\nRoman Numeral: $[toRomansLower(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Roman Numeral: xviii
'); }); it('Number to Characters Test', function() { const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toChar(a)] $[toChar(b)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Characters: R AM
'); }); it('Number to Characters Test - Uppercase', function() { const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharUpper(a)] $[toCharUpper(b)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Characters: R AM
'); }); it('Number to Characters Test - Lowercase', function() { const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharLower(a)] $[toCharLower(b)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Characters: r am
'); }); it('Number to Words Test', function() { const source = `[a]: 80085\n\nWords: $[toWords(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Words: eighty thousand and eighty-five
'); }); it('Number to Words Test - Uppercase', function() { const source = `[a]: 80085\n\nWords: $[toWordsUpper(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Words: EIGHTY THOUSAND AND EIGHTY-FIVE
'); }); it('Number to Words Test - Lowercase', function() { const source = `[a]: 80085\n\nWords: $[toWordsLower(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Words: eighty thousand and eighty-five
'); }); it('Number to Words Test - Capitalized', function() { const source = `[a]: 80085\n\nWords: $[toWordsCaps(a)]`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = hbfm.render(source).trimReturns(); expect(rendered).toBe('Words: Eighty Thousand And Eighty-Five
'); }); }); \ No newline at end of file diff --git a/themes/V3/Blank/snippets/footer.gen.js b/themes/V3/Blank/snippets/footer.gen.js index 596592629..7085f6492 100644 --- a/themes/V3/Blank/snippets/footer.gen.js +++ b/themes/V3/Blank/snippets/footer.gen.js @@ -1,4 +1,4 @@ -import Markdown from '@shared/markdown.js'; +import hbfm from 'hbmarkedwrapper'; export default { createFooterFunc : function(headerSize=1){