mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-24 14:13:02 +00:00
Compare commits
23 Commits
Add-missin
...
toWellForm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8eedcf6d6 | ||
|
|
92d1238a46 | ||
|
|
dceb5e516b | ||
|
|
adb1db1d3c | ||
|
|
e8d1e632b4 | ||
|
|
50fcffb253 | ||
|
|
aae5367ad2 | ||
|
|
40b0c1ce3a | ||
|
|
ba83dfacd9 | ||
|
|
2717e6a9a4 | ||
|
|
d576bddd32 | ||
|
|
ed8c4d0eef | ||
|
|
6e9d293bbe | ||
|
|
7e1312805f | ||
|
|
d629fa1731 | ||
|
|
6301a66fd3 | ||
|
|
912f9f0cf6 | ||
|
|
c63b6ffaf0 | ||
|
|
0c90d1a14d | ||
|
|
abd52f93d8 | ||
|
|
596c4ad68d | ||
|
|
e7f4611a00 | ||
|
|
b45686eb3b |
@@ -70,6 +70,9 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Test - Hard Breaks
|
name: Test - Hard Breaks
|
||||||
command: npm run test:hard-breaks
|
command: npm run test:hard-breaks
|
||||||
|
- run:
|
||||||
|
name: Test - Non-Breaking Spaces
|
||||||
|
command: npm run test:non-breaking-spaces
|
||||||
- run:
|
- run:
|
||||||
name: Test - Variables
|
name: Test - Variables
|
||||||
command: npm run test:variables
|
command: npm run test:variables
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
//╔===--------------- Polyfills --------------===╗//
|
||||||
|
import 'core-js/es/string/to-well-formed.js';
|
||||||
|
//╚===--------------- ---------------===╝//
|
||||||
|
|
||||||
require('./homebrew.less');
|
require('./homebrew.less');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const createClass = require('create-react-class');
|
const createClass = require('create-react-class');
|
||||||
|
|||||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -19,6 +19,7 @@
|
|||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"codemirror": "^5.65.6",
|
"codemirror": "^5.65.6",
|
||||||
"cookie-parser": "^1.4.7",
|
"cookie-parser": "^1.4.7",
|
||||||
|
"core-js": "^3.39.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"create-react-class": "^15.7.0",
|
"create-react-class": "^15.7.0",
|
||||||
"dedent-tabs": "^0.10.3",
|
"dedent-tabs": "^0.10.3",
|
||||||
@@ -40,7 +41,7 @@
|
|||||||
"marked-smartypants-lite": "^1.0.2",
|
"marked-smartypants-lite": "^1.0.2",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"mongoose": "^8.9.1",
|
"mongoose": "^8.9.2",
|
||||||
"nanoid": "5.0.9",
|
"nanoid": "5.0.9",
|
||||||
"nconf": "^0.12.1",
|
"nconf": "^0.12.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
"@stylistic/stylelint-plugin": "^3.1.1",
|
"@stylistic/stylelint-plugin": "^3.1.1",
|
||||||
"babel-plugin-transform-import-meta": "^2.2.1",
|
"babel-plugin-transform-import-meta": "^2.2.1",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.17.0",
|
||||||
"eslint-plugin-jest": "^28.9.0",
|
"eslint-plugin-jest": "^28.10.0",
|
||||||
"eslint-plugin-react": "^7.37.2",
|
"eslint-plugin-react": "^7.37.2",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
@@ -4598,6 +4599,17 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/core-js": {
|
||||||
|
"version": "3.39.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz",
|
||||||
|
"integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/core-js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/core-js-compat": {
|
"node_modules/core-js-compat": {
|
||||||
"version": "3.38.1",
|
"version": "3.38.1",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
|
||||||
@@ -5618,9 +5630,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jest": {
|
"node_modules/eslint-plugin-jest": {
|
||||||
"version": "28.9.0",
|
"version": "28.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.10.0.tgz",
|
||||||
"integrity": "sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ==",
|
"integrity": "sha512-hyMWUxkBH99HpXT3p8hc7REbEZK3D+nk8vHXGgpB+XXsi0gO4PxMSP+pjfUzb67GnV9yawV9a53eUmcde1CCZA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
@@ -10126,9 +10138,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mongoose": {
|
"node_modules/mongoose": {
|
||||||
"version": "8.9.1",
|
"version": "8.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.2.tgz",
|
||||||
"integrity": "sha512-whM6lWMdeKlUm4d2LSLS/q6cWtTp13lUrL5hy2YTsQdTSN+dsAu8HLdLUQOEgtBE59qp4IqLrjSXCSETbxhkQQ==",
|
"integrity": "sha512-mLWynmZS1v8HTeMxyLhskQncS1SkrjW1eLNuFDYGQMQ/5QrFrxTLNwWXeCRZeKT2lXyaxW8bnJC9AKPT9jYMkw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bson": "^6.10.1",
|
"bson": "^6.10.1",
|
||||||
"kareem": "2.6.3",
|
"kareem": "2.6.3",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"test:mustache-syntax:injection": "jest \".*(mustache-syntax).*\" -t '^Injection:.*' --verbose --noStackTrace",
|
"test:mustache-syntax:injection": "jest \".*(mustache-syntax).*\" -t '^Injection:.*' --verbose --noStackTrace",
|
||||||
"test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace",
|
"test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace",
|
||||||
"test:hard-breaks": "jest tests/markdown/hard-breaks.test.js --verbose --noStackTrace",
|
"test:hard-breaks": "jest tests/markdown/hard-breaks.test.js --verbose --noStackTrace",
|
||||||
|
"test:non-breaking-spaces": "jest tests/markdown/non-breaking-spaces.test.js --verbose --noStackTrace",
|
||||||
"test:emojis": "jest tests/markdown/emojis.test.js --verbose --noStackTrace",
|
"test:emojis": "jest tests/markdown/emojis.test.js --verbose --noStackTrace",
|
||||||
"test:route": "jest tests/routes/static-pages.test.js --verbose",
|
"test:route": "jest tests/routes/static-pages.test.js --verbose",
|
||||||
"test:safehtml": "jest tests/html/safeHTML.test.js --verbose",
|
"test:safehtml": "jest tests/html/safeHTML.test.js --verbose",
|
||||||
@@ -92,6 +93,7 @@
|
|||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"codemirror": "^5.65.6",
|
"codemirror": "^5.65.6",
|
||||||
"cookie-parser": "^1.4.7",
|
"cookie-parser": "^1.4.7",
|
||||||
|
"core-js": "^3.39.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"create-react-class": "^15.7.0",
|
"create-react-class": "^15.7.0",
|
||||||
"dedent-tabs": "^0.10.3",
|
"dedent-tabs": "^0.10.3",
|
||||||
@@ -113,7 +115,7 @@
|
|||||||
"marked-smartypants-lite": "^1.0.2",
|
"marked-smartypants-lite": "^1.0.2",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"mongoose": "^8.9.1",
|
"mongoose": "^8.9.2",
|
||||||
"nanoid": "5.0.9",
|
"nanoid": "5.0.9",
|
||||||
"nconf": "^0.12.1",
|
"nconf": "^0.12.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -128,7 +130,7 @@
|
|||||||
"@stylistic/stylelint-plugin": "^3.1.1",
|
"@stylistic/stylelint-plugin": "^3.1.1",
|
||||||
"babel-plugin-transform-import-meta": "^2.2.1",
|
"babel-plugin-transform-import-meta": "^2.2.1",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.17.0",
|
||||||
"eslint-plugin-jest": "^28.9.0",
|
"eslint-plugin-jest": "^28.10.0",
|
||||||
"eslint-plugin-react": "^7.37.2",
|
"eslint-plugin-react": "^7.37.2",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ const { pack, watchFile, livereload } = vitreum;
|
|||||||
import lessTransform from 'vitreum/transforms/less.js';
|
import lessTransform from 'vitreum/transforms/less.js';
|
||||||
import assetTransform from 'vitreum/transforms/asset.js';
|
import assetTransform from 'vitreum/transforms/asset.js';
|
||||||
import babel from '@babel/core';
|
import babel from '@babel/core';
|
||||||
|
import babelConfig from '../babel.config.json' with { type : 'json' };
|
||||||
import less from 'less';
|
import less from 'less';
|
||||||
|
|
||||||
const isDev = !!process.argv.find((arg) => arg === '--dev');
|
const isDev = !!process.argv.find((arg) => arg === '--dev');
|
||||||
|
|
||||||
const babelify = async (code)=>(await babel.transformAsync(code, { presets: [['@babel/preset-env', { 'exclude': ['proposal-dynamic-import'] }], '@babel/preset-react'], plugins: ['@babel/plugin-transform-runtime'] })).code;
|
const babelify = async (code)=>(await babel.transformAsync(code, babelConfig)).code;
|
||||||
|
|
||||||
const transforms = {
|
const transforms = {
|
||||||
'.js' : (code, filename, opts)=>babelify(code),
|
'.js' : (code, filename, opts)=>babelify(code),
|
||||||
|
|||||||
@@ -391,10 +391,31 @@ const forcedParagraphBreaks = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const nonbreakingSpaces = {
|
||||||
|
name : 'nonbreakingSpaces',
|
||||||
|
level : 'inline',
|
||||||
|
start(src) { return src.match(/:>+/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
||||||
|
tokenizer(src, tokens) {
|
||||||
|
const regex = /:(>+)/ym;
|
||||||
|
const match = regex.exec(src);
|
||||||
|
if(match?.length) {
|
||||||
|
return {
|
||||||
|
type : 'nonbreakingSpaces', // Should match "name" above
|
||||||
|
raw : match[0], // Text to consume from the source
|
||||||
|
length : match[1].length,
|
||||||
|
text : ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderer(token) {
|
||||||
|
return ` `.repeat(token.length).concat('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const definitionListsSingleLine = {
|
const definitionListsSingleLine = {
|
||||||
name : 'definitionListsSingleLine',
|
name : 'definitionListsSingleLine',
|
||||||
level : 'block',
|
level : 'block',
|
||||||
start(src) { return src.match(/\n[^\n]*?::[^\n]*/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
start(src) { return src.match(/\n[^\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]*)(?:\n|$)/ym;
|
||||||
let match;
|
let match;
|
||||||
@@ -748,11 +769,12 @@ const tableTerminators = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
Marked.use(MarkedVariables());
|
Marked.use(MarkedVariables());
|
||||||
Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, superSubScripts,
|
Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks,
|
||||||
mustacheSpans, mustacheDivs, mustacheInjectInline] });
|
nonbreakingSpaces, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] });
|
||||||
Marked.use(mustacheInjectBlock);
|
Marked.use(mustacheInjectBlock);
|
||||||
Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
|
Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
|
||||||
Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
|
Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }),
|
||||||
|
MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
|
||||||
|
|
||||||
function cleanUrl(href) {
|
function cleanUrl(href) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
72
tests/markdown/non-breaking-spaces.test.js
Normal file
72
tests/markdown/non-breaking-spaces.test.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* eslint-disable max-lines */
|
||||||
|
|
||||||
|
import Markdown from 'naturalcrit/markdown.js';
|
||||||
|
|
||||||
|
describe('Non-Breaking Spaces', ()=>{
|
||||||
|
test('Single Space', function() {
|
||||||
|
const source = ':>\n\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Double Space', function() {
|
||||||
|
const source = ':>>\n\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Triple Space', function() {
|
||||||
|
const source = ':>>>\n\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Many Space', function() {
|
||||||
|
const source = ':>>>>>>>>>>\n\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Multiple sets of Spaces', function() {
|
||||||
|
const source = ':>>>\n:>>>\n:>>>';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> \n \n </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Pair of inline Spaces', function() {
|
||||||
|
const source = ':>>:>>';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p> </p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Space directly between two paragraphs', function() {
|
||||||
|
const source = 'Line 1\n:>>\nLine 2';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>Line 1\n \nLine 2</p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Ignored inside a code block', function() {
|
||||||
|
const source = '```\n\n:>\n\n```\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<pre><code>\n:>\n</code></pre>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('I am actually a single-line definition list!', function() {
|
||||||
|
const source = 'Term ::> Definition 1\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<dl><dt>Term</dt><dd>> Definition 1</dd>\n</dl>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('I am actually a definition list!', function() {
|
||||||
|
const source = 'Term\n::> Definition 1\n';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<dl><dt>Term</dt>\n<dd>> Definition 1</dd></dl>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('I am actually a two-term definition list!', function() {
|
||||||
|
const source = 'Term\n::> Definition 1\n::>> Definition 2';
|
||||||
|
const rendered = Markdown.render(source).trim();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<dl><dt>Term</dt>\n<dd>> Definition 1</dd>\n<dd>>> Definition 2</dd></dl>`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Reference in New Issue
Block a user