Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPG Awesome Redux #3420

Merged
merged 21 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"test:mustache-syntax:inline": "jest '.*(mustache-syntax).*' -t '^Inline:.*' --verbose --noStackTrace",
"test:mustache-syntax:block": "jest '.*(mustache-syntax).*' -t '^Block:.*' --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:route": "jest tests/routes/static-pages.test.js --verbose",
"phb": "node scripts/phb.js",
"prod": "set NODE_ENV=production && npm run build",
Expand Down Expand Up @@ -102,6 +102,7 @@
"less": "^3.13.1",
"lodash": "^4.17.21",
"marked": "11.2.0",
"marked-emoji": "^1.4.0",
"marked-extended-tables": "^1.0.8",
"marked-gfm-heading-id": "^3.1.3",
"marked-smartypants-lite": "^1.0.2",
Expand Down
1 change: 1 addition & 0 deletions scripts/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"codemirror/addon/edit/closetag.js",
"codemirror/addon/edit/trailingspace.js",
"codemirror/addon/selection/active-line.js",
"codemirror/addon/hint/show-hint.js",
"moment",
"superagent"
]
Expand Down
75 changes: 75 additions & 0 deletions shared/naturalcrit/codeEditor/autocomplete-emoji.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const diceFont = require('../../../themes/fonts/icon fonts/diceFont.js');
const elderberryInn = require('../../../themes/fonts/icon fonts/elderberryInn.js');
const raRedux = require('../../../themes/fonts/icon fonts/raRedux.js');

const emojis = {
...diceFont,
...elderberryInn,
...raRedux,
"fas-heart": "fa-solid fa-heart",
"fas-star": "fa-solid fa-star"
};

const showEmojiAutocomplete = function(CodeMirror, editor) {
CodeMirror.commands.autocomplete = function(editor) {
editor.showHint({
completeSingle: false,
hint: function(editor) {
const cursor = editor.getCursor();
const line = cursor.line;
const lineContent = editor.getLine(line);
const start = lineContent.lastIndexOf(':', cursor.ch - 1) + 1;
const end = cursor.ch;
const currentWord = lineContent.slice(start, end);


const list = Object.keys(emojis).filter(function(emoji) {
return emoji.toLowerCase().indexOf(currentWord.toLowerCase()) >= 0;
}).sort((a, b) => {
const lowerA = a.replace(/\d+/g, function(match) { // Temporarily convert any numbers in emoji string
return match.padStart(4, '0'); // to 4-digits, left-padded with 0's, to aid in
}).toLowerCase(); // sorting numbers, i.e., "d6, d10, d20", not "d10, d20, d6"
const lowerB = b.replace(/\d+/g, function(match) { // Also make lowercase for case-insensitive alpha sorting
return match.padStart(4, '0');
}).toLowerCase();

if (lowerA < lowerB)
return -1;
return 1;
}).map(function(emoji) {
return {
text: emoji + ":", // Text to output to editor when option is selected
render: function(element, self, data) { // How to display the option in the dropdown
const div = document.createElement('div');
div.innerHTML = `<i class="emojiPreview ${emojis[emoji]}"></i> ${emoji}`;
element.appendChild(div);
}
};
});

return {
list: list.length ? list : [],
from: CodeMirror.Pos(line, start),
to: CodeMirror.Pos(line, end)
};
}
});
};

editor.on('inputRead', function(instance, change) {
const cursor = editor.getCursor();
const line = editor.getLine(cursor.line);

// Get the text from the start of the line to the cursor
const textToCursor = line.slice(0, cursor.ch);

// Check if the text ends with ':xyz'
if (/:[^\s:]+$/.test(textToCursor)) {
CodeMirror.commands.autocomplete(editor);
}
});
}

module.exports = {
showEmojiAutocomplete
};
6 changes: 6 additions & 0 deletions shared/naturalcrit/codeEditor/codeEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
const closeTag = require('./close-tag');
const autoCompleteEmojis = require('./autocomplete-emoji');

let CodeMirror;
if(typeof window !== 'undefined'){
Expand Down Expand Up @@ -36,6 +37,8 @@ if(typeof window !== 'undefined'){
//XML code folding is a requirement of the auto-closing tag feature and is not enabled
require('codemirror/addon/fold/xml-fold.js');
require('codemirror/addon/edit/closetag.js');
//Autocompletion
require('codemirror/addon/hint/show-hint.js');

const foldCode = require('./fold-code');
foldCode.registerHomebreweryHelper(CodeMirror);
Expand Down Expand Up @@ -177,7 +180,10 @@ const CodeEditor = createClass({
// return el;
// }
});

// Add custom behaviors (auto-close curlies and auto-complete emojis)
closeTag.autoCloseCurlyBraces(CodeMirror, this.codeMirror);
autoCompleteEmojis.showEmojiAutocomplete(CodeMirror, this.codeMirror);

// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue());});
Expand Down
12 changes: 12 additions & 0 deletions shared/naturalcrit/codeEditor/codeEditor.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
@import (less) 'codemirror/addon/fold/foldgutter.css';
@import (less) 'codemirror/addon/search/matchesonscrollbar.css';
@import (less) 'codemirror/addon/dialog/dialog.css';
@import (less) 'codemirror/addon/hint/show-hint.css';

//Icon fonts included so they can appear in emoji autosuggest dropdown
@import (less) './themes/fonts/icon fonts/diceFont.less';
@import (less) './themes/fonts/icon fonts/elderberryInn.less';
@import (less) './themes/fonts/icon fonts/raRedux.less';

@keyframes sourceMoveAnimation {
50% {background-color: red; color: white;}
Expand Down Expand Up @@ -34,6 +40,7 @@
}
}


//.cm-tab {
// background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAQAAACOs/baAAAARUlEQVR4nGJgIAG8JkXxUAcCtDWemcGR1lY4MvgzCEKY7jSBjgxBDAG09UEQzAe0AMwMHrSOAwEGRtpaMIwAAAAA//8DAG4ID9EKs6YqAAAAAElFTkSuQmCC) no-repeat right;
//}
Expand All @@ -44,3 +51,8 @@
// }
//}
}

.emojiPreview {
font-size: 1.5em;
line-height: 1.2em;
}
38 changes: 33 additions & 5 deletions shared/naturalcrit/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ const Marked = require('marked');
const MarkedExtendedTables = require('marked-extended-tables');
const { markedSmartypantsLite: MarkedSmartypantsLite } = require('marked-smartypants-lite');
const { gfmHeadingId: MarkedGFMHeadingId } = require('marked-gfm-heading-id');
const { markedEmoji: MarkedEmojis} = require('marked-emoji');

//Icon fonts included so they can appear in emoji autosuggest dropdown
const diceFont = require('../../themes/fonts/icon fonts/diceFont.js');
const elderberryInn = require('../../themes/fonts/icon fonts/elderberryInn.js');
const raRedux = require('../../themes/fonts/icon fonts/raRedux.js');

const MathParser = require('expr-eval').Parser;
const renderer = new Marked.Renderer();
const tokenizer = new Marked.Tokenizer();
Expand Down Expand Up @@ -304,10 +311,19 @@ const definitionListsSingleLine = {
let endIndex = 0;
const definitions = [];
while (match = regex.exec(src)) {
definitions.push({
dt : this.lexer.inlineTokens(match[1].trim()),
dd : this.lexer.inlineTokens(match[2].trim())
});
let originalLine = match[0]; // This line and below to handle conflict with emojis
let firstLine = originalLine; // Remove in V4 when definitionListsInline updated to
this.lexer.inlineTokens(firstLine.trim()) // require spaces around `::`
.filter(t => t.type == 'emoji')
.map(emoji => firstLine = firstLine.replace(emoji.raw, 'x'.repeat(emoji.raw.length)));

let newMatch = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym.exec(firstLine);
if(newMatch) {
definitions.push({
dt : this.lexer.inlineTokens(originalLine.slice(0, newMatch[1].length).trim()),
dd : this.lexer.inlineTokens(originalLine.slice(newMatch[1].length + 2).trim())
});
} // End of emoji hack.
endIndex = regex.lastIndex;
}
if(definitions.length) {
Expand Down Expand Up @@ -616,11 +632,23 @@ function MarkedVariables() {
};
//^=====--------------------< Variable Handling >-------------------=====^//

// Emoji options
const MarkedEmojiOptions = {
emojis: {
...diceFont,
...elderberryInn,
...raRedux,
"fas-heart": "fa-solid fa-heart",
"fas-star": "fa-solid fa-star"
},
renderer: (token) => `<i class="${token.emoji}"></i>`
};

Marked.use(MarkedVariables());
Marked.use({ extensions: [definitionListsMultiLine, definitionListsSingleLine, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] });
Marked.use(mustacheInjectBlock);
Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
Marked.use(MarkedExtendedTables(), MarkedGFMHeadingId(), MarkedSmartypantsLite());
Marked.use(MarkedExtendedTables(), MarkedGFMHeadingId(), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));

const nonWordAndColonTest = /[^\w:]/g;
const cleanUrl = function (sanitize, base, href) {
Expand Down
2 changes: 1 addition & 1 deletion themes/V3/5ePHB/style.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import (less) './themes/assets/assets.less';
@import (less) './themes/fonts/icon fonts/font-icons.less';
@import (less) './themes/fonts/icon fonts/elderberryInn.less';
@import (less) './themes/fonts/icon fonts/diceFont.less';

:root {
Expand Down
96 changes: 96 additions & 0 deletions themes/fonts/icon fonts/diceFont.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const diceFont = {
"df-F" : "df F",
"df-F-minus" : "df F-minus",
"df-F-plus" : "df F-plus",
"df-F-zero" : "df F-zero",
"df-d10" : "df d10",
"df-d10-1" : "df d10-1",
"df-d10-10" : "df d10-10",
"df-d10-2" : "df d10-2",
"df-d10-3" : "df d10-3",
"df-d10-4" : "df d10-4",
"df-d10-5" : "df d10-5",
"df-d10-6" : "df d10-6",
"df-d10-7" : "df d10-7",
"df-d10-8" : "df d10-8",
"df-d10-9" : "df d10-9",
"df-d12" : "df d12",
"df-d12-1" : "df d12-1",
"df-d12-10" : "df d12-10",
"df-d12-11" : "df d12-11",
"df-d12-12" : "df d12-12",
"df-d12-2" : "df d12-2",
"df-d12-3" : "df d12-3",
"df-d12-4" : "df d12-4",
"df-d12-5" : "df d12-5",
"df-d12-6" : "df d12-6",
"df-d12-7" : "df d12-7",
"df-d12-8" : "df d12-8",
"df-d12-9" : "df d12-9",
"df-d2" : "df d2",
"df-d2-1" : "df d2-1",
"df-d2-2" : "df d2-2",
"df-d20" : "df d20",
"df-d20-1" : "df d20-1",
"df-d20-10" : "df d20-10",
"df-d20-11" : "df d20-11",
"df-d20-12" : "df d20-12",
"df-d20-13" : "df d20-13",
"df-d20-14" : "df d20-14",
"df-d20-15" : "df d20-15",
"df-d20-16" : "df d20-16",
"df-d20-17" : "df d20-17",
"df-d20-18" : "df d20-18",
"df-d20-19" : "df d20-19",
"df-d20-2" : "df d20-2",
"df-d20-20" : "df d20-20",
"df-d20-3" : "df d20-3",
"df-d20-4" : "df d20-4",
"df-d20-5" : "df d20-5",
"df-d20-6" : "df d20-6",
"df-d20-7" : "df d20-7",
"df-d20-8" : "df d20-8",
"df-d20-9" : "df d20-9",
"df-d4" : "df d4",
"df-d4-1" : "df d4-1",
"df-d4-2" : "df d4-2",
"df-d4-3" : "df d4-3",
"df-d4-4" : "df d4-4",
"df-d6" : "df d6",
"df-d6-1" : "df d6-1",
"df-d6-2" : "df d6-2",
"df-d6-3" : "df d6-3",
"df-d6-4" : "df d6-4",
"df-d6-5" : "df d6-5",
"df-d6-6" : "df d6-6",
"df-d8" : "df d8",
"df-d8-1" : "df d8-1",
"df-d8-2" : "df d8-2",
"df-d8-3" : "df d8-3",
"df-d8-4" : "df d8-4",
"df-d8-5" : "df d8-5",
"df-d8-6" : "df d8-6",
"df-d8-7" : "df d8-7",
"df-d8-8" : "df d8-8",
"df-dot-d6" : "df dot-d6",
"df-dot-d6-1" : "df dot-d6-1",
"df-dot-d6-2" : "df dot-d6-2",
"df-dot-d6-3" : "df dot-d6-3",
"df-dot-d6-4" : "df dot-d6-4",
"df-dot-d6-5" : "df dot-d6-5",
"df-dot-d6-6" : "df dot-d6-6",
"df-small-dot-d6-1" : "df small-dot-d6-1",
"df-small-dot-d6-2" : "df small-dot-d6-2",
"df-small-dot-d6-3" : "df small-dot-d6-3",
"df-small-dot-d6-4" : "df small-dot-d6-4",
"df-small-dot-d6-5" : "df small-dot-d6-5",
"df-small-dot-d6-6" : "df small-dot-d6-6",
"df-solid-small-dot-d6-1" : "df solid-small-dot-d6-1",
"df-solid-small-dot-d6-2" : "df solid-small-dot-d6-2",
"df-solid-small-dot-d6-3" : "df solid-small-dot-d6-3",
"df-solid-small-dot-d6-4" : "df solid-small-dot-d6-4",
"df-solid-small-dot-d6-5" : "df solid-small-dot-d6-5",
"df-solid-small-dot-d6-6" : "df solid-small-dot-d6-6"
}

module.exports = diceFont;
Loading